summaryrefslogtreecommitdiff
path: root/fs/afs/fsclient.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-06-02 18:08:11 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2018-06-02 18:09:27 -0400
commitde52cf922a4a17d0a4cd34d697db62a01c1bd092 (patch)
tree1c12675d523eaa34e01499ae2a70dc6983a1918b /fs/afs/fsclient.c
parent5b86d4ff5dce3271dff54119e06174dc22422903 (diff)
parent4776cab43fd3111618112737a257dc3ef368eddd (diff)
Merge tag 'afs-fixes-20180514' into afs-proc
backmerge AFS fixes that went into mainline and deal with the conflict in fs/afs/fsclient.c Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/afs/fsclient.c')
-rw-r--r--fs/afs/fsclient.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
index b695d9e16c65..2a80bbcc31f9 100644
--- a/fs/afs/fsclient.c
+++ b/fs/afs/fsclient.c
@@ -134,17 +134,35 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
struct afs_read *read_req)
{
const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
+ bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
u64 data_version, size;
u32 type, abort_code;
u8 flags = 0;
+ abort_code = ntohl(xdr->abort_code);
+
if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) {
+ if (xdr->if_version == htonl(0) &&
+ abort_code != 0 &&
+ inline_error) {
+ /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus
+ * whereby it doesn't set the interface version in the error
+ * case.
+ */
+ status->abort_code = abort_code;
+ return 0;
+ }
+
pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
goto bad;
}
+ if (abort_code != 0 && inline_error) {
+ status->abort_code = abort_code;
+ return 0;
+ }
+
type = ntohl(xdr->type);
- abort_code = ntohl(xdr->abort_code);
switch (type) {
case AFS_FTYPE_FILE:
case AFS_FTYPE_DIR:
@@ -161,12 +179,6 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,
}
status->type = type;
break;
- case AFS_FTYPE_INVALID:
- if (abort_code != 0) {
- status->abort_code = abort_code;
- return 0;
- }
- /* Fall through */
default:
goto bad;
}
@@ -261,7 +273,7 @@ static void xdr_decode_AFSCallBack(struct afs_call *call,
write_seqlock(&vnode->cb_lock);
- if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) {
+ if (call->cb_break == afs_cb_break_sum(vnode, cbi)) {
vnode->cb_version = ntohl(*bp++);
cb_expiry = ntohl(*bp++);
vnode->cb_type = ntohl(*bp++);