Uploaded image for project: 'Lustre'
  1. Lustre
  2. LU-12272

Support renameat2() with RENAME_NOREPLACE flag

    XMLWordPrintable

Details

    • Improvement
    • Resolution: Unresolved
    • Minor
    • None
    • Lustre 2.12.0
    • None
    • CentOS 7.6
    • 3
    • 9223372036854775807

    Description

      This is related to a previous ticket LU-11557 and is also about renameat2(), but actually I think it is even more important so I decided to open a separate ticket.

      It would be nice to have support for renameat2() with RENAME_NOREPLACE in Lustre.

      Currently, when renameat2 is called with this flag, Lustre doesn't perform the rename: it either returns errno=EINVAL if the destination file doesn't exist, or we got errno=EEXIST if the destination file already exists (the latter is expected). We see the same behavior with other filesystems that also don't support renameat2() flags.

      Reproducer:

      [sthiell@sh-ln08 login /fir/users/sthiell]$ cat renameat2.c 
      #include <errno.h>
      #include <stdio.h>
      #include <unistd.h>
      #include <linux/fs.h>
      #include <sys/syscall.h>
      
      int main()
      {
        int ret;
      
        ret = syscall(SYS_renameat2, 0, "/fir/users/sthiell/file1", 0, "/fir/users/sthiell/file2", RENAME_NOREPLACE);
        fprintf(stderr, "renameat2 ret=%d errno=%d (%m)\n", ret, errno, errno);
        return ret;
      }
      
      
      [sthiell@sh-ln08 login /fir/users/sthiell]$ gcc -o renameat2 renameat2.c
      [sthiell@sh-ln08 login /fir/users/sthiell]$ rm file1 file2
      rm: cannot remove ‘file1’: No such file or directory
      rm: cannot remove ‘file2’: No such file or directory
      [sthiell@sh-ln08 login /fir/users/sthiell]$ touch file1
      [sthiell@sh-ln08 login /fir/users/sthiell]$ ./renameat2
      renameat2 ret=-1 errno=22 (Invalid argument)
      [sthiell@sh-ln08 login /fir/users/sthiell]$ ls file*
      file1
      [sthiell@sh-ln08 login /fir/users/sthiell]$ touch file2
      [sthiell@sh-ln08 login /fir/users/sthiell]$ ls -i file*
      144117284070328763 file1 144117284070328764 file2
      [sthiell@sh-ln08 login /fir/users/sthiell]$ ./renameat2
      renameat2 ret=-1 errno=17 (File exists)
      [sthiell@sh-ln08 login /fir/users/sthiell]$ ls -i file*
      144117284070328763 file1 144117284070328764 file2
      

      A local filesystem, here XFS, has the expected behavior:

      [sthiell@sh-ln08 login /tmp]$ rm file1 file2
      [sthiell@sh-ln08 login /tmp]$ touch file1
      [sthiell@sh-ln08 login /tmp]$ ls -i file*
      1075302339 file1
      [sthiell@sh-ln08 login /tmp]$ ./renameat2 
      renameat2 ret=0 errno=0 (Success)
      [sthiell@sh-ln08 login /tmp]$ ls -i file*
      1075302339 file2
      [sthiell@sh-ln08 login /tmp]$ touch file1
      [sthiell@sh-ln08 login /tmp]$ ls -i file*
      1075302340 file1  1075302339 file2
      [sthiell@sh-ln08 login /tmp]$ ./renameat2 
      renameat2 ret=-1 errno=17 (File exists)
      [sthiell@sh-ln08 login /tmp]$ ls -i file*
      1075302340 file1  1075302339 file2
      

      There are multiple use cases that I can think for this feature. Our particular use-case for this is to ensure that when multiple renames are done to the same destination file, only the first one would actually succeed and the others would fail with EEXIST. As of today, subsequent renames always override the destination file. Thanks for considering this feature in a future version of Lustre. Happy to discuss this at LUG next week!

      Attachments

        Issue Links

          Activity

            People

              dongyang Dongyang Li
              sthiell Stephane Thiell
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated: