aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2018-10-19 19:57:58 -0400
committerDavid Howells <dhowells@redhat.com>2018-10-23 19:41:08 -0400
commit36bb5f490a542f230beb982475b56d79d72033de (patch)
treed5c10159dfd62049838b39c310643968b52eb1fb /fs/afs
parent35dbfba3111a5ef0663bb89185ce8dfdbef63f8d (diff)
afs: Fix FS.FetchStatus delivery from updating wrong vnode
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>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/fsclient.c16
1 files changed, 5 insertions, 11 deletions
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index 5e3027f21390..f758750e81d8 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -2026,7 +2026,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
2026 struct afs_file_status *status = call->reply[1]; 2026 struct afs_file_status *status = call->reply[1];
2027 struct afs_callback *callback = call->reply[2]; 2027 struct afs_callback *callback = call->reply[2];
2028 struct afs_volsync *volsync = call->reply[3]; 2028 struct afs_volsync *volsync = call->reply[3];
2029 struct afs_vnode *vnode = call->reply[0]; 2029 struct afs_fid *fid = call->reply[0];
2030 const __be32 *bp; 2030 const __be32 *bp;
2031 int ret; 2031 int ret;
2032 2032
@@ -2034,21 +2034,15 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)
2034 if (ret < 0) 2034 if (ret < 0)
2035 return ret; 2035 return ret;
2036 2036
2037 _enter("{%llx:%llu}", vnode->fid.vid, vnode->fid.vnode); 2037 _enter("{%llx:%llu}", fid->vid, fid->vnode);
2038 2038
2039 /* unmarshall the reply once we've received all of it */ 2039 /* unmarshall the reply once we've received all of it */
2040 bp = call->buffer; 2040 bp = call->buffer;
2041 ret = afs_decode_status(call, &bp, status, vnode, 2041 ret = afs_decode_status(call, &bp, status, NULL,
2042 &call->expected_version, NULL); 2042 &call->expected_version, NULL);
2043 if (ret < 0) 2043 if (ret < 0)
2044 return ret; 2044 return ret;
2045 callback[call->count].version = ntohl(bp[0]); 2045 xdr_decode_AFSCallBack_raw(&bp, callback);
2046 callback[call->count].expiry = ntohl(bp[1]);
2047 callback[call->count].type = ntohl(bp[2]);
2048 if (vnode)
2049 xdr_decode_AFSCallBack(call, vnode, &bp);
2050 else
2051 bp += 3;
2052 if (volsync) 2046 if (volsync)
2053 xdr_decode_AFSVolSync(&bp, volsync); 2047 xdr_decode_AFSVolSync(&bp, volsync);
2054 2048
@@ -2089,7 +2083,7 @@ int afs_fs_fetch_status(struct afs_fs_cursor *fc,
2089 } 2083 }
2090 2084
2091 call->key = fc->key; 2085 call->key = fc->key;
2092 call->reply[0] = NULL; /* vnode for fid[0] */ 2086 call->reply[0] = fid;
2093 call->reply[1] = status; 2087 call->reply[1] = status;
2094 call->reply[2] = callback; 2088 call->reply[2] = callback;
2095 call->reply[3] = volsync; 2089 call->reply[3] = volsync;