Re: [PATCH] xfs_io: allow passing an open file to copy_range

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, May 29, 2019 at 5:46 PM Darrick J. Wong <darrick.wong@xxxxxxxxxx> wrote:
>
> On Wed, May 29, 2019 at 01:13:30PM +0300, Amir Goldstein wrote:
> > Commit 1a05efba ("io: open pipes in non-blocking mode")
> > addressed a specific copy_range issue with pipes by always opening
> > pipes in non-blocking mode.
> >
> > This change takes a different approach and allows passing any
> > open file as the source file to copy_range.  Besides providing
> > more flexibility to the copy_range command, this allows xfstests
> > to check if xfs_io supports passing an open file to copy_range.
> >
> > The intended usage is:
> > $ mkfifo fifo
> > $ xfs_io -f -n -r -c "open -f dst" -C "copy_range -f 0" fifo
> >
> > Signed-off-by: Amir Goldstein <amir73il@xxxxxxxxx>
> > ---
> >
> > Darrick,
> >
> > Folowing our discussion on the copy_range bounds test [1],
> > what do you think about using copy_range -f in the copy_range
> > fifo test with a fifo that was explicitly opened non-blocking,
> > instead of trying to figure out if copy_range is going to hang
> > or not?
> >
> > This option is already available with sendfile command and
> > we can make it available for reflink and dedupe commands if
> > we want to. Too bad that these 4 commands have 3 different
> > usage patterns to begin with...
>
> I wonder if there's any sane way to overload the src_file argument such
> that we can pass filetable[] offsets without having to burn more getopt
> flags...?
>
> (Oh wait, I bet you're using the '-f' flag to figure out if xfs_io is
> new enough not to block on fifos, right? :))

Yes, but this time it is not a hack its a feature..

>
> But otherwise this seems like a reasonable approach.
>
> > Thanks,
> > Amir.
> >
> > [1] https://marc.info/?l=fstests&m=155910786017989&w=2
> >
> >  io/copy_file_range.c | 30 ++++++++++++++++++++++++------
> >  man/man8/xfs_io.8    | 10 +++++++---
> >  2 files changed, 31 insertions(+), 9 deletions(-)
> >
> > diff --git a/io/copy_file_range.c b/io/copy_file_range.c
> > index d069e5bb..1f0d2713 100644
> > --- a/io/copy_file_range.c
> > +++ b/io/copy_file_range.c
> > @@ -26,6 +26,8 @@ copy_range_help(void)
> >                                              file at offset 200\n\
> >   'copy_range some_file' - copies all bytes from some_file into the open file\n\
> >                            at position 0\n\
> > + 'copy_range -f 2' - copies all bytes from open file 2 into the current open file\n\
> > +                          at position 0\n\
> >  "));
> >  }
> >
> > @@ -82,11 +84,12 @@ copy_range_f(int argc, char **argv)
> >       int opt;
> >       int ret;
> >       int fd;
> > +     int src_file_arg = 1;
> >       size_t fsblocksize, fssectsize;
> >
> >       init_cvtnum(&fsblocksize, &fssectsize);
> >
> > -     while ((opt = getopt(argc, argv, "s:d:l:")) != -1) {
> > +     while ((opt = getopt(argc, argv, "s:d:l:f:")) != -1) {
> >               switch (opt) {
> >               case 's':
> >                       src = cvtnum(fsblocksize, fssectsize, optarg);
> > @@ -109,15 +112,30 @@ copy_range_f(int argc, char **argv)
> >                               return 0;
> >                       }
> >                       break;
> > +             case 'f':
> > +                     fd = atoi(argv[1]);
> > +                     if (fd < 0 || fd >= filecount) {
> > +                             printf(_("value %d is out of range (0-%d)\n"),
> > +                                     fd, filecount-1);
> > +                             return 0;
> > +                     }
> > +                     fd = filetable[fd].fd;
> > +                     /* Expect no src_file arg */
> > +                     src_file_arg = 0;
> > +                     break;
> >               }
> >       }
> >
> > -     if (optind != argc - 1)
> > +     if (optind != argc - src_file_arg) {
> > +             fprintf(stderr, "optind=%d, argc=%d, src_file_arg=%d\n", optind, argc, src_file_arg);
> >               return command_usage(&copy_range_cmd);
> > +     }
> >
> > -     fd = openfile(argv[optind], NULL, IO_READONLY, 0, NULL);
> > -     if (fd < 0)
> > -             return 0;
> > +     if (src_file_arg) {
>
> I wonder if it would be easier to declare "int fd = -1" and the only do
> the openfile here if fd < 0?
>

I started out with if (fd == -1), but I changed to src_file_arg to
unify the condition for (optind != argc - src_file_arg)
and avoid another condition (i.e. argc - (fd == -1 ? 1 : 0))

Thanks,
Amir.



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux