Skip to content

Commit

Permalink
afs: Set error flag rather than return error from file status decode
Browse files Browse the repository at this point in the history
Set a flag in the call struct to indicate an unmarshalling error rather
than return and handle an error from the decoding of file statuses.  This
flag is checked on a successful return from the delivery function.

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed May 31, 2020
1 parent 8230fd8 commit 38355ee
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 123 deletions.
88 changes: 25 additions & 63 deletions fs/afs/fsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,16 +56,15 @@ static void xdr_dump_bad(const __be32 *bp)
/*
* decode an AFSFetchStatus block
*/
static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
struct afs_call *call,
struct afs_status_cb *scb)
static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
struct afs_call *call,
struct afs_status_cb *scb)
{
const struct afs_xdr_AFSFetchStatus *xdr = (const void *)*_bp;
struct afs_file_status *status = &scb->status;
bool inline_error = (call->operation_ID == afs_FS_InlineBulkStatus);
u64 data_version, size;
u32 type, abort_code;
int ret;

abort_code = ntohl(xdr->abort_code);

Expand All @@ -79,7 +78,7 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
*/
status->abort_code = abort_code;
scb->have_error = true;
goto good;
goto advance;
}

pr_warn("Unknown AFSFetchStatus version %u\n", ntohl(xdr->if_version));
Expand All @@ -89,7 +88,7 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
if (abort_code != 0 && inline_error) {
status->abort_code = abort_code;
scb->have_error = true;
goto good;
goto advance;
}

type = ntohl(xdr->type);
Expand Down Expand Up @@ -125,15 +124,13 @@ static int xdr_decode_AFSFetchStatus(const __be32 **_bp,
data_version |= (u64)ntohl(xdr->data_version_hi) << 32;
status->data_version = data_version;
scb->have_status = true;
good:
ret = 0;
advance:
*_bp = (const void *)*_bp + sizeof(*xdr);
return ret;
return;

bad:
xdr_dump_bad(*_bp);
ret = afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
goto advance;
}

Expand Down Expand Up @@ -254,9 +251,7 @@ static int afs_deliver_fs_fetch_status_vnode(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSCallBack(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

Expand Down Expand Up @@ -419,9 +414,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
return ret;

bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSCallBack(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

Expand Down Expand Up @@ -577,12 +570,8 @@ static int afs_deliver_fs_create_vnode(struct afs_call *call)
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
xdr_decode_AFSFid(&bp, call->out_fid);
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
xdr_decode_AFSCallBack(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

Expand Down Expand Up @@ -691,9 +680,7 @@ static int afs_deliver_fs_dir_status_and_vol(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

_leave(" = 0 [done]");
Expand Down Expand Up @@ -784,12 +771,8 @@ static int afs_deliver_fs_link(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

_leave(" = 0 [done]");
Expand Down Expand Up @@ -878,12 +861,8 @@ static int afs_deliver_fs_symlink(struct afs_call *call)
/* unmarshall the reply once we've received all of it */
bp = call->buffer;
xdr_decode_AFSFid(&bp, call->out_fid);
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

_leave(" = 0 [done]");
Expand Down Expand Up @@ -986,16 +965,12 @@ static int afs_deliver_fs_rename(struct afs_call *call)
if (ret < 0)
return ret;

bp = call->buffer;
/* 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;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_dir_scb);
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

_leave(" = 0 [done]");
Expand Down Expand Up @@ -1103,9 +1078,7 @@ static int afs_deliver_fs_store_data(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

_leave(" = 0 [done]");
Expand Down Expand Up @@ -1283,9 +1256,7 @@ static int afs_deliver_fs_store_status(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

_leave(" = 0 [done]");
Expand Down Expand Up @@ -1952,9 +1923,7 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSCallBack(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

Expand Down Expand Up @@ -2060,10 +2029,7 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)

bp = call->buffer;
scb = &call->out_scb[call->count];
ret = xdr_decode_AFSFetchStatus(&bp, call, scb);
if (ret < 0)
return ret;

xdr_decode_AFSFetchStatus(&bp, call, scb);
call->count++;
if (call->count < call->count2)
goto more_counts;
Expand Down Expand Up @@ -2241,9 +2207,7 @@ static int afs_deliver_fs_fetch_acl(struct afs_call *call)
return ret;

bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

call->unmarshall++;
Expand Down Expand Up @@ -2324,9 +2288,7 @@ static int afs_deliver_fs_file_status_and_vol(struct afs_call *call)
return ret;

bp = call->buffer;
ret = xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
if (ret < 0)
return ret;
xdr_decode_AFSFetchStatus(&bp, call, call->out_scb);
xdr_decode_AFSVolSync(&bp, call->out_volsync);

_leave(" = 0 [done]");
Expand Down
1 change: 1 addition & 0 deletions fs/afs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ struct afs_call {
bool upgrade; /* T to request service upgrade */
bool have_reply_time; /* T if have got reply_time */
bool intr; /* T if interruptible */
bool unmarshalling_error; /* T if an unmarshalling error occurred */
u16 service_id; /* Actual service ID (after upgrade) */
unsigned int debug_id; /* Trace ID */
u32 operation_ID; /* operation ID for an incoming call */
Expand Down
4 changes: 4 additions & 0 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,8 @@ static void afs_deliver_to_call(struct afs_call *call)

ret = call->type->deliver(call);
state = READ_ONCE(call->state);
if (ret == 0 && call->unmarshalling_error)
ret = -EBADMSG;
switch (ret) {
case 0:
afs_queue_call_work(call);
Expand Down Expand Up @@ -963,5 +965,7 @@ noinline int afs_protocol_error(struct afs_call *call, int error,
enum afs_eproto_cause cause)
{
trace_afs_protocol_error(call, error, cause);
if (call)
call->unmarshalling_error = true;
return error;
}
Loading

0 comments on commit 38355ee

Please sign in to comment.