Skip to content

Commit

Permalink
afs: Better tracing of protocol errors
Browse files Browse the repository at this point in the history
Include the site of detection of AFS protocol errors in trace lines to
better be able to determine what went wrong.

Signed-off-by: David Howells <dhowells@redhat.com>
  • Loading branch information
David Howells committed Oct 23, 2018
1 parent 9ea9ce0 commit 160cb95
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 70 deletions.
6 changes: 4 additions & 2 deletions fs/afs/cmservice.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,8 @@ static int afs_deliver_cb_callback(struct afs_call *call)
call->count = ntohl(call->tmp);
_debug("FID count: %u", call->count);
if (call->count > AFSCBMAX)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_cb_fid_count);

call->buffer = kmalloc(array3_size(call->count, 3, 4),
GFP_KERNEL);
Expand Down Expand Up @@ -234,7 +235,8 @@ static int afs_deliver_cb_callback(struct afs_call *call)
call->count2 = ntohl(call->tmp);
_debug("CB count: %u", call->count2);
if (call->count2 != call->count && call->count2 != 0)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_cb_count);
call->offset = 0;
call->unmarshall++;

Expand Down
117 changes: 71 additions & 46 deletions fs/afs/fsclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ static int xdr_decode_AFSFetchStatus(struct afs_call *call,

bad:
xdr_dump_bad(*_bp);
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG, afs_eproto_bad_status);
}

/*
Expand Down Expand Up @@ -399,9 +399,10 @@ 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;
if (afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
xdr_decode_AFSCallBack(call, vnode, &bp);
if (call->reply[1])
xdr_decode_AFSVolSync(&bp, call->reply[1]);
Expand Down Expand Up @@ -580,9 +581,10 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
return ret;

bp = call->buffer;
if (afs_decode_status(call, &bp, &vnode->status, vnode,
&vnode->status.data_version, req) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&vnode->status.data_version, req);
if (ret < 0)
return ret;
xdr_decode_AFSCallBack(call, vnode, &bp);
if (call->reply[1])
xdr_decode_AFSVolSync(&bp, call->reply[1]);
Expand Down Expand Up @@ -733,10 +735,13 @@ 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->reply[1]);
if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) < 0 ||
afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
if (ret < 0)
return ret;
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
xdr_decode_AFSCallBack_raw(&bp, call->reply[3]);
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

Expand Down Expand Up @@ -839,9 +844,10 @@ static int afs_deliver_fs_remove(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
if (afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

_leave(" = 0 [done]");
Expand Down Expand Up @@ -929,10 +935,13 @@ static int afs_deliver_fs_link(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
if (afs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL) < 0 ||
afs_decode_status(call, &bp, &dvnode->status, dvnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &vnode->status, vnode, NULL, NULL);
if (ret < 0)
return ret;
ret = afs_decode_status(call, &bp, &dvnode->status, dvnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

_leave(" = 0 [done]");
Expand Down Expand Up @@ -1016,10 +1025,13 @@ 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->reply[1]);
if (afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL) ||
afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, call->reply[2], NULL, NULL, NULL);
if (ret < 0)
return ret;
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

_leave(" = 0 [done]");
Expand Down Expand Up @@ -1122,13 +1134,16 @@ static int afs_deliver_fs_rename(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
if (afs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
if (new_dvnode != orig_dvnode &&
afs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
&call->expected_version_2, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &orig_dvnode->status, orig_dvnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
if (new_dvnode != orig_dvnode) {
ret = afs_decode_status(call, &bp, &new_dvnode->status, new_dvnode,
&call->expected_version_2, NULL);
if (ret < 0)
return ret;
}
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

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

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
if (afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

afs_pages_written_back(vnode, call);
Expand Down Expand Up @@ -1407,9 +1423,10 @@ static int afs_deliver_fs_store_status(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
if (afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &vnode->status, vnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
/* xdr_decode_AFSVolSync(&bp, call->reply[X]); */

_leave(" = 0 [done]");
Expand Down Expand Up @@ -1612,7 +1629,8 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call)
call->count = ntohl(call->tmp);
_debug("volname length: %u", call->count);
if (call->count >= AFSNAMEMAX)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_volname_len);
call->offset = 0;
call->unmarshall++;

Expand Down Expand Up @@ -1659,7 +1677,8 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call)
call->count = ntohl(call->tmp);
_debug("offline msg length: %u", call->count);
if (call->count >= AFSNAMEMAX)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_offline_msg_len);
call->offset = 0;
call->unmarshall++;

Expand Down Expand Up @@ -1706,7 +1725,8 @@ static int afs_deliver_fs_get_volume_status(struct afs_call *call)
call->count = ntohl(call->tmp);
_debug("motd length: %u", call->count);
if (call->count >= AFSNAMEMAX)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_motd_len);
call->offset = 0;
call->unmarshall++;

Expand Down Expand Up @@ -2109,8 +2129,10 @@ static int afs_deliver_fs_fetch_status(struct afs_call *call)

