Home
Reading
Searching
Subscribe
Sponsors
Statistics
Posting
Contact
Spam
Lists
Links
About
Hosting
Filtering
Features Download
Marketing
Archives
FAQ
Blog
 
Gmane
From: Amit K. Arora <aarora <at> linux.vnet.ibm.com>
Subject: [PATCH 0/5][TAKE8] fallocate system call
Newsgroups: gmane.comp.file-systems.ext4
Date: Friday 13th July 2007 18:41:25 UTC (over 10 years ago)
This is the latest fallocate patchset and is based on 2.6.22.

* Following are the changes from TAKE7:
1) Updated the man page.
2) Merged "revalidate write permissions" patch with the main falloc patch.
3) Added linux/falloc.h and moved FALLOC_FL_KEEP_SIZE flag to it.
   Also removed the two modes (FALLOC_ALLOCATE and FALLOC_RESV_SPACE).
4) Removed comment above sys_fallocate definition.
5) Updated the testcase below to use FALLOC_FL_KEEP_SIZE flag instead
   of previous two modes.

* Following are the changes from TAKE6:
1) We now just have two modes (and no deallocation modes).
2) Updated the man page
3) Added a new patch submitted by David P. Quigley  (Patch 3/6).
4) Used EXT_INIT_MAX_LEN instead of 0x8000 in Patch 6/6.
4) Included below in the end is a small testcase to test fallocate.


* Following are the changes from TAKE5 to TAKE6:
1) Rebased to 2.6.22
2) Added compat wrapper for x86_64
3) Dropped s390 and ia64 patches, since the platform maintaners can
   add the support for fallocate once it is in mainline.
4) Added a change suggested by Andreas for better extent-to-group
   alignment in ext4 (Patch 6/6). Please refer following post:
http:[email protected]/msg02445.html
5) Renamed mode flags and values from "FA_" to "FALLOC_"
6) Added manpage (updated version of the one initially submitted by
   David Chinner).


Todos:
-----
1> Implementation on other architectures (other than i386, x86_64,
   and ppc64). s390(x) and ia64 patches are ready and will be pushed
   by platform maintaners when the fallocate is in mainline.
2> A generic file system operation to handle fallocate
   (generic_fallocate), for filesystems that do _not_ have the fallocate
   inode operation implemented.
3> Changes to glibc,
   a) to support fallocate() system call
   b) to make posix_fallocate() and posix_fallocate64() call fallocate()
4> Patch to e2fsprogs to recognize and display uninitialized extents.


Following patches follow:
Patch 1/5 : manpage for fallocate
Patch 2/5 : fallocate() implementation in i386, x86_64 and powerpc
Patch 3/5 : ext4: fallocate support in ext4
Patch 4/5 : ext4: write support for preallocated blocks
Patch 5/5 : ext4: change for better extent-to-group alignment

**
Attached below is a small testcase to test fallocate. The __NR_fallocate
will
need to be changed depending on the system call number in the kernel (it
may
get changed due to merge) and also depending on the architecture.

--
Regards,
Amit Arora



#include 
#include 
#include 
#include 

#include 
#include 
#include 

#define VERBOSE 0

#define __NR_fallocate                324

#define FALLOC_FL_KEEP_SIZE	0x01

int do_fallocate(int fd, int mode, loff_t offset, loff_t len)
{
  int ret;

  if (VERBOSE)
  	printf("Trying to preallocate blocks (offset=%llu, len=%llu)\n",
		offset, len);
  ret = syscall(__NR_fallocate, fd, mode, offset, len);

  if (ret <0) {
        printf("SYSCALL: received error %d, ret=%d\n", errno, ret);
        close(fd);
        return(1);
  }

  if (VERBOSE)
  	printf("fallocate system call succedded !  ret=%d\n", ret);

  return ret;
}

int test_fallocate(int fd, int mode, loff_t offset, loff_t len)
{
  int ret, blocks;
  struct stat statbuf1, statbuf2;

  fstat(fd, &statbuf1);

  ret = do_fallocate(fd, mode, offset, len);

  fstat(fd, &statbuf2);

  /* check file size after preallocation */
  if (!mode) {
  	if (!ret && statbuf1.st_size < (offset + len) &&
	    statbuf2.st_size != (offset + len)) {
		printf("Error: fallocate succeeded, but the file size did not "
			"change, where it should have!\n");
		ret = 1;
	}
  } else if (statbuf1.st_size != statbuf2.st_size) {
	printf("Error : File size changed, when it should not have!\n");
	ret = 1;
  }

  blocks = ((statbuf2.st_blocks - statbuf1.st_blocks) * 512)/
statbuf2.st_blksize;

  /* Print report */
  printf("# FALLOCATE TEST REPORT #\n");
  printf("\tNew blocks preallocated = %d.\n", blocks);
  printf("\tNumber of bytes preallocated = %d\n", blocks *
statbuf2.st_blksize);
  printf("\tOld file size = %d, New file size %d.\n",
	  statbuf1.st_size, statbuf2.st_size);
  printf("\tOld num blocks = %d, New num blocks %d.\n",
	  (statbuf1.st_blocks * 512)/1024, (statbuf2.st_blocks * 512)/1024);

  return ret;
}


int do_write(int fd, loff_t offset, loff_t len)
{
  int ret;
  char *buf;

  buf = (char *)malloc(len);
  if (!buf) {
	printf("error: malloc failed.\n");
	return(-1);
  }

  if (VERBOSE)
  	printf("Trying to write to file (offset=%llu, len=%llu)\n", 
		offset, len);

  ret = lseek(fd, offset, SEEK_SET);
  if (ret != offset) {
     	printf("lseek() failed error=%d, ret=%d\n", errno, ret);
  	close(fd); 
       	return(-1);
  }

  ret = write(fd, buf, len);
  if (ret != len) {
       	 printf("write() failed error=%d, ret=%d\n", errno, ret);
  		close(fd); 
       		return(-1);
  }

  if (VERBOSE)
  	printf("Write succedded ! Written %llu bytes ret=%d\n", len, ret);

  return ret;
}


int test_write(int fd, loff_t offset, loff_t len)
{
  int ret;

  ret = do_write(fd, offset, len);
  printf("# WRITE TEST REPORT #\n");
  if (ret > 0) printf("\t written %d bytes.\n", ret);
  else printf("\t write operation failed!\n");

  if (ret > 0) return 0;
  else return 1;
}

void usage(char **argv)
{
  printf("\n%s 
 
CD: 4ms