diff options
author | David Howells <dhowells@redhat.com> | 2018-10-19 19:57:58 -0400 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2018-10-23 19:41:08 -0400 |
commit | 36bb5f490a542f230beb982475b56d79d72033de (patch) | |
tree | d5c10159dfd62049838b39c310643968b52eb1fb /fs/afs | |
parent | 35dbfba3111a5ef0663bb89185ce8dfdbef63f8d (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.c | 16 |
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; |