/* unmarshall the reply once we've received all of it */
bp = call->buffer;
afs_decode_status(call, &bp, status, vnode,
&call->expected_version, NULL);
ret = afs_decode_status(call, &bp, status, vnode,
&call->expected_version, NULL);
if (ret < 0)
return ret;
callback[call->count].version = ntohl(bp[0]);
callback[call->count].expiry = ntohl(bp[1]);
callback[call->count].type = ntohl(bp[2]);
Expand Down Expand Up @@ -2206,7 +2228,8 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
tmp = ntohl(call->tmp);
_debug("status count: %u/%u", tmp, call->count2);
if (tmp != call->count2)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_ibulkst_count);

call->count = 0;
call->unmarshall++;
Expand All @@ -2221,10 +2244,11 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)

bp = call->buffer;
statuses = call->reply[1];
if (afs_decode_status(call, &bp, &statuses[call->count],
call->count == 0 ? vnode : NULL,
NULL, NULL) < 0)
return afs_protocol_error(call, -EBADMSG);
ret = afs_decode_status(call, &bp, &statuses[call->count],
call->count == 0 ? vnode : NULL,
NULL, NULL);
if (ret < 0)
return ret;

call->count++;
if (call->count < call->count2)
Expand All @@ -2244,7 +2268,8 @@ static int afs_deliver_fs_inline_bulk_status(struct afs_call *call)
tmp = ntohl(call->tmp);
_debug("CB count: %u", tmp);
if (tmp != call->count2)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_ibulkst_cb_count);
call->count = 0;
call->unmarshall++;
more_cbs:
Expand Down
2 changes: 1 addition & 1 deletion fs/afs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key)
default:
printk("kAFS: AFS vnode with undefined type\n");
read_sequnlock_excl(&vnode->cb_lock);
return afs_protocol_error(NULL, -EBADMSG);
return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type);
}

inode->i_blocks = 0;
Expand Down
2 changes: 1 addition & 1 deletion fs/afs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -931,7 +931,7 @@ extern void afs_flat_call_destructor(struct afs_call *);
extern void afs_send_empty_reply(struct afs_call *);
extern void afs_send_simple_reply(struct afs_call *, const void *, size_t);
extern int afs_extract_data(struct afs_call *, void *, size_t, bool);
extern int afs_protocol_error(struct afs_call *, int);
extern int afs_protocol_error(struct afs_call *, int, enum afs_eproto_cause);

static inline int afs_transfer_reply(struct afs_call *call)
{
Expand Down
5 changes: 3 additions & 2 deletions fs/afs/rxrpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -939,8 +939,9 @@ int afs_extract_data(struct afs_call *call, void *buf, size_t count,
/*
* Log protocol error production.
*/
noinline int afs_protocol_error(struct afs_call *call, int error)
noinline int afs_protocol_error(struct afs_call *call, int error,
enum afs_eproto_cause cause)
{
trace_afs_protocol_error(call, error, __builtin_return_address(0));
trace_afs_protocol_error(call, error, cause);
return error;
}
30 changes: 20 additions & 10 deletions fs/afs/vlclient.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,8 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
call->count2 = ntohl(*bp); /* Type or next count */

if (call->count > YFS_MAXENDPOINTS)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_fsendpt_num);

alist = afs_alloc_addrlist(call->count, FS_SERVICE, AFS_FS_PORT);
if (!alist)
Expand All @@ -475,7 +476,8 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
size = sizeof(__be32) * (1 + 4 + 1);
break;
default:
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_fsendpt_type);
}

size += sizeof(__be32);
Expand All @@ -488,18 +490,21 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
switch (call->count2) {
case YFS_ENDPOINT_IPV4:
if (ntohl(bp[0]) != sizeof(__be32) * 2)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_fsendpt4_len);
afs_merge_fs_addr4(alist, bp[1], ntohl(bp[2]));
bp += 3;
break;
case YFS_ENDPOINT_IPV6:
if (ntohl(bp[0]) != sizeof(__be32) * 5)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_fsendpt6_len);
afs_merge_fs_addr6(alist, bp + 1, ntohl(bp[5]));
bp += 6;
break;
default:
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_fsendpt_type);
}

/* Got either the type of the next entry or the count of
Expand All @@ -518,7 +523,8 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
if (!call->count)
goto end;
if (call->count > YFS_MAXENDPOINTS)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_vlendpt_type);

call->unmarshall = 3;

Expand Down Expand Up @@ -546,7 +552,8 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
size = sizeof(__be32) * (1 + 4 + 1);
break;
default:
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_vlendpt_type);
}

if (call->count > 1)
Expand All @@ -559,16 +566,19 @@ static int afs_deliver_yfsvl_get_endpoints(struct afs_call *call)
switch (call->count2) {
case YFS_ENDPOINT_IPV4:
if (ntohl(bp[0]) != sizeof(__be32) * 2)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_vlendpt4_len);
bp += 3;
break;
case YFS_ENDPOINT_IPV6:
if (ntohl(bp[0]) != sizeof(__be32) * 5)
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_vlendpt6_len);
bp += 6;
break;
default:
return afs_protocol_error(call, -EBADMSG);
return afs_protocol_error(call, -EBADMSG,
afs_eproto_yvl_vlendpt_type);
}

/* Got either the type of the next entry or the count of
Expand Down
Loading

0 comments on commit 160cb95

Please sign in to comment.