xfstests: random fallocate calls in fsx
RFC PATCH 1/1 xfstests: random fallocate calls in fsx
Seems to work for me. Any comments/suggestions?
I can probably make it fall back to the xfs ioctl if fallocate isn't supported, if strongly desired.
aclocal.m4 +11 -0
@@ -511,3 +511,14 @@ AC_DEFUN([AC_PACKAGE_NEED_XFSCTL_MACRO], ]) ]) +AC_DEFUN([AC_PACKAGE_WANT_FALLOCATE], + [ AC_MSG_CHECKING([for fallocate]) + AC_TRY_COMPILE([ +#include <linux/falloc.h> + ], [ + fallocate(0, 0, 0, 0); + ], have_fallocate=true + AC_MSG_RESULT(true), + AC_MSG_RESULT(false)) + AC_SUBST(have_fallocate) + ])
configure.in +1 -0
@@ -62,6 +62,7 @@ in AC_PACKAGE_WANT_GDBM AC_PACKAGE_WANT_AIO AC_PACKAGE_WANT_DMAPI + AC_PACKAGE_WANT_FALLOCATE ;; esac
include/builddefs.in +1 -0
@@ -56,6 +56,7 @@ RPM_VERSION = @rpm_version@ ENABLE_SHARED = @enable_shared@ HAVE_DB = @have_db@ HAVE_AIO = @have_aio@ +HAVE_FALLOCATE = @have_fallocate@ HAVE_DMAPI = @have_dmapi@ HAVE_ATTR_LIST = @have_attr_list@
ltp/Makefile +4 -0
@@ -25,6 +25,10 @@ LCFLAGS += -DAIO LIBAIO = -laio -lpthread endif +ifeq ($(HAVE_FALLOCATE), true) +LCFLAGS += -DFALLOCATE +endif + default: $(TARGETS) include $(BUILDRULES)
ltp/fsx.c +115 -11
220 lines not on this page · raw message
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 4 lines · Eric Sandeen
Seems to work for me. Any comments/suggestions?
I can probably make it fall back to the xfs ioctl if fallocate isn't supported, if strongly desired.
<ping style="hch">ping?</ping>
-Eric
Quoted 297 lines
aclocal.m4 +11
-0@@ -511,3 +511,14 @@ AC_DEFUN([AC_PACKAGE_NEED_XFSCTL_MACRO], ]) ]) +AC_DEFUN([AC_PACKAGE_WANT_FALLOCATE], + [ AC_MSG_CHECKING([for fallocate]) + AC_TRY_COMPILE([ +#include <linux/falloc.h> + ], [ + fallocate(0, 0, 0, 0); + ], have_fallocate=true + AC_MSG_RESULT(true), + AC_MSG_RESULT(false)) + AC_SUBST(have_fallocate) + ])configure.in +1
-0@@ -62,6 +62,7 @@ in AC_PACKAGE_WANT_GDBM AC_PACKAGE_WANT_AIO AC_PACKAGE_WANT_DMAPI + AC_PACKAGE_WANT_FALLOCATE ;; esacinclude/builddefs.in +1
-0@@ -56,6 +56,7 @@ RPM_VERSION = @rpm_version@ ENABLE_SHARED = @enable_shared@ HAVE_DB = @have_db@ HAVE_AIO = @have_aio@ +HAVE_FALLOCATE = @have_fallocate@ HAVE_DMAPI = @have_dmapi@ HAVE_ATTR_LIST = @have_attr_list@ltp/Makefile +4
-0@@ -25,6 +25,10 @@ LCFLAGS += -DAIO LIBAIO = -laio -lpthread endif +ifeq ($(HAVE_FALLOCATE), true) +LCFLAGS += -DFALLOCATE +endif + default: $(TARGETS) include $(BUILDRULES)ltp/fsx.c +115
-11@@ -32,6 +32,9 @@#ifdef AIO #include <libaio.h> #endif +#ifdef FALLOCATE +#include <linux/falloc.h> +#endif #ifndef MAP_FILE # define MAP_FILE 0@@ -65,6 +68,7 @@ int logcount = 0; /* total ops */#define OP_MAPREAD 5#define OP_MAPWRITE 6#define OP_SKIPPED 7 +#define OP_FALLOCATE 8#undef PAGE_SIZE#define PAGE_SIZE getpagesize()@@ -105,6 +109,11 @@ long numops = -1; /* -N flag */int randomoplen =1 ;/* -O flag disables it */ int seed =1 ;/* -S flag */ int mapped_writes =1 ;/* -W flag disables */ +#ifdef FALLOCATE +int fallocate_calls =1 ;/* -F flag disables */ +#else +int fallocate_calls =0 ;/* -F flag disables */ +#endif int mapped_reads =1 ;/* -R flag disables it */ int fsxgoodfd =0 ;int o_direct;/* -Z */ @@ -202,6 +211,7 @@ logdump(void) {int i, count, down;struct log_entry *lp; +char *falloc_type[3 ] = {"PAST_EOF" ,"EXTENDING" ,"INTERIOR" };prt ("LOG DUMP (%d total operations):\n" , logcount);if (logcount <LOGSIZE ) {@@ -265,6 +275,14 @@ logdump(void) badoff < lp->args[!!down])prt ("\t******WWWW" );break ; +case OP_FALLOCATE : +/* 0: offset 1: length 2: where alloced */ +prt ("FALLOCATE %s\tfrom 0x%x to 0x%x" , + falloc_type[lp->args[2 ]], lp->args[0 ], lp->args[0 ] + lp->args[1 ]); +if (badoff >= lp->args[0 ] && + badoff < lp->args[0 ] + lp->args[1 ]) +prt ("\t******FFFF" ); +break ;case OP_SKIPPED :prt ("SKIPPED (no operation)" );break ;@@ -770,6 +788,64 @@ dotruncate(unsigned size) } } +#ifdef FALLOCATE +/* fallocate is basically a no-op unless extending, then a lot like a truncate */ +void +dofallocate (unsigned offset,unsigned length) +{ +unsigned end_offset; +int keep_size; + +if (length ==0 ) { +if (!quiet && testcalls > simulatedopcount) +prt ("skipping zero length fallocate\n" ); +log4 (OP_SKIPPED ,OP_FALLOCATE , offset, length); +return ; + } + + keep_size =random () %2 ; + + end_offset = keep_size ?0 : offset + length; + +if (end_offset > biggest) { + biggest = end_offset; +if (!quiet && testcalls > simulatedopcount) +prt ("fallocating to largest ever: 0x%x\n" , end_offset); + } + +/* +* last arg: +* 1: allocate past EOF +* 2: extending prealloc +* 3: interior prealloc +*/ +log4 (OP_FALLOCATE , offset, length, (end_offset > file_size) ? (keep_size ?1 :2 ) :3 ); + +if (end_offset > file_size) { +memset (good_buf + file_size,'\0' , end_offset - file_size); + file_size = end_offset; + } + +if (testcalls <= simulatedopcount) +return ; + +if ((progressinterval && testcalls % progressinterval ==0 ) || + (debug && (monitorstart ==-1 || monitorend ==-1 || + end_offset <= monitorend))) +prt ("%lu falloc\tfrom 0x%x to 0x%x\n" , testcalls, offset, length); +if (fallocate (fd, keep_size ?FALLOC_FL_KEEP_SIZE :0 , (loff_t )offset, (loff_t )length) ==-1 ) { +prt ("fallocate: %x to %x\n" , offset, length); +prterr ("dofallocate: fallocate" ); +report_failure (161 ); + } +} +#else +void +dofallocate (unsigned offset,unsigned length) +{ +return ; +} +#endif void writefileimage ()@@ -823,7 +899,7 @@ test(void)unsigned long offset;unsigned long size = maxoplen;unsigned long rv =random (); -unsigned long op = rv % (3 + !lite + mapped_writes); +unsigned long op = rv % (3 + !lite + mapped_writes + fallocate_calls);/* turn off the map read if necessary */ @@ -845,22 +921,33 @@ test(void)prt ("%lu...\n" , testcalls);/* -* READ: op = 0 -* WRITE: op = 1 -* MAPREAD: op = 2 -* TRUNCATE: op = 3 -* MAPWRITE: op = 3 or 4 +* lite !lite +* READ: op = 0 0 +* WRITE: op = 1 1 +* MAPREAD: op = 2 2 +* TRUNCATE: op = - 3 +* MAPWRITE: op = 3 4 +* FALLOCATE: op = - 5 */ if (lite ?0 : op ==3 && (style &1 ) ==0 )/* vanilla truncate? */ dotruncate (random () % maxfilelen);else {if (randomoplen) size =random () % (maxoplen+1 ); + +/* truncate */ if (lite ?0 : op ==3 )dotruncate (size);else { offset =random (); -if (op ==1 || op == (lite ?3 :4 )) { +/* fallocate */ +if (op ==5 ) { + offset %= maxfilelen; +if (offset + size > maxfilelen) + size = maxfilelen - offset; +dofallocate (offset, size); +/* write / mapwrite */ + }else if (op ==1 || op == (lite ?3 :4 )) { offset %= maxfilelen;if (offset + size > maxfilelen) size = maxfilelen - offset;@@ -868,6 +955,7 @@ test(void)domapwrite (offset, size); elsedowrite (offset ,size ); +/* read / mapread */ }else {if (file_size) offset %= file_size;@@ -904,7 +992,7 @@ voidusage (void) { fprintf(stdout, "usage: %s", - "fsx [-dnqxALOWZ] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\ + "fsx [-dnqxAFLOWZ] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\ -b opnum: beginning operation number (default 1)\n\ -c P: 1 in P chance of file close+open at each op (default infinity)\n\ -d: debug output for all operations\n\@@ -925,8 +1013,11 @@ usage(void)#ifdef AIO " -A: Use the AIO system calls\n" #endif -" -D startingop: debug output starting at specified operation\n\ --L: fsxLite - no file creations & no file size changes\n\ +" -D startingop: debug output starting at specified operation\n" +#ifdef FALLOCATE +" -F: Do not use fallocate (preallocation) calls\n" +#endif +" -L: fsxLite - no file creations & no file size changes\n\ -N numops: total # operations to do (default infinity)\n\ -O: use oplen (see -o flag) for every op (default random)\n\ -P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\ @@ -1092,7 +1183,7 @@ main(int argc, char **argv)setvbuf (stdout, (char *)0 , _IOLBF,0 );/* line buffered stdout */ -while ((ch =getopt (argc, argv,"b:c:dfl:m:no:p:qr:s:t:w:xyAD:LN:OP:RS:WZ" )) +while ((ch =getopt (argc, argv,"b:c:dfl:m:no:p:qr:s:t:w:xyAD:FLN:OP:RS:WZ" )) !=EOF )switch (ch) {case 'b' :@@ -1186,6 +1277,9 @@ main(int argc, char **argv)if (debugstart <1 )usage ();break ; +case 'F' : + fallocate_calls =0 ; +break ;case 'L' : lite =1 ;break ;@@ -1331,6 +1425,16 @@ main(int argc, char **argv) }else check_trunc_hack (); +#ifdef FALLOCATE +if (!lite && fallocate_calls) { +if (fallocate (fd,0 ,0 ,1 ) && errno ==EOPNOTSUPP ) { +warn ("main: filesystem does not support fallocate, disabling" ); + fallocate_calls =0 ; + }else +ftruncate (fd,0 ); + } +#endif +while (numops ==-1 || numops--)test ();
Quoted 5 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Good idea.
Quoted 4 lines · Eric Sandeen
Seems to work for me. Any comments/suggestions?
I can probably make it fall back to the xfs ioctl if fallocate isn't supported, if strongly desired.
Is the ioctl going away anytime soon? If not, it might be worth having fsx use _both_ if possible, or just the ioctl if fallocate doesn't seem to be available.
Quoted 12 lines
ltp/fsx.c +8
-0@@ -770,6 +788,64 @@ dotruncate(unsigned size) } } +#ifdef FALLOCATE +/* fallocate is basically a no-op unless extending, then a lot like a truncate */ +void +dofallocate (unsigned offset,unsigned length) +{ +unsigned end_offset; +int keep_size; +
ltp/fsx.c dotruncate(unsigned size) · line 808
Quoted 10 lines
ltp/fsx.c +10
-0+if (length ==0 ) { +if (!quiet && testcalls > simulatedopcount) +prt ("skipping zero length fallocate\n" ); +log4 (OP_SKIPPED ,OP_FALLOCATE , offset, length); +return ; + } + + keep_size =random () %2 ; + + end_offset = keep_size ?0 : offset + length;
I prefer seeing explicit ( ) in this case.
...
Signature · 7 lines
Reality is merely an illusion, albeit a very persistent one. - Albert Einstein _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 4 lines · Eric Sandeen
Seems to work for me. Any comments/suggestions?
I can probably make it fall back to the xfs ioctl if fallocate isn't supported, if strongly desired.
ping^3? Does this look ok to folks? It'd be nice to get preallocation coverage in fsx beyond the simple "preallocate first" that's there now.
Thanks,
-Eric
Quoted 297 lines
aclocal.m4 +11
-0@@ -511,3 +511,14 @@ AC_DEFUN([AC_PACKAGE_NEED_XFSCTL_MACRO], ]) ]) +AC_DEFUN([AC_PACKAGE_WANT_FALLOCATE], + [ AC_MSG_CHECKING([for fallocate]) + AC_TRY_COMPILE([ +#include <linux/falloc.h> + ], [ + fallocate(0, 0, 0, 0); + ], have_fallocate=true + AC_MSG_RESULT(true), + AC_MSG_RESULT(false)) + AC_SUBST(have_fallocate) + ])configure.in +1
-0@@ -62,6 +62,7 @@ in AC_PACKAGE_WANT_GDBM AC_PACKAGE_WANT_AIO AC_PACKAGE_WANT_DMAPI + AC_PACKAGE_WANT_FALLOCATE ;; esacinclude/builddefs.in +1
-0@@ -56,6 +56,7 @@ RPM_VERSION = @rpm_version@ ENABLE_SHARED = @enable_shared@ HAVE_DB = @have_db@ HAVE_AIO = @have_aio@ +HAVE_FALLOCATE = @have_fallocate@ HAVE_DMAPI = @have_dmapi@ HAVE_ATTR_LIST = @have_attr_list@ltp/Makefile +4
-0@@ -25,6 +25,10 @@ LCFLAGS += -DAIO LIBAIO = -laio -lpthread endif +ifeq ($(HAVE_FALLOCATE), true) +LCFLAGS += -DFALLOCATE +endif + default: $(TARGETS) include $(BUILDRULES)ltp/fsx.c +115
-11@@ -32,6 +32,9 @@#ifdef AIO #include <libaio.h> #endif +#ifdef FALLOCATE +#include <linux/falloc.h> +#endif #ifndef MAP_FILE # define MAP_FILE 0@@ -65,6 +68,7 @@ int logcount = 0; /* total ops */#define OP_MAPREAD 5#define OP_MAPWRITE 6#define OP_SKIPPED 7 +#define OP_FALLOCATE 8#undef PAGE_SIZE#define PAGE_SIZE getpagesize()@@ -105,6 +109,11 @@ long numops = -1; /* -N flag */int randomoplen =1 ;/* -O flag disables it */ int seed =1 ;/* -S flag */ int mapped_writes =1 ;/* -W flag disables */ +#ifdef FALLOCATE +int fallocate_calls =1 ;/* -F flag disables */ +#else +int fallocate_calls =0 ;/* -F flag disables */ +#endif int mapped_reads =1 ;/* -R flag disables it */ int fsxgoodfd =0 ;int o_direct;/* -Z */ @@ -202,6 +211,7 @@ logdump(void) {int i, count, down;struct log_entry *lp; +char *falloc_type[3 ] = {"PAST_EOF" ,"EXTENDING" ,"INTERIOR" };prt ("LOG DUMP (%d total operations):\n" , logcount);if (logcount <LOGSIZE ) {@@ -265,6 +275,14 @@ logdump(void) badoff < lp->args[!!down])prt ("\t******WWWW" );break ; +case OP_FALLOCATE : +/* 0: offset 1: length 2: where alloced */ +prt ("FALLOCATE %s\tfrom 0x%x to 0x%x" , + falloc_type[lp->args[2 ]], lp->args[0 ], lp->args[0 ] + lp->args[1 ]); +if (badoff >= lp->args[0 ] && + badoff < lp->args[0 ] + lp->args[1 ]) +prt ("\t******FFFF" ); +break ;case OP_SKIPPED :prt ("SKIPPED (no operation)" );break ;@@ -770,6 +788,64 @@ dotruncate(unsigned size) } } +#ifdef FALLOCATE +/* fallocate is basically a no-op unless extending, then a lot like a truncate */ +void +dofallocate (unsigned offset,unsigned length) +{ +unsigned end_offset; +int keep_size; + +if (length ==0 ) { +if (!quiet && testcalls > simulatedopcount) +prt ("skipping zero length fallocate\n" ); +log4 (OP_SKIPPED ,OP_FALLOCATE , offset, length); +return ; + } + + keep_size =random () %2 ; + + end_offset = keep_size ?0 : offset + length; + +if (end_offset > biggest) { + biggest = end_offset; +if (!quiet && testcalls > simulatedopcount) +prt ("fallocating to largest ever: 0x%x\n" , end_offset); + } + +/* +* last arg: +* 1: allocate past EOF +* 2: extending prealloc +* 3: interior prealloc +*/ +log4 (OP_FALLOCATE , offset, length, (end_offset > file_size) ? (keep_size ?1 :2 ) :3 ); + +if (end_offset > file_size) { +memset (good_buf + file_size,'\0' , end_offset - file_size); + file_size = end_offset; + } + +if (testcalls <= simulatedopcount) +return ; + +if ((progressinterval && testcalls % progressinterval ==0 ) || + (debug && (monitorstart ==-1 || monitorend ==-1 || + end_offset <= monitorend))) +prt ("%lu falloc\tfrom 0x%x to 0x%x\n" , testcalls, offset, length); +if (fallocate (fd, keep_size ?FALLOC_FL_KEEP_SIZE :0 , (loff_t )offset, (loff_t )length) ==-1 ) { +prt ("fallocate: %x to %x\n" , offset, length); +prterr ("dofallocate: fallocate" ); +report_failure (161 ); + } +} +#else +void +dofallocate (unsigned offset,unsigned length) +{ +return ; +} +#endif void writefileimage ()@@ -823,7 +899,7 @@ test(void)unsigned long offset;unsigned long size = maxoplen;unsigned long rv =random (); -unsigned long op = rv % (3 + !lite + mapped_writes); +unsigned long op = rv % (3 + !lite + mapped_writes + fallocate_calls);/* turn off the map read if necessary */ @@ -845,22 +921,33 @@ test(void)prt ("%lu...\n" , testcalls);/* -* READ: op = 0 -* WRITE: op = 1 -* MAPREAD: op = 2 -* TRUNCATE: op = 3 -* MAPWRITE: op = 3 or 4 +* lite !lite +* READ: op = 0 0 +* WRITE: op = 1 1 +* MAPREAD: op = 2 2 +* TRUNCATE: op = - 3 +* MAPWRITE: op = 3 4 +* FALLOCATE: op = - 5 */ if (lite ?0 : op ==3 && (style &1 ) ==0 )/* vanilla truncate? */ dotruncate (random () % maxfilelen);else {if (randomoplen) size =random () % (maxoplen+1 ); + +/* truncate */ if (lite ?0 : op ==3 )dotruncate (size);else { offset =random (); -if (op ==1 || op == (lite ?3 :4 )) { +/* fallocate */ +if (op ==5 ) { + offset %= maxfilelen; +if (offset + size > maxfilelen) + size = maxfilelen - offset; +dofallocate (offset, size); +/* write / mapwrite */ + }else if (op ==1 || op == (lite ?3 :4 )) { offset %= maxfilelen;if (offset + size > maxfilelen) size = maxfilelen - offset;@@ -868,6 +955,7 @@ test(void)domapwrite (offset, size); elsedowrite (offset ,size ); +/* read / mapread */ }else {if (file_size) offset %= file_size;@@ -904,7 +992,7 @@ voidusage (void) { fprintf(stdout, "usage: %s", - "fsx [-dnqxALOWZ] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\ + "fsx [-dnqxAFLOWZ] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\ -b opnum: beginning operation number (default 1)\n\ -c P: 1 in P chance of file close+open at each op (default infinity)\n\ -d: debug output for all operations\n\@@ -925,8 +1013,11 @@ usage(void)#ifdef AIO " -A: Use the AIO system calls\n" #endif -" -D startingop: debug output starting at specified operation\n\ --L: fsxLite - no file creations & no file size changes\n\ +" -D startingop: debug output starting at specified operation\n" +#ifdef FALLOCATE +" -F: Do not use fallocate (preallocation) calls\n" +#endif +" -L: fsxLite - no file creations & no file size changes\n\ -N numops: total # operations to do (default infinity)\n\ -O: use oplen (see -o flag) for every op (default random)\n\ -P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\ @@ -1092,7 +1183,7 @@ main(int argc, char **argv)setvbuf (stdout, (char *)0 , _IOLBF,0 );/* line buffered stdout */ -while ((ch =getopt (argc, argv,"b:c:dfl:m:no:p:qr:s:t:w:xyAD:LN:OP:RS:WZ" )) +while ((ch =getopt (argc, argv,"b:c:dfl:m:no:p:qr:s:t:w:xyAD:FLN:OP:RS:WZ" )) !=EOF )switch (ch) {case 'b' :@@ -1186,6 +1277,9 @@ main(int argc, char **argv)if (debugstart <1 )usage ();break ; +case 'F' : + fallocate_calls =0 ; +break ;case 'L' : lite =1 ;break ;@@ -1331,6 +1425,16 @@ main(int argc, char **argv) }else check_trunc_hack (); +#ifdef FALLOCATE +if (!lite && fallocate_calls) { +if (fallocate (fd,0 ,0 ,1 ) && errno ==EOPNOTSUPP ) { +warn ("main: filesystem does not support fallocate, disabling" ); + fallocate_calls =0 ; + }else +ftruncate (fd,0 ); + } +#endif +while (numops ==-1 || numops--)test ();
Quoted 5 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 4 lines · Eric Sandeen
Seems to work for me. Any comments/suggestions?
I can probably make it fall back to the xfs ioctl if fallocate isn't supported, if strongly desired.
Anybody feel like reviewing this? Seems like having fallocate in the mix would be good.
(apologies if it's bitrotted since initial email but it should be generally ok)
-Eric
Quoted 297 lines
aclocal.m4 +11
-0@@ -511,3 +511,14 @@ AC_DEFUN([AC_PACKAGE_NEED_XFSCTL_MACRO], ]) ]) +AC_DEFUN([AC_PACKAGE_WANT_FALLOCATE], + [ AC_MSG_CHECKING([for fallocate]) + AC_TRY_COMPILE([ +#include <linux/falloc.h> + ], [ + fallocate(0, 0, 0, 0); + ], have_fallocate=true + AC_MSG_RESULT(true), + AC_MSG_RESULT(false)) + AC_SUBST(have_fallocate) + ])configure.in +1
-0@@ -62,6 +62,7 @@ in AC_PACKAGE_WANT_GDBM AC_PACKAGE_WANT_AIO AC_PACKAGE_WANT_DMAPI + AC_PACKAGE_WANT_FALLOCATE ;; esacinclude/builddefs.in +1
-0@@ -56,6 +56,7 @@ RPM_VERSION = @rpm_version@ ENABLE_SHARED = @enable_shared@ HAVE_DB = @have_db@ HAVE_AIO = @have_aio@ +HAVE_FALLOCATE = @have_fallocate@ HAVE_DMAPI = @have_dmapi@ HAVE_ATTR_LIST = @have_attr_list@ltp/Makefile +4
-0@@ -25,6 +25,10 @@ LCFLAGS += -DAIO LIBAIO = -laio -lpthread endif +ifeq ($(HAVE_FALLOCATE), true) +LCFLAGS += -DFALLOCATE +endif + default: $(TARGETS) include $(BUILDRULES)ltp/fsx.c +115
-11@@ -32,6 +32,9 @@#ifdef AIO #include <libaio.h> #endif +#ifdef FALLOCATE +#include <linux/falloc.h> +#endif #ifndef MAP_FILE # define MAP_FILE 0@@ -65,6 +68,7 @@ int logcount = 0; /* total ops */#define OP_MAPREAD 5#define OP_MAPWRITE 6#define OP_SKIPPED 7 +#define OP_FALLOCATE 8#undef PAGE_SIZE#define PAGE_SIZE getpagesize()@@ -105,6 +109,11 @@ long numops = -1; /* -N flag */int randomoplen =1 ;/* -O flag disables it */ int seed =1 ;/* -S flag */ int mapped_writes =1 ;/* -W flag disables */ +#ifdef FALLOCATE +int fallocate_calls =1 ;/* -F flag disables */ +#else +int fallocate_calls =0 ;/* -F flag disables */ +#endif int mapped_reads =1 ;/* -R flag disables it */ int fsxgoodfd =0 ;int o_direct;/* -Z */ @@ -202,6 +211,7 @@ logdump(void) {int i, count, down;struct log_entry *lp; +char *falloc_type[3 ] = {"PAST_EOF" ,"EXTENDING" ,"INTERIOR" };prt ("LOG DUMP (%d total operations):\n" , logcount);if (logcount <LOGSIZE ) {@@ -265,6 +275,14 @@ logdump(void) badoff < lp->args[!!down])prt ("\t******WWWW" );break ; +case OP_FALLOCATE : +/* 0: offset 1: length 2: where alloced */ +prt ("FALLOCATE %s\tfrom 0x%x to 0x%x" , + falloc_type[lp->args[2 ]], lp->args[0 ], lp->args[0 ] + lp->args[1 ]); +if (badoff >= lp->args[0 ] && + badoff < lp->args[0 ] + lp->args[1 ]) +prt ("\t******FFFF" ); +break ;case OP_SKIPPED :prt ("SKIPPED (no operation)" );break ;@@ -770,6 +788,64 @@ dotruncate(unsigned size) } } +#ifdef FALLOCATE +/* fallocate is basically a no-op unless extending, then a lot like a truncate */ +void +dofallocate (unsigned offset,unsigned length) +{ +unsigned end_offset; +int keep_size; + +if (length ==0 ) { +if (!quiet && testcalls > simulatedopcount) +prt ("skipping zero length fallocate\n" ); +log4 (OP_SKIPPED ,OP_FALLOCATE , offset, length); +return ; + } + + keep_size =random () %2 ; + + end_offset = keep_size ?0 : offset + length; + +if (end_offset > biggest) { + biggest = end_offset; +if (!quiet && testcalls > simulatedopcount) +prt ("fallocating to largest ever: 0x%x\n" , end_offset); + } + +/* +* last arg: +* 1: allocate past EOF +* 2: extending prealloc +* 3: interior prealloc +*/ +log4 (OP_FALLOCATE , offset, length, (end_offset > file_size) ? (keep_size ?1 :2 ) :3 ); + +if (end_offset > file_size) { +memset (good_buf + file_size,'\0' , end_offset - file_size); + file_size = end_offset; + } + +if (testcalls <= simulatedopcount) +return ; + +if ((progressinterval && testcalls % progressinterval ==0 ) || + (debug && (monitorstart ==-1 || monitorend ==-1 || + end_offset <= monitorend))) +prt ("%lu falloc\tfrom 0x%x to 0x%x\n" , testcalls, offset, length); +if (fallocate (fd, keep_size ?FALLOC_FL_KEEP_SIZE :0 , (loff_t )offset, (loff_t )length) ==-1 ) { +prt ("fallocate: %x to %x\n" , offset, length); +prterr ("dofallocate: fallocate" ); +report_failure (161 ); + } +} +#else +void +dofallocate (unsigned offset,unsigned length) +{ +return ; +} +#endif void writefileimage ()@@ -823,7 +899,7 @@ test(void)unsigned long offset;unsigned long size = maxoplen;unsigned long rv =random (); -unsigned long op = rv % (3 + !lite + mapped_writes); +unsigned long op = rv % (3 + !lite + mapped_writes + fallocate_calls);/* turn off the map read if necessary */ @@ -845,22 +921,33 @@ test(void)prt ("%lu...\n" , testcalls);/* -* READ: op = 0 -* WRITE: op = 1 -* MAPREAD: op = 2 -* TRUNCATE: op = 3 -* MAPWRITE: op = 3 or 4 +* lite !lite +* READ: op = 0 0 +* WRITE: op = 1 1 +* MAPREAD: op = 2 2 +* TRUNCATE: op = - 3 +* MAPWRITE: op = 3 4 +* FALLOCATE: op = - 5 */ if (lite ?0 : op ==3 && (style &1 ) ==0 )/* vanilla truncate? */ dotruncate (random () % maxfilelen);else {if (randomoplen) size =random () % (maxoplen+1 ); + +/* truncate */ if (lite ?0 : op ==3 )dotruncate (size);else { offset =random (); -if (op ==1 || op == (lite ?3 :4 )) { +/* fallocate */ +if (op ==5 ) { + offset %= maxfilelen; +if (offset + size > maxfilelen) + size = maxfilelen - offset; +dofallocate (offset, size); +/* write / mapwrite */ + }else if (op ==1 || op == (lite ?3 :4 )) { offset %= maxfilelen;if (offset + size > maxfilelen) size = maxfilelen - offset;@@ -868,6 +955,7 @@ test(void)domapwrite (offset, size); elsedowrite (offset ,size ); +/* read / mapread */ }else {if (file_size) offset %= file_size;@@ -904,7 +992,7 @@ voidusage (void) { fprintf(stdout, "usage: %s", - "fsx [-dnqxALOWZ] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\ + "fsx [-dnqxAFLOWZ] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\ -b opnum: beginning operation number (default 1)\n\ -c P: 1 in P chance of file close+open at each op (default infinity)\n\ -d: debug output for all operations\n\@@ -925,8 +1013,11 @@ usage(void)#ifdef AIO " -A: Use the AIO system calls\n" #endif -" -D startingop: debug output starting at specified operation\n\ --L: fsxLite - no file creations & no file size changes\n\ +" -D startingop: debug output starting at specified operation\n" +#ifdef FALLOCATE +" -F: Do not use fallocate (preallocation) calls\n" +#endif +" -L: fsxLite - no file creations & no file size changes\n\ -N numops: total # operations to do (default infinity)\n\ -O: use oplen (see -o flag) for every op (default random)\n\ -P: save .fsxlog and .fsxgood files in dirpath (default ./)\n\ @@ -1092,7 +1183,7 @@ main(int argc, char **argv)setvbuf (stdout, (char *)0 , _IOLBF,0 );/* line buffered stdout */ -while ((ch =getopt (argc, argv,"b:c:dfl:m:no:p:qr:s:t:w:xyAD:LN:OP:RS:WZ" )) +while ((ch =getopt (argc, argv,"b:c:dfl:m:no:p:qr:s:t:w:xyAD:FLN:OP:RS:WZ" )) !=EOF )switch (ch) {case 'b' :@@ -1186,6 +1277,9 @@ main(int argc, char **argv)if (debugstart <1 )usage ();break ; +case 'F' : + fallocate_calls =0 ; +break ;case 'L' : lite =1 ;break ;@@ -1331,6 +1425,16 @@ main(int argc, char **argv) }else check_trunc_hack (); +#ifdef FALLOCATE +if (!lite && fallocate_calls) { +if (fallocate (fd,0 ,0 ,1 ) && errno ==EOPNOTSUPP ) { +warn ("main: filesystem does not support fallocate, disabling" ); + fallocate_calls =0 ; + }else +ftruncate (fd,0 ); + } +#endif +while (numops ==-1 || numops--)test ();
Quoted 5 lines
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs
Quoted 8 lines · Eric Sandeen
Quoted 4 lines · Eric Sandeen
Seems to work for me. Any comments/suggestions?
I can probably make it fall back to the xfs ioctl if fallocate isn't supported, if strongly desired.
Anybody feel like reviewing this? Seems like having fallocate in the mix would be good.
Looks like all of the autoconf magic went in with the fiemap-tester changes, so a rebase is definitely needed... :/
Otherwise the changes seem sane - I can't find anything obviously wrong reading over them. I say clean it up, check it doesn't obviously break and check it in...
Cheers,
Dave.
Signature · 7 lines
Dave Chinner [email protected] _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs