• David Howells's avatar
    afs: Fix silly rename · b6489a49
    David Howells authored
    Fix AFS's silly rename by the following means:
    
     (1) Set the destination directory in afs_do_silly_rename() so as to avoid
         misbehaviour and indicate that the directory data version will
         increment by 1 so as to avoid warnings about unexpected changes in the
         DV.  Also indicate that the ctime should be updated to avoid xfstest
         grumbling.
    
     (2) Note when the server indicates that a directory changed more than we
         expected (AFS_OPERATION_DIR_CONFLICT), indicating a conflict with a
         third party change, checking on successful completion of unlink and
         rename.
    
         The problem is that the FS.RemoveFile RPC op doesn't report the status
         of the unlinked file, though YFS.RemoveFile2 does.  This can be
         mitigated by the assumption that if the directory DV cranked by
         exactly 1, we can be sure we removed one link from the file; further,
         ordinarily in AFS, files cannot be hardlinked across directories, so
         if we reduce nlink to 0, the file is deleted.
    
         However, if the directory DV jumps by more than 1, we cannot know if a
         third party intervened by adding or removing a link on the file we
         just removed a link from.
    
         The same also goes for any vnode that is at the destination of the
         FS.Rename RPC op.
    
     (3) Make afs_vnode_commit_status() apply the nlink drop inside the cb_lock
         section along with the other attribute updates if ->op_unlinked is set
         on the descriptor for the appropriate vnode.
    
     (4) Issue a follow up status fetch to the unlinked file in the event of a
         third party conflict that makes it impossible for us to know if we
         actually deleted the file or not.
    
     (5) Provide a flag, AFS_VNODE_SILLY_DELETED, to make afs_getattr() lie to
         the user about the nlink of a silly deleted file so that it appears as
         0, not 1.
    
    Found with the generic/035 and generic/084 xfstests.
    
    Fixes: e49c7b2f ("afs: Build an abstraction around an "operation" concept")
    Reported-by: default avatarMarc Dionne <marc.dionne@auristor.com>
    Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
    b6489a49
dir_silly.c 7.35 KB