Commit 85085aac authored by Chuck Lever's avatar Chuck Lever Committed by J. Bruce Fields

NFSD: Refactor nfsd_dispatch() error paths

nfsd_dispatch() is a hot path. Ensure the compiler takes the
processing of rare error cases out of line.
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent 4c96cb56
...@@ -1021,29 +1021,24 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) ...@@ -1021,29 +1021,24 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
dprintk("nfsd_dispatch: vers %d proc %d\n", dprintk("nfsd_dispatch: vers %d proc %d\n",
rqstp->rq_vers, rqstp->rq_proc); rqstp->rq_vers, rqstp->rq_proc);
if (nfs_request_too_big(rqstp, proc)) { if (nfs_request_too_big(rqstp, proc))
dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers); goto out_too_large;
*statp = rpc_garbage_args;
return 1;
}
/* /*
* Give the xdr decoder a chance to change this if it wants * Give the xdr decoder a chance to change this if it wants
* (necessary in the NFSv4.0 compound case) * (necessary in the NFSv4.0 compound case)
*/ */
rqstp->rq_cachetype = proc->pc_cachetype; rqstp->rq_cachetype = proc->pc_cachetype;
if (!proc->pc_decode(rqstp, argv->iov_base)) { if (!proc->pc_decode(rqstp, argv->iov_base))
dprintk("nfsd: failed to decode arguments!\n"); goto out_decode_err;
*statp = rpc_garbage_args;
return 1;
}
switch (nfsd_cache_lookup(rqstp)) { switch (nfsd_cache_lookup(rqstp)) {
case RC_DOIT: case RC_DOIT:
break; break;
case RC_REPLY: case RC_REPLY:
return 1; goto out_cached_reply;
case RC_DROPIT: case RC_DROPIT:
return 0; goto out_dropit;
} }
/* /*
...@@ -1055,11 +1050,8 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) ...@@ -1055,11 +1050,8 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
nfserr = proc->pc_func(rqstp); nfserr = proc->pc_func(rqstp);
nfserr = map_new_errors(rqstp->rq_vers, nfserr); nfserr = map_new_errors(rqstp->rq_vers, nfserr);
if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) { if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags))
dprintk("nfsd: Dropping request; may be revisited later\n"); goto out_update_drop;
nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
return 0;
}
if (rqstp->rq_proc != 0) if (rqstp->rq_proc != 0)
*nfserrp++ = nfserr; *nfserrp++ = nfserr;
...@@ -1067,17 +1059,35 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) ...@@ -1067,17 +1059,35 @@ int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp)
/* /*
* For NFSv2, additional info is never returned in case of an error. * For NFSv2, additional info is never returned in case of an error.
*/ */
if (!(nfserr && rqstp->rq_vers == 2)) { if (!(nfserr && rqstp->rq_vers == 2))
if (!proc->pc_encode(rqstp, nfserrp)) { if (!proc->pc_encode(rqstp, nfserrp))
goto out_encode_err;
nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
out_cached_reply:
return 1;
out_too_large:
dprintk("nfsd: NFSv%d argument too large\n", rqstp->rq_vers);
*statp = rpc_garbage_args;
return 1;
out_decode_err:
dprintk("nfsd: failed to decode arguments!\n");
*statp = rpc_garbage_args;
return 1;
out_update_drop:
dprintk("nfsd: Dropping request; may be revisited later\n");
nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
out_dropit:
return 0;
out_encode_err:
dprintk("nfsd: failed to encode result!\n"); dprintk("nfsd: failed to encode result!\n");
nfsd_cache_update(rqstp, RC_NOCACHE, NULL); nfsd_cache_update(rqstp, RC_NOCACHE, NULL);
*statp = rpc_system_err; *statp = rpc_system_err;
return 1; return 1;
}
}
nfsd_cache_update(rqstp, rqstp->rq_cachetype, statp + 1);
return 1;
} }
int nfsd_pool_stats_open(struct inode *inode, struct file *file) int nfsd_pool_stats_open(struct inode *inode, struct file *file)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment