Skip to content

Commit 17ba6f0

Browse files
committed
afs: Fix error handling with lookup via FS.InlineBulkStatus
When afs does a lookup, it tries to use FS.InlineBulkStatus to preemptively look up a bunch of files in the parent directory and cache this locally, on the basis that we might want to look at them too (for example if someone does an ls on a directory, they may want want to then stat every file listed). FS.InlineBulkStatus can be considered a compound op with the normal abort code applying to the compound as a whole. Each status fetch within the compound is then given its own individual abort code - but assuming no error that prevents the bulk fetch from returning the compound result will be 0, even if all the constituent status fetches failed. At the conclusion of afs_do_lookup(), we should use the abort code from the appropriate status to determine the error to return, if any - but instead it is assumed that we were successful if the op as a whole succeeded and we return an incompletely initialised inode, resulting in ENOENT, no matter the actual reason. In the particular instance reported, a vnode with no permission granted to be accessed is being given a UAEACCES abort code which should be reported as EACCES, but is instead being reported as ENOENT. Fix this by abandoning the inode (which will be cleaned up with the op) if file[1] has an abort code indicated and turn that abort code into an error instead. Whilst we're at it, add a tracepoint so that the abort codes of the individual subrequests of FS.InlineBulkStatus can be logged. At the moment only the container abort code can be 0. Fixes: e49c7b2 ("afs: Build an abstraction around an "operation" concept") Reported-by: Jeffrey Altman <[email protected]> Signed-off-by: David Howells <[email protected]> Reviewed-by: Marc Dionne <[email protected]> cc: [email protected]
1 parent 57e9d49 commit 17ba6f0

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

fs/afs/dir.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -716,6 +716,8 @@ static void afs_do_lookup_success(struct afs_operation *op)
716716
break;
717717
}
718718

719+
if (vp->scb.status.abort_code)
720+
trace_afs_bulkstat_error(op, &vp->fid, i, vp->scb.status.abort_code);
719721
if (!vp->scb.have_status && !vp->scb.have_error)
720722
continue;
721723

@@ -905,12 +907,16 @@ static struct inode *afs_do_lookup(struct inode *dir, struct dentry *dentry,
905907
afs_begin_vnode_operation(op);
906908
afs_wait_for_operation(op);
907909
}
908-
inode = ERR_PTR(afs_op_error(op));
909910

910911
out_op:
911912
if (!afs_op_error(op)) {
912-
inode = &op->file[1].vnode->netfs.inode;
913-
op->file[1].vnode = NULL;
913+
if (op->file[1].scb.status.abort_code) {
914+
afs_op_accumulate_error(op, -ECONNABORTED,
915+
op->file[1].scb.status.abort_code);
916+
} else {
917+
inode = &op->file[1].vnode->netfs.inode;
918+
op->file[1].vnode = NULL;
919+
}
914920
}
915921

916922
if (op->file[0].scb.have_status)

include/trace/events/afs.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,31 @@ TRACE_EVENT(afs_file_error,
10711071
__print_symbolic(__entry->where, afs_file_errors))
10721072
);
10731073

1074+
TRACE_EVENT(afs_bulkstat_error,
1075+
TP_PROTO(struct afs_operation *op, struct afs_fid *fid, unsigned int index, s32 abort),
1076+
1077+
TP_ARGS(op, fid, index, abort),
1078+
1079+
TP_STRUCT__entry(
1080+
__field_struct(struct afs_fid, fid)
1081+
__field(unsigned int, op)
1082+
__field(unsigned int, index)
1083+
__field(s32, abort)
1084+
),
1085+
1086+
TP_fast_assign(
1087+
__entry->op = op->debug_id;
1088+
__entry->fid = *fid;
1089+
__entry->index = index;
1090+
__entry->abort = abort;
1091+
),
1092+
1093+
TP_printk("OP=%08x[%02x] %llx:%llx:%x a=%d",
1094+
__entry->op, __entry->index,
1095+
__entry->fid.vid, __entry->fid.vnode, __entry->fid.unique,
1096+
__entry->abort)
1097+
);
1098+
10741099
TRACE_EVENT(afs_cm_no_server,
10751100
TP_PROTO(struct afs_call *call, struct sockaddr_rxrpc *srx),
10761101

0 commit comments

Comments
 (0)