]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
afs: Fix FS.FetchStatus delivery from updating wrong vnode
authorDavid Howells <dhowells@redhat.com>
Fri, 19 Oct 2018 23:57:58 +0000 (00:57 +0100)
committerDavid Howells <dhowells@redhat.com>
Tue, 23 Oct 2018 23:41:08 +0000 (00:41 +0100)
The FS.FetchStatus reply delivery function was updating inode of the
directory in which a lookup had been done with the status of the looked up
file.  This corrupts some of the directory state.

Fixes: 5cf9dd55a0ec ("afs: Prospectively look up extra files when doing a single lookup")
Signed-off-by: David Howells <dhowells@redhat.com>
fs/afs/fsclient.c

index 5e3027f213909dc6864834c250d324c1ffae9877..f758750e81d87fc7044dbf1a44e89fb020e308ca 100644 (file)
@@ -2026,7 +2026,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
        struct afs_file_status *status = call->reply[1];
        struct afs_callback *callback = call->reply[2];
        struct afs_volsync *volsync = call->reply[3];
-       struct afs_vnode *vnode = call->reply[0];
+       struct afs_fid *fid = call->reply[0];
        const __be32 *bp;
        int ret;
 
@@ -2034,21 +2034,15 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
        if (ret < 0)
                return ret;
 
-       _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode);
+       _enter("{%llx:%llu}", fid->vid, fid->vnode);
 
        /* unmarshall the reply once we've received all of it */
        bp = call->buffer;
-       ret = afs_decode_status(call, &bp, status, vnode,
+       ret = afs_decode_status(call, &bp, status, NULL,
                                &call->expected_version, NULL);
        if (ret < 0)
                return ret;
-       callback[call->count].version   = ntohl(bp[0]);
-       callback[call->count].expiry    = ntohl(bp[1]);
-       callback[call->count].type      = ntohl(bp[2]);
-       if (vnode)
-               xdr_decode_AFSCallBack(call, vnode, &bp);
-       else
-               bp += 3;
+       xdr_decode_AFSCallBack_raw(&bp, callback);
        if (volsync)
                xdr_decode_AFSVolSync(&bp, volsync);
 
@@ -2089,7 +2083,7 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
        }
 
        call->key = fc->key;
-       call->reply[0] = NULL; /* vnode for fid[0] */
+       call->reply[0] = fid;
        call->reply[1] = status;
        call->reply[2] = callback;
        call->reply[3] = volsync;