• Al Viro's avatar
    nfs_instantiate(): prevent multiple aliases for directory inode · b0c6108e
    Al Viro authored
    Since NFS allows open-by-fhandle, we have to cope with the possibility
    of mkdir vs. open-by-guessed-handle races.  A local filesystem could
    decide what the inumber of the new object will be and insert a locked
    inode with that inumber into icache _before_ the on-disk data structures
    begin to look good and unlock it only once it has a dentry alias, so
    that open-by-handle coming first would quietly fail and mkdir coming
    first would have open-by-handle grab its dentry.
    
    For NFS it's a non-starter - the icache key is server-supplied fhandle
    and we do not get that until the object has been fully created on server.
    We really have to deal with the possibility that open-by-handle gets
    the in-core inode and attaches a dentry to it before mkdir does.
    
    Solution: let nfs_mkdir() use d_splice_alias() to catch those.  We can
    	* get an error.  Just return it to our caller.
    	* get NULL - no preexisting dentry aliases, we'd just done what
    d_add() would've done.  Success.
    	* get a reference to preexisting alias.  In that case the alias
    had been moved in place of nfs_mkdir() argument (and hashed there), while
    nfs_mkdir() argument is left unhashed negative.  Which is just fine for
    ->mkdir() callers, all we need is to release the reference we'd got from
    d_splice_alias() and report success.
    
    Cc: Trond Myklebust <trond.myklebust@primarydata.com>
    Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
    b0c6108e
dir.c 64.9 KB