aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/fsclient.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2020-04-08 20:56:20 +0100
committerDavid Howells <dhowells@redhat.com>2020-04-13 15:09:01 +0100
commitb98f0ec91c42d87a70da42726b852ac8d78a3257 (patch)
tree26fa47281faa787c90c31f350724c7585008fa7a /fs/afs/fsclient.c
parentafs: Fix decoding of inline abort codes from version 1 status records (diff)
downloadlinux-dev-b98f0ec91c42d87a70da42726b852ac8d78a3257.tar.xz
linux-dev-b98f0ec91c42d87a70da42726b852ac8d78a3257.zip
afs: Fix rename operation status delivery
The afs_deliver_fs_rename() and yfs_deliver_fs_rename() functions both only decode the second file status returned unless the parent directories are different - unfortunately, this means that the xdr pointer isn't advanced and the volsync record will be read incorrectly in such an instance. Fix this by always decoding the second status into the second status/callback block which wasn't being used if the dirs were the same. The afs_update_dentry_version() calls that update the directory data version numbers on the dentries can then unconditionally use the second status record as this will always reflect the state of the destination dir (the two records will be identical if the destination dir is the same as the source dir) Fixes: 260a980317da ("[AFS]: Add "directory write" support.") Fixes: 30062bd13e36 ("afs: Implement YFS support in the fs client") Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/afs/fsclient.c')
-rw-r--r--fs/afs/fsclient.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index de4331670c84..68fc46634346 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -986,16 +986,16 @@ static int afs_deliver_fs_rename(struct afs_call *call)
if (ret < 0)
return ret;
- /* unmarshall the reply once we've received all of it */
+ /* If the two dirs are the same, we have two copies of the same status
+ * report, so we just decode it twice.
+ */
bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
if (ret < 0)
return ret;
- if (call->out_dir_scb != call->out_scb) {
- ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
- if (ret < 0)
- return ret;
- }
+ ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
+ if (ret < 0)
+ return ret;
xdr_decode_AFSVolSync(&bp, call->out_volsync);
_leave(" = 0 [done]");