add a new test for racing AIO COW writes
This can be used to trigger an assert in the current XFS code because it can't handle the case where there are COW extents on a file, but none at or below the range converted by the AIO completion handler.
Note that it doesn't trigger the assert 100% but fairly reliably.
src/aio-dio-regress/aio-dio-cow-race.c new file +119 -0
@@ -0,0 +1,119 @@ +/* +* Copyright (c) Christoph Hellwig. All Rights Reserved. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it would be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <libgen.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/ioctl.h> +#include <linux/fs.h> + +#include <libaio.h> + +#ifndef FICLONE +#define FICLONE _IOW(0x94, 9, int) +#endif + +#define IO_PATTERN 0xab + +int main (int argc,char *argv[]) +{ +struct io_context *ctx =NULL ; +struct io_event evs[4 ]; +struct iocb iocb1, iocb2, iocb3, iocb4; +struct iocb *iocbs[] = { &iocb1, &iocb2, &iocb3, &iocb4 }; +void *buf; +int fd, clone, err =0 ; +unsigned long buf_size =getpagesize () *2 ; +char *filename, *clonename; + +if (argc !=3 ) { +fprintf (stderr,"usage: %s filename clonename\n" , argv[0 ]); +exit (1 ); + } + + err =posix_memalign (&buf,getpagesize (), buf_size); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"posix_memalign" ); +return 1 ; + } +memset (buf,IO_PATTERN , buf_size); + + filename = argv[1 ]; + fd =open (filename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (fd ==-1 ) { +perror ("open" ); +return 1 ; + } + +if (write (fd, buf, buf_size) != buf_size) { +perror ("write" ); +return 1 ; + } + + clonename = argv[2 ]; + clone =open (clonename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (clone ==-1 ) { +perror ("open clone" ); +return 1 ; + } + +if (ioctl (clone,FICLONE , fd)) { +perror ("FICLONE" ); +return 1 ; + } + + err =io_setup (4 , &ctx); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err), +"io_setup" ); +return 1 ; + } + +/* +* Test overlapping aio writes, where an earlier one clears the whole +* range of a later aio, thus leaving nothing to do for the I/O +* completion to do. To make things harder also make sure there is +* other outstanding COW I/O. +*/ +io_prep_pwrite (&iocb1, fd, buf, buf_size,0 ); +io_prep_pwrite (&iocb2, fd, buf, buf_size /2 ,0 ); +io_prep_pwrite (&iocb3, fd, buf, buf_size /2 , buf_size); +io_prep_pwrite (&iocb4, fd, buf, buf_size,0 ); + + err =io_submit (ctx,4 , iocbs); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_submit" ); +return 1 ; + } + + err =io_getevents (ctx,4 ,4 , evs,NULL ); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_getevents" ); +return 1 ; + } + +return 0 ; +}
tests/generic/463 new file +60 -0
60 lines not on this page · raw message
tests/generic/group +1 -0
@@ -465,3 +465,4 @@ 460 auto quick rw 461 auto shutdown stress 462 auto quick dax +463 auto quick reflink dangerous
Darrick J. Wong
Reviewed-byQuoted 204 lines · Christoph Hellwig
This can be used to trigger an assert in the current XFS code because it can't handle the case where there are COW extents on a file, but none at or below the range converted by the AIO completion handler.
Note that it doesn't trigger the assert 100% but fairly reliably.
Signed-off-by Christoph Hellwig <[email protected]>src/aio-dio-regress/aio-dio-cow-race.c new file +119
-0@@ -0,0 +1,119 @@ +/* +* Copyright (c) Christoph Hellwig. All Rights Reserved. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it would be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <libgen.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/ioctl.h> +#include <linux/fs.h> + +#include <libaio.h> + +#ifndef FICLONE +#define FICLONE _IOW(0x94, 9, int) +#endif + +#define IO_PATTERN 0xab + +int main (int argc,char *argv[]) +{ +struct io_context *ctx =NULL ; +struct io_event evs[4 ]; +struct iocb iocb1, iocb2, iocb3, iocb4; +struct iocb *iocbs[] = { &iocb1, &iocb2, &iocb3, &iocb4 }; +void *buf; +int fd, clone, err =0 ; +unsigned long buf_size =getpagesize () *2 ; +char *filename, *clonename; + +if (argc !=3 ) { +fprintf (stderr,"usage: %s filename clonename\n" , argv[0 ]); +exit (1 ); + } + + err =posix_memalign (&buf,getpagesize (), buf_size); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"posix_memalign" ); +return 1 ; + } +memset (buf,IO_PATTERN , buf_size); + + filename = argv[1 ]; + fd =open (filename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (fd ==-1 ) { +perror ("open" ); +return 1 ; + } + +if (write (fd, buf, buf_size) != buf_size) { +perror ("write" ); +return 1 ; + } + + clonename = argv[2 ]; + clone =open (clonename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (clone ==-1 ) { +perror ("open clone" ); +return 1 ; + } + +if (ioctl (clone,FICLONE , fd)) { +perror ("FICLONE" ); +return 1 ; + } + + err =io_setup (4 , &ctx); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err), +"io_setup" ); +return 1 ; + } + +/* +* Test overlapping aio writes, where an earlier one clears the whole +* range of a later aio, thus leaving nothing to do for the I/O +* completion to do. To make things harder also make sure there is +* other outstanding COW I/O. +*/ +io_prep_pwrite (&iocb1, fd, buf, buf_size,0 ); +io_prep_pwrite (&iocb2, fd, buf, buf_size /2 ,0 ); +io_prep_pwrite (&iocb3, fd, buf, buf_size /2 , buf_size); +io_prep_pwrite (&iocb4, fd, buf, buf_size,0 ); + + err =io_submit (ctx,4 , iocbs); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_submit" ); +return 1 ; + } + + err =io_getevents (ctx,4 ,4 , evs,NULL ); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_getevents" ); +return 1 ; + } + +return 0 ; +}tests/generic/463 new file +60
-0@@ -0,0 +1,60 @@ +#! /bin/bash +# FS QA Test 463 +# +# Test racy COW AIO write completions. +# +#----------------------------------------------------------------------- +# Copyright (c) 2017 Christoph Hellwig. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* + rm -f $TEST_DIR/file $TEST_DIR/clone +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# remove previous $seqres.full before test +rm -f $seqres.full + +_supported_fs generic +_supported_os Linux + +_require_test +_require_test_reflink +_require_aio +_require_odirect + +$here/src/aio-dio-regress/aio-dio-cow-race $TEST_DIR/file $TEST_DIR/clone + +echo "Silence is golden" +status=0 +exittests/generic/group +0
-0
tests/generic/group line 468
Quoted 4 lines
tests/generic/group +1
-0@@ -465,3 +465,4 @@ 460 auto quick rw 461 auto shutdown stress 462 auto quick dax +463 auto quick reflink dangerous
'clone', not 'reflink'.
Otherwise looks ok,
--D
Quoted 4 lines
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
add a new test for racing AIO COW writes V2
In reply to Christoph HellwigThis can be used to trigger an assert in the current XFS code because it can't handle the case where there are COW extents on a file, but none at or below the range converted by the AIO completion handler.
src/aio-dio-regress/aio-dio-cow-race.c new file +119 -0
@@ -0,0 +1,119 @@ +/* +* Copyright (c) Christoph Hellwig. All Rights Reserved. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it would be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <libgen.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/ioctl.h> +#include <linux/fs.h> + +#include <libaio.h> + +#ifndef FICLONE +#define FICLONE _IOW(0x94, 9, int) +#endif + +#define IO_PATTERN 0xab + +int main (int argc,char *argv[]) +{ +struct io_context *ctx =NULL ; +struct io_event evs[4 ]; +struct iocb iocb1, iocb2, iocb3, iocb4; +struct iocb *iocbs[] = { &iocb1, &iocb2, &iocb3, &iocb4 }; +void *buf; +int fd, clone, err =0 ; +unsigned long buf_size =getpagesize () *2 ; +char *filename, *clonename; + +if (argc !=3 ) { +fprintf (stderr,"usage: %s filename clonename\n" , argv[0 ]); +exit (1 ); + } + + err =posix_memalign (&buf,getpagesize (), buf_size); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"posix_memalign" ); +return 1 ; + } +memset (buf,IO_PATTERN , buf_size); + + filename = argv[1 ]; + fd =open (filename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (fd ==-1 ) { +perror ("open" ); +return 1 ; + } + +if (write (fd, buf, buf_size) != buf_size) { +perror ("write" ); +return 1 ; + } + + clonename = argv[2 ]; + clone =open (clonename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (clone ==-1 ) { +perror ("open clone" ); +return 1 ; + } + +if (ioctl (clone,FICLONE , fd)) { +perror ("FICLONE" ); +return 1 ; + } + + err =io_setup (4 , &ctx); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err), +"io_setup" ); +return 1 ; + } + +/* +* Test overlapping aio writes, where an earlier one clears the whole +* range of a later aio, thus leaving nothing to do for the I/O +* completion to do. To make things harder also make sure there is +* other outstanding COW I/O. +*/ +io_prep_pwrite (&iocb1, fd, buf, buf_size,0 ); +io_prep_pwrite (&iocb2, fd, buf, buf_size /2 ,0 ); +io_prep_pwrite (&iocb3, fd, buf, buf_size /2 , buf_size); +io_prep_pwrite (&iocb4, fd, buf, buf_size,0 ); + + err =io_submit (ctx,4 , iocbs); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_submit" ); +return 1 ; + } + + err =io_getevents (ctx,4 ,4 , evs,NULL ); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_getevents" ); +return 1 ; + } + +return 0 ; +}
tests/generic/463 new file +60 -0
60 lines not on this page · raw message
tests/generic/group +1 -0
@@ -465,3 +465,4 @@ 460 auto quick rw 461 auto shutdown stress 462 auto quick dax +463 auto quick clone dangerous
Darrick J. Wong
Reviewed-byRe: add a new test for racing AIO COW writes V2
Quoted 5 lines · Christoph Hellwig
This can be used to trigger an assert in the current XFS code because it can't handle the case where there are COW extents on a file, but none at or below the range converted by the AIO completion handler.
Signed-off-by Christoph Hellwig <[email protected]>
Looks ok,
Quoted 205 lines
src/aio-dio-regress/aio-dio-cow-race.c new file +119
-0@@ -0,0 +1,119 @@ +/* +* Copyright (c) Christoph Hellwig. All Rights Reserved. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it would be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <libgen.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/ioctl.h> +#include <linux/fs.h> + +#include <libaio.h> + +#ifndef FICLONE +#define FICLONE _IOW(0x94, 9, int) +#endif + +#define IO_PATTERN 0xab + +int main (int argc,char *argv[]) +{ +struct io_context *ctx =NULL ; +struct io_event evs[4 ]; +struct iocb iocb1, iocb2, iocb3, iocb4; +struct iocb *iocbs[] = { &iocb1, &iocb2, &iocb3, &iocb4 }; +void *buf; +int fd, clone, err =0 ; +unsigned long buf_size =getpagesize () *2 ; +char *filename, *clonename; + +if (argc !=3 ) { +fprintf (stderr,"usage: %s filename clonename\n" , argv[0 ]); +exit (1 ); + } + + err =posix_memalign (&buf,getpagesize (), buf_size); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"posix_memalign" ); +return 1 ; + } +memset (buf,IO_PATTERN , buf_size); + + filename = argv[1 ]; + fd =open (filename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (fd ==-1 ) { +perror ("open" ); +return 1 ; + } + +if (write (fd, buf, buf_size) != buf_size) { +perror ("write" ); +return 1 ; + } + + clonename = argv[2 ]; + clone =open (clonename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (clone ==-1 ) { +perror ("open clone" ); +return 1 ; + } + +if (ioctl (clone,FICLONE , fd)) { +perror ("FICLONE" ); +return 1 ; + } + + err =io_setup (4 , &ctx); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err), +"io_setup" ); +return 1 ; + } + +/* +* Test overlapping aio writes, where an earlier one clears the whole +* range of a later aio, thus leaving nothing to do for the I/O +* completion to do. To make things harder also make sure there is +* other outstanding COW I/O. +*/ +io_prep_pwrite (&iocb1, fd, buf, buf_size,0 ); +io_prep_pwrite (&iocb2, fd, buf, buf_size /2 ,0 ); +io_prep_pwrite (&iocb3, fd, buf, buf_size /2 , buf_size); +io_prep_pwrite (&iocb4, fd, buf, buf_size,0 ); + + err =io_submit (ctx,4 , iocbs); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_submit" ); +return 1 ; + } + + err =io_getevents (ctx,4 ,4 , evs,NULL ); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_getevents" ); +return 1 ; + } + +return 0 ; +}tests/generic/463 new file +60
-0@@ -0,0 +1,60 @@ +#! /bin/bash +# FS QA Test 463 +# +# Test racy COW AIO write completions. +# +#----------------------------------------------------------------------- +# Copyright (c) 2017 Christoph Hellwig. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* + rm -f $TEST_DIR/file $TEST_DIR/clone +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink + +# remove previous $seqres.full before test +rm -f $seqres.full + +_supported_fs generic +_supported_os Linux + +_require_test +_require_test_reflink +_require_aio +_require_odirect + +$here/src/aio-dio-regress/aio-dio-cow-race $TEST_DIR/file $TEST_DIR/clone + +echo "Silence is golden" +status=0 +exittests/generic/group +1
-1@@ -465,3 +465,4 @@ 460 auto quick rw 461 auto shutdown stress 462 auto quick dax +463 auto quick clone dangerous --To unsubscribe from this list: send the line "unsubscribe linux-xfs" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: add a new test for racing AIO COW writes V2
In reply to Christoph HellwigQuoted 5 lines · Christoph Hellwig
This can be used to trigger an assert in the current XFS code because it can't handle the case where there are COW extents on a file, but none at or below the range converted by the AIO completion handler.
Signed-off-by Christoph Hellwig <[email protected]>
I fixed several minor issues on commit (see inline comments).
I haven't reproduced the assert failure yet on my test vm, but as the commit log in v1 patch, it's not 100% reproducible, maybe I'm just lucky (or not lucky :)
src/aio-dio-regress/aio-dio-cow-race.c
Quoted 6 lines
src/aio-dio-regress/aio-dio-cow-race.c new file +0
-0
Added new gitignore entry for this new binary file.
Quoted 80 lines
src/aio-dio-regress/aio-dio-cow-race.c new file +79
-0@@ -0,0 +1,119 @@ +/* +* Copyright (c) Christoph Hellwig. All Rights Reserved. +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it would be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write the Free Software Foundation, +* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include <sys/stat.h> +#include <sys/types.h> +#include <errno.h> +#include <libgen.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/ioctl.h> +#include <linux/fs.h> + +#include <libaio.h> + +#ifndef FICLONE +#define FICLONE _IOW(0x94, 9, int) +#endif + +#define IO_PATTERN 0xab + +int main (int argc,char *argv[]) +{ +struct io_context *ctx =NULL ; +struct io_event evs[4 ]; +struct iocb iocb1, iocb2, iocb3, iocb4; +struct iocb *iocbs[] = { &iocb1, &iocb2, &iocb3, &iocb4 }; +void *buf; +int fd, clone, err =0 ; +unsigned long buf_size =getpagesize () *2 ; +char *filename, *clonename; + +if (argc !=3 ) { +fprintf (stderr,"usage: %s filename clonename\n" , argv[0 ]); +exit (1 ); + } + + err =posix_memalign (&buf,getpagesize (), buf_size); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"posix_memalign" ); +return 1 ; + } +memset (buf,IO_PATTERN , buf_size); + + filename = argv[1 ]; + fd =open (filename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (fd ==-1 ) { +perror ("open" ); +return 1 ; + } + +if (write (fd, buf, buf_size) != buf_size) { +perror ("write" ); +return 1 ; + } + + clonename = argv[2 ]; + clone =open (clonename,O_DIRECT |O_CREAT |O_TRUNC |O_RDWR ,0600 ); +if (clone ==-1 ) { +perror ("open clone" ); +return 1 ; + } +
src/aio-dio-regress/aio-dio-cow-race.c line 89
Quoted 10 lines
src/aio-dio-regress/aio-dio-cow-race.c new file +10
-0+if (ioctl (clone,FICLONE , fd)) { +perror ("FICLONE" ); +return 1 ; + } + + err =io_setup (4 , &ctx); +if (err) { +fprintf (stderr,"error %s during %s\n" , +strerror (err), +"io_setup" );
This error message format looks weired, I changed it to
fprintf(stderr, "io_setup error %s\n", strerror(err));
Did the same to io_submit and io_getevents.
Quoted 80 lines
src/aio-dio-regress/aio-dio-cow-race.c new file +30
-0+return 1 ; + } + +/* +* Test overlapping aio writes, where an earlier one clears the whole +* range of a later aio, thus leaving nothing to do for the I/O +* completion to do. To make things harder also make sure there is +* other outstanding COW I/O. +*/ +io_prep_pwrite (&iocb1, fd, buf, buf_size,0 ); +io_prep_pwrite (&iocb2, fd, buf, buf_size /2 ,0 ); +io_prep_pwrite (&iocb3, fd, buf, buf_size /2 , buf_size); +io_prep_pwrite (&iocb4, fd, buf, buf_size,0 ); + + err =io_submit (ctx,4 , iocbs); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_submit" ); +return 1 ; + } + + err =io_getevents (ctx,4 ,4 , evs,NULL ); +if (err !=4 ) { +fprintf (stderr,"error %s during %s\n" , +strerror (err),"io_getevents" ); +return 1 ; + } + +return 0 ; +}tests/generic/463 new file +44
-0@@ -0,0 +1,60 @@ +#! /bin/bash +# FS QA Test 463 +# +# Test racy COW AIO write completions. +# +#----------------------------------------------------------------------- +# Copyright (c) 2017 Christoph Hellwig. All Rights Reserved. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it would be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +#----------------------------------------------------------------------- +# + +seq=`basename $0` +seqres=$RESULT_DIR/$seq +echo "QA output created by $seq" + +here=`pwd` +tmp=/tmp/$$ +status=1 # failure is the default! +trap "_cleanup; exit \$status" 0 1 2 3 15 + +_cleanup() +{ + cd / + rm -f $tmp.* + rm -f $TEST_DIR/file $TEST_DIR/clone +} + +# get standard environment, filters and checks +. ./common/rc +. ./common/filter +. ./common/reflink +
tests/generic/463 line 54
Quoted 10 lines
tests/generic/463 new file +10
-0+# remove previous $seqres.full before test +rm -f $seqres.full + +_supported_fs generic +_supported_os Linux + +_require_test +_require_test_reflink +_require_aio +_require_odirect
Need _require_test_program "aio-dio-regress/aio-dio-cow-race"
But a single '_require_aiodio "aio-dio-cow-race"' did all the three requirements check above.
tests/generic/463 line 56
Quoted 2 lines
tests/generic/463 new file +2
-0+ +$here/src/aio-dio-regress/aio-dio-cow-race $TEST_DIR/file $TEST_DIR/clone
With _require_aiodio, we can use $AIO_TEST here for the test binary.
tests/generic/463 line 58
Quoted 2 lines
tests/generic/463 new file +2
-0+ +echo "Silence is golden"
Added generic/463.out file too.
Thanks,
Eryu
Quoted 15 lines
tests/generic/463 new file +2
-0+status=0 +exittests/generic/group +1
-1@@ -465,3 +465,4 @@ 460 auto quick rw 461 auto shutdown stress 462 auto quick dax +463 auto quick clone dangerous --To unsubscribe from this list: send the line "unsubscribe fstests" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: add a new test for racing AIO COW writes V2
Quoted 5 lines · Eryu Guan
Quoted 4 lines · Christoph Hellwig
This can be used to trigger an assert in the current XFS code because it can't handle the case where there are COW extents on a file, but none at or below the range converted by the AIO completion handler.
Quoted 7 lines
Quoted 1 line
Signed-off-by Christoph Hellwig <[email protected]>I fixed several minor issues on commit (see inline comments).
I haven't reproduced the assert failure yet on my test vm, but as the commit log in v1 patch, it's not 100% reproducible, maybe I'm just lucky (or not lucky :)
Hmm, I only got 1 non-reproduce out of about 100 runs. Maybe your device is too fast, as this was in a VM.