diff options
Diffstat (limited to 'fs/afs/fsclient.c')
| -rw-r--r-- | fs/afs/fsclient.c | 28 |
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, | |||
| 134 | struct afs_read *read_req) | 134 | struct afs_read *read_req) |
| 135 | { | 135 | { |
| 136 | const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; | 136 | const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp; |
| 137 | bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus); | ||
| 137 | u64 data_version, size; | 138 | u64 data_version, size; |
| 138 | u32 type, abort_code; | 139 | u32 type, abort_code; |
| 139 | u8 flags = 0; | 140 | u8 flags = 0; |
| 140 | 141 | ||
| 142 | abort_code = ntohl(xdr->abort_code); | ||
| 143 | |||
| 141 | if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) { | 144 | if (xdr->if_version != htonl(AFS_FSTATUS_VERSION)) { |
| 145 | if (xdr->if_version == htonl(0) && | ||
| 146 | abort_code != 0 && | ||
| 147 | inline_error) { | ||
| 148 | /* The OpenAFS fileserver has a bug in FS.InlineBulkStatus | ||
| 149 | * whereby it doesn't set the interface version in the error | ||
| 150 | * case. | ||
| 151 | */ | ||
| 152 | status->abort_code = abort_code; | ||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 142 | pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); | 156 | pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version)); |
| 143 | goto bad; | 157 | goto bad; |
| 144 | } | 158 | } |
| 145 | 159 | ||
| 160 | if (abort_code != 0 && inline_error) { | ||
| 161 | status->abort_code = abort_code; | ||
| 162 | return 0; | ||
| 163 | } | ||
| 164 | |||
| 146 | type = ntohl(xdr->type); | 165 | type = ntohl(xdr->type); |
| 147 | abort_code = ntohl(xdr->abort_code); | ||
| 148 | switch (type) { | 166 | switch (type) { |
| 149 | case AFS_FTYPE_FILE: | 167 | case AFS_FTYPE_FILE: |
| 150 | case AFS_FTYPE_DIR: | 168 | case AFS_FTYPE_DIR: |
| @@ -161,12 +179,6 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call, | |||
| 161 | } | 179 | } |
| 162 | status->type = type; | 180 | status->type = type; |
| 163 | break; | 181 | break; |
| 164 | case AFS_FTYPE_INVALID: | ||
| 165 | if (abort_code != 0) { | ||
| 166 | status->abort_code = abort_code; | ||
| 167 | return 0; | ||
| 168 | } | ||
| 169 | /* Fall through */ | ||
| 170 | default: | 182 | default: |
| 171 | goto bad; | 183 | goto bad; |
| 172 | } | 184 | } |
| @@ -261,7 +273,7 @@ static void xdr_decode_AFSCallBack(struct afs_call *call, | |||
| 261 | 273 | ||
| 262 | write_seqlock(&vnode->cb_lock); | 274 | write_seqlock(&vnode->cb_lock); |
| 263 | 275 | ||
| 264 | if (call->cb_break == (vnode->cb_break + cbi->server->cb_s_break)) { | 276 | if (call->cb_break == afs_cb_break_sum(vnode, cbi)) { |
| 265 | vnode->cb_version = ntohl(*bp++); | 277 | vnode->cb_version = ntohl(*bp++); |
| 266 | cb_expiry = ntohl(*bp++); | 278 | cb_expiry = ntohl(*bp++); |
| 267 | vnode->cb_type = ntohl(*bp++); | 279 | vnode->cb_type = ntohl(*bp++); |
