nfs_opendir_cb should not queue a READDIR on error
Explanation of the bug: - nfs_opendir_cb() queues a READDIR when it receives RPC_STATUS_ERROR. - rpc_purge_all_pdus() explicitly says that no further pdus should be queued when rpc_purge_all_pdus() is invoked and the outqueue is being cleared. - Since nfs_opendir_cb() is called in rpc_purge_all_pdus() with status=RPC_STATUS_ERROR, this invariant is broken. Fix: - Invoke check_nfs3_error() which will invoke the appropriate callback with the right error. - Disallow queueing a request in the if blocklibnfs-4.0.0-vitalif
parent
8b064bf971
commit
df72323c46
19
lib/nfs_v3.c
19
lib/nfs_v3.c
|
@ -2714,8 +2714,14 @@ nfs3_opendir_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
|
||||
assert(rpc->magic == RPC_CONTEXT_MAGIC);
|
||||
|
||||
if (status == RPC_STATUS_ERROR ||
|
||||
(status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP)) {
|
||||
if (check_nfs3_error(nfs, status, data, command_data)) {
|
||||
nfs_free_nfsdir(nfsdir);
|
||||
data->continue_data = NULL;
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP) {
|
||||
READDIR3args args;
|
||||
|
||||
args.dir.data.data_len = data->fh.len;
|
||||
|
@ -2738,15 +2744,6 @@ nfs3_opendir_cb(struct rpc_context *rpc, int status, void *command_data,
|
|||
return;
|
||||
}
|
||||
|
||||
if (status == RPC_STATUS_CANCEL) {
|
||||
data->cb(-EINTR, nfs, "Command was cancelled",
|
||||
data->private_data);
|
||||
nfs_free_nfsdir(nfsdir);
|
||||
data->continue_data = NULL;
|
||||
free_nfs_cb_data(data);
|
||||
return;
|
||||
}
|
||||
|
||||
if (res->status != NFS3_OK) {
|
||||
nfs_set_error(nfs, "NFS: READDIRPLUS of %s failed with "
|
||||
"%s(%d)", data->saved_path,
|
||||
|
|
Loading…
Reference in New Issue