diff options
59 files changed, 2758 insertions, 2405 deletions
diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c index d3e40db28930..c349fc0f9b80 100644 --- a/fs/lockd/clnt4xdr.c +++ b/fs/lockd/clnt4xdr.c @@ -381,8 +381,9 @@ static void encode_nlm4_lock(struct xdr_stream *xdr, */ static void nlm4_xdr_enc_testargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -402,8 +403,9 @@ static void nlm4_xdr_enc_testargs(struct rpc_rqst *req, */ static void nlm4_xdr_enc_lockargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -424,8 +426,9 @@ static void nlm4_xdr_enc_lockargs(struct rpc_rqst *req, */ static void nlm4_xdr_enc_cancargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -442,8 +445,9 @@ static void nlm4_xdr_enc_cancargs(struct rpc_rqst *req, */ static void nlm4_xdr_enc_unlockargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -458,8 +462,10 @@ static void nlm4_xdr_enc_unlockargs(struct rpc_rqst *req, */ static void nlm4_xdr_enc_res(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_res *result) + const void *data) { + const struct nlm_res *result = data; + encode_cookie(xdr, &result->cookie); encode_nlm4_stat(xdr, result->status); } @@ -479,8 +485,10 @@ static void nlm4_xdr_enc_res(struct rpc_rqst *req, */ static void nlm4_xdr_enc_testres(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_res *result) + const void *data) { + const struct nlm_res *result = data; + encode_cookie(xdr, &result->cookie); encode_nlm4_stat(xdr, result->status); if (result->status == nlm_lck_denied) @@ -525,8 +533,9 @@ out: static int nlm4_xdr_dec_testres(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nlm_res *result) + void *data) { + struct nlm_res *result = data; int error; error = decode_cookie(xdr, &result->cookie); @@ -545,8 +554,9 @@ out: */ static int nlm4_xdr_dec_res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nlm_res *result) + void *data) { + struct nlm_res *result = data; int error; error = decode_cookie(xdr, &result->cookie); @@ -566,15 +576,15 @@ out: #define PROC(proc, argtype, restype) \ [NLMPROC_##proc] = { \ .p_proc = NLMPROC_##proc, \ - .p_encode = (kxdreproc_t)nlm4_xdr_enc_##argtype, \ - .p_decode = (kxdrdproc_t)nlm4_xdr_dec_##restype, \ + .p_encode = nlm4_xdr_enc_##argtype, \ + .p_decode = nlm4_xdr_dec_##restype, \ .p_arglen = NLM4_##argtype##_sz, \ .p_replen = NLM4_##restype##_sz, \ .p_statidx = NLMPROC_##proc, \ .p_name = #proc, \ } -static struct rpc_procinfo nlm4_procedures[] = { +static const struct rpc_procinfo nlm4_procedures[] = { PROC(TEST, testargs, testres), PROC(LOCK, lockargs, res), PROC(CANCEL, cancargs, res), @@ -592,8 +602,10 @@ static struct rpc_procinfo nlm4_procedures[] = { PROC(GRANTED_RES, res, norep), }; +static unsigned int nlm_version4_counts[ARRAY_SIZE(nlm4_procedures)]; const struct rpc_version nlm_version4 = { .number = 4, .nrprocs = ARRAY_SIZE(nlm4_procedures), .procs = nlm4_procedures, + .counts = nlm_version4_counts, }; diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index 3e9f7874b975..3b4724a6c4ee 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c @@ -374,8 +374,9 @@ static void encode_nlm_lock(struct xdr_stream *xdr, */ static void nlm_xdr_enc_testargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -395,8 +396,9 @@ static void nlm_xdr_enc_testargs(struct rpc_rqst *req, */ static void nlm_xdr_enc_lockargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -417,8 +419,9 @@ static void nlm_xdr_enc_lockargs(struct rpc_rqst *req, */ static void nlm_xdr_enc_cancargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -435,8 +438,9 @@ static void nlm_xdr_enc_cancargs(struct rpc_rqst *req, */ static void nlm_xdr_enc_unlockargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_args *args) + const void *data) { + const struct nlm_args *args = data; const struct nlm_lock *lock = &args->lock; encode_cookie(xdr, &args->cookie); @@ -451,8 +455,10 @@ static void nlm_xdr_enc_unlockargs(struct rpc_rqst *req, */ static void nlm_xdr_enc_res(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_res *result) + const void *data) { + const struct nlm_res *result = data; + encode_cookie(xdr, &result->cookie); encode_nlm_stat(xdr, result->status); } @@ -479,8 +485,10 @@ static void encode_nlm_testrply(struct xdr_stream *xdr, static void nlm_xdr_enc_testres(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nlm_res *result) + const void *data) { + const struct nlm_res *result = data; + encode_cookie(xdr, &result->cookie); encode_nlm_stat(xdr, result->status); encode_nlm_testrply(xdr, result); @@ -523,8 +531,9 @@ out: static int nlm_xdr_dec_testres(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nlm_res *result) + void *data) { + struct nlm_res *result = data; int error; error = decode_cookie(xdr, &result->cookie); @@ -543,8 +552,9 @@ out: */ static int nlm_xdr_dec_res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nlm_res *result) + void *data) { + struct nlm_res *result = data; int error; error = decode_cookie(xdr, &result->cookie); @@ -564,15 +574,15 @@ out: #define PROC(proc, argtype, restype) \ [NLMPROC_##proc] = { \ .p_proc = NLMPROC_##proc, \ - .p_encode = (kxdreproc_t)nlm_xdr_enc_##argtype, \ - .p_decode = (kxdrdproc_t)nlm_xdr_dec_##restype, \ + .p_encode = nlm_xdr_enc_##argtype, \ + .p_decode = nlm_xdr_dec_##restype, \ .p_arglen = NLM_##argtype##_sz, \ .p_replen = NLM_##restype##_sz, \ .p_statidx = NLMPROC_##proc, \ .p_name = #proc, \ } -static struct rpc_procinfo nlm_procedures[] = { +static const struct rpc_procinfo nlm_procedures[] = { PROC(TEST, testargs, testres), PROC(LOCK, lockargs, res), PROC(CANCEL, cancargs, res), @@ -590,16 +600,20 @@ static struct rpc_procinfo nlm_procedures[] = { PROC(GRANTED_RES, res, norep), }; +static unsigned int nlm_version1_counts[ARRAY_SIZE(nlm_procedures)]; static const struct rpc_version nlm_version1 = { - .number = 1, - .nrprocs = ARRAY_SIZE(nlm_procedures), - .procs = nlm_procedures, + .number = 1, + .nrprocs = ARRAY_SIZE(nlm_procedures), + .procs = nlm_procedures, + .counts = nlm_version1_counts, }; +static unsigned int nlm_version3_counts[ARRAY_SIZE(nlm_procedures)]; static const struct rpc_version nlm_version3 = { - .number = 3, - .nrprocs = ARRAY_SIZE(nlm_procedures), - .procs = nlm_procedures, + .number = 3, + .nrprocs = ARRAY_SIZE(nlm_procedures), + .procs = nlm_procedures, + .counts = nlm_version3_counts, }; static const struct rpc_version *nlm_versions[] = { @@ -613,9 +627,9 @@ static const struct rpc_version *nlm_versions[] = { static struct rpc_stat nlm_rpc_stats; const struct rpc_program nlm_program = { - .name = "lockd", - .number = NLM_PROGRAM, - .nrvers = ARRAY_SIZE(nlm_versions), - .version = nlm_versions, - .stats = &nlm_rpc_stats, + .name = "lockd", + .number = NLM_PROGRAM, + .nrvers = ARRAY_SIZE(nlm_versions), + .version = nlm_versions, + .stats = &nlm_rpc_stats, }; diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index 19166d4a8d31..9d8166c39c54 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -476,22 +476,23 @@ static void encode_priv(struct xdr_stream *xdr, const struct nsm_args *argp) } static void nsm_xdr_enc_mon(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nsm_args *argp) + const void *argp) { encode_mon_id(xdr, argp); encode_priv(xdr, argp); } static void nsm_xdr_enc_unmon(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nsm_args *argp) + const void *argp) { encode_mon_id(xdr, argp); } static int nsm_xdr_dec_stat_res(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nsm_res *resp) + void *data) { + struct nsm_res *resp = data; __be32 *p; p = xdr_inline_decode(xdr, 4 + 4); @@ -507,8 +508,9 @@ static int nsm_xdr_dec_stat_res(struct rpc_rqst *rqstp, static int nsm_xdr_dec_stat(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nsm_res *resp) + void *data) { + struct nsm_res *resp = data; __be32 *p; p = xdr_inline_decode(xdr, 4); @@ -529,11 +531,11 @@ static int nsm_xdr_dec_stat(struct rpc_rqst *rqstp, #define SM_monres_sz 2 #define SM_unmonres_sz 1 -static struct rpc_procinfo nsm_procedures[] = { +static const struct rpc_procinfo nsm_procedures[] = { [NSMPROC_MON] = { .p_proc = NSMPROC_MON, - .p_encode = (kxdreproc_t)nsm_xdr_enc_mon, - .p_decode = (kxdrdproc_t)nsm_xdr_dec_stat_res, + .p_encode = nsm_xdr_enc_mon, + .p_decode = nsm_xdr_dec_stat_res, .p_arglen = SM_mon_sz, .p_replen = SM_monres_sz, .p_statidx = NSMPROC_MON, @@ -541,8 +543,8 @@ static struct rpc_procinfo nsm_procedures[] = { }, [NSMPROC_UNMON] = { .p_proc = NSMPROC_UNMON, - .p_encode = (kxdreproc_t)nsm_xdr_enc_unmon, - .p_decode = (kxdrdproc_t)nsm_xdr_dec_stat, + .p_encode = nsm_xdr_enc_unmon, + .p_decode = nsm_xdr_dec_stat, .p_arglen = SM_mon_id_sz, .p_replen = SM_unmonres_sz, .p_statidx = NSMPROC_UNMON, @@ -550,10 +552,12 @@ static struct rpc_procinfo nsm_procedures[] = { }, }; +static unsigned int nsm_version1_counts[ARRAY_SIZE(nsm_procedures)]; static const struct rpc_version nsm_version1 = { - .number = 1, - .nrprocs = ARRAY_SIZE(nsm_procedures), - .procs = nsm_procedures + .number = 1, + .nrprocs = ARRAY_SIZE(nsm_procedures), + .procs = nsm_procedures, + .counts = nsm_version1_counts, }; static const struct rpc_version *nsm_version[] = { @@ -563,9 +567,9 @@ static const struct rpc_version *nsm_version[] = { static struct rpc_stat nsm_stats; static const struct rpc_program nsm_program = { - .name = "statd", - .number = NSM_PROGRAM, - .nrvers = ARRAY_SIZE(nsm_version), - .version = nsm_version, - .stats = &nsm_stats + .name = "statd", + .number = NSM_PROGRAM, + .nrvers = ARRAY_SIZE(nsm_version), + .version = nsm_version, + .stats = &nsm_stats }; diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 5d481e8a1b5d..726b6cecf430 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c @@ -739,27 +739,33 @@ module_exit(exit_nlm); /* * Define NLM program and procedures */ -static struct svc_version nlmsvc_version1 = { - .vs_vers = 1, - .vs_nproc = 17, - .vs_proc = nlmsvc_procedures, - .vs_xdrsize = NLMSVC_XDRSIZE, +static unsigned int nlmsvc_version1_count[17]; +static const struct svc_version nlmsvc_version1 = { + .vs_vers = 1, + .vs_nproc = 17, + .vs_proc = nlmsvc_procedures, + .vs_count = nlmsvc_version1_count, + .vs_xdrsize = NLMSVC_XDRSIZE, }; -static struct svc_version nlmsvc_version3 = { - .vs_vers = 3, - .vs_nproc = 24, - .vs_proc = nlmsvc_procedures, - .vs_xdrsize = NLMSVC_XDRSIZE, +static unsigned int nlmsvc_version3_count[24]; +static const struct svc_version nlmsvc_version3 = { + .vs_vers = 3, + .vs_nproc = 24, + .vs_proc = nlmsvc_procedures, + .vs_count = nlmsvc_version3_count, + .vs_xdrsize = NLMSVC_XDRSIZE, }; #ifdef CONFIG_LOCKD_V4 -static struct svc_version nlmsvc_version4 = { - .vs_vers = 4, - .vs_nproc = 24, - .vs_proc = nlmsvc_procedures4, - .vs_xdrsize = NLMSVC_XDRSIZE, +static unsigned int nlmsvc_version4_count[24]; +static const struct svc_version nlmsvc_version4 = { + .vs_vers = 4, + .vs_nproc = 24, + .vs_proc = nlmsvc_procedures4, + .vs_count = nlmsvc_version4_count, + .vs_xdrsize = NLMSVC_XDRSIZE, }; #endif -static struct svc_version * nlmsvc_version[] = { +static const struct svc_version *nlmsvc_version[] = { [1] = &nlmsvc_version1, [3] = &nlmsvc_version3, #ifdef CONFIG_LOCKD_V4 diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 09c576f26c7b..82925f17ec45 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -62,7 +62,7 @@ no_locks: * NULL: Test for presence of service */ static __be32 -nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) +nlm4svc_proc_null(struct svc_rqst *rqstp) { dprintk("lockd: NULL called\n"); return rpc_success; @@ -72,9 +72,9 @@ nlm4svc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) * TEST: Check for conflicting lock */ static __be32 -nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +__nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; __be32 rc = rpc_success; @@ -99,9 +99,15 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, } static __be32 -nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlm4svc_proc_test(struct svc_rqst *rqstp) { + return __nlm4svc_proc_test(rqstp, rqstp->rq_resp); +} + +static __be32 +__nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp) +{ + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; __be32 rc = rpc_success; @@ -141,9 +147,15 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, } static __be32 -nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlm4svc_proc_lock(struct svc_rqst *rqstp) +{ + return __nlm4svc_proc_lock(rqstp, rqstp->rq_resp); +} + +static __be32 +__nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; @@ -170,13 +182,19 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } +static __be32 +nlm4svc_proc_cancel(struct svc_rqst *rqstp) +{ + return __nlm4svc_proc_cancel(rqstp, rqstp->rq_resp); +} + /* * UNLOCK: release a lock */ static __be32 -nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +__nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; @@ -203,14 +221,21 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } +static __be32 +nlm4svc_proc_unlock(struct svc_rqst *rqstp) +{ + return __nlm4svc_proc_unlock(rqstp, rqstp->rq_resp); +} + /* * GRANTED: A server calls us to tell that a process' lock request * was granted */ static __be32 -nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +__nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; + resp->cookie = argp->cookie; dprintk("lockd: GRANTED called\n"); @@ -219,6 +244,12 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } +static __be32 +nlm4svc_proc_granted(struct svc_rqst *rqstp) +{ + return __nlm4svc_proc_granted(rqstp, rqstp->rq_resp); +} + /* * This is the generic lockd callback for async RPC calls */ @@ -243,9 +274,10 @@ static const struct rpc_call_ops nlm4svc_callback_ops = { * because we send the callback before the reply proper. I hope this * doesn't break any clients. */ -static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, - __be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) +static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, + __be32 (*func)(struct svc_rqst *, struct nlm_res *)) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_rqst *call; __be32 stat; @@ -261,7 +293,7 @@ static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args if (call == NULL) return rpc_system_err; - stat = func(rqstp, argp, &call->a_res); + stat = func(rqstp, &call->a_res); if (stat != 0) { nlmsvc_release_call(call); return stat; @@ -273,48 +305,44 @@ static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args return rpc_success; } -static __be32 nlm4svc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlm4svc_proc_test_msg(struct svc_rqst *rqstp) { dprintk("lockd: TEST_MSG called\n"); - return nlm4svc_callback(rqstp, NLMPROC_TEST_RES, argp, nlm4svc_proc_test); + return nlm4svc_callback(rqstp, NLMPROC_TEST_RES, __nlm4svc_proc_test); } -static __be32 nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlm4svc_proc_lock_msg(struct svc_rqst *rqstp) { dprintk("lockd: LOCK_MSG called\n"); - return nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlm4svc_proc_lock); + return nlm4svc_callback(rqstp, NLMPROC_LOCK_RES, __nlm4svc_proc_lock); } -static __be32 nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlm4svc_proc_cancel_msg(struct svc_rqst *rqstp) { dprintk("lockd: CANCEL_MSG called\n"); - return nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlm4svc_proc_cancel); + return nlm4svc_callback(rqstp, NLMPROC_CANCEL_RES, __nlm4svc_proc_cancel); } -static __be32 nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlm4svc_proc_unlock_msg(struct svc_rqst *rqstp) { dprintk("lockd: UNLOCK_MSG called\n"); - return nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlm4svc_proc_unlock); + return nlm4svc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlm4svc_proc_unlock); } -static __be32 nlm4svc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlm4svc_proc_granted_msg(struct svc_rqst *rqstp) { dprintk("lockd: GRANTED_MSG called\n"); - return nlm4svc_callback(rqstp, NLMPROC_GRANTED_RES, argp, nlm4svc_proc_granted); + return nlm4svc_callback(rqstp, NLMPROC_GRANTED_RES, __nlm4svc_proc_granted); } /* * SHARE: create a DOS share or alter existing share. */ static __be32 -nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlm4svc_proc_share(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; + struct nlm_res *resp = rqstp->rq_resp; struct nlm_host *host; struct nlm_file *file; @@ -345,9 +373,10 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, * UNSHARE: Release a DOS share. */ static __be32 -nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlm4svc_proc_unshare(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; + struct nlm_res *resp = rqstp->rq_resp; struct nlm_host *host; struct nlm_file *file; @@ -378,22 +407,23 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, * NM_LOCK: Create an unmonitored lock */ static __be32 -nlm4svc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlm4svc_proc_nm_lock(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; + dprintk("lockd: NM_LOCK called\n"); argp->monitor = 0; /* just clean the monitor flag */ - return nlm4svc_proc_lock(rqstp, argp, resp); + return nlm4svc_proc_lock(rqstp); } /* * FREE_ALL: Release all locks and shares held by client */ static __be32 -nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +nlm4svc_proc_free_all(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; /* Obtain client */ @@ -409,9 +439,10 @@ nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, * SM_NOTIFY: private callback from statd (not part of official NLM proto) */ static __be32 -nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, - void *resp) +nlm4svc_proc_sm_notify(struct svc_rqst *rqstp) { + struct nlm_reboot *argp = rqstp->rq_argp; + dprintk("lockd: SM_NOTIFY called\n"); if (!nlm_privileged_requester(rqstp)) { @@ -429,9 +460,10 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, * client sent a GRANTED_RES, let's remove the associated block */ static __be32 -nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, - void *resp) +nlm4svc_proc_granted_res(struct svc_rqst *rqstp) { + struct nlm_res *argp = rqstp->rq_argp; + if (!nlmsvc_ops) return rpc_success; @@ -463,9 +495,9 @@ nlm4svc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, struct nlm_void { int dummy; }; #define PROC(name, xargt, xrest, argt, rest, respsize) \ - { .pc_func = (svc_procfunc) nlm4svc_proc_##name, \ - .pc_decode = (kxdrproc_t) nlm4svc_decode_##xargt, \ - .pc_encode = (kxdrproc_t) nlm4svc_encode_##xrest, \ + { .pc_func = nlm4svc_proc_##name, \ + .pc_decode = nlm4svc_decode_##xargt, \ + .pc_encode = nlm4svc_encode_##xrest, \ .pc_release = NULL, \ .pc_argsize = sizeof(struct nlm_##argt), \ .pc_ressize = sizeof(struct nlm_##rest), \ @@ -475,7 +507,7 @@ struct nlm_void { int dummy; }; #define No (1+1024/4) /* netobj */ #define St 1 /* status */ #define Rg 4 /* range (offset + length) */ -struct svc_procedure nlmsvc_procedures4[] = { +const struct svc_procedure nlmsvc_procedures4[] = { PROC(null, void, void, void, void, 1), PROC(test, testargs, testres, args, res, Ck+St+2+No+Rg), PROC(lock, lockargs, res, args, res, Ck+St), diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index fb26b9f522e7..07915162581d 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -92,7 +92,7 @@ no_locks: * NULL: Test for presence of service */ static __be32 -nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) +nlmsvc_proc_null(struct svc_rqst *rqstp) { dprintk("lockd: NULL called\n"); return rpc_success; @@ -102,9 +102,9 @@ nlmsvc_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) * TEST: Check for conflicting lock */ static __be32 -nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +__nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; __be32 rc = rpc_success; @@ -130,9 +130,15 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, } static __be32 -nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlmsvc_proc_test(struct svc_rqst *rqstp) { + return __nlmsvc_proc_test(rqstp, rqstp->rq_resp); +} + +static __be32 +__nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp) +{ + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; __be32 rc = rpc_success; @@ -172,9 +178,15 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, } static __be32 -nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlmsvc_proc_lock(struct svc_rqst *rqstp) +{ + return __nlmsvc_proc_lock(rqstp, rqstp->rq_resp); +} + +static __be32 +__nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; struct net *net = SVC_NET(rqstp); @@ -202,13 +214,19 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } +static __be32 +nlmsvc_proc_cancel(struct svc_rqst *rqstp) +{ + return __nlmsvc_proc_cancel(rqstp, rqstp->rq_resp); +} + /* * UNLOCK: release a lock */ static __be32 -nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +__nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_file *file; struct net *net = SVC_NET(rqstp); @@ -236,14 +254,21 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } +static __be32 +nlmsvc_proc_unlock(struct svc_rqst *rqstp) +{ + return __nlmsvc_proc_unlock(rqstp, rqstp->rq_resp); +} + /* * GRANTED: A server calls us to tell that a process' lock request * was granted */ static __be32 -nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +__nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_res *resp) { + struct nlm_args *argp = rqstp->rq_argp; + resp->cookie = argp->cookie; dprintk("lockd: GRANTED called\n"); @@ -252,6 +277,12 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; } +static __be32 +nlmsvc_proc_granted(struct svc_rqst *rqstp) +{ + return __nlmsvc_proc_granted(rqstp, rqstp->rq_resp); +} + /* * This is the generic lockd callback for async RPC calls */ @@ -284,9 +315,10 @@ static const struct rpc_call_ops nlmsvc_callback_ops = { * because we send the callback before the reply proper. I hope this * doesn't break any clients. */ -static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args *argp, - __be32 (*func)(struct svc_rqst *, struct nlm_args *, struct nlm_res *)) +static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, + __be32 (*func)(struct svc_rqst *, struct nlm_res *)) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; struct nlm_rqst *call; __be32 stat; @@ -302,7 +334,7 @@ static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args if (call == NULL) return rpc_system_err; - stat = func(rqstp, argp, &call->a_res); + stat = func(rqstp, &call->a_res); if (stat != 0) { nlmsvc_release_call(call); return stat; @@ -314,50 +346,46 @@ static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args return rpc_success; } -static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlmsvc_proc_test_msg(struct svc_rqst *rqstp) { dprintk("lockd: TEST_MSG called\n"); - return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, argp, nlmsvc_proc_test); + return nlmsvc_callback(rqstp, NLMPROC_TEST_RES, __nlmsvc_proc_test); } -static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlmsvc_proc_lock_msg(struct svc_rqst *rqstp) { dprintk("lockd: LOCK_MSG called\n"); - return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, argp, nlmsvc_proc_lock); + return nlmsvc_callback(rqstp, NLMPROC_LOCK_RES, __nlmsvc_proc_lock); } -static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +static __be32 nlmsvc_proc_cancel_msg(struct svc_rqst *rqstp) { dprintk("lockd: CANCEL_MSG called\n"); - return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, argp, nlmsvc_proc_cancel); + return nlmsvc_callback(rqstp, NLMPROC_CANCEL_RES, __nlmsvc_proc_cancel); } static __be32 -nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +nlmsvc_proc_unlock_msg(struct svc_rqst *rqstp) { dprintk("lockd: UNLOCK_MSG called\n"); - return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, argp, nlmsvc_proc_unlock); + return nlmsvc_callback(rqstp, NLMPROC_UNLOCK_RES, __nlmsvc_proc_unlock); } static __be32 -nlmsvc_proc_granted_msg(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +nlmsvc_proc_granted_msg(struct svc_rqst *rqstp) { dprintk("lockd: GRANTED_MSG called\n"); - return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, argp, nlmsvc_proc_granted); + return nlmsvc_callback(rqstp, NLMPROC_GRANTED_RES, __nlmsvc_proc_granted); } /* * SHARE: create a DOS share or alter existing share. */ static __be32 -nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlmsvc_proc_share(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; + struct nlm_res *resp = rqstp->rq_resp; struct nlm_host *host; struct nlm_file *file; @@ -388,9 +416,10 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, * UNSHARE: Release a DOS share. */ static __be32 -nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlmsvc_proc_unshare(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; + struct nlm_res *resp = rqstp->rq_resp; struct nlm_host *host; struct nlm_file *file; @@ -421,22 +450,23 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, * NM_LOCK: Create an unmonitored lock */ static __be32 -nlmsvc_proc_nm_lock(struct svc_rqst *rqstp, struct nlm_args *argp, - struct nlm_res *resp) +nlmsvc_proc_nm_lock(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; + dprintk("lockd: NM_LOCK called\n"); argp->monitor = 0; /* just clean the monitor flag */ - return nlmsvc_proc_lock(rqstp, argp, resp); + return nlmsvc_proc_lock(rqstp); } /* * FREE_ALL: Release all locks and shares held by client */ static __be32 -nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, - void *resp) +nlmsvc_proc_free_all(struct svc_rqst *rqstp) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_host *host; /* Obtain client */ @@ -452,9 +482,10 @@ nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, * SM_NOTIFY: private callback from statd (not part of official NLM proto) */ static __be32 -nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, - void *resp) +nlmsvc_proc_sm_notify(struct svc_rqst *rqstp) { + struct nlm_reboot *argp = rqstp->rq_argp; + dprintk("lockd: SM_NOTIFY called\n"); if (!nlm_privileged_requester(rqstp)) { @@ -472,9 +503,10 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, * client sent a GRANTED_RES, let's remove the associated block */ static __be32 -nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, - void *resp) +nlmsvc_proc_granted_res(struct svc_rqst *rqstp) { + struct nlm_res *argp = rqstp->rq_argp; + if (!nlmsvc_ops) return rpc_success; @@ -505,9 +537,9 @@ nlmsvc_proc_granted_res(struct svc_rqst *rqstp, struct nlm_res *argp, struct nlm_void { int dummy; }; #define PROC(name, xargt, xrest, argt, rest, respsize) \ - { .pc_func = (svc_procfunc) nlmsvc_proc_##name, \ - .pc_decode = (kxdrproc_t) nlmsvc_decode_##xargt, \ - .pc_encode = (kxdrproc_t) nlmsvc_encode_##xrest, \ + { .pc_func = nlmsvc_proc_##name, \ + .pc_decode = nlmsvc_decode_##xargt, \ + .pc_encode = nlmsvc_encode_##xrest, \ .pc_release = NULL, \ .pc_argsize = sizeof(struct nlm_##argt), \ .pc_ressize = sizeof(struct nlm_##rest), \ @@ -519,7 +551,7 @@ struct nlm_void { int dummy; }; #define No (1+1024/4) /* Net Obj */ #define Rg 2 /* range - offset + size */ -struct svc_procedure nlmsvc_procedures[] = { +const struct svc_procedure nlmsvc_procedures[] = { PROC(null, void, void, void, void, 1), PROC(test, testargs, testres, args, res, Ck+St+2+No+Rg), PROC(lock, lockargs, res, args, res, Ck+St), diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 5b651daad518..442bbd0b0b29 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -182,8 +182,9 @@ nlm_encode_testres(__be32 *p, struct nlm_res *resp) * First, the server side XDR functions */ int -nlmsvc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_testargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; u32 exclusive; if (!(p = nlm_decode_cookie(p, &argp->cookie))) @@ -199,16 +200,19 @@ nlmsvc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_encode_testres(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_resp; + if (!(p = nlm_encode_testres(p, resp))) return 0; return xdr_ressize_check(rqstp, p); } int -nlmsvc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; u32 exclusive; if (!(p = nlm_decode_cookie(p, &argp->cookie))) @@ -227,8 +231,9 @@ nlmsvc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; u32 exclusive; if (!(p = nlm_decode_cookie(p, &argp->cookie))) @@ -243,8 +248,10 @@ nlmsvc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; + if (!(p = nlm_decode_cookie(p, &argp->cookie)) || !(p = nlm_decode_lock(p, &argp->lock))) return 0; @@ -253,8 +260,9 @@ nlmsvc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlmsvc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_lock *lock = &argp->lock; memset(lock, 0, sizeof(*lock)); @@ -274,8 +282,10 @@ nlmsvc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlmsvc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_encode_shareres(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_resp; + if (!(p = nlm_encode_cookie(p, &resp->cookie))) return 0; *p++ = resp->status; @@ -284,8 +294,10 @@ nlmsvc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlmsvc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_encode_res(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_resp; + if (!(p = nlm_encode_cookie(p, &resp->cookie))) return 0; *p++ = resp->status; @@ -293,8 +305,9 @@ nlmsvc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlmsvc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) +nlmsvc_decode_notify(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_lock *lock = &argp->lock; if (!(p = xdr_decode_string_inplace(p, &lock->caller, @@ -305,8 +318,10 @@ nlmsvc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) } int -nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp) +nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_reboot *argp = rqstp->rq_argp; + if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN))) return 0; argp->state = ntohl(*p++); @@ -316,8 +331,10 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp) } int -nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_argp; + if (!(p = nlm_decode_cookie(p, &resp->cookie))) return 0; resp->status = *p++; @@ -325,13 +342,13 @@ nlmsvc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlmsvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlmsvc_decode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_argsize_check(rqstp, p); } int -nlmsvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlmsvc_encode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); } diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index dfa4789cd460..2a0cd5679c49 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c @@ -179,8 +179,9 @@ nlm4_encode_testres(__be32 *p, struct nlm_res *resp) * First, the server side XDR functions */ int -nlm4svc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_testargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; u32 exclusive; if (!(p = nlm4_decode_cookie(p, &argp->cookie))) @@ -196,16 +197,19 @@ nlm4svc_decode_testargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_encode_testres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_encode_testres(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_resp; + if (!(p = nlm4_encode_testres(p, resp))) return 0; return xdr_ressize_check(rqstp, p); } int -nlm4svc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; u32 exclusive; if (!(p = nlm4_decode_cookie(p, &argp->cookie))) @@ -224,8 +228,9 @@ nlm4svc_decode_lockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; u32 exclusive; if (!(p = nlm4_decode_cookie(p, &argp->cookie))) @@ -240,8 +245,10 @@ nlm4svc_decode_cancargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; + if (!(p = nlm4_decode_cookie(p, &argp->cookie)) || !(p = nlm4_decode_lock(p, &argp->lock))) return 0; @@ -250,8 +257,9 @@ nlm4svc_decode_unlockargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) +nlm4svc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_lock *lock = &argp->lock; memset(lock, 0, sizeof(*lock)); @@ -271,8 +279,10 @@ nlm4svc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p, nlm_args *argp) } int -nlm4svc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_encode_shareres(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_resp; + if (!(p = nlm4_encode_cookie(p, &resp->cookie))) return 0; *p++ = resp->status; @@ -281,8 +291,10 @@ nlm4svc_encode_shareres(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlm4svc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_encode_res(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_resp; + if (!(p = nlm4_encode_cookie(p, &resp->cookie))) return 0; *p++ = resp->status; @@ -290,8 +302,9 @@ nlm4svc_encode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlm4svc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) +nlm4svc_decode_notify(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_args *argp = rqstp->rq_argp; struct nlm_lock *lock = &argp->lock; if (!(p = xdr_decode_string_inplace(p, &lock->caller, @@ -302,8 +315,10 @@ nlm4svc_decode_notify(struct svc_rqst *rqstp, __be32 *p, struct nlm_args *argp) } int -nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp) +nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_reboot *argp = rqstp->rq_argp; + if (!(p = xdr_decode_string_inplace(p, &argp->mon, &argp->len, SM_MAXSTRLEN))) return 0; argp->state = ntohl(*p++); @@ -313,8 +328,10 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp } int -nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) +nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p) { + struct nlm_res *resp = rqstp->rq_argp; + if (!(p = nlm4_decode_cookie(p, &resp->cookie))) return 0; resp->status = *p++; @@ -322,13 +339,13 @@ nlm4svc_decode_res(struct svc_rqst *rqstp, __be32 *p, struct nlm_res *resp) } int -nlm4svc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlm4svc_decode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_argsize_check(rqstp, p); } int -nlm4svc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nlm4svc_encode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); } diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c index 73a1f928226c..34323877ec13 100644 --- a/fs/nfs/callback.c +++ b/fs/nfs/callback.c @@ -439,7 +439,7 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp) /* * Define NFS4 callback program */ -static struct svc_version *nfs4_callback_version[] = { +static const struct svc_version *nfs4_callback_version[] = { [1] = &nfs4_callback_version1, [4] = &nfs4_callback_version4, }; diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h index c701c308fac5..3dc54d7cb19c 100644 --- a/fs/nfs/callback.h +++ b/fs/nfs/callback.h @@ -114,8 +114,7 @@ struct cb_sequenceres { uint32_t csr_target_highestslotid; }; -extern __be32 nfs4_callback_sequence(struct cb_sequenceargs *args, - struct cb_sequenceres *res, +extern __be32 nfs4_callback_sequence(void *argp, void *resp, struct cb_process_state *cps); #define RCA4_TYPE_MASK_RDATA_DLG 0 @@ -134,15 +133,13 @@ struct cb_recallanyargs { uint32_t craa_type_mask; }; -extern __be32 nfs4_callback_recallany(struct cb_recallanyargs *args, - void *dummy, +extern __be32 nfs4_callback_recallany(void *argp, void *resp, struct cb_process_state *cps); struct cb_recallslotargs { uint32_t crsa_target_highest_slotid; }; -extern __be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, - void *dummy, +extern __be32 nfs4_callback_recallslot(void *argp, void *resp, struct cb_process_state *cps); struct cb_layoutrecallargs { @@ -159,9 +156,8 @@ struct cb_layoutrecallargs { }; }; -extern __be32 nfs4_callback_layoutrecall( - struct cb_layoutrecallargs *args, - void *dummy, struct cb_process_state *cps); +extern __be32 nfs4_callback_layoutrecall(void *argp, void *resp, + struct cb_process_state *cps); struct cb_devicenotifyitem { uint32_t cbd_notify_type; @@ -175,9 +171,8 @@ struct cb_devicenotifyargs { struct cb_devicenotifyitem *devs; }; -extern __be32 nfs4_callback_devicenotify( - struct cb_devicenotifyargs *args, - void *dummy, struct cb_process_state *cps); +extern __be32 nfs4_callback_devicenotify(void *argp, void *resp, + struct cb_process_state *cps); struct cb_notify_lock_args { struct nfs_fh cbnl_fh; @@ -185,15 +180,13 @@ struct cb_notify_lock_args { bool cbnl_valid; }; -extern __be32 nfs4_callback_notify_lock(struct cb_notify_lock_args *args, - void *dummy, +extern __be32 nfs4_callback_notify_lock(void *argp, void *resp, struct cb_process_state *cps); #endif /* CONFIG_NFS_V4_1 */ extern int check_gss_callback_principal(struct nfs_client *, struct svc_rqst *); -extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args, - struct cb_getattrres *res, +extern __be32 nfs4_callback_getattr(void *argp, void *resp, struct cb_process_state *cps); -extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, +extern __be32 nfs4_callback_recall(void *argp, void *resp, struct cb_process_state *cps); #if IS_ENABLED(CONFIG_NFS_V4) extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 52479f180ea1..5427cdf04c5a 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c @@ -19,10 +19,11 @@ #define NFSDBG_FACILITY NFSDBG_CALLBACK -__be32 nfs4_callback_getattr(struct cb_getattrargs *args, - struct cb_getattrres *res, +__be32 nfs4_callback_getattr(void *argp, void *resp, struct cb_process_state *cps) { + struct cb_getattrargs *args = argp; + struct cb_getattrres *res = resp; struct nfs_delegation *delegation; struct nfs_inode *nfsi; struct inode *inode; @@ -68,9 +69,10 @@ out: return res->status; } -__be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, +__be32 nfs4_callback_recall(void *argp, void *resp, struct cb_process_state *cps) { + struct cb_recallargs *args = argp; struct inode *inode; __be32 res; @@ -324,9 +326,10 @@ static u32 do_callback_layoutrecall(struct nfs_client *clp, return initiate_bulk_draining(clp, args); } -__be32 nfs4_callback_layoutrecall(struct cb_layoutrecallargs *args, - void *dummy, struct cb_process_state *cps) +__be32 nfs4_callback_layoutrecall(void *argp, void *resp, + struct cb_process_state *cps) { + struct cb_layoutrecallargs *args = argp; u32 res = NFS4ERR_OP_NOT_IN_SESSION; if (cps->clp) @@ -345,9 +348,10 @@ static void pnfs_recall_all_layouts(struct nfs_client *clp) do_callback_layoutrecall(clp, &args); } -__be32 nfs4_callback_devicenotify(struct cb_devicenotifyargs *args, - void *dummy, struct cb_process_state *cps) +__be32 nfs4_callback_devicenotify(void *argp, void *resp, + struct cb_process_state *cps) { + struct cb_devicenotifyargs *args = argp; int i; __be32 res = 0; struct nfs_client *clp = cps->clp; @@ -469,10 +473,11 @@ out: return status; } -__be32 nfs4_callback_sequence(struct cb_sequenceargs *args, - struct cb_sequenceres *res, +__be32 nfs4_callback_sequence(void *argp, void *resp, struct cb_process_state *cps) { + struct cb_sequenceargs *args = argp; + struct cb_sequenceres *res = resp; struct nfs4_slot_table *tbl; struct nfs4_slot *slot; struct nfs_client *clp; @@ -571,9 +576,10 @@ validate_bitmap_values(unsigned long mask) return (mask & ~RCA4_TYPE_MASK_ALL) == 0; } -__be32 nfs4_callback_recallany(struct cb_recallanyargs *args, void *dummy, +__be32 nfs4_callback_recallany(void *argp, void *resp, struct cb_process_state *cps) { + struct cb_recallanyargs *args = argp; __be32 status; fmode_t flags = 0; @@ -606,9 +612,10 @@ out: } /* Reduce the fore channel's max_slots to the target value */ -__be32 nfs4_callback_recallslot(struct cb_recallslotargs *args, void *dummy, +__be32 nfs4_callback_recallslot(void *argp, void *resp, struct cb_process_state *cps) { + struct cb_recallslotargs *args = argp; struct nfs4_slot_table *fc_tbl; __be32 status; @@ -631,9 +638,11 @@ out: return status; } -__be32 nfs4_callback_notify_lock(struct cb_notify_lock_args *args, void *dummy, +__be32 nfs4_callback_notify_lock(void *argp, void *resp, struct cb_process_state *cps) { + struct cb_notify_lock_args *args = argp; + if (!cps->clp) /* set in cb_sequence */ return htonl(NFS4ERR_OP_NOT_IN_SESSION); diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c index 390ac9c39c59..681dd642f119 100644 --- a/fs/nfs/callback_xdr.c +++ b/fs/nfs/callback_xdr.c @@ -43,32 +43,27 @@ /* Internal error code */ #define NFS4ERR_RESOURCE_HDR 11050 -typedef __be32 (*callback_process_op_t)(void *, void *, - struct cb_process_state *); -typedef __be32 (*callback_decode_arg_t)(struct svc_rqst *, struct xdr_stream *, void *); -typedef __be32 (*callback_encode_res_t)(struct svc_rqst *, struct xdr_stream *, void *); - - struct callback_op { - callback_process_op_t process_op; - callback_decode_arg_t decode_args; - callback_encode_res_t encode_res; + __be32 (*process_op)(void *, void *, struct cb_process_state *); + __be32 (*decode_args)(struct svc_rqst *, struct xdr_stream *, void *); + __be32 (*encode_res)(struct svc_rqst *, struct xdr_stream *, + const void *); long res_maxsize; }; static struct callback_op callback_ops[]; -static __be32 nfs4_callback_null(struct svc_rqst *rqstp, void *argp, void *resp) +static __be32 nfs4_callback_null(struct svc_rqst *rqstp) { return htonl(NFS4_OK); } -static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +static int nfs4_decode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_argsize_check(rqstp, p); } -static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); } @@ -184,8 +179,10 @@ static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) return 0; } -static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_getattrargs *args) +static __be32 decode_getattr_args(struct svc_rqst *rqstp, + struct xdr_stream *xdr, void *argp) { + struct cb_getattrargs *args = argp; __be32 status; status = decode_fh(xdr, &args->fh); @@ -194,8 +191,10 @@ static __be32 decode_getattr_args(struct svc_rqst *rqstp, struct xdr_stream *xdr return decode_bitmap(xdr, args->bitmap); } -static __be32 decode_recall_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_recallargs *args) +static __be32 decode_recall_args(struct svc_rqst *rqstp, + struct xdr_stream *xdr, void *argp) { + struct cb_recallargs *args = argp; __be32 *p; __be32 status; @@ -217,9 +216,9 @@ static __be32 decode_layout_stateid(struct xdr_stream *xdr, nfs4_stateid *statei } static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, - struct xdr_stream *xdr, - struct cb_layoutrecallargs *args) + struct xdr_stream *xdr, void *argp) { + struct cb_layoutrecallargs *args = argp; __be32 *p; __be32 status = 0; uint32_t iomode; @@ -262,8 +261,9 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, static __be32 decode_devicenotify_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, - struct cb_devicenotifyargs *args) + void *argp) { + struct cb_devicenotifyargs *args = argp; __be32 *p; __be32 status = 0; u32 tmp; @@ -403,8 +403,9 @@ out: static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, - struct cb_sequenceargs *args) + void *argp) { + struct cb_sequenceargs *args = argp; __be32 *p; int i; __be32 status; @@ -450,8 +451,9 @@ out_free: static __be32 decode_recallany_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, - struct cb_recallanyargs *args) + void *argp) { + struct cb_recallanyargs *args = argp; uint32_t bitmap[2]; __be32 *p, status; @@ -469,8 +471,9 @@ static __be32 decode_recallany_args(struct svc_rqst *rqstp, static __be32 decode_recallslot_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, - struct cb_recallslotargs *args) + void *argp) { + struct cb_recallslotargs *args = argp; __be32 *p; p = read_buf(xdr, 4); @@ -510,8 +513,10 @@ static __be32 decode_lockowner(struct xdr_stream *xdr, struct cb_notify_lock_arg return 0; } -static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct cb_notify_lock_args *args) +static __be32 decode_notify_lock_args(struct svc_rqst *rqstp, + struct xdr_stream *xdr, void *argp) { + struct cb_notify_lock_args *args = argp; __be32 status; status = decode_fh(xdr, &args->cbnl_fh); @@ -641,8 +646,10 @@ static __be32 encode_op_hdr(struct xdr_stream *xdr, uint32_t op, __be32 res) return 0; } -static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, const struct cb_getattrres *res) +static __be32 encode_getattr_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, + const void *resp) { + const struct cb_getattrres *res = resp; __be32 *savep = NULL; __be32 status = res->status; @@ -683,8 +690,9 @@ static __be32 encode_sessionid(struct xdr_stream *xdr, static __be32 encode_cb_sequence_res(struct svc_rqst *rqstp, struct xdr_stream *xdr, - const struct cb_sequenceres *res) + const void *resp) { + const struct cb_sequenceres *res = resp; __be32 *p; __be32 status = res->csr_status; @@ -871,7 +879,7 @@ encode_hdr: /* * Decode, process and encode a COMPOUND */ -static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *resp) +static __be32 nfs4_callback_compound(struct svc_rqst *rqstp) { struct cb_compound_hdr_arg hdr_arg = { 0 }; struct cb_compound_hdr_res hdr_res = { NULL }; @@ -907,7 +915,8 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp, void *argp, void *r while (status == 0 && nops != hdr_arg.nops) { status = process_op(nops, rqstp, &xdr_in, - argp, &xdr_out, resp, &cps); + rqstp->rq_argp, &xdr_out, rqstp->rq_resp, + &cps); nops++; } @@ -937,48 +946,46 @@ static struct callback_op callback_ops[] = { .res_maxsize = CB_OP_HDR_RES_MAXSZ, }, [OP_CB_GETATTR] = { - .process_op = (callback_process_op_t)nfs4_callback_getattr, - .decode_args = (callback_decode_arg_t)decode_getattr_args, - .encode_res = (callback_encode_res_t)encode_getattr_res, + .process_op = nfs4_callback_getattr, + .decode_args = decode_getattr_args, + .encode_res = encode_getattr_res, .res_maxsize = CB_OP_GETATTR_RES_MAXSZ, }, [OP_CB_RECALL] = { - .process_op = (callback_process_op_t)nfs4_callback_recall, - .decode_args = (callback_decode_arg_t)decode_recall_args, + .process_op = nfs4_callback_recall, + .decode_args = decode_recall_args, .res_maxsize = CB_OP_RECALL_RES_MAXSZ, }, #if defined(CONFIG_NFS_V4_1) [OP_CB_LAYOUTRECALL] = { - .process_op = (callback_process_op_t)nfs4_callback_layoutrecall, - .decode_args = - (callback_decode_arg_t)decode_layoutrecall_args, + .process_op = nfs4_callback_layoutrecall, + .decode_args = decode_layoutrecall_args, .res_maxsize = CB_OP_LAYOUTRECALL_RES_MAXSZ, }, [OP_CB_NOTIFY_DEVICEID] = { - .process_op = (callback_process_op_t)nfs4_callback_devicenotify, - .decode_args = - (callback_decode_arg_t)decode_devicenotify_args, + .process_op = nfs4_callback_devicenotify, + .decode_args = decode_devicenotify_args, .res_maxsize = CB_OP_DEVICENOTIFY_RES_MAXSZ, }, [OP_CB_SEQUENCE] = { - .process_op = (callback_process_op_t)nfs4_callback_sequence, - .decode_args = (callback_decode_arg_t)decode_cb_sequence_args, - .encode_res = (callback_encode_res_t)encode_cb_sequence_res, + .process_op = nfs4_callback_sequence, + .decode_args = decode_cb_sequence_args, + .encode_res = encode_cb_sequence_res, .res_maxsize = CB_OP_SEQUENCE_RES_MAXSZ, }, [OP_CB_RECALL_ANY] = { - .process_op = (callback_process_op_t)nfs4_callback_recallany, - .decode_args = (callback_decode_arg_t)decode_recallany_args, + .process_op = nfs4_callback_recallany, + .decode_args = decode_recallany_args, .res_maxsize = CB_OP_RECALLANY_RES_MAXSZ, }, [OP_CB_RECALL_SLOT] = { - .process_op = (callback_process_op_t)nfs4_callback_recallslot, - .decode_args = (callback_decode_arg_t)decode_recallslot_args, + .process_op = nfs4_callback_recallslot, + .decode_args = decode_recallslot_args, .res_maxsize = CB_OP_RECALLSLOT_RES_MAXSZ, }, [OP_CB_NOTIFY_LOCK] = { - .process_op = (callback_process_op_t)nfs4_callback_notify_lock, - .decode_args = (callback_decode_arg_t)decode_notify_lock_args, + .process_op = nfs4_callback_notify_lock, + .decode_args = decode_notify_lock_args, .res_maxsize = CB_OP_NOTIFY_LOCK_RES_MAXSZ, }, #endif /* CONFIG_NFS_V4_1 */ @@ -987,36 +994,40 @@ static struct callback_op callback_ops[] = { /* * Define NFS4 callback procedures */ -static struct svc_procedure nfs4_callback_procedures1[] = { +static const struct svc_procedure nfs4_callback_procedures1[] = { [CB_NULL] = { .pc_func = nfs4_callback_null, - .pc_decode = (kxdrproc_t)nfs4_decode_void, - .pc_encode = (kxdrproc_t)nfs4_encode_void, + .pc_decode = nfs4_decode_void, + .pc_encode = nfs4_encode_void, .pc_xdrressize = 1, }, [CB_COMPOUND] = { .pc_func = nfs4_callback_compound, - .pc_encode = (kxdrproc_t)nfs4_encode_void, + .pc_encode = nfs4_encode_void, .pc_argsize = 256, .pc_ressize = 256, .pc_xdrressize = NFS4_CALLBACK_BUFSIZE, } }; -struct svc_version nfs4_callback_version1 = { +static unsigned int nfs4_callback_count1[ARRAY_SIZE(nfs4_callback_procedures1)]; +const struct svc_version nfs4_callback_version1 = { .vs_vers = 1, .vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1), .vs_proc = nfs4_callback_procedures1, + .vs_count = nfs4_callback_count1, .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, .vs_dispatch = NULL, .vs_hidden = true, .vs_need_cong_ctrl = true, }; -struct svc_version nfs4_callback_version4 = { +static unsigned int nfs4_callback_count4[ARRAY_SIZE(nfs4_callback_procedures1)]; +const struct svc_version nfs4_callback_version4 = { .vs_vers = 4, .vs_nproc = ARRAY_SIZE(nfs4_callback_procedures1), .vs_proc = nfs4_callback_procedures1, + .vs_count = nfs4_callback_count4, .vs_xdrsize = NFS4_CALLBACK_XDRSIZE, .vs_dispatch = NULL, .vs_hidden = true, diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 8701d7617964..c7ebba9eb611 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -226,8 +226,8 @@ static inline void nfs_fs_proc_exit(void) #endif /* callback_xdr.c */ -extern struct svc_version nfs4_callback_version1; -extern struct svc_version nfs4_callback_version4; +extern const struct svc_version nfs4_callback_version1; +extern const struct svc_version nfs4_callback_version4; struct nfs_pageio_descriptor; /* pagelist.c */ @@ -271,12 +271,12 @@ static inline bool nfs_match_open_context(const struct nfs_open_context *ctx1, } /* nfs2xdr.c */ -extern struct rpc_procinfo nfs_procedures[]; +extern const struct rpc_procinfo nfs_procedures[]; extern int nfs2_decode_dirent(struct xdr_stream *, struct nfs_entry *, int); /* nfs3xdr.c */ -extern struct rpc_procinfo nfs3_procedures[]; +extern const struct rpc_procinfo nfs3_procedures[]; extern int nfs3_decode_dirent(struct xdr_stream *, struct nfs_entry *, int); @@ -293,7 +293,7 @@ extern const u32 nfs41_maxgetdevinfo_overhead; /* nfs4proc.c */ #if IS_ENABLED(CONFIG_NFS_V4) -extern struct rpc_procinfo nfs4_procedures[]; +extern const struct rpc_procinfo nfs4_procedures[]; #endif #ifdef CONFIG_NFS_V4_SECURITY_LABEL diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 09b190015df4..3efe946672be 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -304,7 +304,7 @@ static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname) } static void mnt_xdr_enc_dirpath(struct rpc_rqst *req, struct xdr_stream *xdr, - const char *dirpath) + const void *dirpath) { encode_mntdirpath(xdr, dirpath); } @@ -357,8 +357,9 @@ static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res) static int mnt_xdr_dec_mountres(struct rpc_rqst *req, struct xdr_stream *xdr, - struct mountres *res) + void *data) { + struct mountres *res = data; int status; status = decode_status(xdr, res); @@ -449,8 +450,9 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res) static int mnt_xdr_dec_mountres3(struct rpc_rqst *req, struct xdr_stream *xdr, - struct mountres *res) + void *data) { + struct mountres *res = data; int status; status = decode_fhs_status(xdr, res); @@ -464,11 +466,11 @@ static int mnt_xdr_dec_mountres3(struct rpc_rqst *req, return decode_auth_flavors(xdr, res); } -static struct rpc_procinfo mnt_procedures[] = { +static const struct rpc_procinfo mnt_procedures[] = { [MOUNTPROC_MNT] = { .p_proc = MOUNTPROC_MNT, - .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, - .p_decode = (kxdrdproc_t)mnt_xdr_dec_mountres, + .p_encode = mnt_xdr_enc_dirpath, + .p_decode = mnt_xdr_dec_mountres, .p_arglen = MNT_enc_dirpath_sz, .p_replen = MNT_dec_mountres_sz, .p_statidx = MOUNTPROC_MNT, @@ -476,18 +478,18 @@ static struct rpc_procinfo mnt_procedures[] = { }, [MOUNTPROC_UMNT] = { .p_proc = MOUNTPROC_UMNT, - .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, + .p_encode = mnt_xdr_enc_dirpath, .p_arglen = MNT_enc_dirpath_sz, .p_statidx = MOUNTPROC_UMNT, .p_name = "UMOUNT", }, }; -static struct rpc_procinfo mnt3_procedures[] = { +static const struct rpc_procinfo mnt3_procedures[] = { [MOUNTPROC3_MNT] = { .p_proc = MOUNTPROC3_MNT, - .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, - .p_decode = (kxdrdproc_t)mnt_xdr_dec_mountres3, + .p_encode = mnt_xdr_enc_dirpath, + .p_decode = mnt_xdr_dec_mountres3, .p_arglen = MNT_enc_dirpath_sz, .p_replen = MNT_dec_mountres3_sz, .p_statidx = MOUNTPROC3_MNT, @@ -495,24 +497,27 @@ static struct rpc_procinfo mnt3_procedures[] = { }, [MOUNTPROC3_UMNT] = { .p_proc = MOUNTPROC3_UMNT, - .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, + .p_encode = mnt_xdr_enc_dirpath, .p_arglen = MNT_enc_dirpath_sz, .p_statidx = MOUNTPROC3_UMNT, .p_name = "UMOUNT", }, }; - +static unsigned int mnt_counts[ARRAY_SIZE(mnt_procedures)]; static const struct rpc_version mnt_version1 = { .number = 1, .nrprocs = ARRAY_SIZE(mnt_procedures), .procs = mnt_procedures, + .counts = mnt_counts, }; +static unsigned int mnt3_counts[ARRAY_SIZE(mnt_procedures)]; static const struct rpc_version mnt_version3 = { .number = 3, .nrprocs = ARRAY_SIZE(mnt3_procedures), .procs = mnt3_procedures, + .counts = mnt3_counts, }; static const struct rpc_version *mnt_version[] = { diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index b4e03ed8599d..c8a7e98c1371 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -568,8 +568,10 @@ out_default: static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_fh *fh) + const void *data) { + const struct nfs_fh *fh = data; + encode_fhandle(xdr, fh); } @@ -583,23 +585,29 @@ static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req, */ static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_sattrargs *args) + const void *data) { + const struct nfs_sattrargs *args = data; + encode_fhandle(xdr, args->fh); encode_sattr(xdr, args->sattr); } static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_diropargs *args) + const void *data) { + const struct nfs_diropargs *args = data; + encode_diropargs(xdr, args->fh, args->name, args->len); } static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_readlinkargs *args) + const void *data) { + const struct nfs_readlinkargs *args = data; + encode_fhandle(xdr, args->fh); prepare_reply_buffer(req, args->pages, args->pgbase, args->pglen, NFS_readlinkres_sz); @@ -632,8 +640,10 @@ static void encode_readargs(struct xdr_stream *xdr, static void nfs2_xdr_enc_readargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_pgio_args *args) + const void *data) { + const struct nfs_pgio_args *args = data; + encode_readargs(xdr, args); prepare_reply_buffer(req, args->pages, args->pgbase, args->count, NFS_readres_sz); @@ -672,8 +682,10 @@ static void encode_writeargs(struct xdr_stream *xdr, static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_pgio_args *args) + const void *data) { + const struct nfs_pgio_args *args = data; + encode_writeargs(xdr, args); xdr->buf->flags |= XDRBUF_WRITE; } @@ -688,16 +700,20 @@ static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req, */ static void nfs2_xdr_enc_createargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_createargs *args) + const void *data) { + const struct nfs_createargs *args = data; + encode_diropargs(xdr, args->fh, args->name, args->len); encode_sattr(xdr, args->sattr); } static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_removeargs *args) + const void *data) { + const struct nfs_removeargs *args = data; + encode_diropargs(xdr, args->fh, args->name.name, args->name.len); } @@ -711,8 +727,9 @@ static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req, */ static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_renameargs *args) + const void *data) { + const struct nfs_renameargs *args = data; const struct qstr *old = args->old_name; const struct qstr *new = args->new_name; @@ -730,8 +747,10 @@ static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req, */ static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_linkargs *args) + const void *data) { + const struct nfs_linkargs *args = data; + encode_fhandle(xdr, args->fromfh); encode_diropargs(xdr, args->tofh, args->toname, args->tolen); } @@ -747,8 +766,10 @@ static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req, */ static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_symlinkargs *args) + const void *data) { + const struct nfs_symlinkargs *args = data; + encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen); encode_path(xdr, args->pages, args->pathlen); encode_sattr(xdr, args->sattr); @@ -777,8 +798,10 @@ static void encode_readdirargs(struct xdr_stream *xdr, static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_readdirargs *args) + const void *data) { + const struct nfs_readdirargs *args = data; + encode_readdirargs(xdr, args); prepare_reply_buffer(req, args->pages, 0, args->count, NFS_readdirres_sz); @@ -809,13 +832,13 @@ out_default: } static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_fattr *result) + void *result) { return decode_attrstat(xdr, result, NULL); } static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_diropok *result) + void *result) { return decode_diropres(xdr, result); } @@ -860,8 +883,9 @@ out_default: * }; */ static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_pgio_res *result) + void *data) { + struct nfs_pgio_res *result = data; enum nfs_stat status; int error; @@ -882,8 +906,10 @@ out_default: } static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_pgio_res *result) + void *data) { + struct nfs_pgio_res *result = data; + /* All NFSv2 writes are "file sync" writes */ result->verf->committed = NFS_FILE_SYNC; return decode_attrstat(xdr, result->fattr, &result->op_status); @@ -1034,7 +1060,7 @@ out_overflow: } static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs2_fsstat *result) + void *result) { enum nfs_stat status; int error; @@ -1118,15 +1144,15 @@ static int nfs_stat_to_errno(enum nfs_stat status) #define PROC(proc, argtype, restype, timer) \ [NFSPROC_##proc] = { \ .p_proc = NFSPROC_##proc, \ - .p_encode = (kxdreproc_t)nfs2_xdr_enc_##argtype, \ - .p_decode = (kxdrdproc_t)nfs2_xdr_dec_##restype, \ + .p_encode = nfs2_xdr_enc_##argtype, \ + .p_decode = nfs2_xdr_dec_##restype, \ .p_arglen = NFS_##argtype##_sz, \ .p_replen = NFS_##restype##_sz, \ .p_timer = timer, \ .p_statidx = NFSPROC_##proc, \ .p_name = #proc, \ } -struct rpc_procinfo nfs_procedures[] = { +const struct rpc_procinfo nfs_procedures[] = { PROC(GETATTR, fhandle, attrstat, 1), PROC(SETATTR, sattrargs, attrstat, 0), PROC(LOOKUP, diropargs, diropres, 2), @@ -1144,8 +1170,10 @@ struct rpc_procinfo nfs_procedures[] = { PROC(STATFS, fhandle, statfsres, 0), }; +static unsigned int nfs_version2_counts[ARRAY_SIZE(nfs_procedures)]; const struct rpc_version nfs_version2 = { .number = 2, .nrprocs = ARRAY_SIZE(nfs_procedures), - .procs = nfs_procedures + .procs = nfs_procedures, + .counts = nfs_version2_counts, }; diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 267126d32ec0..670eddb3ae36 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -846,8 +846,10 @@ static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh, */ static void nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_fh *fh) + const void *data) { + const struct nfs_fh *fh = data; + encode_nfs_fh3(xdr, fh); } @@ -884,8 +886,9 @@ static void encode_sattrguard3(struct xdr_stream *xdr, static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_sattrargs *args) + const void *data) { + const struct nfs3_sattrargs *args = data; encode_nfs_fh3(xdr, args->fh); encode_sattr3(xdr, args->sattr); encode_sattrguard3(xdr, args); @@ -900,8 +903,10 @@ static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, */ static void nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_diropargs *args) + const void *data) { + const struct nfs3_diropargs *args = data; + encode_diropargs3(xdr, args->fh, args->name, args->len); } @@ -922,8 +927,10 @@ static void encode_access3args(struct xdr_stream *xdr, static void nfs3_xdr_enc_access3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_accessargs *args) + const void *data) { + const struct nfs3_accessargs *args = data; + encode_access3args(xdr, args); } @@ -936,8 +943,10 @@ static void nfs3_xdr_enc_access3args(struct rpc_rqst *req, */ static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_readlinkargs *args) + const void *data) { + const struct nfs3_readlinkargs *args = data; + encode_nfs_fh3(xdr, args->fh); prepare_reply_buffer(req, args->pages, args->pgbase, args->pglen, NFS3_readlinkres_sz); @@ -966,8 +975,10 @@ static void encode_read3args(struct xdr_stream *xdr, static void nfs3_xdr_enc_read3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_pgio_args *args) + const void *data) { + const struct nfs_pgio_args *args = data; + encode_read3args(xdr, args); prepare_reply_buffer(req, args->pages, args->pgbase, args->count, NFS3_readres_sz); @@ -1008,8 +1019,10 @@ static void encode_write3args(struct xdr_stream *xdr, static void nfs3_xdr_enc_write3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_pgio_args *args) + const void *data) { + const struct nfs_pgio_args *args = data; + encode_write3args(xdr, args); xdr->buf->flags |= XDRBUF_WRITE; } @@ -1055,8 +1068,10 @@ static void encode_createhow3(struct xdr_stream *xdr, static void nfs3_xdr_enc_create3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_createargs *args) + const void *data) { + const struct nfs3_createargs *args = data; + encode_diropargs3(xdr, args->fh, args->name, args->len); encode_createhow3(xdr, args); } @@ -1071,8 +1086,10 @@ static void nfs3_xdr_enc_create3args(struct rpc_rqst *req, */ static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_mkdirargs *args) + const void *data) { + const struct nfs3_mkdirargs *args = data; + encode_diropargs3(xdr, args->fh, args->name, args->len); encode_sattr3(xdr, args->sattr); } @@ -1091,16 +1108,20 @@ static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, * }; */ static void encode_symlinkdata3(struct xdr_stream *xdr, - const struct nfs3_symlinkargs *args) + const void *data) { + const struct nfs3_symlinkargs *args = data; + encode_sattr3(xdr, args->sattr); encode_nfspath3(xdr, args->pages, args->pathlen); } static void nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_symlinkargs *args) + const void *data) { + const struct nfs3_symlinkargs *args = data; + encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen); encode_symlinkdata3(xdr, args); xdr->buf->flags |= XDRBUF_WRITE; @@ -1160,8 +1181,10 @@ static void encode_mknoddata3(struct xdr_stream *xdr, static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_mknodargs *args) + const void *data) { + const struct nfs3_mknodargs *args = data; + encode_diropargs3(xdr, args->fh, args->name, args->len); encode_mknoddata3(xdr, args); } @@ -1175,8 +1198,10 @@ static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, */ static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_removeargs *args) + const void *data) { + const struct nfs_removeargs *args = data; + encode_diropargs3(xdr, args->fh, args->name.name, args->name.len); } @@ -1190,8 +1215,9 @@ static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req, */ static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_renameargs *args) + const void *data) { + const struct nfs_renameargs *args = data; const struct qstr *old = args->old_name; const struct qstr *new = args->new_name; @@ -1209,8 +1235,10 @@ static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req, */ static void nfs3_xdr_enc_link3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_linkargs *args) + const void *data) { + const struct nfs3_linkargs *args = data; + encode_nfs_fh3(xdr, args->fromfh); encode_diropargs3(xdr, args->tofh, args->toname, args->tolen); } @@ -1240,8 +1268,10 @@ static void encode_readdir3args(struct xdr_stream *xdr, static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_readdirargs *args) + const void *data) { + const struct nfs3_readdirargs *args = data; + encode_readdir3args(xdr, args); prepare_reply_buffer(req, args->pages, 0, args->count, NFS3_readdirres_sz); @@ -1280,8 +1310,10 @@ static void encode_readdirplus3args(struct xdr_stream *xdr, static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_readdirargs *args) + const void *data) { + const struct nfs3_readdirargs *args = data; + encode_readdirplus3args(xdr, args); prepare_reply_buffer(req, args->pages, 0, args->count, NFS3_readdirres_sz); @@ -1310,8 +1342,10 @@ static void encode_commit3args(struct xdr_stream *xdr, static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_commitargs *args) + const void *data) { + const struct nfs_commitargs *args = data; + encode_commit3args(xdr, args); } @@ -1319,8 +1353,10 @@ static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req, static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_getaclargs *args) + const void *data) { + const struct nfs3_getaclargs *args = data; + encode_nfs_fh3(xdr, args->fh); encode_uint32(xdr, args->mask); if (args->mask & (NFS_ACL | NFS_DFACL)) @@ -1331,8 +1367,9 @@ static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs3_setaclargs *args) + const void *data) { + const struct nfs3_setaclargs *args = data; unsigned int base; int error; @@ -1382,7 +1419,7 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, */ static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_fattr *result) + void *result) { enum nfs_stat status; int error; @@ -1419,7 +1456,7 @@ out_default: */ static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_fattr *result) + void *result) { enum nfs_stat status; int error; @@ -1460,8 +1497,9 @@ out_status: */ static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs3_diropres *result) + void *data) { + struct nfs3_diropres *result = data; enum nfs_stat status; int error; @@ -1507,8 +1545,9 @@ out_default: */ static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs3_accessres *result) + void *data) { + struct nfs3_accessres *result = data; enum nfs_stat status; int error; @@ -1548,7 +1587,7 @@ out_default: */ static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_fattr *result) + void *result) { enum nfs_stat status; int error; @@ -1626,8 +1665,9 @@ out_overflow: } static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_pgio_res *result) + void *data) { + struct nfs_pgio_res *result = data; enum nfs_stat status; int error; @@ -1699,8 +1739,9 @@ out_eio: } static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_pgio_res *result) + void *data) { + struct nfs_pgio_res *result = data; enum nfs_stat status; int error; @@ -1764,8 +1805,9 @@ out: static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs3_diropres *result) + void *data) { + struct nfs3_diropres *result = data; enum nfs_stat status; int error; @@ -1804,8 +1846,9 @@ out_default: */ static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_removeres *result) + void *data) { + struct nfs_removeres *result = data; enum nfs_stat status; int error; @@ -1845,8 +1888,9 @@ out_status: */ static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_renameres *result) + void *data) { + struct nfs_renameres *result = data; enum nfs_stat status; int error; @@ -1888,8 +1932,9 @@ out_status: * }; */ static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs3_linkres *result) + void *data) { + struct nfs3_linkres *result = data; enum nfs_stat status; int error; @@ -2072,8 +2117,9 @@ out: static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs3_readdirres *result) + void *data) { + struct nfs3_readdirres *result = data; enum nfs_stat status; int error; @@ -2140,8 +2186,9 @@ out_overflow: static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_fsstat *result) + void *data) { + struct nfs_fsstat *result = data; enum nfs_stat status; int error; @@ -2216,8 +2263,9 @@ out_overflow: static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_fsinfo *result) + void *data) { + struct nfs_fsinfo *result = data; enum nfs_stat status; int error; @@ -2279,8 +2327,9 @@ out_overflow: static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_pathconf *result) + void *data) { + struct nfs_pathconf *result = data; enum nfs_stat status; int error; @@ -2320,8 +2369,9 @@ out_status: */ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_commitres *result) + void *data) { + struct nfs_commitres *result = data; enum nfs_stat status; int error; @@ -2389,7 +2439,7 @@ out: static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs3_getaclres *result) + void *result) { enum nfs_stat status; int error; @@ -2408,7 +2458,7 @@ out_default: static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_fattr *result) + void *result) { enum nfs_stat status; int error; @@ -2495,8 +2545,8 @@ static int nfs3_stat_to_errno(enum nfs_stat status) #define PROC(proc, argtype, restype, timer) \ [NFS3PROC_##proc] = { \ .p_proc = NFS3PROC_##proc, \ - .p_encode = (kxdreproc_t)nfs3_xdr_enc_##argtype##3args, \ - .p_decode = (kxdrdproc_t)nfs3_xdr_dec_##restype##3res, \ + .p_encode = nfs3_xdr_enc_##argtype##3args, \ + .p_decode = nfs3_xdr_dec_##restype##3res, \ .p_arglen = NFS3_##argtype##args_sz, \ .p_replen = NFS3_##restype##res_sz, \ .p_timer = timer, \ @@ -2504,7 +2554,7 @@ static int nfs3_stat_to_errno(enum nfs_stat status) .p_name = #proc, \ } -struct rpc_procinfo nfs3_procedures[] = { +const struct rpc_procinfo nfs3_procedures[] = { PROC(GETATTR, getattr, getattr, 1), PROC(SETATTR, setattr, setattr, 0), PROC(LOOKUP, lookup, lookup, 2), @@ -2528,18 +2578,20 @@ struct rpc_procinfo nfs3_procedures[] = { PROC(COMMIT, commit, commit, 5), }; +static unsigned int nfs_version3_counts[ARRAY_SIZE(nfs3_procedures)]; const struct rpc_version nfs_version3 = { .number = 3, .nrprocs = ARRAY_SIZE(nfs3_procedures), - .procs = nfs3_procedures + .procs = nfs3_procedures, + .counts = nfs_version3_counts, }; #ifdef CONFIG_NFS_V3_ACL -static struct rpc_procinfo nfs3_acl_procedures[] = { +static const struct rpc_procinfo nfs3_acl_procedures[] = { [ACLPROC3_GETACL] = { .p_proc = ACLPROC3_GETACL, - .p_encode = (kxdreproc_t)nfs3_xdr_enc_getacl3args, - .p_decode = (kxdrdproc_t)nfs3_xdr_dec_getacl3res, + .p_encode = nfs3_xdr_enc_getacl3args, + .p_decode = nfs3_xdr_dec_getacl3res, .p_arglen = ACL3_getaclargs_sz, .p_replen = ACL3_getaclres_sz, .p_timer = 1, @@ -2547,8 +2599,8 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { }, [ACLPROC3_SETACL] = { .p_proc = ACLPROC3_SETACL, - .p_encode = (kxdreproc_t)nfs3_xdr_enc_setacl3args, - .p_decode = (kxdrdproc_t)nfs3_xdr_dec_setacl3res, + .p_encode = nfs3_xdr_enc_setacl3args, + .p_decode = nfs3_xdr_dec_setacl3res, .p_arglen = ACL3_setaclargs_sz, .p_replen = ACL3_setaclres_sz, .p_timer = 0, @@ -2556,10 +2608,11 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { }, }; +static unsigned int nfs3_acl_counts[ARRAY_SIZE(nfs3_acl_procedures)]; const struct rpc_version nfsacl_version3 = { .number = 3, - .nrprocs = sizeof(nfs3_acl_procedures)/ - sizeof(nfs3_acl_procedures[0]), + .nrprocs = ARRAY_SIZE(nfs3_acl_procedures), .procs = nfs3_acl_procedures, + .counts = nfs3_acl_counts, }; #endif /* CONFIG_NFS_V3_ACL */ diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c index 528362f69cc1..5ee1b0f0d904 100644 --- a/fs/nfs/nfs42xdr.c +++ b/fs/nfs/nfs42xdr.c @@ -112,7 +112,7 @@ decode_getattr_maxsz) static void encode_fallocate(struct xdr_stream *xdr, - struct nfs42_falloc_args *args) + const struct nfs42_falloc_args *args) { encode_nfs4_stateid(xdr, &args->falloc_stateid); encode_uint64(xdr, args->falloc_offset); @@ -120,7 +120,7 @@ static void encode_fallocate(struct xdr_stream *xdr, } static void encode_allocate(struct xdr_stream *xdr, - struct nfs42_falloc_args *args, + const struct nfs42_falloc_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_ALLOCATE, decode_allocate_maxsz, hdr); @@ -128,7 +128,7 @@ static void encode_allocate(struct xdr_stream *xdr, } static void encode_copy(struct xdr_stream *xdr, - struct nfs42_copy_args *args, + const struct nfs42_copy_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_COPY, decode_copy_maxsz, hdr); @@ -145,7 +145,7 @@ static void encode_copy(struct xdr_stream *xdr, } static void encode_deallocate(struct xdr_stream *xdr, - struct nfs42_falloc_args *args, + const struct nfs42_falloc_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_DEALLOCATE, decode_deallocate_maxsz, hdr); @@ -153,7 +153,7 @@ static void encode_deallocate(struct xdr_stream *xdr, } static void encode_seek(struct xdr_stream *xdr, - struct nfs42_seek_args *args, + const struct nfs42_seek_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_SEEK, decode_seek_maxsz, hdr); @@ -163,7 +163,7 @@ static void encode_seek(struct xdr_stream *xdr, } static void encode_layoutstats(struct xdr_stream *xdr, - struct nfs42_layoutstat_args *args, + const struct nfs42_layoutstat_args *args, struct nfs42_layoutstat_devinfo *devinfo, struct compound_hdr *hdr) { @@ -191,7 +191,7 @@ static void encode_layoutstats(struct xdr_stream *xdr, } static void encode_clone(struct xdr_stream *xdr, - struct nfs42_clone_args *args, + const struct nfs42_clone_args *args, struct compound_hdr *hdr) { __be32 *p; @@ -210,8 +210,9 @@ static void encode_clone(struct xdr_stream *xdr, */ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs42_falloc_args *args) + const void *data) { + const struct nfs42_falloc_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -225,7 +226,7 @@ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, } static void encode_copy_commit(struct xdr_stream *xdr, - struct nfs42_copy_args *args, + const struct nfs42_copy_args *args, struct compound_hdr *hdr) { __be32 *p; @@ -241,8 +242,9 @@ static void encode_copy_commit(struct xdr_stream *xdr, */ static void nfs4_xdr_enc_copy(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs42_copy_args *args) + const void *data) { + const struct nfs42_copy_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -262,8 +264,9 @@ static void nfs4_xdr_enc_copy(struct rpc_rqst *req, */ static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs42_falloc_args *args) + const void *data) { + const struct nfs42_falloc_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -281,8 +284,9 @@ static void nfs4_xdr_enc_deallocate(struct rpc_rqst *req, */ static void nfs4_xdr_enc_seek(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs42_seek_args *args) + const void *data) { + const struct nfs42_seek_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -299,8 +303,9 @@ static void nfs4_xdr_enc_seek(struct rpc_rqst *req, */ static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs42_layoutstat_args *args) + const void *data) { + const struct nfs42_layoutstat_args *args = data; int i; struct compound_hdr hdr = { @@ -321,8 +326,9 @@ static void nfs4_xdr_enc_layoutstats(struct rpc_rqst *req, */ static void nfs4_xdr_enc_clone(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs42_clone_args *args) + const void *data) { + const struct nfs42_clone_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -448,8 +454,9 @@ static int decode_clone(struct xdr_stream *xdr) */ static int nfs4_xdr_dec_allocate(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs42_falloc_res *res) + void *data) { + struct nfs42_falloc_res *res = data; struct compound_hdr hdr; int status; @@ -475,8 +482,9 @@ out: */ static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs42_copy_res *res) + void *data) { + struct nfs42_copy_res *res = data; struct compound_hdr hdr; int status; @@ -508,8 +516,9 @@ out: */ static int nfs4_xdr_dec_deallocate(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs42_falloc_res *res) + void *data) { + struct nfs42_falloc_res *res = data; struct compound_hdr hdr; int status; @@ -535,8 +544,9 @@ out: */ static int nfs4_xdr_dec_seek(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs42_seek_res *res) + void *data) { + struct nfs42_seek_res *res = data; struct compound_hdr hdr; int status; @@ -559,8 +569,9 @@ out: */ static int nfs4_xdr_dec_layoutstats(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs42_layoutstat_res *res) + void *data) { + struct nfs42_layoutstat_res *res = data; struct compound_hdr hdr; int status, i; @@ -589,8 +600,9 @@ out: */ static int nfs4_xdr_dec_clone(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs42_clone_res *res) + void *data) { + struct nfs42_clone_res *res = data; struct compound_hdr hdr; int status; diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index af285cc27ccf..40bd05f05e74 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -493,13 +493,13 @@ static inline void nfs4_unregister_sysctl(void) #endif /* nfs4xdr.c */ -extern struct rpc_procinfo nfs4_procedures[]; +extern const struct rpc_procinfo nfs4_procedures[]; struct nfs4_mount_data; /* callback_xdr.c */ -extern struct svc_version nfs4_callback_version1; -extern struct svc_version nfs4_callback_version4; +extern const struct svc_version nfs4_callback_version1; +extern const struct svc_version nfs4_callback_version4; static inline void nfs4_stateid_copy(nfs4_stateid *dst, const nfs4_stateid *src) { diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 3aebfdc82b30..0f1f290c97cd 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1651,7 +1651,8 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) } static void -encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr) +encode_setacl(struct xdr_stream *xdr, const struct nfs_setaclargs *arg, + struct compound_hdr *hdr) { __be32 *p; @@ -1735,7 +1736,7 @@ static void encode_secinfo(struct xdr_stream *xdr, const struct qstr *name, stru #if defined(CONFIG_NFS_V4_1) /* NFSv4.1 operations */ static void encode_bind_conn_to_session(struct xdr_stream *xdr, - struct nfs41_bind_conn_to_session_args *args, + const struct nfs41_bind_conn_to_session_args *args, struct compound_hdr *hdr) { __be32 *p; @@ -1748,7 +1749,7 @@ static void encode_bind_conn_to_session(struct xdr_stream *xdr, *p = (args->use_conn_in_rdma_mode) ? cpu_to_be32(1) : cpu_to_be32(0); } -static void encode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map) +static void encode_op_map(struct xdr_stream *xdr, const struct nfs4_op_map *op_map) { unsigned int i; encode_uint32(xdr, NFS4_OP_MAP_NUM_WORDS); @@ -1757,7 +1758,7 @@ static void encode_op_map(struct xdr_stream *xdr, struct nfs4_op_map *op_map) } static void encode_exchange_id(struct xdr_stream *xdr, - struct nfs41_exchange_id_args *args, + const struct nfs41_exchange_id_args *args, struct compound_hdr *hdr) { __be32 *p; @@ -1809,7 +1810,7 @@ static void encode_exchange_id(struct xdr_stream *xdr, } static void encode_create_session(struct xdr_stream *xdr, - struct nfs41_create_session_args *args, + const struct nfs41_create_session_args *args, struct compound_hdr *hdr) { __be32 *p; @@ -1862,7 +1863,7 @@ static void encode_create_session(struct xdr_stream *xdr, } static void encode_destroy_session(struct xdr_stream *xdr, - struct nfs4_session *session, + const struct nfs4_session *session, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_DESTROY_SESSION, decode_destroy_session_maxsz, hdr); @@ -1878,7 +1879,7 @@ static void encode_destroy_clientid(struct xdr_stream *xdr, } static void encode_reclaim_complete(struct xdr_stream *xdr, - struct nfs41_reclaim_complete_args *args, + const struct nfs41_reclaim_complete_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_RECLAIM_COMPLETE, decode_reclaim_complete_maxsz, hdr); @@ -1974,7 +1975,7 @@ encode_layoutget(struct xdr_stream *xdr, static int encode_layoutcommit(struct xdr_stream *xdr, struct inode *inode, - struct nfs4_layoutcommit_args *args, + const struct nfs4_layoutcommit_args *args, struct compound_hdr *hdr) { __be32 *p; @@ -2044,7 +2045,7 @@ encode_secinfo_no_name(struct xdr_stream *xdr, } static void encode_test_stateid(struct xdr_stream *xdr, - struct nfs41_test_stateid_args *args, + const struct nfs41_test_stateid_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_TEST_STATEID, decode_test_stateid_maxsz, hdr); @@ -2053,7 +2054,7 @@ static void encode_test_stateid(struct xdr_stream *xdr, } static void encode_free_stateid(struct xdr_stream *xdr, - struct nfs41_free_stateid_args *args, + const struct nfs41_free_stateid_args *args, struct compound_hdr *hdr) { encode_op_hdr(xdr, OP_FREE_STATEID, decode_free_stateid_maxsz, hdr); @@ -2086,8 +2087,9 @@ static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args) * Encode an ACCESS request */ static void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_accessargs *args) + const void *data) { + const struct nfs4_accessargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2104,8 +2106,9 @@ static void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode LOOKUP request */ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_lookup_arg *args) + const void *data) { + const struct nfs4_lookup_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2124,8 +2127,9 @@ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr, */ static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_lookup_root_arg *args) + const void *data) { + const struct nfs4_lookup_root_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2142,8 +2146,9 @@ static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, * Encode REMOVE request */ static void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_removeargs *args) + const void *data) { + const struct nfs_removeargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2159,8 +2164,9 @@ static void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode RENAME request */ static void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs_renameargs *args) + const void *data) { + const struct nfs_renameargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2178,8 +2184,9 @@ static void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode LINK request */ static void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_link_arg *args) + const void *data) { + const struct nfs4_link_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2199,8 +2206,9 @@ static void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode CREATE request */ static void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_create_arg *args) + const void *data) { + const struct nfs4_create_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2218,8 +2226,10 @@ static void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode SYMLINK request */ static void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_create_arg *args) + const void *data) { + const struct nfs4_create_arg *args = data; + nfs4_xdr_enc_create(req, xdr, args); } @@ -2227,8 +2237,9 @@ static void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode GETATTR request */ static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_getattr_arg *args) + const void *data) { + const struct nfs4_getattr_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2244,8 +2255,9 @@ static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode a CLOSE request */ static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_closeargs *args) + const void *data) { + const struct nfs_closeargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2265,8 +2277,9 @@ static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode an OPEN request */ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_openargs *args) + const void *data) { + const struct nfs_openargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2287,8 +2300,9 @@ static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, */ static void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_open_confirmargs *args) + const void *data) { + const struct nfs_open_confirmargs *args = data; struct compound_hdr hdr = { .nops = 0, }; @@ -2304,8 +2318,9 @@ static void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, */ static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_openargs *args) + const void *data) { + const struct nfs_openargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2325,8 +2340,9 @@ static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, */ static void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_closeargs *args) + const void *data) { + const struct nfs_closeargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2344,8 +2360,9 @@ static void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, * Encode a LOCK request */ static void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_lock_args *args) + const void *data) { + const struct nfs_lock_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2361,8 +2378,9 @@ static void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode a LOCKT request */ static void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_lockt_args *args) + const void *data) { + const struct nfs_lockt_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2378,8 +2396,9 @@ static void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode a LOCKU request */ static void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_locku_args *args) + const void *data) { + const struct nfs_locku_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2393,8 +2412,9 @@ static void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr, static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_release_lockowner_args *args) + const void *data) { + const struct nfs_release_lockowner_args *args = data; struct compound_hdr hdr = { .minorversion = 0, }; @@ -2408,8 +2428,9 @@ static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, * Encode a READLINK request */ static void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_readlink *args) + const void *data) { + const struct nfs4_readlink *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2428,8 +2449,9 @@ static void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode a READDIR request */ static void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_readdir_arg *args) + const void *data) { + const struct nfs4_readdir_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2451,8 +2473,9 @@ static void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode a READ request */ static void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_pgio_args *args) + const void *data) { + const struct nfs_pgio_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2472,8 +2495,9 @@ static void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode an SETATTR request */ static void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_setattrargs *args) + const void *data) { + const struct nfs_setattrargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2490,8 +2514,9 @@ static void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode a GETACL request */ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_getaclargs *args) + const void *data) { + const struct nfs_getaclargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2513,8 +2538,9 @@ static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, * Encode a WRITE request */ static void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_pgio_args *args) + const void *data) { + const struct nfs_pgio_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2533,8 +2559,9 @@ static void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr, * a COMMIT request */ static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_commitargs *args) + const void *data) { + const struct nfs_commitargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2550,8 +2577,9 @@ static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr, * FSINFO request */ static void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_fsinfo_arg *args) + const void *data) { + const struct nfs4_fsinfo_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2567,8 +2595,9 @@ static void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, * a PATHCONF request */ static void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_pathconf_arg *args) + const void *data) { + const struct nfs4_pathconf_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2585,8 +2614,9 @@ static void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, * a STATFS request */ static void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_statfs_arg *args) + const void *data) { + const struct nfs4_statfs_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2604,8 +2634,9 @@ static void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, */ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_server_caps_arg *args) + const void *data) { + const struct nfs4_server_caps_arg *args = data; const u32 *bitmask = args->bitmask; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), @@ -2622,8 +2653,10 @@ static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req, * a RENEW request */ static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_client *clp) + const void *data) + { + const struct nfs_client *clp = data; struct compound_hdr hdr = { .nops = 0, }; @@ -2638,8 +2671,9 @@ static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr, */ static void nfs4_xdr_enc_setclientid(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_setclientid *sc) + const void *data) { + const struct nfs4_setclientid *sc = data; struct compound_hdr hdr = { .nops = 0, }; @@ -2654,8 +2688,9 @@ static void nfs4_xdr_enc_setclientid(struct rpc_rqst *req, */ static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_setclientid_res *arg) + const void *data) { + const struct nfs4_setclientid_res *arg = data; struct compound_hdr hdr = { .nops = 0, }; @@ -2670,8 +2705,9 @@ static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, */ static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfs4_delegreturnargs *args) + const void *data) { + const struct nfs4_delegreturnargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2692,8 +2728,9 @@ static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, */ static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_fs_locations_arg *args) + const void *data) { + const struct nfs4_fs_locations_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2715,8 +2752,8 @@ static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, } /* Set up reply kvec to capture returned fs_locations array. */ - xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page, - 0, PAGE_SIZE); + xdr_inline_pages(&req->rq_rcv_buf, replen << 2, + (struct page **)&args->page, 0, PAGE_SIZE); encode_nops(&hdr); } @@ -2725,8 +2762,9 @@ static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, */ static void nfs4_xdr_enc_secinfo(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_secinfo_arg *args) + const void *data) { + const struct nfs4_secinfo_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2743,8 +2781,9 @@ static void nfs4_xdr_enc_secinfo(struct rpc_rqst *req, */ static void nfs4_xdr_enc_fsid_present(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_fsid_present_arg *args) + const void *data) { + const struct nfs4_fsid_present_arg *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2764,8 +2803,9 @@ static void nfs4_xdr_enc_fsid_present(struct rpc_rqst *req, */ static void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs41_bind_conn_to_session_args *args) + const void *data) { + const struct nfs41_bind_conn_to_session_args *args = data; struct compound_hdr hdr = { .minorversion = args->client->cl_mvops->minor_version, }; @@ -2780,8 +2820,9 @@ static void nfs4_xdr_enc_bind_conn_to_session(struct rpc_rqst *req, */ static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs41_exchange_id_args *args) + const void *data) { + const struct nfs41_exchange_id_args *args = data; struct compound_hdr hdr = { .minorversion = args->client->cl_mvops->minor_version, }; @@ -2796,8 +2837,9 @@ static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, */ static void nfs4_xdr_enc_create_session(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs41_create_session_args *args) + const void *data) { + const struct nfs41_create_session_args *args = data; struct compound_hdr hdr = { .minorversion = args->client->cl_mvops->minor_version, }; @@ -2812,8 +2854,9 @@ static void nfs4_xdr_enc_create_session(struct rpc_rqst *req, */ static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_session *session) + const void *data) { + const struct nfs4_session *session = data; struct compound_hdr hdr = { .minorversion = session->clp->cl_mvops->minor_version, }; @@ -2828,8 +2871,9 @@ static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, */ static void nfs4_xdr_enc_destroy_clientid(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_client *clp) + const void *data) { + const struct nfs_client *clp = data; struct compound_hdr hdr = { .minorversion = clp->cl_mvops->minor_version, }; @@ -2843,8 +2887,9 @@ static void nfs4_xdr_enc_destroy_clientid(struct rpc_rqst *req, * a SEQUENCE request */ static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_sequence_args *args) + const void *data) { + const struct nfs4_sequence_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(args), }; @@ -2859,8 +2904,9 @@ static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr, */ static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_get_lease_time_args *args) + const void *data) { + const struct nfs4_get_lease_time_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), }; @@ -2878,8 +2924,9 @@ static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, */ static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs41_reclaim_complete_args *args) + const void *data) { + const struct nfs41_reclaim_complete_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args) }; @@ -2895,8 +2942,9 @@ static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, */ static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_getdeviceinfo_args *args) + const void *data) { + const struct nfs4_getdeviceinfo_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2919,8 +2967,9 @@ static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, */ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_layoutget_args *args) + const void *data) { + const struct nfs4_layoutget_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2941,8 +2990,9 @@ static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, */ static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_layoutcommit_args *args) + const void *priv) { + const struct nfs4_layoutcommit_args *args = priv; struct nfs4_layoutcommit_data *data = container_of(args, struct nfs4_layoutcommit_data, args); struct compound_hdr hdr = { @@ -2962,8 +3012,9 @@ static void nfs4_xdr_enc_layoutcommit(struct rpc_rqst *req, */ static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_layoutreturn_args *args) + const void *data) { + const struct nfs4_layoutreturn_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2978,10 +3029,11 @@ static void nfs4_xdr_enc_layoutreturn(struct rpc_rqst *req, /* * Encode SECINFO_NO_NAME request */ -static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, +static void nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs41_secinfo_no_name_args *args) + const void *data) { + const struct nfs41_secinfo_no_name_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -2991,7 +3043,6 @@ static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, encode_putrootfh(xdr, &hdr); encode_secinfo_no_name(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* @@ -2999,8 +3050,9 @@ static int nfs4_xdr_enc_secinfo_no_name(struct rpc_rqst *req, */ static void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs41_test_stateid_args *args) + const void *data) { + const struct nfs41_test_stateid_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -3016,8 +3068,9 @@ static void nfs4_xdr_enc_test_stateid(struct rpc_rqst *req, */ static void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs41_free_stateid_args *args) + const void *data) { + const struct nfs41_free_stateid_args *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -6101,8 +6154,9 @@ int decode_layoutreturn(struct xdr_stream *xdr, */ static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_closeres *res) + void *data) { + struct nfs_closeres *res = data; struct compound_hdr hdr; int status; @@ -6130,8 +6184,9 @@ out: * Decode ACCESS response */ static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_accessres *res) + void *data) { + struct nfs4_accessres *res = data; struct compound_hdr hdr; int status; @@ -6156,8 +6211,9 @@ out: * Decode LOOKUP response */ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_lookup_res *res) + void *data) { + struct nfs4_lookup_res *res = data; struct compound_hdr hdr; int status; @@ -6186,8 +6242,9 @@ out: */ static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_lookup_res *res) + void *data) { + struct nfs4_lookup_res *res = data; struct compound_hdr hdr; int status; @@ -6212,8 +6269,9 @@ out: * Decode REMOVE response */ static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_removeres *res) + void *data) { + struct nfs_removeres *res = data; struct compound_hdr hdr; int status; @@ -6235,8 +6293,9 @@ out: * Decode RENAME response */ static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_renameres *res) + void *data) { + struct nfs_renameres *res = data; struct compound_hdr hdr; int status; @@ -6264,8 +6323,9 @@ out: * Decode LINK response */ static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_link_res *res) + void *data) { + struct nfs4_link_res *res = data; struct compound_hdr hdr; int status; @@ -6303,8 +6363,9 @@ out: * Decode CREATE response */ static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_create_res *res) + void *data) { + struct nfs4_create_res *res = data; struct compound_hdr hdr; int status; @@ -6332,7 +6393,7 @@ out: * Decode SYMLINK response */ static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_create_res *res) + void *res) { return nfs4_xdr_dec_create(rqstp, xdr, res); } @@ -6341,8 +6402,9 @@ static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr, * Decode GETATTR response */ static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_getattr_res *res) + void *data) { + struct nfs4_getattr_res *res = data; struct compound_hdr hdr; int status; @@ -6364,8 +6426,9 @@ out: * Encode an SETACL request */ static void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs_setaclargs *args) + const void *data) { + const struct nfs_setaclargs *args = data; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; @@ -6382,8 +6445,9 @@ static void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr, */ static int nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_setaclres *res) + void *data) { + struct nfs_setaclres *res = data; struct compound_hdr hdr; int status; @@ -6406,8 +6470,9 @@ out: */ static int nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_getaclres *res) + void *data) { + struct nfs_getaclres *res = data; struct compound_hdr hdr; int status; @@ -6434,8 +6499,9 @@ out: * Decode CLOSE response */ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_closeres *res) + void *data) { + struct nfs_closeres *res = data; struct compound_hdr hdr; int status; @@ -6468,8 +6534,9 @@ out: * Decode OPEN response */ static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_openres *res) + void *data) { + struct nfs_openres *res = data; struct compound_hdr hdr; int status; @@ -6500,8 +6567,9 @@ out: */ static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_open_confirmres *res) + void *data) { + struct nfs_open_confirmres *res = data; struct compound_hdr hdr; int status; @@ -6521,8 +6589,9 @@ out: */ static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_openres *res) + void *data) { + struct nfs_openres *res = data; struct compound_hdr hdr; int status; @@ -6550,8 +6619,9 @@ out: */ static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_setattrres *res) + void *data) { + struct nfs_setattrres *res = data; struct compound_hdr hdr; int status; @@ -6576,8 +6646,9 @@ out: * Decode LOCK response */ static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_lock_res *res) + void *data) { + struct nfs_lock_res *res = data; struct compound_hdr hdr; int status; @@ -6599,8 +6670,9 @@ out: * Decode LOCKT response */ static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_lockt_res *res) + void *data) { + struct nfs_lockt_res *res = data; struct compound_hdr hdr; int status; @@ -6622,8 +6694,9 @@ out: * Decode LOCKU response */ static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_locku_res *res) + void *data) { + struct nfs_locku_res *res = data; struct compound_hdr hdr; int status; @@ -6658,8 +6731,9 @@ static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp, */ static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_readlink_res *res) + void *data) { + struct nfs4_readlink_res *res = data; struct compound_hdr hdr; int status; @@ -6681,8 +6755,9 @@ out: * Decode READDIR response */ static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_readdir_res *res) + void *data) { + struct nfs4_readdir_res *res = data; struct compound_hdr hdr; int status; @@ -6704,8 +6779,9 @@ out: * Decode Read response */ static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_pgio_res *res) + void *data) { + struct nfs_pgio_res *res = data; struct compound_hdr hdr; int status; @@ -6730,8 +6806,9 @@ out: * Decode WRITE response */ static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_pgio_res *res) + void *data) { + struct nfs_pgio_res *res = data; struct compound_hdr hdr; int status; @@ -6760,8 +6837,9 @@ out: * Decode COMMIT response */ static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs_commitres *res) + void *data) { + struct nfs_commitres *res = data; struct compound_hdr hdr; int status; @@ -6784,8 +6862,9 @@ out: * Decode FSINFO response */ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_fsinfo_res *res) + void *data) { + struct nfs4_fsinfo_res *res = data; struct compound_hdr hdr; int status; @@ -6803,8 +6882,9 @@ static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, * Decode PATHCONF response */ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_pathconf_res *res) + void *data) { + struct nfs4_pathconf_res *res = data; struct compound_hdr hdr; int status; @@ -6822,8 +6902,9 @@ static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, * Decode STATFS response */ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_statfs_res *res) + void *data) { + struct nfs4_statfs_res *res = data; struct compound_hdr hdr; int status; @@ -6842,8 +6923,9 @@ static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, */ static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_server_caps_res *res) + void *data) { + struct nfs4_server_caps_res *res = data; struct compound_hdr hdr; int status; @@ -6881,8 +6963,9 @@ static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr, */ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_setclientid_res *res) + void *data) { + struct nfs4_setclientid_res *res = data; struct compound_hdr hdr; int status; @@ -6896,7 +6979,8 @@ static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, * Decode SETCLIENTID_CONFIRM response */ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, - struct xdr_stream *xdr) + struct xdr_stream *xdr, + void *data) { struct compound_hdr hdr; int status; @@ -6912,8 +6996,9 @@ static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, */ static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_delegreturnres *res) + void *data) { + struct nfs4_delegreturnres *res = data; struct compound_hdr hdr; int status; @@ -6947,8 +7032,9 @@ out: */ static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, struct xdr_stream *xdr, - struct nfs4_fs_locations_res *res) + void *data) { + struct nfs4_fs_locations_res *res = data; struct compound_hdr hdr; int status; @@ -6990,8 +7076,9 @@ out: */ static int nfs4_xdr_dec_secinfo(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_secinfo_res *res) + void *data) { + struct nfs4_secinfo_res *res = data; struct compound_hdr hdr; int status; @@ -7014,8 +7101,9 @@ out: */ static int nfs4_xdr_dec_fsid_present(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_fsid_present_res *res) + void *data) { + struct nfs4_fsid_present_res *res = data; struct compound_hdr hdr; int status; @@ -7075,7 +7163,7 @@ static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, */ static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs41_create_session_res *res) + void *res) { struct compound_hdr hdr; int status; @@ -7123,7 +7211,7 @@ static int nfs4_xdr_dec_destroy_clientid(struct rpc_rqst *rqstp, */ static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_sequence_res *res) + void *res) { struct compound_hdr hdr; int status; @@ -7139,8 +7227,9 @@ static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, */ static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_get_lease_time_res *res) + void *data) { + struct nfs4_get_lease_time_res *res = data; struct compound_hdr hdr; int status; @@ -7159,8 +7248,9 @@ static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, */ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs41_reclaim_complete_res *res) + void *data) { + struct nfs41_reclaim_complete_res *res = data; struct compound_hdr hdr; int status; @@ -7177,8 +7267,9 @@ static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, */ static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_getdeviceinfo_res *res) + void *data) { + struct nfs4_getdeviceinfo_res *res = data; struct compound_hdr hdr; int status; @@ -7198,8 +7289,9 @@ out: */ static int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_layoutget_res *res) + void *data) { + struct nfs4_layoutget_res *res = data; struct compound_hdr hdr; int status; @@ -7222,8 +7314,9 @@ out: */ static int nfs4_xdr_dec_layoutreturn(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_layoutreturn_res *res) + void *data) { + struct nfs4_layoutreturn_res *res = data; struct compound_hdr hdr; int status; @@ -7246,8 +7339,9 @@ out: */ static int nfs4_xdr_dec_layoutcommit(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_layoutcommit_res *res) + void *data) { + struct nfs4_layoutcommit_res *res = data; struct compound_hdr hdr; int status; @@ -7273,8 +7367,9 @@ out: */ static int nfs4_xdr_dec_secinfo_no_name(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs4_secinfo_res *res) + void *data) { + struct nfs4_secinfo_res *res = data; struct compound_hdr hdr; int status; @@ -7297,8 +7392,9 @@ out: */ static int nfs4_xdr_dec_test_stateid(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs41_test_stateid_res *res) + void *data) { + struct nfs41_test_stateid_res *res = data; struct compound_hdr hdr; int status; @@ -7318,8 +7414,9 @@ out: */ static int nfs4_xdr_dec_free_stateid(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfs41_free_stateid_res *res) + void *data) { + struct nfs41_free_stateid_res *res = data; struct compound_hdr hdr; int status; @@ -7484,8 +7581,8 @@ nfs4_stat_to_errno(int stat) #define PROC(proc, argtype, restype) \ [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_COMPOUND, \ - .p_encode = (kxdreproc_t)nfs4_xdr_##argtype, \ - .p_decode = (kxdrdproc_t)nfs4_xdr_##restype, \ + .p_encode = nfs4_xdr_##argtype, \ + .p_decode = nfs4_xdr_##restype, \ .p_arglen = NFS4_##argtype##_sz, \ .p_replen = NFS4_##restype##_sz, \ .p_statidx = NFSPROC4_CLNT_##proc, \ @@ -7497,7 +7594,7 @@ nfs4_stat_to_errno(int stat) .p_name = #proc, \ } -struct rpc_procinfo nfs4_procedures[] = { +const struct rpc_procinfo nfs4_procedures[] = { PROC(READ, enc_read, dec_read), PROC(WRITE, enc_write, dec_write), PROC(COMMIT, enc_commit, dec_commit), @@ -7564,10 +7661,12 @@ struct rpc_procinfo nfs4_procedures[] = { #endif /* CONFIG_NFS_V4_2 */ }; +static unsigned int nfs_version4_counts[ARRAY_SIZE(nfs4_procedures)]; const struct rpc_version nfs_version4 = { .number = 4, .nrprocs = ARRAY_SIZE(nfs4_procedures), - .procs = nfs4_procedures + .procs = nfs4_procedures, + .counts = nfs_version4_counts, }; /* diff --git a/fs/nfsd/current_stateid.h b/fs/nfsd/current_stateid.h index 4123551208d8..34075cee573a 100644 --- a/fs/nfsd/current_stateid.h +++ b/fs/nfsd/current_stateid.h @@ -8,21 +8,33 @@ extern void clear_current_stateid(struct nfsd4_compound_state *cstate); /* * functions to set current state id */ -extern void nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *); -extern void nfsd4_set_openstateid(struct nfsd4_compound_state *, struct nfsd4_open *); -extern void nfsd4_set_lockstateid(struct nfsd4_compound_state *, struct nfsd4_lock *); -extern void nfsd4_set_closestateid(struct nfsd4_compound_state *, struct nfsd4_close *); +extern void nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_set_openstateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_set_lockstateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_set_closestateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); /* * functions to consume current state id */ -extern void nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *); -extern void nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *, struct nfsd4_delegreturn *); -extern void nfsd4_get_freestateid(struct nfsd4_compound_state *, struct nfsd4_free_stateid *); -extern void nfsd4_get_setattrstateid(struct nfsd4_compound_state *, struct nfsd4_setattr *); -extern void nfsd4_get_closestateid(struct nfsd4_compound_state *, struct nfsd4_close *); -extern void nfsd4_get_lockustateid(struct nfsd4_compound_state *, struct nfsd4_locku *); -extern void nfsd4_get_readstateid(struct nfsd4_compound_state *, struct nfsd4_read *); -extern void nfsd4_get_writestateid(struct nfsd4_compound_state *, struct nfsd4_write *); +extern void nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_get_freestateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_get_setattrstateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_get_closestateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_get_lockustateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_get_readstateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); +extern void nfsd4_get_writestateid(struct nfsd4_compound_state *, + union nfsd4_op_u *); #endif /* _NFSD4_CURRENT_STATE_H */ diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 838f90f3f890..6276ec8608b0 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c @@ -19,7 +19,7 @@ * NULL call. */ static __be32 -nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) +nfsacld_proc_null(struct svc_rqst *rqstp) { return nfs_ok; } @@ -27,9 +27,10 @@ nfsacld_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) /* * Get the Access and/or Default ACL of a file. */ -static __be32 nfsacld_proc_getacl(struct svc_rqst * rqstp, - struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) +static __be32 nfsacld_proc_getacl(struct svc_rqst *rqstp) { + struct nfsd3_getaclargs *argp = rqstp->rq_argp; + struct nfsd3_getaclres *resp = rqstp->rq_resp; struct posix_acl *acl; struct inode *inode; svc_fh *fh; @@ -87,10 +88,10 @@ fail: /* * Set the Access and/or Default ACL of a file. */ -static __be32 nfsacld_proc_setacl(struct svc_rqst * rqstp, - struct nfsd3_setaclargs *argp, - struct nfsd_attrstat *resp) +static __be32 nfsacld_proc_setacl(struct svc_rqst *rqstp) { + struct nfsd3_setaclargs *argp = rqstp->rq_argp; + struct nfsd_attrstat *resp = rqstp->rq_resp; struct inode *inode; svc_fh *fh; __be32 nfserr = 0; @@ -141,9 +142,10 @@ out_errno: /* * Check file attributes */ -static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp, - struct nfsd_fhandle *argp, struct nfsd_attrstat *resp) +static __be32 nfsacld_proc_getattr(struct svc_rqst *rqstp) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + struct nfsd_attrstat *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); @@ -158,9 +160,10 @@ static __be32 nfsacld_proc_getattr(struct svc_rqst * rqstp, /* * Check file access */ -static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, - struct nfsd3_accessres *resp) +static __be32 nfsacld_proc_access(struct svc_rqst *rqstp) { + struct nfsd3_accessargs *argp = rqstp->rq_argp; + struct nfsd3_accessres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: ACCESS(2acl) %s 0x%x\n", @@ -179,9 +182,10 @@ static __be32 nfsacld_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessarg /* * XDR decode functions */ -static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclargs *argp) +static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_getaclargs *argp = rqstp->rq_argp; + p = nfs2svc_decode_fh(p, &argp->fh); if (!p) return 0; @@ -191,9 +195,9 @@ static int nfsaclsvc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, } -static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_setaclargs *argp) +static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_setaclargs *argp = rqstp->rq_argp; struct kvec *head = rqstp->rq_arg.head; unsigned int base; int n; @@ -217,18 +221,20 @@ static int nfsaclsvc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, return (n > 0); } -static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_fhandle *argp) +static int nfsaclsvc_decode_fhandleargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + p = nfs2svc_decode_fh(p, &argp->fh); if (!p) return 0; return xdr_argsize_check(rqstp, p); } -static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_accessargs *argp) +static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_accessargs *argp = rqstp->rq_argp; + p = nfs2svc_decode_fh(p, &argp->fh); if (!p) return 0; @@ -245,15 +251,15 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, * There must be an encoding function for void results so svc_process * will work properly. */ -static int nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) +static int nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); } /* GETACL */ -static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclres *resp) +static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_getaclres *resp = rqstp->rq_resp; struct dentry *dentry = resp->fh.fh_dentry; struct inode *inode; struct kvec *head = rqstp->rq_res.head; @@ -296,17 +302,19 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, return (n > 0); } -static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_attrstat *resp) +static int nfsaclsvc_encode_attrstatres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_attrstat *resp = rqstp->rq_resp; + p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat); return xdr_ressize_check(rqstp, p); } /* ACCESS */ -static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_accessres *resp) +static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_accessres *resp = rqstp->rq_resp; + p = nfs2svc_encode_fattr(rqstp, p, &resp->fh, &resp->stat); *p++ = htonl(resp->access); return xdr_ressize_check(rqstp, p); @@ -315,27 +323,27 @@ static int nfsaclsvc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, /* * XDR release functions */ -static int nfsaclsvc_release_getacl(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclres *resp) +static void nfsaclsvc_release_getacl(struct svc_rqst *rqstp) { + struct nfsd3_getaclres *resp = rqstp->rq_resp; + fh_put(&resp->fh); posix_acl_release(resp->acl_access); posix_acl_release(resp->acl_default); - return 1; } -static int nfsaclsvc_release_attrstat(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_attrstat *resp) +static void nfsaclsvc_release_attrstat(struct svc_rqst *rqstp) { + struct nfsd_attrstat *resp = rqstp->rq_resp; + fh_put(&resp->fh); - return 1; } -static int nfsaclsvc_release_access(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_accessres *resp) +static void nfsaclsvc_release_access(struct svc_rqst *rqstp) { - fh_put(&resp->fh); - return 1; + struct nfsd3_accessres *resp = rqstp->rq_resp; + + fh_put(&resp->fh); } #define nfsaclsvc_decode_voidargs NULL @@ -345,24 +353,24 @@ static int nfsaclsvc_release_access(struct svc_rqst *rqstp, __be32 *p, #define nfsd3_voidres nfsd3_voidargs struct nfsd3_voidargs { int dummy; }; -#define PROC(name, argt, rest, relt, cache, respsize) \ - { (svc_procfunc) nfsacld_proc_##name, \ - (kxdrproc_t) nfsaclsvc_decode_##argt##args, \ - (kxdrproc_t) nfsaclsvc_encode_##rest##res, \ - (kxdrproc_t) nfsaclsvc_release_##relt, \ - sizeof(struct nfsd3_##argt##args), \ - sizeof(struct nfsd3_##rest##res), \ - 0, \ - cache, \ - respsize, \ - } +#define PROC(name, argt, rest, relt, cache, respsize) \ +{ \ + .pc_func = nfsacld_proc_##name, \ + .pc_decode = nfsaclsvc_decode_##argt##args, \ + .pc_encode = nfsaclsvc_encode_##rest##res, \ + .pc_release = nfsaclsvc_release_##relt, \ + .pc_argsize = sizeof(struct nfsd3_##argt##args), \ + .pc_ressize = sizeof(struct nfsd3_##rest##res), \ + .pc_cachetype = cache, \ + .pc_xdrressize = respsize, \ +} #define ST 1 /* status*/ #define AT 21 /* attributes */ #define pAT (1+AT) /* post attributes - conditional */ #define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */ -static struct svc_procedure nfsd_acl_procedures2[] = { +static const struct svc_procedure nfsd_acl_procedures2[] = { PROC(null, void, void, void, RC_NOCACHE, ST), PROC(getacl, getacl, getacl, getacl, RC_NOCACHE, ST+1+2*(1+ACL)), PROC(setacl, setacl, attrstat, attrstat, RC_NOCACHE, ST+AT), @@ -370,10 +378,12 @@ static struct svc_procedure nfsd_acl_procedures2[] = { PROC(access, access, access, access, RC_NOCACHE, ST+AT+1), }; -struct svc_version nfsd_acl_version2 = { - .vs_vers = 2, - .vs_nproc = 5, - .vs_proc = nfsd_acl_procedures2, - .vs_dispatch = nfsd_dispatch, - .vs_xdrsize = NFS3_SVC_XDRSIZE, +static unsigned int nfsd_acl_count2[ARRAY_SIZE(nfsd_acl_procedures2)]; +const struct svc_version nfsd_acl_version2 = { + .vs_vers = 2, + .vs_nproc = 5, + .vs_proc = nfsd_acl_procedures2, + .vs_count = nfsd_acl_count2, + .vs_dispatch = nfsd_dispatch, + .vs_xdrsize = NFS3_SVC_XDRSIZE, }; diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index dcb5f79076c0..01976529f042 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c @@ -18,7 +18,7 @@ * NULL call. */ static __be32 -nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) +nfsd3_proc_null(struct svc_rqst *rqstp) { return nfs_ok; } @@ -26,9 +26,10 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) /* * Get the Access and/or Default ACL of a file. */ -static __be32 nfsd3_proc_getacl(struct svc_rqst * rqstp, - struct nfsd3_getaclargs *argp, struct nfsd3_getaclres *resp) +static __be32 nfsd3_proc_getacl(struct svc_rqst *rqstp) { + struct nfsd3_getaclargs *argp = rqstp->rq_argp; + struct nfsd3_getaclres *resp = rqstp->rq_resp; struct posix_acl *acl; struct inode *inode; svc_fh *fh; @@ -80,10 +81,10 @@ fail: /* * Set the Access and/or Default ACL of a file. */ -static __be32 nfsd3_proc_setacl(struct svc_rqst * rqstp, - struct nfsd3_setaclargs *argp, - struct nfsd3_attrstat *resp) +static __be32 nfsd3_proc_setacl(struct svc_rqst *rqstp) { + struct nfsd3_setaclargs *argp = rqstp->rq_argp; + struct nfsd3_attrstat *resp = rqstp->rq_resp; struct inode *inode; svc_fh *fh; __be32 nfserr = 0; @@ -123,9 +124,10 @@ out: /* * XDR decode functions */ -static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclargs *args) +static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_getaclargs *args = rqstp->rq_argp; + p = nfs3svc_decode_fh(p, &args->fh); if (!p) return 0; @@ -135,9 +137,9 @@ static int nfs3svc_decode_getaclargs(struct svc_rqst *rqstp, __be32 *p, } -static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_setaclargs *args) +static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_setaclargs *args = rqstp->rq_argp; struct kvec *head = rqstp->rq_arg.head; unsigned int base; int n; @@ -166,9 +168,9 @@ static int nfs3svc_decode_setaclargs(struct svc_rqst *rqstp, __be32 *p, */ /* GETACL */ -static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclres *resp) +static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_getaclres *resp = rqstp->rq_resp; struct dentry *dentry = resp->fh.fh_dentry; p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); @@ -211,9 +213,10 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, } /* SETACL */ -static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_attrstat *resp) +static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_attrstat *resp = rqstp->rq_resp; + p = nfs3svc_encode_post_op_attr(rqstp, p, &resp->fh); return xdr_ressize_check(rqstp, p); @@ -222,13 +225,13 @@ static int nfs3svc_encode_setaclres(struct svc_rqst *rqstp, __be32 *p, /* * XDR release functions */ -static int nfs3svc_release_getacl(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_getaclres *resp) +static void nfs3svc_release_getacl(struct svc_rqst *rqstp) { + struct nfsd3_getaclres *resp = rqstp->rq_resp; + fh_put(&resp->fh); posix_acl_release(resp->acl_access); posix_acl_release(resp->acl_default); - return 1; } #define nfs3svc_decode_voidargs NULL @@ -237,34 +240,36 @@ static int nfs3svc_release_getacl(struct svc_rqst *rqstp, __be32 *p, #define nfsd3_voidres nfsd3_voidargs struct nfsd3_voidargs { int dummy; }; -#define PROC(name, argt, rest, relt, cache, respsize) \ - { (svc_procfunc) nfsd3_proc_##name, \ - (kxdrproc_t) nfs3svc_decode_##argt##args, \ - (kxdrproc_t) nfs3svc_encode_##rest##res, \ - (kxdrproc_t) nfs3svc_release_##relt, \ - sizeof(struct nfsd3_##argt##args), \ - sizeof(struct nfsd3_##rest##res), \ - 0, \ - cache, \ - respsize, \ - } +#define PROC(name, argt, rest, relt, cache, respsize) \ +{ \ + .pc_func = nfsd3_proc_##name, \ + .pc_decode = nfs3svc_decode_##argt##args, \ + .pc_encode = nfs3svc_encode_##rest##res, \ + .pc_release = nfs3svc_release_##relt, \ + .pc_argsize = sizeof(struct nfsd3_##argt##args), \ + .pc_ressize = sizeof(struct nfsd3_##rest##res), \ + .pc_cachetype = cache, \ + .pc_xdrressize = respsize, \ +} #define ST 1 /* status*/ #define AT 21 /* attributes */ #define pAT (1+AT) /* post attributes - conditional */ #define ACL (1+NFS_ACL_MAX_ENTRIES*3) /* Access Control List */ -static struct svc_procedure nfsd_acl_procedures3[] = { +static const struct svc_procedure nfsd_acl_procedures3[] = { PROC(null, void, void, void, RC_NOCACHE, ST), PROC(getacl, getacl, getacl, getacl, RC_NOCACHE, ST+1+2*(1+ACL)), PROC(setacl, setacl, setacl, fhandle, RC_NOCACHE, ST+pAT), }; -struct svc_version nfsd_acl_version3 = { - .vs_vers = 3, - .vs_nproc = 3, - .vs_proc = nfsd_acl_procedures3, - .vs_dispatch = nfsd_dispatch, - .vs_xdrsize = NFS3_SVC_XDRSIZE, +static unsigned int nfsd_acl_count3[ARRAY_SIZE(nfsd_acl_procedures3)]; +const struct svc_version nfsd_acl_version3 = { + .vs_vers = 3, + .vs_nproc = 3, + .vs_proc = nfsd_acl_procedures3, + .vs_count = nfsd_acl_count3, + .vs_dispatch = nfsd_dispatch, + .vs_xdrsize = NFS3_SVC_XDRSIZE, }; diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 045c9081eabe..2cb56a0d6625 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -31,7 +31,7 @@ static int nfs3_ftypes[] = { * NULL call. */ static __be32 -nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) +nfsd3_proc_null(struct svc_rqst *rqstp) { return nfs_ok; } @@ -40,9 +40,10 @@ nfsd3_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) * Get a file's attributes */ static __be32 -nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, - struct nfsd3_attrstat *resp) +nfsd3_proc_getattr(struct svc_rqst *rqstp) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + struct nfsd3_attrstat *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: GETATTR(3) %s\n", @@ -63,9 +64,10 @@ nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, * Set a file's attributes */ static __be32 -nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp, - struct nfsd3_attrstat *resp) +nfsd3_proc_setattr(struct svc_rqst *rqstp) { + struct nfsd3_sattrargs *argp = rqstp->rq_argp; + struct nfsd3_attrstat *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: SETATTR(3) %s\n", @@ -81,9 +83,10 @@ nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp, * Look up a path name component */ static __be32 -nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, - struct nfsd3_diropres *resp) +nfsd3_proc_lookup(struct svc_rqst *rqstp) { + struct nfsd3_diropargs *argp = rqstp->rq_argp; + struct nfsd3_diropres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: LOOKUP(3) %s %.*s\n", @@ -105,9 +108,10 @@ nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, * Check file access */ static __be32 -nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, - struct nfsd3_accessres *resp) +nfsd3_proc_access(struct svc_rqst *rqstp) { + struct nfsd3_accessargs *argp = rqstp->rq_argp; + struct nfsd3_accessres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: ACCESS(3) %s 0x%x\n", @@ -124,9 +128,10 @@ nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp, * Read a symlink. */ static __be32 -nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp, - struct nfsd3_readlinkres *resp) +nfsd3_proc_readlink(struct svc_rqst *rqstp) { + struct nfsd3_readlinkargs *argp = rqstp->rq_argp; + struct nfsd3_readlinkres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh)); @@ -142,9 +147,10 @@ nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp, * Read a portion of a file. */ static __be32 -nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp, - struct nfsd3_readres *resp) +nfsd3_proc_read(struct svc_rqst *rqstp) { + struct nfsd3_readargs *argp = rqstp->rq_argp; + struct nfsd3_readres *resp = rqstp->rq_resp; __be32 nfserr; u32 max_blocksize = svc_max_payload(rqstp); unsigned long cnt = min(argp->count, max_blocksize); @@ -179,9 +185,10 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp, * Write data to a file */ static __be32 -nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp, - struct nfsd3_writeres *resp) +nfsd3_proc_write(struct svc_rqst *rqstp) { + struct nfsd3_writeargs *argp = rqstp->rq_argp; + struct nfsd3_writeres *resp = rqstp->rq_resp; __be32 nfserr; unsigned long cnt = argp->len; @@ -206,9 +213,10 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp, * first reports about SunOS compatibility problems start to pour in... */ static __be32 -nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, - struct nfsd3_diropres *resp) +nfsd3_proc_create(struct svc_rqst *rqstp) { + struct nfsd3_createargs *argp = rqstp->rq_argp; + struct nfsd3_diropres *resp = rqstp->rq_resp; svc_fh *dirfhp, *newfhp = NULL; struct iattr *attr; __be32 nfserr; @@ -243,9 +251,10 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, * Make directory. This operation is not idempotent. */ static __be32 -nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, - struct nfsd3_diropres *resp) +nfsd3_proc_mkdir(struct svc_rqst *rqstp) { + struct nfsd3_createargs *argp = rqstp->rq_argp; + struct nfsd3_diropres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: MKDIR(3) %s %.*s\n", @@ -263,9 +272,10 @@ nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp, } static __be32 -nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp, - struct nfsd3_diropres *resp) +nfsd3_proc_symlink(struct svc_rqst *rqstp) { + struct nfsd3_symlinkargs *argp = rqstp->rq_argp; + struct nfsd3_diropres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: SYMLINK(3) %s %.*s -> %.*s\n", @@ -284,9 +294,10 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp, * Make socket/fifo/device. */ static __be32 -nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp, - struct nfsd3_diropres *resp) +nfsd3_proc_mknod(struct svc_rqst *rqstp) { + struct nfsd3_mknodargs *argp = rqstp->rq_argp; + struct nfsd3_diropres *resp = rqstp->rq_resp; __be32 nfserr; int type; dev_t rdev = 0; @@ -321,9 +332,10 @@ nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp, * Remove file/fifo/socket etc. */ static __be32 -nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, - struct nfsd3_attrstat *resp) +nfsd3_proc_remove(struct svc_rqst *rqstp) { + struct nfsd3_diropargs *argp = rqstp->rq_argp; + struct nfsd3_attrstat *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: REMOVE(3) %s %.*s\n", @@ -342,9 +354,10 @@ nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, * Remove a directory */ static __be32 -nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, - struct nfsd3_attrstat *resp) +nfsd3_proc_rmdir(struct svc_rqst *rqstp) { + struct nfsd3_diropargs *argp = rqstp->rq_argp; + struct nfsd3_attrstat *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: RMDIR(3) %s %.*s\n", @@ -359,9 +372,10 @@ nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp, } static __be32 -nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp, - struct nfsd3_renameres *resp) +nfsd3_proc_rename(struct svc_rqst *rqstp) { + struct nfsd3_renameargs *argp = rqstp->rq_argp; + struct nfsd3_renameres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: RENAME(3) %s %.*s ->\n", @@ -381,9 +395,10 @@ nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp, } static __be32 -nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp, - struct nfsd3_linkres *resp) +nfsd3_proc_link(struct svc_rqst *rqstp) { + struct nfsd3_linkargs *argp = rqstp->rq_argp; + struct nfsd3_linkres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: LINK(3) %s ->\n", @@ -404,9 +419,10 @@ nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp, * Read a portion of a directory. */ static __be32 -nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, - struct nfsd3_readdirres *resp) +nfsd3_proc_readdir(struct svc_rqst *rqstp) { + struct nfsd3_readdirargs *argp = rqstp->rq_argp; + struct nfsd3_readdirres *resp = rqstp->rq_resp; __be32 nfserr; int count; @@ -440,9 +456,10 @@ nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, * For now, we choose to ignore the dircount parameter. */ static __be32 -nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, - struct nfsd3_readdirres *resp) +nfsd3_proc_readdirplus(struct svc_rqst *rqstp) { + struct nfsd3_readdirargs *argp = rqstp->rq_argp; + struct nfsd3_readdirres *resp = rqstp->rq_resp; __be32 nfserr; int count = 0; loff_t offset; @@ -507,9 +524,10 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp, * Get file system stats */ static __be32 -nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, - struct nfsd3_fsstatres *resp) +nfsd3_proc_fsstat(struct svc_rqst *rqstp) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + struct nfsd3_fsstatres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: FSSTAT(3) %s\n", @@ -524,9 +542,10 @@ nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, * Get file system info */ static __be32 -nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, - struct nfsd3_fsinfores *resp) +nfsd3_proc_fsinfo(struct svc_rqst *rqstp) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + struct nfsd3_fsinfores *resp = rqstp->rq_resp; __be32 nfserr; u32 max_blocksize = svc_max_payload(rqstp); @@ -567,9 +586,10 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, * Get pathconf info for the specified file */ static __be32 -nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, - struct nfsd3_pathconfres *resp) +nfsd3_proc_pathconf(struct svc_rqst *rqstp) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + struct nfsd3_pathconfres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: PATHCONF(3) %s\n", @@ -610,9 +630,10 @@ nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, * Commit a file (range) to stable storage. */ static __be32 -nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp, - struct nfsd3_commitres *resp) +nfsd3_proc_commit(struct svc_rqst *rqstp) { + struct nfsd3_commitargs *argp = rqstp->rq_argp; + struct nfsd3_commitres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: COMMIT(3) %s %u@%Lu\n", @@ -647,233 +668,221 @@ nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp, #define nfsd3_voidres nfsd3_voidargs struct nfsd3_voidargs { int dummy; }; -#define PROC(name, argt, rest, relt, cache, respsize) \ - { (svc_procfunc) nfsd3_proc_##name, \ - (kxdrproc_t) nfs3svc_decode_##argt##args, \ - (kxdrproc_t) nfs3svc_encode_##rest##res, \ - (kxdrproc_t) nfs3svc_release_##relt, \ - sizeof(struct nfsd3_##argt##args), \ - sizeof(struct nfsd3_##rest##res), \ - 0, \ - cache, \ - respsize, \ - } - #define ST 1 /* status*/ #define FH 17 /* filehandle with length */ #define AT 21 /* attributes */ #define pAT (1+AT) /* post attributes - conditional */ #define WC (7+pAT) /* WCC attributes */ -static struct svc_procedure nfsd_procedures3[22] = { +static const struct svc_procedure nfsd_procedures3[22] = { [NFS3PROC_NULL] = { - .pc_func = (svc_procfunc) nfsd3_proc_null, - .pc_encode = (kxdrproc_t) nfs3svc_encode_voidres, + .pc_func = nfsd3_proc_null, + .pc_encode = nfs3svc_encode_voidres, .pc_argsize = sizeof(struct nfsd3_voidargs), .pc_ressize = sizeof(struct nfsd3_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST, }, [NFS3PROC_GETATTR] = { - .pc_func = (svc_procfunc) nfsd3_proc_getattr, - .pc_decode = (kxdrproc_t) nfs3svc_decode_fhandleargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_attrstatres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_getattr, + .pc_decode = nfs3svc_decode_fhandleargs, + .pc_encode = nfs3svc_encode_attrstatres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_fhandleargs), .pc_ressize = sizeof(struct nfsd3_attrstatres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT, }, [NFS3PROC_SETATTR] = { - .pc_func = (svc_procfunc) nfsd3_proc_setattr, - .pc_decode = (kxdrproc_t) nfs3svc_decode_sattrargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_wccstatres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_setattr, + .pc_decode = nfs3svc_decode_sattrargs, + .pc_encode = nfs3svc_encode_wccstatres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_sattrargs), .pc_ressize = sizeof(struct nfsd3_wccstatres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC, }, [NFS3PROC_LOOKUP] = { - .pc_func = (svc_procfunc) nfsd3_proc_lookup, - .pc_decode = (kxdrproc_t) nfs3svc_decode_diropargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_diropres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle2, + .pc_func = nfsd3_proc_lookup, + .pc_decode = nfs3svc_decode_diropargs, + .pc_encode = nfs3svc_encode_diropres, + .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_diropargs), .pc_ressize = sizeof(struct nfsd3_diropres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+FH+pAT+pAT, }, [NFS3PROC_ACCESS] = { - .pc_func = (svc_procfunc) nfsd3_proc_access, - .pc_decode = (kxdrproc_t) nfs3svc_decode_accessargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_accessres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_access, + .pc_decode = nfs3svc_decode_accessargs, + .pc_encode = nfs3svc_encode_accessres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_accessargs), .pc_ressize = sizeof(struct nfsd3_accessres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+1, }, [NFS3PROC_READLINK] = { - .pc_func = (svc_procfunc) nfsd3_proc_readlink, - .pc_decode = (kxdrproc_t) nfs3svc_decode_readlinkargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_readlinkres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_readlink, + .pc_decode = nfs3svc_decode_readlinkargs, + .pc_encode = nfs3svc_encode_readlinkres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_readlinkargs), .pc_ressize = sizeof(struct nfsd3_readlinkres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+1+NFS3_MAXPATHLEN/4, }, [NFS3PROC_READ] = { - .pc_func = (svc_procfunc) nfsd3_proc_read, - .pc_decode = (kxdrproc_t) nfs3svc_decode_readargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_readres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_read, + .pc_decode = nfs3svc_decode_readargs, + .pc_encode = nfs3svc_encode_readres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_readargs), .pc_ressize = sizeof(struct nfsd3_readres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+4+NFSSVC_MAXBLKSIZE/4, }, [NFS3PROC_WRITE] = { - .pc_func = (svc_procfunc) nfsd3_proc_write, - .pc_decode = (kxdrproc_t) nfs3svc_decode_writeargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_writeres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_write, + .pc_decode = nfs3svc_decode_writeargs, + .pc_encode = nfs3svc_encode_writeres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_writeargs), .pc_ressize = sizeof(struct nfsd3_writeres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC+4, }, [NFS3PROC_CREATE] = { - .pc_func = (svc_procfunc) nfsd3_proc_create, - .pc_decode = (kxdrproc_t) nfs3svc_decode_createargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_createres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle2, + .pc_func = nfsd3_proc_create, + .pc_decode = nfs3svc_decode_createargs, + .pc_encode = nfs3svc_encode_createres, + .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_createargs), .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, }, [NFS3PROC_MKDIR] = { - .pc_func = (svc_procfunc) nfsd3_proc_mkdir, - .pc_decode = (kxdrproc_t) nfs3svc_decode_mkdirargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_createres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle2, + .pc_func = nfsd3_proc_mkdir, + .pc_decode = nfs3svc_decode_mkdirargs, + .pc_encode = nfs3svc_encode_createres, + .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_mkdirargs), .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, }, [NFS3PROC_SYMLINK] = { - .pc_func = (svc_procfunc) nfsd3_proc_symlink, - .pc_decode = (kxdrproc_t) nfs3svc_decode_symlinkargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_createres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle2, + .pc_func = nfsd3_proc_symlink, + .pc_decode = nfs3svc_decode_symlinkargs, + .pc_encode = nfs3svc_encode_createres, + .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_symlinkargs), .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, }, [NFS3PROC_MKNOD] = { - .pc_func = (svc_procfunc) nfsd3_proc_mknod, - .pc_decode = (kxdrproc_t) nfs3svc_decode_mknodargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_createres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle2, + .pc_func = nfsd3_proc_mknod, + .pc_decode = nfs3svc_decode_mknodargs, + .pc_encode = nfs3svc_encode_createres, + .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_mknodargs), .pc_ressize = sizeof(struct nfsd3_createres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+(1+FH+pAT)+WC, }, [NFS3PROC_REMOVE] = { - .pc_func = (svc_procfunc) nfsd3_proc_remove, - .pc_decode = (kxdrproc_t) nfs3svc_decode_diropargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_wccstatres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_remove, + .pc_decode = nfs3svc_decode_diropargs, + .pc_encode = nfs3svc_encode_wccstatres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_diropargs), .pc_ressize = sizeof(struct nfsd3_wccstatres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC, }, [NFS3PROC_RMDIR] = { - .pc_func = (svc_procfunc) nfsd3_proc_rmdir, - .pc_decode = (kxdrproc_t) nfs3svc_decode_diropargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_wccstatres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_rmdir, + .pc_decode = nfs3svc_decode_diropargs, + .pc_encode = nfs3svc_encode_wccstatres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_diropargs), .pc_ressize = sizeof(struct nfsd3_wccstatres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC, }, [NFS3PROC_RENAME] = { - .pc_func = (svc_procfunc) nfsd3_proc_rename, - .pc_decode = (kxdrproc_t) nfs3svc_decode_renameargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_renameres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle2, + .pc_func = nfsd3_proc_rename, + .pc_decode = nfs3svc_decode_renameargs, + .pc_encode = nfs3svc_encode_renameres, + .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_renameargs), .pc_ressize = sizeof(struct nfsd3_renameres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+WC+WC, }, [NFS3PROC_LINK] = { - .pc_func = (svc_procfunc) nfsd3_proc_link, - .pc_decode = (kxdrproc_t) nfs3svc_decode_linkargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_linkres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle2, + .pc_func = nfsd3_proc_link, + .pc_decode = nfs3svc_decode_linkargs, + .pc_encode = nfs3svc_encode_linkres, + .pc_release = nfs3svc_release_fhandle2, .pc_argsize = sizeof(struct nfsd3_linkargs), .pc_ressize = sizeof(struct nfsd3_linkres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+pAT+WC, }, [NFS3PROC_READDIR] = { - .pc_func = (svc_procfunc) nfsd3_proc_readdir, - .pc_decode = (kxdrproc_t) nfs3svc_decode_readdirargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_readdirres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_readdir, + .pc_decode = nfs3svc_decode_readdirargs, + .pc_encode = nfs3svc_encode_readdirres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_readdirargs), .pc_ressize = sizeof(struct nfsd3_readdirres), .pc_cachetype = RC_NOCACHE, }, [NFS3PROC_READDIRPLUS] = { - .pc_func = (svc_procfunc) nfsd3_proc_readdirplus, - .pc_decode = (kxdrproc_t) nfs3svc_decode_readdirplusargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_readdirres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_readdirplus, + .pc_decode = nfs3svc_decode_readdirplusargs, + .pc_encode = nfs3svc_encode_readdirres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_readdirplusargs), .pc_ressize = sizeof(struct nfsd3_readdirres), .pc_cachetype = RC_NOCACHE, }, [NFS3PROC_FSSTAT] = { - .pc_func = (svc_procfunc) nfsd3_proc_fsstat, - .pc_decode = (kxdrproc_t) nfs3svc_decode_fhandleargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_fsstatres, + .pc_func = nfsd3_proc_fsstat, + .pc_decode = nfs3svc_decode_fhandleargs, + .pc_encode = nfs3svc_encode_fsstatres, .pc_argsize = sizeof(struct nfsd3_fhandleargs), .pc_ressize = sizeof(struct nfsd3_fsstatres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+2*6+1, }, [NFS3PROC_FSINFO] = { - .pc_func = (svc_procfunc) nfsd3_proc_fsinfo, - .pc_decode = (kxdrproc_t) nfs3svc_decode_fhandleargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_fsinfores, + .pc_func = nfsd3_proc_fsinfo, + .pc_decode = nfs3svc_decode_fhandleargs, + .pc_encode = nfs3svc_encode_fsinfores, .pc_argsize = sizeof(struct nfsd3_fhandleargs), .pc_ressize = sizeof(struct nfsd3_fsinfores), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+12, }, [NFS3PROC_PATHCONF] = { - .pc_func = (svc_procfunc) nfsd3_proc_pathconf, - .pc_decode = (kxdrproc_t) nfs3svc_decode_fhandleargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_pathconfres, + .pc_func = nfsd3_proc_pathconf, + .pc_decode = nfs3svc_decode_fhandleargs, + .pc_encode = nfs3svc_encode_pathconfres, .pc_argsize = sizeof(struct nfsd3_fhandleargs), .pc_ressize = sizeof(struct nfsd3_pathconfres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+pAT+6, }, [NFS3PROC_COMMIT] = { - .pc_func = (svc_procfunc) nfsd3_proc_commit, - .pc_decode = (kxdrproc_t) nfs3svc_decode_commitargs, - .pc_encode = (kxdrproc_t) nfs3svc_encode_commitres, - .pc_release = (kxdrproc_t) nfs3svc_release_fhandle, + .pc_func = nfsd3_proc_commit, + .pc_decode = nfs3svc_decode_commitargs, + .pc_encode = nfs3svc_encode_commitres, + .pc_release = nfs3svc_release_fhandle, .pc_argsize = sizeof(struct nfsd3_commitargs), .pc_ressize = sizeof(struct nfsd3_commitres), .pc_cachetype = RC_NOCACHE, @@ -881,10 +890,12 @@ static struct svc_procedure nfsd_procedures3[22] = { }, }; -struct svc_version nfsd_version3 = { - .vs_vers = 3, - .vs_nproc = 22, - .vs_proc = nfsd_procedures3, - .vs_dispatch = nfsd_dispatch, - .vs_xdrsize = NFS3_SVC_XDRSIZE, +static unsigned int nfsd_count3[ARRAY_SIZE(nfsd_procedures3)]; +const struct svc_version nfsd_version3 = { + .vs_vers = 3, + .vs_nproc = 22, + .vs_proc = nfsd_procedures3, + .vs_dispatch = nfsd_dispatch, + .vs_count = nfsd_count3, + .vs_xdrsize = NFS3_SVC_XDRSIZE, }; diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 452334694a5d..bf444b664011 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -260,7 +260,7 @@ void fill_post_wcc(struct svc_fh *fhp) printk("nfsd: inode locked twice during operation.\n"); err = fh_getattr(fhp, &fhp->fh_post_attr); - fhp->fh_post_change = d_inode(fhp->fh_dentry)->i_version; + fhp->fh_post_change = nfsd4_change_attribute(d_inode(fhp->fh_dentry)); if (err) { fhp->fh_post_saved = false; /* Grab the ctime anyway - set_change_info might use it */ @@ -273,8 +273,10 @@ void fill_post_wcc(struct svc_fh *fhp) * XDR decode functions */ int -nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args) +nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_fhandle *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -282,9 +284,10 @@ nfs3svc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *a } int -nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_sattrargs *args) +nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_sattrargs *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -300,9 +303,10 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_diropargs *args) +nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_diropargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->fh)) || !(p = decode_filename(p, &args->name, &args->len))) return 0; @@ -311,9 +315,10 @@ nfs3svc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_accessargs *args) +nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_accessargs *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -323,9 +328,9 @@ nfs3svc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_readargs *args) +nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_readargs *args = rqstp->rq_argp; unsigned int len; int v; u32 max_blocksize = svc_max_payload(rqstp); @@ -353,9 +358,9 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_writeargs *args) +nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_writeargs *args = rqstp->rq_argp; unsigned int len, v, hdr, dlen; u32 max_blocksize = svc_max_payload(rqstp); struct kvec *head = rqstp->rq_arg.head; @@ -413,9 +418,10 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_createargs *args) +nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_createargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->fh)) || !(p = decode_filename(p, &args->name, &args->len))) return 0; @@ -435,10 +441,12 @@ nfs3svc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, return xdr_argsize_check(rqstp, p); } + int -nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_createargs *args) +nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_createargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->fh)) || !(p = decode_filename(p, &args->name, &args->len))) return 0; @@ -448,9 +456,9 @@ nfs3svc_decode_mkdirargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_symlinkargs *args) +nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_symlinkargs *args = rqstp->rq_argp; unsigned int len, avail; char *old, *new; struct kvec *vec; @@ -500,9 +508,10 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_mknodargs *args) +nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_mknodargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->fh)) || !(p = decode_filename(p, &args->name, &args->len))) return 0; @@ -522,9 +531,10 @@ nfs3svc_decode_mknodargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_renameargs *args) +nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_renameargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->ffh)) || !(p = decode_filename(p, &args->fname, &args->flen)) || !(p = decode_fh(p, &args->tfh)) @@ -535,9 +545,10 @@ nfs3svc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_readlinkargs *args) +nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_readlinkargs *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -547,9 +558,10 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_linkargs *args) +nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_linkargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->ffh)) || !(p = decode_fh(p, &args->tfh)) || !(p = decode_filename(p, &args->tname, &args->tlen))) @@ -559,9 +571,9 @@ nfs3svc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_readdirargs *args) +nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_readdirargs *args = rqstp->rq_argp; p = decode_fh(p, &args->fh); if (!p) return 0; @@ -576,9 +588,9 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_readdirargs *args) +nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_readdirargs *args = rqstp->rq_argp; int len; u32 max_blocksize = svc_max_payload(rqstp); @@ -602,9 +614,9 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, } int -nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_commitargs *args) +nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_commitargs *args = rqstp->rq_argp; p = decode_fh(p, &args->fh); if (!p) return 0; @@ -622,16 +634,17 @@ nfs3svc_decode_commitargs(struct svc_rqst *rqstp, __be32 *p, * will work properly. */ int -nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfs3svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); } /* GETATTR */ int -nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_attrstat *resp) +nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_attrstat *resp = rqstp->rq_resp; + if (resp->status == 0) { lease_get_mtime(d_inode(resp->fh.fh_dentry), &resp->stat.mtime); @@ -642,18 +655,20 @@ nfs3svc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, /* SETATTR, REMOVE, RMDIR */ int -nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_attrstat *resp) +nfs3svc_encode_wccstat(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_attrstat *resp = rqstp->rq_resp; + p = encode_wcc_data(rqstp, p, &resp->fh); return xdr_ressize_check(rqstp, p); } /* LOOKUP */ int -nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_diropres *resp) +nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_diropres *resp = rqstp->rq_resp; + if (resp->status == 0) { p = encode_fh(p, &resp->fh); p = encode_post_op_attr(rqstp, p, &resp->fh); @@ -664,9 +679,10 @@ nfs3svc_encode_diropres(struct svc_rqst *rqstp, __be32 *p, /* ACCESS */ int -nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_accessres *resp) +nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_accessres *resp = rqstp->rq_resp; + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) *p++ = htonl(resp->access); @@ -675,9 +691,10 @@ nfs3svc_encode_accessres(struct svc_rqst *rqstp, __be32 *p, /* READLINK */ int -nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_readlinkres *resp) +nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_readlinkres *resp = rqstp->rq_resp; + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) { *p++ = htonl(resp->len); @@ -696,9 +713,10 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, /* READ */ int -nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_readres *resp) +nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_readres *resp = rqstp->rq_resp; + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) { *p++ = htonl(resp->count); @@ -720,9 +738,9 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, __be32 *p, /* WRITE */ int -nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_writeres *resp) +nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_writeres *resp = rqstp->rq_resp; struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); p = encode_wcc_data(rqstp, p, &resp->fh); @@ -737,9 +755,10 @@ nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p, /* CREATE, MKDIR, SYMLINK, MKNOD */ int -nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_diropres *resp) +nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_diropres *resp = rqstp->rq_resp; + if (resp->status == 0) { *p++ = xdr_one; p = encode_fh(p, &resp->fh); @@ -751,9 +770,10 @@ nfs3svc_encode_createres(struct svc_rqst *rqstp, __be32 *p, /* RENAME */ int -nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_renameres *resp) +nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_renameres *resp = rqstp->rq_resp; + p = encode_wcc_data(rqstp, p, &resp->ffh); p = encode_wcc_data(rqstp, p, &resp->tfh); return xdr_ressize_check(rqstp, p); @@ -761,9 +781,10 @@ nfs3svc_encode_renameres(struct svc_rqst *rqstp, __be32 *p, /* LINK */ int -nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_linkres *resp) +nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_linkres *resp = rqstp->rq_resp; + p = encode_post_op_attr(rqstp, p, &resp->fh); p = encode_wcc_data(rqstp, p, &resp->tfh); return xdr_ressize_check(rqstp, p); @@ -771,9 +792,10 @@ nfs3svc_encode_linkres(struct svc_rqst *rqstp, __be32 *p, /* READDIR */ int -nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_readdirres *resp) +nfs3svc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_readdirres *resp = rqstp->rq_resp; + p = encode_post_op_attr(rqstp, p, &resp->fh); if (resp->status == 0) { @@ -1021,9 +1043,9 @@ nfs3svc_encode_entry_plus(void *cd, const char *name, /* FSSTAT */ int -nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_fsstatres *resp) +nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_fsstatres *resp = rqstp->rq_resp; struct kstatfs *s = &resp->stats; u64 bs = s->f_bsize; @@ -1043,9 +1065,10 @@ nfs3svc_encode_fsstatres(struct svc_rqst *rqstp, __be32 *p, /* FSINFO */ int -nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_fsinfores *resp) +nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_fsinfores *resp = rqstp->rq_resp; + *p++ = xdr_zero; /* no post_op_attr */ if (resp->status == 0) { @@ -1067,9 +1090,10 @@ nfs3svc_encode_fsinfores(struct svc_rqst *rqstp, __be32 *p, /* PATHCONF */ int -nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_pathconfres *resp) +nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_pathconfres *resp = rqstp->rq_resp; + *p++ = xdr_zero; /* no post_op_attr */ if (resp->status == 0) { @@ -1086,9 +1110,9 @@ nfs3svc_encode_pathconfres(struct svc_rqst *rqstp, __be32 *p, /* COMMIT */ int -nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_commitres *resp) +nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd3_commitres *resp = rqstp->rq_resp; struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); p = encode_wcc_data(rqstp, p, &resp->fh); @@ -1103,19 +1127,19 @@ nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p, /* * XDR release functions */ -int -nfs3svc_release_fhandle(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_attrstat *resp) +void +nfs3svc_release_fhandle(struct svc_rqst *rqstp) { + struct nfsd3_attrstat *resp = rqstp->rq_resp; + fh_put(&resp->fh); - return 1; } -int -nfs3svc_release_fhandle2(struct svc_rqst *rqstp, __be32 *p, - struct nfsd3_fhandle_pair *resp) +void +nfs3svc_release_fhandle2(struct svc_rqst *rqstp) { + struct nfsd3_fhandle_pair *resp = rqstp->rq_resp; + fh_put(&resp->fh1); fh_put(&resp->fh2); - return 1; } diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 0274db6e65d0..b45083c0f9ae 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -468,7 +468,7 @@ static int decode_cb_sequence4res(struct xdr_stream *xdr, * NB: Without this zero space reservation, callbacks over krb5p fail */ static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr, - void *__unused) + const void *__unused) { xdr_reserve_space(xdr, 0); } @@ -477,8 +477,9 @@ static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr, * 20.2. Operation 4: CB_RECALL - Recall a Delegation */ static void nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfsd4_callback *cb) + const void *data) { + const struct nfsd4_callback *cb = data; const struct nfs4_delegation *dp = cb_to_delegation(cb); struct nfs4_cb_compound_hdr hdr = { .ident = cb->cb_clp->cl_cb_ident, @@ -512,8 +513,9 @@ static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr, */ static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfsd4_callback *cb) + void *data) { + struct nfsd4_callback *cb = data; struct nfs4_cb_compound_hdr hdr; int status; @@ -585,8 +587,9 @@ static void encode_cb_layout4args(struct xdr_stream *xdr, static void nfs4_xdr_enc_cb_layout(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfsd4_callback *cb) + const void *data) { + const struct nfsd4_callback *cb = data; const struct nfs4_layout_stateid *ls = container_of(cb, struct nfs4_layout_stateid, ls_recall); struct nfs4_cb_compound_hdr hdr = { @@ -602,8 +605,9 @@ static void nfs4_xdr_enc_cb_layout(struct rpc_rqst *req, static int nfs4_xdr_dec_cb_layout(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfsd4_callback *cb) + void *data) { + struct nfsd4_callback *cb = data; struct nfs4_cb_compound_hdr hdr; int status; @@ -631,8 +635,9 @@ static void encode_stateowner(struct xdr_stream *xdr, struct nfs4_stateowner *so static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct nfsd4_callback *cb) + const void *data) { + const struct nfsd4_callback *cb = data; const struct nfsd4_blocked_lock *nbl = container_of(cb, struct nfsd4_blocked_lock, nbl_cb); struct nfs4_lockowner *lo = (struct nfs4_lockowner *)nbl->nbl_lock.fl_owner; @@ -659,8 +664,9 @@ static void nfs4_xdr_enc_cb_notify_lock(struct rpc_rqst *req, static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct nfsd4_callback *cb) + void *data) { + struct nfsd4_callback *cb = data; struct nfs4_cb_compound_hdr hdr; int status; @@ -682,15 +688,15 @@ static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp, #define PROC(proc, call, argtype, restype) \ [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_CB_##call, \ - .p_encode = (kxdreproc_t)nfs4_xdr_enc_##argtype, \ - .p_decode = (kxdrdproc_t)nfs4_xdr_dec_##restype, \ + .p_encode = nfs4_xdr_enc_##argtype, \ + .p_decode = nfs4_xdr_dec_##restype, \ .p_arglen = NFS4_enc_##argtype##_sz, \ .p_replen = NFS4_dec_##restype##_sz, \ .p_statidx = NFSPROC4_CB_##call, \ .p_name = #proc, \ } -static struct rpc_procinfo nfs4_cb_procedures[] = { +static const struct rpc_procinfo nfs4_cb_procedures[] = { PROC(CB_NULL, NULL, cb_null, cb_null), PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall), #ifdef CONFIG_NFSD_PNFS @@ -699,7 +705,8 @@ static struct rpc_procinfo nfs4_cb_procedures[] = { PROC(CB_NOTIFY_LOCK, COMPOUND, cb_notify_lock, cb_notify_lock), }; -static struct rpc_version nfs_cb_version4 = { +static unsigned int nfs4_cb_counts[ARRAY_SIZE(nfs4_cb_procedures)]; +static const struct rpc_version nfs_cb_version4 = { /* * Note on the callback rpc program version number: despite language in rfc * 5661 section 18.36.3 requiring servers to use 4 in this field, the @@ -709,7 +716,8 @@ static struct rpc_version nfs_cb_version4 = { */ .number = 1, .nrprocs = ARRAY_SIZE(nfs4_cb_procedures), - .procs = nfs4_cb_procedures + .procs = nfs4_cb_procedures, + .counts = nfs4_cb_counts, }; static const struct rpc_version *nfs_cb_version[] = { diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index dadb3bf305b2..d27e75ad25e3 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -344,8 +344,9 @@ copy_clientid(clientid_t *clid, struct nfsd4_session *session) static __be32 nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_open *open) + union nfsd4_op_u *u) { + struct nfsd4_open *open = &u->open; __be32 status; struct svc_fh *resfh = NULL; struct net *net = SVC_NET(rqstp); @@ -467,14 +468,14 @@ out: */ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_op *op) { - struct nfsd4_open *open = (struct nfsd4_open *)&op->u; + struct nfsd4_open *open = &op->u.open; if (!seqid_mutating_err(ntohl(op->status))) return op->status; if (nfsd4_has_session(cstate)) return op->status; open->op_xdr_error = op->status; - return nfsd4_open(rqstp, cstate, open); + return nfsd4_open(rqstp, cstate, &op->u); } /* @@ -482,19 +483,21 @@ static __be32 nfsd4_open_omfg(struct svc_rqst *rqstp, struct nfsd4_compound_stat */ static __be32 nfsd4_getfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct svc_fh **getfh) + union nfsd4_op_u *u) { if (!cstate->current_fh.fh_dentry) return nfserr_nofilehandle; - *getfh = &cstate->current_fh; + u->getfh = &cstate->current_fh; return nfs_ok; } static __be32 nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_putfh *putfh) + union nfsd4_op_u *u) { + struct nfsd4_putfh *putfh = &u->putfh; + fh_put(&cstate->current_fh); cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen; memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval, @@ -504,7 +507,7 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - void *arg) + union nfsd4_op_u *u) { __be32 status; @@ -515,7 +518,7 @@ nfsd4_putrootfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - void *arg) + union nfsd4_op_u *u) { if (!cstate->save_fh.fh_dentry) return nfserr_restorefh; @@ -530,7 +533,7 @@ nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - void *arg) + union nfsd4_op_u *u) { if (!cstate->current_fh.fh_dentry) return nfserr_nofilehandle; @@ -548,8 +551,10 @@ nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, */ static __be32 nfsd4_access(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_access *access) + union nfsd4_op_u *u) { + struct nfsd4_access *access = &u->access; + if (access->ac_req_access & ~NFS3_ACCESS_FULL) return nfserr_inval; @@ -574,8 +579,10 @@ static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net) static __be32 nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_commit *commit) + union nfsd4_op_u *u) { + struct nfsd4_commit *commit = &u->commit; + gen_boot_verifier(&commit->co_verf, SVC_NET(rqstp)); return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset, commit->co_count); @@ -583,8 +590,9 @@ nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_create *create) + union nfsd4_op_u *u) { + struct nfsd4_create *create = &u->create; struct svc_fh resfh; __be32 status; dev_t rdev; @@ -670,8 +678,9 @@ out: static __be32 nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_getattr *getattr) + union nfsd4_op_u *u) { + struct nfsd4_getattr *getattr = &u->getattr; __be32 status; status = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_NOP); @@ -691,8 +700,9 @@ nfsd4_getattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_link *link) + union nfsd4_op_u *u) { + struct nfsd4_link *link = &u->link; __be32 status = nfserr_nofilehandle; if (!cstate->save_fh.fh_dentry) @@ -723,24 +733,25 @@ static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) static __be32 nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - void *arg) + union nfsd4_op_u *u) { return nfsd4_do_lookupp(rqstp, &cstate->current_fh); } static __be32 nfsd4_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_lookup *lookup) + union nfsd4_op_u *u) { return nfsd_lookup(rqstp, &cstate->current_fh, - lookup->lo_name, lookup->lo_len, + u->lookup.lo_name, u->lookup.lo_len, &cstate->current_fh); } static __be32 nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_read *read) + union nfsd4_op_u *u) { + struct nfsd4_read *read = &u->read; __be32 status; read->rd_filp = NULL; @@ -775,8 +786,9 @@ out: static __be32 nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_readdir *readdir) + union nfsd4_op_u *u) { + struct nfsd4_readdir *readdir = &u->readdir; u64 cookie = readdir->rd_cookie; static const nfs4_verifier zeroverf; @@ -800,17 +812,18 @@ nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_readlink(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_readlink *readlink) + union nfsd4_op_u *u) { - readlink->rl_rqstp = rqstp; - readlink->rl_fhp = &cstate->current_fh; + u->readlink.rl_rqstp = rqstp; + u->readlink.rl_fhp = &cstate->current_fh; return nfs_ok; } static __be32 nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_remove *remove) + union nfsd4_op_u *u) { + struct nfsd4_remove *remove = &u->remove; __be32 status; if (opens_in_grace(SVC_NET(rqstp))) @@ -826,8 +839,9 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_rename *rename) + union nfsd4_op_u *u) { + struct nfsd4_rename *rename = &u->rename; __be32 status = nfserr_nofilehandle; if (!cstate->save_fh.fh_dentry) @@ -847,8 +861,9 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_secinfo *secinfo) + union nfsd4_op_u *u) { + struct nfsd4_secinfo *secinfo = &u->secinfo; struct svc_export *exp; struct dentry *dentry; __be32 err; @@ -876,11 +891,11 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_secinfo_no_name *sin) + union nfsd4_op_u *u) { __be32 err; - switch (sin->sin_style) { + switch (u->secinfo_no_name.sin_style) { case NFS4_SECINFO_STYLE4_CURRENT_FH: break; case NFS4_SECINFO_STYLE4_PARENT: @@ -892,15 +907,16 @@ nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstat return nfserr_inval; } - sin->sin_exp = exp_get(cstate->current_fh.fh_export); + u->secinfo_no_name.sin_exp = exp_get(cstate->current_fh.fh_export); fh_put(&cstate->current_fh); return nfs_ok; } static __be32 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_setattr *setattr) + union nfsd4_op_u *u) { + struct nfsd4_setattr *setattr = &u->setattr; __be32 status = nfs_ok; int err; @@ -960,8 +976,9 @@ static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write) static __be32 nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_write *write) + union nfsd4_op_u *u) { + struct nfsd4_write *write = &u->write; stateid_t *stateid = &write->wr_stateid; struct file *filp = NULL; __be32 status = nfs_ok; @@ -1034,8 +1051,9 @@ out_put_src: static __be32 nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_clone *clone) + union nfsd4_op_u *u) { + struct nfsd4_clone *clone = &u->clone; struct file *src, *dst; __be32 status; @@ -1055,8 +1073,9 @@ out: static __be32 nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_copy *copy) + union nfsd4_op_u *u) { + struct nfsd4_copy *copy = &u->copy; struct file *src, *dst; __be32 status; ssize_t bytes; @@ -1111,23 +1130,24 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, static __be32 nfsd4_allocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_fallocate *fallocate) + union nfsd4_op_u *u) { - return nfsd4_fallocate(rqstp, cstate, fallocate, 0); + return nfsd4_fallocate(rqstp, cstate, &u->allocate, 0); } static __be32 nfsd4_deallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_fallocate *fallocate) + union nfsd4_op_u *u) { - return nfsd4_fallocate(rqstp, cstate, fallocate, + return nfsd4_fallocate(rqstp, cstate, &u->deallocate, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE); } static __be32 nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_seek *seek) + union nfsd4_op_u *u) { + struct nfsd4_seek *seek = &u->seek; int whence; __be32 status; struct file *file; @@ -1232,21 +1252,21 @@ out_kfree: static __be32 nfsd4_nverify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_verify *verify) + union nfsd4_op_u *u) { __be32 status; - status = _nfsd4_verify(rqstp, cstate, verify); + status = _nfsd4_verify(rqstp, cstate, &u->verify); return status == nfserr_not_same ? nfs_ok : status; } static __be32 nfsd4_verify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_verify *verify) + union nfsd4_op_u *u) { __be32 status; - status = _nfsd4_verify(rqstp, cstate, verify); + status = _nfsd4_verify(rqstp, cstate, &u->nverify); return status == nfserr_same ? nfs_ok : status; } @@ -1271,9 +1291,9 @@ nfsd4_layout_verify(struct svc_export *exp, unsigned int layout_type) static __be32 nfsd4_getdeviceinfo(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_getdeviceinfo *gdp) + struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { + struct nfsd4_getdeviceinfo *gdp = &u->getdeviceinfo; const struct nfsd4_layout_ops *ops; struct nfsd4_deviceid_map *map; struct svc_export *exp; @@ -1317,9 +1337,9 @@ out: static __be32 nfsd4_layoutget(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_layoutget *lgp) + struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { + struct nfsd4_layoutget *lgp = &u->layoutget; struct svc_fh *current_fh = &cstate->current_fh; const struct nfsd4_layout_ops *ops; struct nfs4_layout_stateid *ls; @@ -1397,9 +1417,9 @@ out: static __be32 nfsd4_layoutcommit(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_layoutcommit *lcp) + struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { + struct nfsd4_layoutcommit *lcp = &u->layoutcommit; const struct nfsd4_layout_seg *seg = &lcp->lc_seg; struct svc_fh *current_fh = &cstate->current_fh; const struct nfsd4_layout_ops *ops; @@ -1461,9 +1481,9 @@ out: static __be32 nfsd4_layoutreturn(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_layoutreturn *lrp) + struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { + struct nfsd4_layoutreturn *lrp = &u->layoutreturn; struct svc_fh *current_fh = &cstate->current_fh; __be32 nfserr; @@ -1510,7 +1530,7 @@ out: * NULL call. */ static __be32 -nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) +nfsd4_proc_null(struct svc_rqst *rqstp) { return nfs_ok; } @@ -1521,12 +1541,6 @@ static inline void nfsd4_increment_op_stats(u32 opnum) nfsdstats.nfs4_opcount[opnum]++; } -typedef __be32(*nfsd4op_func)(struct svc_rqst *, struct nfsd4_compound_state *, - void *); -typedef u32(*nfsd4op_rsize)(struct svc_rqst *, struct nfsd4_op *op); -typedef void(*stateid_setter)(struct nfsd4_compound_state *, void *); -typedef void(*stateid_getter)(struct nfsd4_compound_state *, void *); - enum nfsd4_op_flags { ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */ ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */ @@ -1558,16 +1572,19 @@ enum nfsd4_op_flags { }; struct nfsd4_operation { - nfsd4op_func op_func; + __be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *, + union nfsd4_op_u *); u32 op_flags; char *op_name; /* Try to get response size before operation */ - nfsd4op_rsize op_rsize_bop; - stateid_getter op_get_currentstateid; - stateid_setter op_set_currentstateid; + u32 (*op_rsize_bop)(struct svc_rqst *, struct nfsd4_op *); + void (*op_get_currentstateid)(struct nfsd4_compound_state *, + union nfsd4_op_u *); + void (*op_set_currentstateid)(struct nfsd4_compound_state *, + union nfsd4_op_u *); }; -static struct nfsd4_operation nfsd4_ops[]; +static const struct nfsd4_operation nfsd4_ops[]; static const char *nfsd4_op_name(unsigned opnum); @@ -1604,7 +1621,7 @@ static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args) return nfs_ok; } -static inline struct nfsd4_operation *OPDESC(struct nfsd4_op *op) +static inline const struct nfsd4_operation *OPDESC(struct nfsd4_op *op) { return &nfsd4_ops[op->opnum]; } @@ -1622,10 +1639,9 @@ static bool need_wrongsec_check(struct svc_rqst *rqstp) struct nfsd4_compoundargs *argp = rqstp->rq_argp; struct nfsd4_op *this = &argp->ops[resp->opcnt - 1]; struct nfsd4_op *next = &argp->ops[resp->opcnt]; - struct nfsd4_operation *thisd; - struct nfsd4_operation *nextd; + const struct nfsd4_operation *thisd = OPDESC(this); + const struct nfsd4_operation *nextd; - thisd = OPDESC(this); /* * Most ops check wronsec on our own; only the putfh-like ops * have special rules. @@ -1673,12 +1689,12 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, * COMPOUND call. */ static __be32 -nfsd4_proc_compound(struct svc_rqst *rqstp, - struct nfsd4_compoundargs *args, - struct nfsd4_compoundres *resp) +nfsd4_proc_compound(struct svc_rqst *rqstp) { + struct nfsd4_compoundargs *args = rqstp->rq_argp; + struct nfsd4_compoundres *resp = rqstp->rq_resp; struct nfsd4_op *op; - struct nfsd4_operation *opdesc; + const struct nfsd4_operation *opdesc; struct nfsd4_compound_state *cstate = &resp->cstate; struct svc_fh *current_fh = &cstate->current_fh; struct svc_fh *save_fh = &cstate->save_fh; @@ -2091,360 +2107,360 @@ static inline u32 nfsd4_seek_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) return (op_encode_hdr_size + 3) * sizeof(__be32); } -static struct nfsd4_operation nfsd4_ops[] = { +static const struct nfsd4_operation nfsd4_ops[] = { [OP_ACCESS] = { - .op_func = (nfsd4op_func)nfsd4_access, + .op_func = nfsd4_access, .op_name = "OP_ACCESS", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_access_rsize, + .op_rsize_bop = nfsd4_access_rsize, }, [OP_CLOSE] = { - .op_func = (nfsd4op_func)nfsd4_close, + .op_func = nfsd4_close, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_CLOSE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, - .op_get_currentstateid = (stateid_getter)nfsd4_get_closestateid, - .op_set_currentstateid = (stateid_setter)nfsd4_set_closestateid, + .op_rsize_bop = nfsd4_status_stateid_rsize, + .op_get_currentstateid = nfsd4_get_closestateid, + .op_set_currentstateid = nfsd4_set_closestateid, }, [OP_COMMIT] = { - .op_func = (nfsd4op_func)nfsd4_commit, + .op_func = nfsd4_commit, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_COMMIT", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_commit_rsize, + .op_rsize_bop = nfsd4_commit_rsize, }, [OP_CREATE] = { - .op_func = (nfsd4op_func)nfsd4_create, + .op_func = nfsd4_create, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME | OP_CLEAR_STATEID, .op_name = "OP_CREATE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_rsize, + .op_rsize_bop = nfsd4_create_rsize, }, [OP_DELEGRETURN] = { - .op_func = (nfsd4op_func)nfsd4_delegreturn, + .op_func = nfsd4_delegreturn, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_DELEGRETURN", .op_rsize_bop = nfsd4_only_status_rsize, - .op_get_currentstateid = (stateid_getter)nfsd4_get_delegreturnstateid, + .op_get_currentstateid = nfsd4_get_delegreturnstateid, }, [OP_GETATTR] = { - .op_func = (nfsd4op_func)nfsd4_getattr, + .op_func = nfsd4_getattr, .op_flags = ALLOWED_ON_ABSENT_FS, .op_rsize_bop = nfsd4_getattr_rsize, .op_name = "OP_GETATTR", }, [OP_GETFH] = { - .op_func = (nfsd4op_func)nfsd4_getfh, + .op_func = nfsd4_getfh, .op_name = "OP_GETFH", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_getfh_rsize, + .op_rsize_bop = nfsd4_getfh_rsize, }, [OP_LINK] = { - .op_func = (nfsd4op_func)nfsd4_link, + .op_func = nfsd4_link, .op_flags = ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_LINK", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_link_rsize, + .op_rsize_bop = nfsd4_link_rsize, }, [OP_LOCK] = { - .op_func = (nfsd4op_func)nfsd4_lock, + .op_func = nfsd4_lock, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_LOCK", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize, - .op_set_currentstateid = (stateid_setter)nfsd4_set_lockstateid, + .op_rsize_bop = nfsd4_lock_rsize, + .op_set_currentstateid = nfsd4_set_lockstateid, }, [OP_LOCKT] = { - .op_func = (nfsd4op_func)nfsd4_lockt, + .op_func = nfsd4_lockt, .op_name = "OP_LOCKT", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_lock_rsize, + .op_rsize_bop = nfsd4_lock_rsize, }, [OP_LOCKU] = { - .op_func = (nfsd4op_func)nfsd4_locku, + .op_func = nfsd4_locku, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_LOCKU", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, - .op_get_currentstateid = (stateid_getter)nfsd4_get_lockustateid, + .op_rsize_bop = nfsd4_status_stateid_rsize, + .op_get_currentstateid = nfsd4_get_lockustateid, }, [OP_LOOKUP] = { - .op_func = (nfsd4op_func)nfsd4_lookup, + .op_func = nfsd4_lookup, .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, .op_name = "OP_LOOKUP", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_LOOKUPP] = { - .op_func = (nfsd4op_func)nfsd4_lookupp, + .op_func = nfsd4_lookupp, .op_flags = OP_HANDLES_WRONGSEC | OP_CLEAR_STATEID, .op_name = "OP_LOOKUPP", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_NVERIFY] = { - .op_func = (nfsd4op_func)nfsd4_nverify, + .op_func = nfsd4_nverify, .op_name = "OP_NVERIFY", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_OPEN] = { - .op_func = (nfsd4op_func)nfsd4_open, + .op_func = nfsd4_open, .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, .op_name = "OP_OPEN", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_open_rsize, - .op_set_currentstateid = (stateid_setter)nfsd4_set_openstateid, + .op_rsize_bop = nfsd4_open_rsize, + .op_set_currentstateid = nfsd4_set_openstateid, }, [OP_OPEN_CONFIRM] = { - .op_func = (nfsd4op_func)nfsd4_open_confirm, + .op_func = nfsd4_open_confirm, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_OPEN_CONFIRM", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, + .op_rsize_bop = nfsd4_status_stateid_rsize, }, [OP_OPEN_DOWNGRADE] = { - .op_func = (nfsd4op_func)nfsd4_open_downgrade, + .op_func = nfsd4_open_downgrade, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_OPEN_DOWNGRADE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_status_stateid_rsize, - .op_get_currentstateid = (stateid_getter)nfsd4_get_opendowngradestateid, - .op_set_currentstateid = (stateid_setter)nfsd4_set_opendowngradestateid, + .op_rsize_bop = nfsd4_status_stateid_rsize, + .op_get_currentstateid = nfsd4_get_opendowngradestateid, + .op_set_currentstateid = nfsd4_set_opendowngradestateid, }, [OP_PUTFH] = { - .op_func = (nfsd4op_func)nfsd4_putfh, + .op_func = nfsd4_putfh, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID, .op_name = "OP_PUTFH", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_PUTPUBFH] = { - .op_func = (nfsd4op_func)nfsd4_putrootfh, + .op_func = nfsd4_putrootfh, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID, .op_name = "OP_PUTPUBFH", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_PUTROOTFH] = { - .op_func = (nfsd4op_func)nfsd4_putrootfh, + .op_func = nfsd4_putrootfh, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_IS_PUTFH_LIKE | OP_CLEAR_STATEID, .op_name = "OP_PUTROOTFH", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_READ] = { - .op_func = (nfsd4op_func)nfsd4_read, + .op_func = nfsd4_read, .op_name = "OP_READ", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_read_rsize, - .op_get_currentstateid = (stateid_getter)nfsd4_get_readstateid, + .op_rsize_bop = nfsd4_read_rsize, + .op_get_currentstateid = nfsd4_get_readstateid, }, [OP_READDIR] = { - .op_func = (nfsd4op_func)nfsd4_readdir, + .op_func = nfsd4_readdir, .op_name = "OP_READDIR", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_readdir_rsize, + .op_rsize_bop = nfsd4_readdir_rsize, }, [OP_READLINK] = { - .op_func = (nfsd4op_func)nfsd4_readlink, + .op_func = nfsd4_readlink, .op_name = "OP_READLINK", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_readlink_rsize, + .op_rsize_bop = nfsd4_readlink_rsize, }, [OP_REMOVE] = { - .op_func = (nfsd4op_func)nfsd4_remove, + .op_func = nfsd4_remove, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_REMOVE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_remove_rsize, + .op_rsize_bop = nfsd4_remove_rsize, }, [OP_RENAME] = { - .op_func = (nfsd4op_func)nfsd4_rename, + .op_func = nfsd4_rename, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_RENAME", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_rename_rsize, + .op_rsize_bop = nfsd4_rename_rsize, }, [OP_RENEW] = { - .op_func = (nfsd4op_func)nfsd4_renew, + .op_func = nfsd4_renew, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING, .op_name = "OP_RENEW", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_RESTOREFH] = { - .op_func = (nfsd4op_func)nfsd4_restorefh, + .op_func = nfsd4_restorefh, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_IS_PUTFH_LIKE | OP_MODIFIES_SOMETHING, .op_name = "OP_RESTOREFH", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_SAVEFH] = { - .op_func = (nfsd4op_func)nfsd4_savefh, + .op_func = nfsd4_savefh, .op_flags = OP_HANDLES_WRONGSEC | OP_MODIFIES_SOMETHING, .op_name = "OP_SAVEFH", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_SECINFO] = { - .op_func = (nfsd4op_func)nfsd4_secinfo, + .op_func = nfsd4_secinfo, .op_flags = OP_HANDLES_WRONGSEC, .op_name = "OP_SECINFO", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_secinfo_rsize, + .op_rsize_bop = nfsd4_secinfo_rsize, }, [OP_SETATTR] = { - .op_func = (nfsd4op_func)nfsd4_setattr, + .op_func = nfsd4_setattr, .op_name = "OP_SETATTR", .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, - .op_rsize_bop = (nfsd4op_rsize)nfsd4_setattr_rsize, - .op_get_currentstateid = (stateid_getter)nfsd4_get_setattrstateid, + .op_rsize_bop = nfsd4_setattr_rsize, + .op_get_currentstateid = nfsd4_get_setattrstateid, }, [OP_SETCLIENTID] = { - .op_func = (nfsd4op_func)nfsd4_setclientid, + .op_func = nfsd4_setclientid, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_SETCLIENTID", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_setclientid_rsize, + .op_rsize_bop = nfsd4_setclientid_rsize, }, [OP_SETCLIENTID_CONFIRM] = { - .op_func = (nfsd4op_func)nfsd4_setclientid_confirm, + .op_func = nfsd4_setclientid_confirm, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_SETCLIENTID_CONFIRM", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_VERIFY] = { - .op_func = (nfsd4op_func)nfsd4_verify, + .op_func = nfsd4_verify, .op_name = "OP_VERIFY", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_WRITE] = { - .op_func = (nfsd4op_func)nfsd4_write, + .op_func = nfsd4_write, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_WRITE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_write_rsize, - .op_get_currentstateid = (stateid_getter)nfsd4_get_writestateid, + .op_rsize_bop = nfsd4_write_rsize, + .op_get_currentstateid = nfsd4_get_writestateid, }, [OP_RELEASE_LOCKOWNER] = { - .op_func = (nfsd4op_func)nfsd4_release_lockowner, + .op_func = nfsd4_release_lockowner, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS | OP_MODIFIES_SOMETHING, .op_name = "OP_RELEASE_LOCKOWNER", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, /* NFSv4.1 operations */ [OP_EXCHANGE_ID] = { - .op_func = (nfsd4op_func)nfsd4_exchange_id, + .op_func = nfsd4_exchange_id, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP | OP_MODIFIES_SOMETHING, .op_name = "OP_EXCHANGE_ID", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_exchange_id_rsize, + .op_rsize_bop = nfsd4_exchange_id_rsize, }, [OP_BACKCHANNEL_CTL] = { - .op_func = (nfsd4op_func)nfsd4_backchannel_ctl, + .op_func = nfsd4_backchannel_ctl, .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, .op_name = "OP_BACKCHANNEL_CTL", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_BIND_CONN_TO_SESSION] = { - .op_func = (nfsd4op_func)nfsd4_bind_conn_to_session, + .op_func = nfsd4_bind_conn_to_session, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP | OP_MODIFIES_SOMETHING, .op_name = "OP_BIND_CONN_TO_SESSION", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_bind_conn_to_session_rsize, + .op_rsize_bop = nfsd4_bind_conn_to_session_rsize, }, [OP_CREATE_SESSION] = { - .op_func = (nfsd4op_func)nfsd4_create_session, + .op_func = nfsd4_create_session, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP | OP_MODIFIES_SOMETHING, .op_name = "OP_CREATE_SESSION", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_create_session_rsize, + .op_rsize_bop = nfsd4_create_session_rsize, }, [OP_DESTROY_SESSION] = { - .op_func = (nfsd4op_func)nfsd4_destroy_session, + .op_func = nfsd4_destroy_session, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP | OP_MODIFIES_SOMETHING, .op_name = "OP_DESTROY_SESSION", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_SEQUENCE] = { - .op_func = (nfsd4op_func)nfsd4_sequence, + .op_func = nfsd4_sequence, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP, .op_name = "OP_SEQUENCE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_sequence_rsize, + .op_rsize_bop = nfsd4_sequence_rsize, }, [OP_DESTROY_CLIENTID] = { - .op_func = (nfsd4op_func)nfsd4_destroy_clientid, + .op_func = nfsd4_destroy_clientid, .op_flags = ALLOWED_WITHOUT_FH | ALLOWED_AS_FIRST_OP | OP_MODIFIES_SOMETHING, .op_name = "OP_DESTROY_CLIENTID", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_RECLAIM_COMPLETE] = { - .op_func = (nfsd4op_func)nfsd4_reclaim_complete, + .op_func = nfsd4_reclaim_complete, .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, .op_name = "OP_RECLAIM_COMPLETE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_SECINFO_NO_NAME] = { - .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, + .op_func = nfsd4_secinfo_no_name, .op_flags = OP_HANDLES_WRONGSEC, .op_name = "OP_SECINFO_NO_NAME", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_secinfo_rsize, + .op_rsize_bop = nfsd4_secinfo_rsize, }, [OP_TEST_STATEID] = { - .op_func = (nfsd4op_func)nfsd4_test_stateid, + .op_func = nfsd4_test_stateid, .op_flags = ALLOWED_WITHOUT_FH, .op_name = "OP_TEST_STATEID", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_test_stateid_rsize, + .op_rsize_bop = nfsd4_test_stateid_rsize, }, [OP_FREE_STATEID] = { - .op_func = (nfsd4op_func)nfsd4_free_stateid, + .op_func = nfsd4_free_stateid, .op_flags = ALLOWED_WITHOUT_FH | OP_MODIFIES_SOMETHING, .op_name = "OP_FREE_STATEID", - .op_get_currentstateid = (stateid_getter)nfsd4_get_freestateid, - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_get_currentstateid = nfsd4_get_freestateid, + .op_rsize_bop = nfsd4_only_status_rsize, }, #ifdef CONFIG_NFSD_PNFS [OP_GETDEVICEINFO] = { - .op_func = (nfsd4op_func)nfsd4_getdeviceinfo, + .op_func = nfsd4_getdeviceinfo, .op_flags = ALLOWED_WITHOUT_FH, .op_name = "OP_GETDEVICEINFO", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_getdeviceinfo_rsize, + .op_rsize_bop = nfsd4_getdeviceinfo_rsize, }, [OP_LAYOUTGET] = { - .op_func = (nfsd4op_func)nfsd4_layoutget, + .op_func = nfsd4_layoutget, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_LAYOUTGET", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_layoutget_rsize, + .op_rsize_bop = nfsd4_layoutget_rsize, }, [OP_LAYOUTCOMMIT] = { - .op_func = (nfsd4op_func)nfsd4_layoutcommit, + .op_func = nfsd4_layoutcommit, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_LAYOUTCOMMIT", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_layoutcommit_rsize, + .op_rsize_bop = nfsd4_layoutcommit_rsize, }, [OP_LAYOUTRETURN] = { - .op_func = (nfsd4op_func)nfsd4_layoutreturn, + .op_func = nfsd4_layoutreturn, .op_flags = OP_MODIFIES_SOMETHING, .op_name = "OP_LAYOUTRETURN", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_layoutreturn_rsize, + .op_rsize_bop = nfsd4_layoutreturn_rsize, }, #endif /* CONFIG_NFSD_PNFS */ /* NFSv4.2 operations */ [OP_ALLOCATE] = { - .op_func = (nfsd4op_func)nfsd4_allocate, + .op_func = nfsd4_allocate, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_ALLOCATE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_DEALLOCATE] = { - .op_func = (nfsd4op_func)nfsd4_deallocate, + .op_func = nfsd4_deallocate, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_DEALLOCATE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_CLONE] = { - .op_func = (nfsd4op_func)nfsd4_clone, + .op_func = nfsd4_clone, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_CLONE", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize, + .op_rsize_bop = nfsd4_only_status_rsize, }, [OP_COPY] = { - .op_func = (nfsd4op_func)nfsd4_copy, + .op_func = nfsd4_copy, .op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME, .op_name = "OP_COPY", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_copy_rsize, + .op_rsize_bop = nfsd4_copy_rsize, }, [OP_SEEK] = { - .op_func = (nfsd4op_func)nfsd4_seek, + .op_func = nfsd4_seek, .op_name = "OP_SEEK", - .op_rsize_bop = (nfsd4op_rsize)nfsd4_seek_rsize, + .op_rsize_bop = nfsd4_seek_rsize, }, }; @@ -2515,19 +2531,19 @@ static const char *nfsd4_op_name(unsigned opnum) #define nfsd4_voidres nfsd4_voidargs struct nfsd4_voidargs { int dummy; }; -static struct svc_procedure nfsd_procedures4[2] = { +static const struct svc_procedure nfsd_procedures4[2] = { [NFSPROC4_NULL] = { - .pc_func = (svc_procfunc) nfsd4_proc_null, - .pc_encode = (kxdrproc_t) nfs4svc_encode_voidres, + .pc_func = nfsd4_proc_null, + .pc_encode = nfs4svc_encode_voidres, .pc_argsize = sizeof(struct nfsd4_voidargs), .pc_ressize = sizeof(struct nfsd4_voidres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = 1, }, [NFSPROC4_COMPOUND] = { - .pc_func = (svc_procfunc) nfsd4_proc_compound, - .pc_decode = (kxdrproc_t) nfs4svc_decode_compoundargs, - .pc_encode = (kxdrproc_t) nfs4svc_encode_compoundres, + .pc_func = nfsd4_proc_compound, + .pc_decode = nfs4svc_decode_compoundargs, + .pc_encode = nfs4svc_encode_compoundres, .pc_argsize = sizeof(struct nfsd4_compoundargs), .pc_ressize = sizeof(struct nfsd4_compoundres), .pc_release = nfsd4_release_compoundargs, @@ -2536,10 +2552,12 @@ static struct svc_procedure nfsd_procedures4[2] = { }, }; -struct svc_version nfsd_version4 = { +static unsigned int nfsd_count3[ARRAY_SIZE(nfsd_procedures4)]; +const struct svc_version nfsd_version4 = { .vs_vers = 4, .vs_nproc = 2, .vs_proc = nfsd_procedures4, + .vs_count = nfsd_count3, .vs_dispatch = nfsd_dispatch, .vs_xdrsize = NFS4_SVC_XDRSIZE, .vs_rpcb_optnl = true, diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 22002fb75a18..0c04f81aa63b 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2402,10 +2402,10 @@ static bool client_has_state(struct nfs4_client *clp) } __be32 -nfsd4_exchange_id(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_exchange_id *exid) +nfsd4_exchange_id(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { + struct nfsd4_exchange_id *exid = &u->exchange_id; struct nfs4_client *conf, *new; struct nfs4_client *unconf = NULL; __be32 status; @@ -2698,9 +2698,9 @@ static __be32 nfsd4_check_cb_sec(struct nfsd4_cb_sec *cbs) __be32 nfsd4_create_session(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_create_session *cr_ses) + struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { + struct nfsd4_create_session *cr_ses = &u->create_session; struct sockaddr *sa = svc_addr(rqstp); struct nfs4_client *conf, *unconf; struct nfs4_client *old = NULL; @@ -2824,8 +2824,11 @@ static __be32 nfsd4_map_bcts_dir(u32 *dir) return nfserr_inval; } -__be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_backchannel_ctl *bc) +__be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { + struct nfsd4_backchannel_ctl *bc = &u->backchannel_ctl; struct nfsd4_session *session = cstate->session; struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); __be32 status; @@ -2845,8 +2848,9 @@ __be32 nfsd4_backchannel_ctl(struct svc_rqst *rqstp, struct nfsd4_compound_state __be32 nfsd4_bind_conn_to_session(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_bind_conn_to_session *bcts) + union nfsd4_op_u *u) { + struct nfsd4_bind_conn_to_session *bcts = &u->bind_conn_to_session; __be32 status; struct nfsd4_conn *conn; struct nfsd4_session *session; @@ -2886,10 +2890,10 @@ static bool nfsd4_compound_in_session(struct nfsd4_session *session, struct nfs4 } __be32 -nfsd4_destroy_session(struct svc_rqst *r, - struct nfsd4_compound_state *cstate, - struct nfsd4_destroy_session *sessionid) +nfsd4_destroy_session(struct svc_rqst *r, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { + struct nfsd4_destroy_session *sessionid = &u->destroy_session; struct nfsd4_session *ses; __be32 status; int ref_held_by_me = 0; @@ -2983,10 +2987,10 @@ static bool nfsd4_request_too_big(struct svc_rqst *rqstp, } __be32 -nfsd4_sequence(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_sequence *seq) +nfsd4_sequence(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { + struct nfsd4_sequence *seq = &u->sequence; struct nfsd4_compoundres *resp = rqstp->rq_resp; struct xdr_stream *xdr = &resp->xdr; struct nfsd4_session *session; @@ -3120,8 +3124,11 @@ nfsd4_sequence_done(struct nfsd4_compoundres *resp) } __be32 -nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_destroy_clientid *dc) +nfsd4_destroy_clientid(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { + struct nfsd4_destroy_clientid *dc = &u->destroy_clientid; struct nfs4_client *conf, *unconf; struct nfs4_client *clp = NULL; __be32 status = 0; @@ -3161,8 +3168,10 @@ out: } __be32 -nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc) +nfsd4_reclaim_complete(struct svc_rqst *rqstp, + struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { + struct nfsd4_reclaim_complete *rc = &u->reclaim_complete; __be32 status = 0; if (rc->rca_one_fs) { @@ -3199,8 +3208,9 @@ out: __be32 nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_setclientid *setclid) + union nfsd4_op_u *u) { + struct nfsd4_setclientid *setclid = &u->setclientid; struct xdr_netobj clname = setclid->se_name; nfs4_verifier clverifier = setclid->se_verf; struct nfs4_client *conf, *new; @@ -3257,9 +3267,11 @@ out: __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_setclientid_confirm *setclientid_confirm) + struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { + struct nfsd4_setclientid_confirm *setclientid_confirm = + &u->setclientid_confirm; struct nfs4_client *conf, *unconf; struct nfs4_client *old = NULL; nfs4_verifier confirm = setclientid_confirm->sc_confirm; @@ -4506,8 +4518,9 @@ void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate, __be32 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - clientid_t *clid) + union nfsd4_op_u *u) { + clientid_t *clid = &u->renew; struct nfs4_client *clp; __be32 status; struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); @@ -4993,8 +5006,9 @@ out: */ __be32 nfsd4_test_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_test_stateid *test_stateid) + union nfsd4_op_u *u) { + struct nfsd4_test_stateid *test_stateid = &u->test_stateid; struct nfsd4_test_stateid_id *stateid; struct nfs4_client *cl = cstate->session->se_client; @@ -5033,8 +5047,9 @@ out: __be32 nfsd4_free_stateid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_free_stateid *free_stateid) + union nfsd4_op_u *u) { + struct nfsd4_free_stateid *free_stateid = &u->free_stateid; stateid_t *stateid = &free_stateid->fr_stateid; struct nfs4_stid *s; struct nfs4_delegation *dp; @@ -5162,8 +5177,9 @@ static __be32 nfs4_preprocess_confirmed_seqid_op(struct nfsd4_compound_state *cs __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_open_confirm *oc) + union nfsd4_op_u *u) { + struct nfsd4_open_confirm *oc = &u->open_confirm; __be32 status; struct nfs4_openowner *oo; struct nfs4_ol_stateid *stp; @@ -5230,9 +5246,9 @@ static inline void nfs4_stateid_downgrade(struct nfs4_ol_stateid *stp, u32 to_ac __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, - struct nfsd4_compound_state *cstate, - struct nfsd4_open_downgrade *od) + struct nfsd4_compound_state *cstate, union nfsd4_op_u *u) { + struct nfsd4_open_downgrade *od = &u->open_downgrade; __be32 status; struct nfs4_ol_stateid *stp; struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id); @@ -5300,8 +5316,9 @@ static void nfsd4_close_open_stateid(struct nfs4_ol_stateid *s) */ __be32 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_close *close) + union nfsd4_op_u *u) { + struct nfsd4_close *close = &u->close; __be32 status; struct nfs4_ol_stateid *stp; struct net *net = SVC_NET(rqstp); @@ -5330,8 +5347,9 @@ out: __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_delegreturn *dr) + union nfsd4_op_u *u) { + struct nfsd4_delegreturn *dr = &u->delegreturn; struct nfs4_delegation *dp; stateid_t *stateid = &dr->dr_stateid; struct nfs4_stid *s; @@ -5706,8 +5724,9 @@ out: */ __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_lock *lock) + union nfsd4_op_u *u) { + struct nfsd4_lock *lock = &u->lock; struct nfs4_openowner *open_sop = NULL; struct nfs4_lockowner *lock_sop = NULL; struct nfs4_ol_stateid *lock_stp = NULL; @@ -5939,8 +5958,9 @@ static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct */ __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_lockt *lockt) + union nfsd4_op_u *u) { + struct nfsd4_lockt *lockt = &u->lockt; struct file_lock *file_lock = NULL; struct nfs4_lockowner *lo = NULL; __be32 status; @@ -6012,8 +6032,9 @@ out: __be32 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_locku *locku) + union nfsd4_op_u *u) { + struct nfsd4_locku *locku = &u->locku; struct nfs4_ol_stateid *stp; struct file *filp = NULL; struct file_lock *file_lock = NULL; @@ -6119,8 +6140,9 @@ check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner) __be32 nfsd4_release_lockowner(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - struct nfsd4_release_lockowner *rlockowner) + union nfsd4_op_u *u) { + struct nfsd4_release_lockowner *rlockowner = &u->release_lockowner; clientid_t *clid = &rlockowner->rl_clientid; struct nfs4_stateowner *sop; struct nfs4_lockowner *lo = NULL; @@ -7103,27 +7125,31 @@ clear_current_stateid(struct nfsd4_compound_state *cstate) * functions to set current state id */ void -nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp) +nfsd4_set_opendowngradestateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - put_stateid(cstate, &odp->od_stateid); + put_stateid(cstate, &u->open_downgrade.od_stateid); } void -nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, struct nfsd4_open *open) +nfsd4_set_openstateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - put_stateid(cstate, &open->op_stateid); + put_stateid(cstate, &u->open.op_stateid); } void -nfsd4_set_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close) +nfsd4_set_closestateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - put_stateid(cstate, &close->cl_stateid); + put_stateid(cstate, &u->close.cl_stateid); } void -nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, struct nfsd4_lock *lock) +nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - put_stateid(cstate, &lock->lk_resp_stateid); + put_stateid(cstate, &u->lock.lk_resp_stateid); } /* @@ -7131,49 +7157,57 @@ nfsd4_set_lockstateid(struct nfsd4_compound_state *cstate, struct nfsd4_lock *lo */ void -nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, struct nfsd4_open_downgrade *odp) +nfsd4_get_opendowngradestateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &odp->od_stateid); + get_stateid(cstate, &u->open_downgrade.od_stateid); } void -nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *cstate, struct nfsd4_delegreturn *drp) +nfsd4_get_delegreturnstateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &drp->dr_stateid); + get_stateid(cstate, &u->delegreturn.dr_stateid); } void -nfsd4_get_freestateid(struct nfsd4_compound_state *cstate, struct nfsd4_free_stateid *fsp) +nfsd4_get_freestateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &fsp->fr_stateid); + get_stateid(cstate, &u->free_stateid.fr_stateid); } void -nfsd4_get_setattrstateid(struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) +nfsd4_get_setattrstateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &setattr->sa_stateid); + get_stateid(cstate, &u->setattr.sa_stateid); } void -nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, struct nfsd4_close *close) +nfsd4_get_closestateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &close->cl_stateid); + get_stateid(cstate, &u->close.cl_stateid); } void -nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, struct nfsd4_locku *locku) +nfsd4_get_lockustateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &locku->lu_stateid); + get_stateid(cstate, &u->locku.lu_stateid); } void -nfsd4_get_readstateid(struct nfsd4_compound_state *cstate, struct nfsd4_read *read) +nfsd4_get_readstateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &read->rd_stateid); + get_stateid(cstate, &u->read.rd_stateid); } void -nfsd4_get_writestateid(struct nfsd4_compound_state *cstate, struct nfsd4_write *write) +nfsd4_get_writestateid(struct nfsd4_compound_state *cstate, + union nfsd4_op_u *u) { - get_stateid(cstate, &write->wr_stateid); + get_stateid(cstate, &u->write.wr_stateid); } diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 26780d53a6f9..20fbcab97753 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1973,7 +1973,7 @@ static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode, *p++ = cpu_to_be32(convert_to_wallclock(exp->cd->flush_time)); *p++ = 0; } else if (IS_I_VERSION(inode)) { - p = xdr_encode_hyper(p, inode->i_version); + p = xdr_encode_hyper(p, nfsd4_change_attribute(inode)); } else { *p++ = cpu_to_be32(stat->ctime.tv_sec); *p++ = cpu_to_be32(stat->ctime.tv_nsec); @@ -4538,14 +4538,13 @@ nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op) } int -nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfs4svc_encode_voidres(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); } -int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) +void nfsd4_release_compoundargs(struct svc_rqst *rqstp) { - struct svc_rqst *rqstp = rq; struct nfsd4_compoundargs *args = rqstp->rq_argp; if (args->ops != args->iops) { @@ -4559,12 +4558,13 @@ int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp) args->to_free = tb->next; kfree(tb); } - return 1; } int -nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundargs *args) +nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd4_compoundargs *args = rqstp->rq_argp; + if (rqstp->rq_arg.head[0].iov_len % 4) { /* client is nuts */ dprintk("%s: compound not properly padded! (peeraddr=%pISc xid=0x%x)", @@ -4584,11 +4584,12 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_comp } int -nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compoundres *resp) +nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p) { /* * All that remains is to write the tag and operation count... */ + struct nfsd4_compoundres *resp = rqstp->rq_resp; struct xdr_buf *buf = resp->xdr.buf; WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len + diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h index d96606801d47..b9c538ab7a59 100644 --- a/fs/nfsd/nfsd.h +++ b/fs/nfsd/nfsd.h @@ -60,7 +60,7 @@ struct readdir_cd { extern struct svc_program nfsd_program; -extern struct svc_version nfsd_version2, nfsd_version3, +extern const struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; extern struct mutex nfsd_mutex; extern spinlock_t nfsd_drc_lock; @@ -86,12 +86,12 @@ void nfsd_destroy(struct net *net); #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) #ifdef CONFIG_NFSD_V2_ACL -extern struct svc_version nfsd_acl_version2; +extern const struct svc_version nfsd_acl_version2; #else #define nfsd_acl_version2 NULL #endif #ifdef CONFIG_NFSD_V3_ACL -extern struct svc_version nfsd_acl_version3; +extern const struct svc_version nfsd_acl_version3; #else #define nfsd_acl_version3 NULL #endif diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index f84fe6bf9aee..e47cf6c2ac28 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -241,6 +241,28 @@ fh_clear_wcc(struct svc_fh *fhp) } /* + * We could use i_version alone as the change attribute. However, + * i_version can go backwards after a reboot. On its own that doesn't + * necessarily cause a problem, but if i_version goes backwards and then + * is incremented again it could reuse a value that was previously used + * before boot, and a client who queried the two values might + * incorrectly assume nothing changed. + * + * By using both ctime and the i_version counter we guarantee that as + * long as time doesn't go backwards we never reuse an old value. + */ +static inline u64 nfsd4_change_attribute(struct inode *inode) +{ + u64 chattr; + + chattr = inode->i_ctime.tv_sec; + chattr <<= 30; + chattr += inode->i_ctime.tv_nsec; + chattr += inode->i_version; + return chattr; +} + +/* * Fill in the pre_op attr for the wcc data */ static inline void @@ -253,7 +275,7 @@ fill_pre_wcc(struct svc_fh *fhp) fhp->fh_pre_mtime = inode->i_mtime; fhp->fh_pre_ctime = inode->i_ctime; fhp->fh_pre_size = inode->i_size; - fhp->fh_pre_change = inode->i_version; + fhp->fh_pre_change = nfsd4_change_attribute(inode); fhp->fh_pre_saved = true; } } diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 03a7e9da4da0..5076ae2b8258 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -17,7 +17,7 @@ typedef struct svc_buf svc_buf; static __be32 -nfsd_proc_null(struct svc_rqst *rqstp, void *argp, void *resp) +nfsd_proc_null(struct svc_rqst *rqstp) { return nfs_ok; } @@ -39,9 +39,10 @@ nfsd_return_dirop(__be32 err, struct nfsd_diropres *resp) * N.B. After this call resp->fh needs an fh_put */ static __be32 -nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, - struct nfsd_attrstat *resp) +nfsd_proc_getattr(struct svc_rqst *rqstp) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + struct nfsd_attrstat *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: GETATTR %s\n", SVCFH_fmt(&argp->fh)); @@ -56,9 +57,10 @@ nfsd_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle *argp, * N.B. After this call resp->fh needs an fh_put */ static __be32 -nfsd_proc_setattr(struct svc_rqst *rqstp, struct nfsd_sattrargs *argp, - struct nfsd_attrstat *resp) +nfsd_proc_setattr(struct svc_rqst *rqstp) { + struct nfsd_sattrargs *argp = rqstp->rq_argp; + struct nfsd_attrstat *resp = rqstp->rq_resp; struct iattr *iap = &argp->attrs; struct svc_fh *fhp; __be32 nfserr; @@ -122,9 +124,10 @@ done: * N.B. After this call resp->fh needs an fh_put */ static __be32 -nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, - struct nfsd_diropres *resp) +nfsd_proc_lookup(struct svc_rqst *rqstp) { + struct nfsd_diropargs *argp = rqstp->rq_argp; + struct nfsd_diropres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: LOOKUP %s %.*s\n", @@ -142,9 +145,10 @@ nfsd_proc_lookup(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, * Read a symlink. */ static __be32 -nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp, - struct nfsd_readlinkres *resp) +nfsd_proc_readlink(struct svc_rqst *rqstp) { + struct nfsd_readlinkargs *argp = rqstp->rq_argp; + struct nfsd_readlinkres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: READLINK %s\n", SVCFH_fmt(&argp->fh)); @@ -162,9 +166,10 @@ nfsd_proc_readlink(struct svc_rqst *rqstp, struct nfsd_readlinkargs *argp, * N.B. After this call resp->fh needs an fh_put */ static __be32 -nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, - struct nfsd_readres *resp) +nfsd_proc_read(struct svc_rqst *rqstp) { + struct nfsd_readargs *argp = rqstp->rq_argp; + struct nfsd_readres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: READ %s %d bytes at %d\n", @@ -200,9 +205,10 @@ nfsd_proc_read(struct svc_rqst *rqstp, struct nfsd_readargs *argp, * N.B. After this call resp->fh needs an fh_put */ static __be32 -nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp, - struct nfsd_attrstat *resp) +nfsd_proc_write(struct svc_rqst *rqstp) { + struct nfsd_writeargs *argp = rqstp->rq_argp; + struct nfsd_attrstat *resp = rqstp->rq_resp; __be32 nfserr; unsigned long cnt = argp->len; @@ -222,9 +228,10 @@ nfsd_proc_write(struct svc_rqst *rqstp, struct nfsd_writeargs *argp, * N.B. After this call _both_ argp->fh and resp->fh need an fh_put */ static __be32 -nfsd_proc_create(struct svc_rqst *rqstp, struct nfsd_createargs *argp, - struct nfsd_diropres *resp) +nfsd_proc_create(struct svc_rqst *rqstp) { + struct nfsd_createargs *argp = rqstp->rq_argp; + struct nfsd_diropres *resp = rqstp->rq_resp; svc_fh *dirfhp = &argp->fh; svc_fh *newfhp = &resp->fh; struct iattr *attr = &argp->attrs; @@ -377,9 +384,9 @@ done: } static __be32 -nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, - void *resp) +nfsd_proc_remove(struct svc_rqst *rqstp) { + struct nfsd_diropargs *argp = rqstp->rq_argp; __be32 nfserr; dprintk("nfsd: REMOVE %s %.*s\n", SVCFH_fmt(&argp->fh), @@ -392,9 +399,9 @@ nfsd_proc_remove(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, } static __be32 -nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp, - void *resp) +nfsd_proc_rename(struct svc_rqst *rqstp) { + struct nfsd_renameargs *argp = rqstp->rq_argp; __be32 nfserr; dprintk("nfsd: RENAME %s %.*s -> \n", @@ -410,9 +417,9 @@ nfsd_proc_rename(struct svc_rqst *rqstp, struct nfsd_renameargs *argp, } static __be32 -nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp, - void *resp) +nfsd_proc_link(struct svc_rqst *rqstp) { + struct nfsd_linkargs *argp = rqstp->rq_argp; __be32 nfserr; dprintk("nfsd: LINK %s ->\n", @@ -430,9 +437,9 @@ nfsd_proc_link(struct svc_rqst *rqstp, struct nfsd_linkargs *argp, } static __be32 -nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp, - void *resp) +nfsd_proc_symlink(struct svc_rqst *rqstp) { + struct nfsd_symlinkargs *argp = rqstp->rq_argp; struct svc_fh newfh; __be32 nfserr; @@ -460,9 +467,10 @@ nfsd_proc_symlink(struct svc_rqst *rqstp, struct nfsd_symlinkargs *argp, * N.B. After this call resp->fh needs an fh_put */ static __be32 -nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp, - struct nfsd_diropres *resp) +nfsd_proc_mkdir(struct svc_rqst *rqstp) { + struct nfsd_createargs *argp = rqstp->rq_argp; + struct nfsd_diropres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: MKDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); @@ -484,9 +492,9 @@ nfsd_proc_mkdir(struct svc_rqst *rqstp, struct nfsd_createargs *argp, * Remove a directory */ static __be32 -nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, - void *resp) +nfsd_proc_rmdir(struct svc_rqst *rqstp) { + struct nfsd_diropargs *argp = rqstp->rq_argp; __be32 nfserr; dprintk("nfsd: RMDIR %s %.*s\n", SVCFH_fmt(&argp->fh), argp->len, argp->name); @@ -500,9 +508,10 @@ nfsd_proc_rmdir(struct svc_rqst *rqstp, struct nfsd_diropargs *argp, * Read a portion of a directory. */ static __be32 -nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp, - struct nfsd_readdirres *resp) +nfsd_proc_readdir(struct svc_rqst *rqstp) { + struct nfsd_readdirargs *argp = rqstp->rq_argp; + struct nfsd_readdirres *resp = rqstp->rq_resp; int count; __be32 nfserr; loff_t offset; @@ -540,9 +549,10 @@ nfsd_proc_readdir(struct svc_rqst *rqstp, struct nfsd_readdirargs *argp, * Get file system info */ static __be32 -nfsd_proc_statfs(struct svc_rqst * rqstp, struct nfsd_fhandle *argp, - struct nfsd_statfsres *resp) +nfsd_proc_statfs(struct svc_rqst *rqstp) { + struct nfsd_fhandle *argp = rqstp->rq_argp; + struct nfsd_statfsres *resp = rqstp->rq_resp; __be32 nfserr; dprintk("nfsd: STATFS %s\n", SVCFH_fmt(&argp->fh)); @@ -563,168 +573,168 @@ struct nfsd_void { int dummy; }; #define FH 8 /* filehandle */ #define AT 18 /* attributes */ -static struct svc_procedure nfsd_procedures2[18] = { +static const struct svc_procedure nfsd_procedures2[18] = { [NFSPROC_NULL] = { - .pc_func = (svc_procfunc) nfsd_proc_null, - .pc_decode = (kxdrproc_t) nfssvc_decode_void, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_func = nfsd_proc_null, + .pc_decode = nfssvc_decode_void, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_void), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST, }, [NFSPROC_GETATTR] = { - .pc_func = (svc_procfunc) nfsd_proc_getattr, - .pc_decode = (kxdrproc_t) nfssvc_decode_fhandle, - .pc_encode = (kxdrproc_t) nfssvc_encode_attrstat, - .pc_release = (kxdrproc_t) nfssvc_release_fhandle, + .pc_func = nfsd_proc_getattr, + .pc_decode = nfssvc_decode_fhandle, + .pc_encode = nfssvc_encode_attrstat, + .pc_release = nfssvc_release_fhandle, .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT, }, [NFSPROC_SETATTR] = { - .pc_func = (svc_procfunc) nfsd_proc_setattr, - .pc_decode = (kxdrproc_t) nfssvc_decode_sattrargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_attrstat, - .pc_release = (kxdrproc_t) nfssvc_release_fhandle, + .pc_func = nfsd_proc_setattr, + .pc_decode = nfssvc_decode_sattrargs, + .pc_encode = nfssvc_encode_attrstat, + .pc_release = nfssvc_release_fhandle, .pc_argsize = sizeof(struct nfsd_sattrargs), .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+AT, }, [NFSPROC_ROOT] = { - .pc_decode = (kxdrproc_t) nfssvc_decode_void, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_decode = nfssvc_decode_void, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_void), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST, }, [NFSPROC_LOOKUP] = { - .pc_func = (svc_procfunc) nfsd_proc_lookup, - .pc_decode = (kxdrproc_t) nfssvc_decode_diropargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_diropres, - .pc_release = (kxdrproc_t) nfssvc_release_fhandle, + .pc_func = nfsd_proc_lookup, + .pc_decode = nfssvc_decode_diropargs, + .pc_encode = nfssvc_encode_diropres, + .pc_release = nfssvc_release_fhandle, .pc_argsize = sizeof(struct nfsd_diropargs), .pc_ressize = sizeof(struct nfsd_diropres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+FH+AT, }, [NFSPROC_READLINK] = { - .pc_func = (svc_procfunc) nfsd_proc_readlink, - .pc_decode = (kxdrproc_t) nfssvc_decode_readlinkargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_readlinkres, + .pc_func = nfsd_proc_readlink, + .pc_decode = nfssvc_decode_readlinkargs, + .pc_encode = nfssvc_encode_readlinkres, .pc_argsize = sizeof(struct nfsd_readlinkargs), .pc_ressize = sizeof(struct nfsd_readlinkres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+1+NFS_MAXPATHLEN/4, }, [NFSPROC_READ] = { - .pc_func = (svc_procfunc) nfsd_proc_read, - .pc_decode = (kxdrproc_t) nfssvc_decode_readargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_readres, - .pc_release = (kxdrproc_t) nfssvc_release_fhandle, + .pc_func = nfsd_proc_read, + .pc_decode = nfssvc_decode_readargs, + .pc_encode = nfssvc_encode_readres, + .pc_release = nfssvc_release_fhandle, .pc_argsize = sizeof(struct nfsd_readargs), .pc_ressize = sizeof(struct nfsd_readres), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST+AT+1+NFSSVC_MAXBLKSIZE_V2/4, }, [NFSPROC_WRITECACHE] = { - .pc_decode = (kxdrproc_t) nfssvc_decode_void, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_decode = nfssvc_decode_void, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_void), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_NOCACHE, .pc_xdrressize = ST, }, [NFSPROC_WRITE] = { - .pc_func = (svc_procfunc) nfsd_proc_write, - .pc_decode = (kxdrproc_t) nfssvc_decode_writeargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_attrstat, - .pc_release = (kxdrproc_t) nfssvc_release_fhandle, + .pc_func = nfsd_proc_write, + .pc_decode = nfssvc_decode_writeargs, + .pc_encode = nfssvc_encode_attrstat, + .pc_release = nfssvc_release_fhandle, .pc_argsize = sizeof(struct nfsd_writeargs), .pc_ressize = sizeof(struct nfsd_attrstat), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+AT, }, [NFSPROC_CREATE] = { - .pc_func = (svc_procfunc) nfsd_proc_create, - .pc_decode = (kxdrproc_t) nfssvc_decode_createargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_diropres, - .pc_release = (kxdrproc_t) nfssvc_release_fhandle, + .pc_func = nfsd_proc_create, + .pc_decode = nfssvc_decode_createargs, + .pc_encode = nfssvc_encode_diropres, + .pc_release = nfssvc_release_fhandle, .pc_argsize = sizeof(struct nfsd_createargs), .pc_ressize = sizeof(struct nfsd_diropres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+FH+AT, }, [NFSPROC_REMOVE] = { - .pc_func = (svc_procfunc) nfsd_proc_remove, - .pc_decode = (kxdrproc_t) nfssvc_decode_diropargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_func = nfsd_proc_remove, + .pc_decode = nfssvc_decode_diropargs, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_diropargs), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, }, [NFSPROC_RENAME] = { - .pc_func = (svc_procfunc) nfsd_proc_rename, - .pc_decode = (kxdrproc_t) nfssvc_decode_renameargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_func = nfsd_proc_rename, + .pc_decode = nfssvc_decode_renameargs, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_renameargs), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, }, [NFSPROC_LINK] = { - .pc_func = (svc_procfunc) nfsd_proc_link, - .pc_decode = (kxdrproc_t) nfssvc_decode_linkargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_func = nfsd_proc_link, + .pc_decode = nfssvc_decode_linkargs, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_linkargs), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, }, [NFSPROC_SYMLINK] = { - .pc_func = (svc_procfunc) nfsd_proc_symlink, - .pc_decode = (kxdrproc_t) nfssvc_decode_symlinkargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_func = nfsd_proc_symlink, + .pc_decode = nfssvc_decode_symlinkargs, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_symlinkargs), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, }, [NFSPROC_MKDIR] = { - .pc_func = (svc_procfunc) nfsd_proc_mkdir, - .pc_decode = (kxdrproc_t) nfssvc_decode_createargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_diropres, - .pc_release = (kxdrproc_t) nfssvc_release_fhandle, + .pc_func = nfsd_proc_mkdir, + .pc_decode = nfssvc_decode_createargs, + .pc_encode = nfssvc_encode_diropres, + .pc_release = nfssvc_release_fhandle, .pc_argsize = sizeof(struct nfsd_createargs), .pc_ressize = sizeof(struct nfsd_diropres), .pc_cachetype = RC_REPLBUFF, .pc_xdrressize = ST+FH+AT, }, [NFSPROC_RMDIR] = { - .pc_func = (svc_procfunc) nfsd_proc_rmdir, - .pc_decode = (kxdrproc_t) nfssvc_decode_diropargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_void, + .pc_func = nfsd_proc_rmdir, + .pc_decode = nfssvc_decode_diropargs, + .pc_encode = nfssvc_encode_void, .pc_argsize = sizeof(struct nfsd_diropargs), .pc_ressize = sizeof(struct nfsd_void), .pc_cachetype = RC_REPLSTAT, .pc_xdrressize = ST, }, [NFSPROC_READDIR] = { - .pc_func = (svc_procfunc) nfsd_proc_readdir, - .pc_decode = (kxdrproc_t) nfssvc_decode_readdirargs, - .pc_encode = (kxdrproc_t) nfssvc_encode_readdirres, + .pc_func = nfsd_proc_readdir, + .pc_decode = nfssvc_decode_readdirargs, + .pc_encode = nfssvc_encode_readdirres, .pc_argsize = sizeof(struct nfsd_readdirargs), .pc_ressize = sizeof(struct nfsd_readdirres), .pc_cachetype = RC_NOCACHE, }, [NFSPROC_STATFS] = { - .pc_func = (svc_procfunc) nfsd_proc_statfs, - .pc_decode = (kxdrproc_t) nfssvc_decode_fhandle, - .pc_encode = (kxdrproc_t) nfssvc_encode_statfsres, + .pc_func = nfsd_proc_statfs, + .pc_decode = nfssvc_decode_fhandle, + .pc_encode = nfssvc_encode_statfsres, .pc_argsize = sizeof(struct nfsd_fhandle), .pc_ressize = sizeof(struct nfsd_statfsres), .pc_cachetype = RC_NOCACHE, @@ -733,12 +743,14 @@ static struct svc_procedure nfsd_procedures2[18] = { }; -struct svc_version nfsd_version2 = { - .vs_vers = 2, - .vs_nproc = 18, - .vs_proc = nfsd_procedures2, - .vs_dispatch = nfsd_dispatch, - .vs_xdrsize = NFS2_SVC_XDRSIZE, +static unsigned int nfsd_count2[ARRAY_SIZE(nfsd_procedures2)]; +const struct svc_version nfsd_version2 = { + .vs_vers = 2, + .vs_nproc = 18, + .vs_proc = nfsd_procedures2, + .vs_count = nfsd_count2, + .vs_dispatch = nfsd_dispatch, + .vs_xdrsize = NFS2_SVC_XDRSIZE, }; /* diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 59979f0bbd4b..063ae7de2c12 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c @@ -68,14 +68,14 @@ unsigned long nfsd_drc_mem_used; #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) static struct svc_stat nfsd_acl_svcstats; -static struct svc_version * nfsd_acl_version[] = { +static const struct svc_version *nfsd_acl_version[] = { [2] = &nfsd_acl_version2, [3] = &nfsd_acl_version3, }; #define NFSD_ACL_MINVERS 2 #define NFSD_ACL_NRVERS ARRAY_SIZE(nfsd_acl_version) -static struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS]; +static const struct svc_version *nfsd_acl_versions[NFSD_ACL_NRVERS]; static struct svc_program nfsd_acl_program = { .pg_prog = NFS_ACL_PROGRAM, @@ -92,7 +92,7 @@ static struct svc_stat nfsd_acl_svcstats = { }; #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ -static struct svc_version * nfsd_version[] = { +static const struct svc_version *nfsd_version[] = { [2] = &nfsd_version2, #if defined(CONFIG_NFSD_V3) [3] = &nfsd_version3, @@ -104,7 +104,7 @@ static struct svc_version * nfsd_version[] = { #define NFSD_MINVERS 2 #define NFSD_NRVERS ARRAY_SIZE(nfsd_version) -static struct svc_version *nfsd_versions[NFSD_NRVERS]; +static const struct svc_version *nfsd_versions[NFSD_NRVERS]; struct svc_program nfsd_program = { #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) @@ -756,7 +756,7 @@ static __be32 map_new_errors(u32 vers, __be32 nfserr) * problem, we enforce these assumptions here: */ static bool nfs_request_too_big(struct svc_rqst *rqstp, - struct svc_procedure *proc) + const struct svc_procedure *proc) { /* * The ACL code has more careful bounds-checking and is not @@ -781,8 +781,7 @@ static bool nfs_request_too_big(struct svc_rqst *rqstp, int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) { - struct svc_procedure *proc; - kxdrproc_t xdr; + const struct svc_procedure *proc; __be32 nfserr; __be32 *nfserrp; @@ -801,9 +800,8 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) */ rqstp->rq_cachetype = proc->pc_cachetype; /* Decode arguments */ - xdr = proc->pc_decode; - if (xdr && !xdr(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base, - rqstp->rq_argp)) { + if (proc->pc_decode && + !proc->pc_decode(rqstp, (__be32*)rqstp->rq_arg.head[0].iov_base)) { dprintk("nfsd: failed to decode arguments!\n"); *statp = rpc_garbage_args; return 1; @@ -827,7 +825,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) rqstp->rq_res.head[0].iov_len += sizeof(__be32); /* Now call the procedure handler, and encode NFS status. */ - nfserr = proc->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); + nfserr = proc->pc_func(rqstp); nfserr = map_new_errors(rqstp->rq_vers, nfserr); if (nfserr == nfserr_dropit || test_bit(RQ_DROPME, &rqstp->rq_flags)) { dprintk("nfsd: Dropping request; may be revisited later\n"); @@ -842,9 +840,7 @@ nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp) * For NFSv2, additional info is never returned in case of an error. */ if (!(nfserr && rqstp->rq_vers == 2)) { - xdr = proc->pc_encode; - if (xdr && !xdr(rqstp, nfserrp, - rqstp->rq_resp)) { + if (proc->pc_encode && !proc->pc_encode(rqstp, nfserrp)) { /* Failed to encode result. Release cache entry */ dprintk("nfsd: failed to encode result!\n"); nfsd_cache_update(rqstp, RC_NOCACHE, NULL); diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index de07ff625777..e4da2717982d 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -206,14 +206,16 @@ __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *f * XDR decode functions */ int -nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfssvc_decode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_argsize_check(rqstp, p); } int -nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *args) +nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_fhandle *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -221,9 +223,10 @@ nfssvc_decode_fhandle(struct svc_rqst *rqstp, __be32 *p, struct nfsd_fhandle *ar } int -nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_sattrargs *args) +nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_sattrargs *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -233,9 +236,10 @@ nfssvc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_diropargs *args) +nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_diropargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->fh)) || !(p = decode_filename(p, &args->name, &args->len))) return 0; @@ -244,9 +248,9 @@ nfssvc_decode_diropargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_readargs *args) +nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_readargs *args = rqstp->rq_argp; unsigned int len; int v; p = decode_fh(p, &args->fh); @@ -276,9 +280,9 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_writeargs *args) +nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_writeargs *args = rqstp->rq_argp; unsigned int len, hdr, dlen; struct kvec *head = rqstp->rq_arg.head; int v; @@ -332,9 +336,10 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_createargs *args) +nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_createargs *args = rqstp->rq_argp; + if ( !(p = decode_fh(p, &args->fh)) || !(p = decode_filename(p, &args->name, &args->len))) return 0; @@ -344,9 +349,10 @@ nfssvc_decode_createargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_renameargs *args) +nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_renameargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->ffh)) || !(p = decode_filename(p, &args->fname, &args->flen)) || !(p = decode_fh(p, &args->tfh)) @@ -357,8 +363,10 @@ nfssvc_decode_renameargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readlinkargs *args) +nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_readlinkargs *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -368,9 +376,10 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readli } int -nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_linkargs *args) +nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_linkargs *args = rqstp->rq_argp; + if (!(p = decode_fh(p, &args->ffh)) || !(p = decode_fh(p, &args->tfh)) || !(p = decode_filename(p, &args->tname, &args->tlen))) @@ -380,9 +389,10 @@ nfssvc_decode_linkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_symlinkargs *args) +nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_symlinkargs *args = rqstp->rq_argp; + if ( !(p = decode_fh(p, &args->ffh)) || !(p = decode_filename(p, &args->fname, &args->flen)) || !(p = decode_pathname(p, &args->tname, &args->tlen))) @@ -393,9 +403,10 @@ nfssvc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_readdirargs *args) +nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_readdirargs *args = rqstp->rq_argp; + p = decode_fh(p, &args->fh); if (!p) return 0; @@ -411,32 +422,35 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p, * XDR encode functions */ int -nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) +nfssvc_encode_void(struct svc_rqst *rqstp, __be32 *p) { return xdr_ressize_check(rqstp, p); } int -nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_attrstat *resp) +nfssvc_encode_attrstat(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_attrstat *resp = rqstp->rq_resp; + p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); return xdr_ressize_check(rqstp, p); } int -nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_diropres *resp) +nfssvc_encode_diropres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_diropres *resp = rqstp->rq_resp; + p = encode_fh(p, &resp->fh); p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); return xdr_ressize_check(rqstp, p); } int -nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_readlinkres *resp) +nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_readlinkres *resp = rqstp->rq_resp; + *p++ = htonl(resp->len); xdr_ressize_check(rqstp, p); rqstp->rq_res.page_len = resp->len; @@ -450,9 +464,10 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_readres *resp) +nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_readres *resp = rqstp->rq_resp; + p = encode_fattr(rqstp, p, &resp->fh, &resp->stat); *p++ = htonl(resp->count); xdr_ressize_check(rqstp, p); @@ -469,9 +484,10 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_readdirres *resp) +nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_readdirres *resp = rqstp->rq_resp; + xdr_ressize_check(rqstp, p); p = resp->buffer; *p++ = 0; /* no more entries */ @@ -482,9 +498,9 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, __be32 *p, } int -nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_statfsres *resp) +nfssvc_encode_statfsres(struct svc_rqst *rqstp, __be32 *p) { + struct nfsd_statfsres *resp = rqstp->rq_resp; struct kstatfs *stat = &resp->stats; *p++ = htonl(NFSSVC_MAXBLKSIZE_V2); /* max transfer size */ @@ -543,10 +559,10 @@ nfssvc_encode_entry(void *ccdv, const char *name, /* * XDR release functions */ -int -nfssvc_release_fhandle(struct svc_rqst *rqstp, __be32 *p, - struct nfsd_fhandle *resp) +void +nfssvc_release_fhandle(struct svc_rqst *rqstp) { + struct nfsd_fhandle *resp = rqstp->rq_resp; + fh_put(&resp->fh); - return 1; } diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h index 4f0481d63804..457ce45e5084 100644 --- a/fs/nfsd/xdr.h +++ b/fs/nfsd/xdr.h @@ -131,40 +131,30 @@ union nfsd_xdrstore { #define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore) -int nfssvc_decode_void(struct svc_rqst *, __be32 *, void *); -int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); -int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *, - struct nfsd_sattrargs *); -int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *, - struct nfsd_diropargs *); -int nfssvc_decode_readargs(struct svc_rqst *, __be32 *, - struct nfsd_readargs *); -int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *, - struct nfsd_writeargs *); -int nfssvc_decode_createargs(struct svc_rqst *, __be32 *, - struct nfsd_createargs *); -int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *, - struct nfsd_renameargs *); -int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *, - struct nfsd_readlinkargs *); -int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *, - struct nfsd_linkargs *); -int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *, - struct nfsd_symlinkargs *); -int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *, - struct nfsd_readdirargs *); -int nfssvc_encode_void(struct svc_rqst *, __be32 *, void *); -int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *, struct nfsd_attrstat *); -int nfssvc_encode_diropres(struct svc_rqst *, __be32 *, struct nfsd_diropres *); -int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *, struct nfsd_readlinkres *); -int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); -int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); -int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); +int nfssvc_decode_void(struct svc_rqst *, __be32 *); +int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *); +int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_readargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_createargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *); +int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *); +int nfssvc_encode_void(struct svc_rqst *, __be32 *); +int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *); +int nfssvc_encode_diropres(struct svc_rqst *, __be32 *); +int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *); +int nfssvc_encode_readres(struct svc_rqst *, __be32 *); +int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *); +int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *); int nfssvc_encode_entry(void *, const char *name, int namlen, loff_t offset, u64 ino, unsigned int); -int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); +void nfssvc_release_fhandle(struct svc_rqst *); /* Helper functions for NFSv2 ACL code */ __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp, struct kstat *stat); diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h index 335e04aaf7db..80d7da620e91 100644 --- a/fs/nfsd/xdr3.h +++ b/fs/nfsd/xdr3.h @@ -269,71 +269,41 @@ union nfsd3_xdrstore { #define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore) -int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); -int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *, - struct nfsd3_sattrargs *); -int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *, - struct nfsd3_diropargs *); -int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *, - struct nfsd3_accessargs *); -int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *, - struct nfsd3_readargs *); -int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *, - struct nfsd3_writeargs *); -int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *, - struct nfsd3_createargs *); -int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *, - struct nfsd3_createargs *); -int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *, - struct nfsd3_mknodargs *); -int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *, - struct nfsd3_renameargs *); -int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *, - struct nfsd3_readlinkargs *); -int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *, - struct nfsd3_linkargs *); -int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *, - struct nfsd3_symlinkargs *); -int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *, - struct nfsd3_readdirargs *); -int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *, - struct nfsd3_readdirargs *); -int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *, - struct nfsd3_commitargs *); -int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *, void *); -int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *, - struct nfsd3_attrstat *); -int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *, - struct nfsd3_attrstat *); -int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *, - struct nfsd3_diropres *); -int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *, - struct nfsd3_accessres *); -int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *, - struct nfsd3_readlinkres *); -int nfs3svc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd3_readres *); -int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *, struct nfsd3_writeres *); -int nfs3svc_encode_createres(struct svc_rqst *, __be32 *, - struct nfsd3_diropres *); -int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *, - struct nfsd3_renameres *); -int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *, - struct nfsd3_linkres *); -int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *, - struct nfsd3_readdirres *); -int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *, - struct nfsd3_fsstatres *); -int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *, - struct nfsd3_fsinfores *); -int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *, - struct nfsd3_pathconfres *); -int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *, - struct nfsd3_commitres *); - -int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, - struct nfsd3_attrstat *); -int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, - struct nfsd3_fhandle_pair *); +int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *); +int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *); +int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *); +int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *); +int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *); +int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_readres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_createres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *); +int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *); +int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *); + +void nfs3svc_release_fhandle(struct svc_rqst *); +void nfs3svc_release_fhandle2(struct svc_rqst *); int nfs3svc_encode_entry(void *, const char *name, int namlen, loff_t offset, u64 ino, unsigned int); diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 8fda4abdf3b1..72c6ad136107 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -539,7 +539,7 @@ struct nfsd4_seek { struct nfsd4_op { int opnum; __be32 status; - union { + union nfsd4_op_u { struct nfsd4_access access; struct nfsd4_close close; struct nfsd4_commit commit; @@ -577,6 +577,7 @@ struct nfsd4_op { struct nfsd4_bind_conn_to_session bind_conn_to_session; struct nfsd4_create_session create_session; struct nfsd4_destroy_session destroy_session; + struct nfsd4_destroy_clientid destroy_clientid; struct nfsd4_sequence sequence; struct nfsd4_reclaim_complete reclaim_complete; struct nfsd4_test_stateid test_stateid; @@ -585,6 +586,7 @@ struct nfsd4_op { struct nfsd4_layoutget layoutget; struct nfsd4_layoutcommit layoutcommit; struct nfsd4_layoutreturn layoutreturn; + struct nfsd4_secinfo_no_name secinfo_no_name; /* NFSv4.2 */ struct nfsd4_fallocate allocate; @@ -682,11 +684,9 @@ set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) bool nfsd4_mach_creds_match(struct nfs4_client *cl, struct svc_rqst *rqstp); -int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); -int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *, - struct nfsd4_compoundargs *); -int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, - struct nfsd4_compoundres *); +int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *); +int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *); +int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *); __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *, u32); void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); void nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op); @@ -695,27 +695,26 @@ __be32 nfsd4_encode_fattr_to_buf(__be32 **p, int words, struct dentry *dentry, u32 *bmval, struct svc_rqst *, int ignore_crossmnt); extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_setclientid *setclid); + struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_setclientid_confirm *setclientid_confirm); + struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_exchange_id *); -extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_backchannel_ctl *); -extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_bind_conn_to_session *); + struct nfsd4_compound_state *, union nfsd4_op_u *u); +extern __be32 nfsd4_backchannel_ctl(struct svc_rqst *, + struct nfsd4_compound_state *, union nfsd4_op_u *u); +extern __be32 nfsd4_bind_conn_to_session(struct svc_rqst *, + struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_create_session(struct svc_rqst *, - struct nfsd4_compound_state *, - struct nfsd4_create_session *); + struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_sequence(struct svc_rqst *, - struct nfsd4_compound_state *, - struct nfsd4_sequence *); + struct nfsd4_compound_state *, union nfsd4_op_u *u); extern void nfsd4_sequence_done(struct nfsd4_compoundres *resp); extern __be32 nfsd4_destroy_session(struct svc_rqst *, - struct nfsd4_compound_state *, - struct nfsd4_destroy_session *); -extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_destroy_clientid *); -__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, struct nfsd4_reclaim_complete *); + struct nfsd4_compound_state *, union nfsd4_op_u *u); +extern __be32 nfsd4_destroy_clientid(struct svc_rqst *, struct nfsd4_compound_state *, + union nfsd4_op_u *u); +__be32 nfsd4_reclaim_complete(struct svc_rqst *, struct nfsd4_compound_state *, + union nfsd4_op_u *u); extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, struct nfsd4_open *open, struct nfsd_net *nn); extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, @@ -724,34 +723,29 @@ extern void nfsd4_cstate_clear_replay(struct nfsd4_compound_state *cstate); extern void nfsd4_cleanup_open_state(struct nfsd4_compound_state *cstate, struct nfsd4_open *open); extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); -extern __be32 nfsd4_close(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_close *close); + struct nfsd4_compound_state *, union nfsd4_op_u *u); +extern __be32 nfsd4_close(struct svc_rqst *rqstp, struct nfsd4_compound_state *, + union nfsd4_op_u *u); extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_open_downgrade *od); + struct nfsd4_compound_state *, union nfsd4_op_u *u); extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *, - struct nfsd4_lock *lock); -extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_lockt *lockt); -extern __be32 nfsd4_locku(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_locku *locku); + union nfsd4_op_u *u); +extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *, + union nfsd4_op_u *u); +extern __be32 nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *, + union nfsd4_op_u *u); extern __be32 nfsd4_release_lockowner(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, - struct nfsd4_release_lockowner *rlockowner); -extern int nfsd4_release_compoundargs(void *rq, __be32 *p, void *resp); + struct nfsd4_compound_state *, union nfsd4_op_u *u); +extern void nfsd4_release_compoundargs(struct svc_rqst *rqstp); extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); -extern __be32 nfsd4_renew(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, clientid_t *clid); + struct nfsd4_compound_state *, union nfsd4_op_u *u); +extern __be32 nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *, + union nfsd4_op_u *u); extern __be32 nfsd4_test_stateid(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_test_stateid *test_stateid); + struct nfsd4_compound_state *, union nfsd4_op_u *); extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp, - struct nfsd4_compound_state *, struct nfsd4_free_stateid *free_stateid); + struct nfsd4_compound_state *, union nfsd4_op_u *); extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr); #endif diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 41f7b6a04d69..3eca67728366 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -192,9 +192,9 @@ struct nlm_block { * Global variables */ extern const struct rpc_program nlm_program; -extern struct svc_procedure nlmsvc_procedures[]; +extern const struct svc_procedure nlmsvc_procedures[]; #ifdef CONFIG_LOCKD_V4 -extern struct svc_procedure nlmsvc_procedures4[]; +extern const struct svc_procedure nlmsvc_procedures4[]; #endif extern int nlmsvc_grace_period; extern unsigned long nlmsvc_timeout; diff --git a/include/linux/lockd/xdr.h b/include/linux/lockd/xdr.h index d39ed1cc5fbf..7acbecc21a40 100644 --- a/include/linux/lockd/xdr.h +++ b/include/linux/lockd/xdr.h @@ -95,19 +95,19 @@ struct nlm_reboot { */ #define NLMSVC_XDRSIZE sizeof(struct nlm_args) -int nlmsvc_decode_testargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_encode_testres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_decode_lockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_decode_cancargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_decode_unlockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_encode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_decode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_encode_void(struct svc_rqst *, __be32 *, void *); -int nlmsvc_decode_void(struct svc_rqst *, __be32 *, void *); -int nlmsvc_decode_shareargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_encode_shareres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlmsvc_decode_notify(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlmsvc_decode_reboot(struct svc_rqst *, __be32 *, struct nlm_reboot *); +int nlmsvc_decode_testargs(struct svc_rqst *, __be32 *); +int nlmsvc_encode_testres(struct svc_rqst *, __be32 *); +int nlmsvc_decode_lockargs(struct svc_rqst *, __be32 *); +int nlmsvc_decode_cancargs(struct svc_rqst *, __be32 *); +int nlmsvc_decode_unlockargs(struct svc_rqst *, __be32 *); +int nlmsvc_encode_res(struct svc_rqst *, __be32 *); +int nlmsvc_decode_res(struct svc_rqst *, __be32 *); +int nlmsvc_encode_void(struct svc_rqst *, __be32 *); +int nlmsvc_decode_void(struct svc_rqst *, __be32 *); +int nlmsvc_decode_shareargs(struct svc_rqst *, __be32 *); +int nlmsvc_encode_shareres(struct svc_rqst *, __be32 *); +int nlmsvc_decode_notify(struct svc_rqst *, __be32 *); +int nlmsvc_decode_reboot(struct svc_rqst *, __be32 *); /* int nlmclt_encode_testargs(struct rpc_rqst *, u32 *, struct nlm_args *); int nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *); diff --git a/include/linux/lockd/xdr4.h b/include/linux/lockd/xdr4.h index e58c88b52ce1..bf1645609225 100644 --- a/include/linux/lockd/xdr4.h +++ b/include/linux/lockd/xdr4.h @@ -23,19 +23,19 @@ -int nlm4svc_decode_testargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_encode_testres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_decode_lockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_decode_cancargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_decode_unlockargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_encode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_decode_res(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_encode_void(struct svc_rqst *, __be32 *, void *); -int nlm4svc_decode_void(struct svc_rqst *, __be32 *, void *); -int nlm4svc_decode_shareargs(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_encode_shareres(struct svc_rqst *, __be32 *, struct nlm_res *); -int nlm4svc_decode_notify(struct svc_rqst *, __be32 *, struct nlm_args *); -int nlm4svc_decode_reboot(struct svc_rqst *, __be32 *, struct nlm_reboot *); +int nlm4svc_decode_testargs(struct svc_rqst *, __be32 *); +int nlm4svc_encode_testres(struct svc_rqst *, __be32 *); +int nlm4svc_decode_lockargs(struct svc_rqst *, __be32 *); +int nlm4svc_decode_cancargs(struct svc_rqst *, __be32 *); +int nlm4svc_decode_unlockargs(struct svc_rqst *, __be32 *); +int nlm4svc_encode_res(struct svc_rqst *, __be32 *); +int nlm4svc_decode_res(struct svc_rqst *, __be32 *); +int nlm4svc_encode_void(struct svc_rqst *, __be32 *); +int nlm4svc_decode_void(struct svc_rqst *, __be32 *); +int nlm4svc_decode_shareargs(struct svc_rqst *, __be32 *); +int nlm4svc_encode_shareres(struct svc_rqst *, __be32 *); +int nlm4svc_decode_notify(struct svc_rqst *, __be32 *); +int nlm4svc_decode_reboot(struct svc_rqst *, __be32 *); /* int nlmclt_encode_testargs(struct rpc_rqst *, u32 *, struct nlm_args *); int nlmclt_encode_lockargs(struct rpc_rqst *, u32 *, struct nlm_args *); diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 6095ecba0dde..55ef67bea06b 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -39,7 +39,7 @@ struct rpc_clnt { struct list_head cl_tasks; /* List of tasks */ spinlock_t cl_lock; /* spinlock */ struct rpc_xprt __rcu * cl_xprt; /* transport */ - struct rpc_procinfo * cl_procinfo; /* procedure info */ + const struct rpc_procinfo *cl_procinfo; /* procedure info */ u32 cl_prog, /* RPC program number */ cl_vers, /* RPC version number */ cl_maxproc; /* max procedure number */ @@ -87,7 +87,8 @@ struct rpc_program { struct rpc_version { u32 number; /* version number */ unsigned int nrprocs; /* number of procs */ - struct rpc_procinfo * procs; /* procedure array */ + const struct rpc_procinfo *procs; /* procedure array */ + unsigned int *counts; /* call counts */ }; /* @@ -99,7 +100,6 @@ struct rpc_procinfo { kxdrdproc_t p_decode; /* XDR decode function */ unsigned int p_arglen; /* argument hdr length (u32) */ unsigned int p_replen; /* reply hdr length (u32) */ - unsigned int p_count; /* call count */ unsigned int p_timer; /* Which RTT timer to use */ u32 p_statidx; /* Which procedure to account */ const char * p_name; /* name of procedure */ diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h index 9d7529ffc4ce..50a99a117da7 100644 --- a/include/linux/sunrpc/sched.h +++ b/include/linux/sunrpc/sched.h @@ -22,7 +22,7 @@ */ struct rpc_procinfo; struct rpc_message { - struct rpc_procinfo * rpc_proc; /* Procedure information */ + const struct rpc_procinfo *rpc_proc; /* Procedure information */ void * rpc_argp; /* Arguments */ void * rpc_resp; /* Result */ struct rpc_cred * rpc_cred; /* Credentials */ diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 11cef5a7bc87..a3f8af9bd543 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -237,7 +237,7 @@ struct svc_rqst { struct svc_serv * rq_server; /* RPC service definition */ struct svc_pool * rq_pool; /* thread pool */ - struct svc_procedure * rq_procinfo; /* procedure info */ + const struct svc_procedure *rq_procinfo;/* procedure info */ struct auth_ops * rq_authop; /* authentication flavour */ struct svc_cred rq_cred; /* auth info */ void * rq_xprt_ctxt; /* transport specific context ptr */ @@ -246,7 +246,7 @@ struct svc_rqst { size_t rq_xprt_hlen; /* xprt header len */ struct xdr_buf rq_arg; struct xdr_buf rq_res; - struct page * rq_pages[RPCSVC_MAXPAGES]; + struct page *rq_pages[RPCSVC_MAXPAGES + 1]; struct page * *rq_respages; /* points into rq_pages */ struct page * *rq_next_page; /* next reply page to use */ struct page * *rq_page_end; /* one past the last page */ @@ -384,7 +384,7 @@ struct svc_program { unsigned int pg_lovers; /* lowest version */ unsigned int pg_hivers; /* highest version */ unsigned int pg_nvers; /* number of versions */ - struct svc_version ** pg_vers; /* version array */ + const struct svc_version **pg_vers; /* version array */ char * pg_name; /* service name */ char * pg_class; /* class name: services sharing authentication */ struct svc_stat * pg_stats; /* rpc statistics */ @@ -397,7 +397,8 @@ struct svc_program { struct svc_version { u32 vs_vers; /* version number */ u32 vs_nproc; /* number of procedures */ - struct svc_procedure * vs_proc; /* per-procedure info */ + const struct svc_procedure *vs_proc; /* per-procedure info */ + unsigned int *vs_count; /* call counts */ u32 vs_xdrsize; /* xdrsize needed for this version */ /* Don't register with rpcbind */ @@ -419,15 +420,17 @@ struct svc_version { /* * RPC procedure info */ -typedef __be32 (*svc_procfunc)(struct svc_rqst *, void *argp, void *resp); struct svc_procedure { - svc_procfunc pc_func; /* process the request */ - kxdrproc_t pc_decode; /* XDR decode args */ - kxdrproc_t pc_encode; /* XDR encode result */ - kxdrproc_t pc_release; /* XDR free result */ + /* process the request: */ + __be32 (*pc_func)(struct svc_rqst *); + /* XDR decode args: */ + int (*pc_decode)(struct svc_rqst *, __be32 *data); + /* XDR encode result: */ + int (*pc_encode)(struct svc_rqst *, __be32 *data); + /* XDR free result: */ + void (*pc_release)(struct svc_rqst *); unsigned int pc_argsize; /* argument struct size */ unsigned int pc_ressize; /* result struct size */ - unsigned int pc_count; /* call count */ unsigned int pc_cachetype; /* cache info (NFS) */ unsigned int pc_xdrressize; /* maximum size of XDR reply */ }; diff --git a/include/linux/sunrpc/svc_rdma.h b/include/linux/sunrpc/svc_rdma.h index f3787d800ba4..995c6fe9ee90 100644 --- a/include/linux/sunrpc/svc_rdma.h +++ b/include/linux/sunrpc/svc_rdma.h @@ -77,46 +77,25 @@ extern atomic_t rdma_stat_sq_prod; */ struct svc_rdma_op_ctxt { struct list_head list; - struct svc_rdma_op_ctxt *read_hdr; - struct svc_rdma_fastreg_mr *frmr; - int hdr_count; struct xdr_buf arg; struct ib_cqe cqe; - struct ib_cqe reg_cqe; - struct ib_cqe inv_cqe; u32 byte_len; - u32 position; struct svcxprt_rdma *xprt; - unsigned long flags; enum dma_data_direction direction; int count; unsigned int mapped_sges; + int hdr_count; struct ib_send_wr send_wr; struct ib_sge sge[1 + RPCRDMA_MAX_INLINE_THRESH / PAGE_SIZE]; struct page *pages[RPCSVC_MAXPAGES]; }; -struct svc_rdma_fastreg_mr { - struct ib_mr *mr; - struct scatterlist *sg; - int sg_nents; - unsigned long access_flags; - enum dma_data_direction direction; - struct list_head frmr_list; -}; - -#define RDMACTXT_F_LAST_CTXT 2 - -#define SVCRDMA_DEVCAP_FAST_REG 1 /* fast mr registration */ -#define SVCRDMA_DEVCAP_READ_W_INV 2 /* read w/ invalidate */ - struct svcxprt_rdma { struct svc_xprt sc_xprt; /* SVC transport structure */ struct rdma_cm_id *sc_cm_id; /* RDMA connection id */ struct list_head sc_accept_q; /* Conn. waiting accept */ int sc_ord; /* RDMA read limit */ int sc_max_sge; - int sc_max_sge_rd; /* max sge for read target */ bool sc_snd_w_inv; /* OK to use Send With Invalidate */ atomic_t sc_sq_avail; /* SQEs ready to be consumed */ @@ -141,14 +120,6 @@ struct svcxprt_rdma { struct ib_qp *sc_qp; struct ib_cq *sc_rq_cq; struct ib_cq *sc_sq_cq; - int (*sc_reader)(struct svcxprt_rdma *, - struct svc_rqst *, - struct svc_rdma_op_ctxt *, - int *, u32 *, u32, u32, u64, bool); - u32 sc_dev_caps; /* distilled device caps */ - unsigned int sc_frmr_pg_list_len; - struct list_head sc_frmr_q; - spinlock_t sc_frmr_q_lock; spinlock_t sc_lock; /* transport lock */ @@ -185,20 +156,14 @@ extern int svc_rdma_handle_bc_reply(struct rpc_xprt *xprt, __be32 *rdma_resp, struct xdr_buf *rcvbuf); -/* svc_rdma_marshal.c */ -extern int svc_rdma_xdr_decode_req(struct xdr_buf *); - /* svc_rdma_recvfrom.c */ extern int svc_rdma_recvfrom(struct svc_rqst *); -extern int rdma_read_chunk_lcl(struct svcxprt_rdma *, struct svc_rqst *, - struct svc_rdma_op_ctxt *, int *, u32 *, - u32, u32, u64, bool); -extern int rdma_read_chunk_frmr(struct svcxprt_rdma *, struct svc_rqst *, - struct svc_rdma_op_ctxt *, int *, u32 *, - u32, u32, u64, bool); /* svc_rdma_rw.c */ extern void svc_rdma_destroy_rw_ctxts(struct svcxprt_rdma *rdma); +extern int svc_rdma_recv_read_chunk(struct svcxprt_rdma *rdma, + struct svc_rqst *rqstp, + struct svc_rdma_op_ctxt *head, __be32 *p); extern int svc_rdma_send_write_chunk(struct svcxprt_rdma *rdma, __be32 *wr_ch, struct xdr_buf *xdr); extern int svc_rdma_send_reply_chunk(struct svcxprt_rdma *rdma, @@ -226,9 +191,6 @@ extern int svc_rdma_create_listen(struct svc_serv *, int, struct sockaddr *); extern struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *); extern void svc_rdma_put_context(struct svc_rdma_op_ctxt *, int); extern void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt); -extern struct svc_rdma_fastreg_mr *svc_rdma_get_frmr(struct svcxprt_rdma *); -extern void svc_rdma_put_frmr(struct svcxprt_rdma *, - struct svc_rdma_fastreg_mr *); extern void svc_sq_reap(struct svcxprt_rdma *); extern void svc_rq_reap(struct svcxprt_rdma *); extern void svc_rdma_prep_reply_hdr(struct svc_rqst *); diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 054c8cde18f3..261b48a2701d 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -17,6 +17,8 @@ #include <asm/unaligned.h> #include <linux/scatterlist.h> +struct rpc_rqst; + /* * Buffer adjustment */ @@ -33,13 +35,6 @@ struct xdr_netobj { }; /* - * This is the legacy generic XDR function. rqstp is either a rpc_rqst - * (client side) or svc_rqst pointer (server side). - * Encode functions always assume there's enough room in the buffer. - */ -typedef int (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj); - -/* * Basic structure for transmission/reception of a client XDR message. * Features a header (for a linear buffer containing RPC headers * and the data payload for short messages), and then an array of @@ -222,8 +217,10 @@ struct xdr_stream { /* * These are the xdr_stream style generic XDR encode and decode functions. */ -typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); -typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); +typedef void (*kxdreproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + const void *obj); +typedef int (*kxdrdproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + void *obj); extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index f0c6a8c78a56..46b295e4f2b8 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c @@ -55,15 +55,15 @@ enum { #define PROC(proc, name) \ [GSSX_##proc] = { \ .p_proc = GSSX_##proc, \ - .p_encode = (kxdreproc_t)gssx_enc_##name, \ - .p_decode = (kxdrdproc_t)gssx_dec_##name, \ + .p_encode = gssx_enc_##name, \ + .p_decode = gssx_dec_##name, \ .p_arglen = GSSX_ARG_##name##_sz, \ .p_replen = GSSX_RES_##name##_sz, \ .p_statidx = GSSX_##proc, \ .p_name = #proc, \ } -static struct rpc_procinfo gssp_procedures[] = { +static const struct rpc_procinfo gssp_procedures[] = { PROC(INDICATE_MECHS, indicate_mechs), PROC(GET_CALL_CONTEXT, get_call_context), PROC(IMPORT_AND_CANON_NAME, import_and_canon_name), @@ -364,11 +364,12 @@ void gssp_free_upcall_data(struct gssp_upcall_data *data) /* * Initialization stuff */ - +static unsigned int gssp_version1_counts[ARRAY_SIZE(gssp_procedures)]; static const struct rpc_version gssp_version1 = { .number = GSSPROXY_VERS_1, .nrprocs = ARRAY_SIZE(gssp_procedures), .procs = gssp_procedures, + .counts = gssp_version1_counts, }; static const struct rpc_version *gssp_version[] = { diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index 25d9a9cf7b66..c4778cae58ef 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c @@ -44,7 +44,7 @@ static int gssx_dec_bool(struct xdr_stream *xdr, u32 *v) } static int gssx_enc_buffer(struct xdr_stream *xdr, - gssx_buffer *buf) + const gssx_buffer *buf) { __be32 *p; @@ -56,7 +56,7 @@ static int gssx_enc_buffer(struct xdr_stream *xdr, } static int gssx_enc_in_token(struct xdr_stream *xdr, - struct gssp_in_token *in) + const struct gssp_in_token *in) { __be32 *p; @@ -130,7 +130,7 @@ static int gssx_dec_option(struct xdr_stream *xdr, } static int dummy_enc_opt_array(struct xdr_stream *xdr, - struct gssx_option_array *oa) + const struct gssx_option_array *oa) { __be32 *p; @@ -348,7 +348,7 @@ static int gssx_dec_status(struct xdr_stream *xdr, } static int gssx_enc_call_ctx(struct xdr_stream *xdr, - struct gssx_call_ctx *ctx) + const struct gssx_call_ctx *ctx) { struct gssx_option opt; __be32 *p; @@ -733,8 +733,9 @@ static int gssx_enc_cb(struct xdr_stream *xdr, struct gssx_cb *cb) void gssx_enc_accept_sec_context(struct rpc_rqst *req, struct xdr_stream *xdr, - struct gssx_arg_accept_sec_context *arg) + const void *data) { + const struct gssx_arg_accept_sec_context *arg = data; int err; err = gssx_enc_call_ctx(xdr, &arg->call_ctx); @@ -789,8 +790,9 @@ done: int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct gssx_res_accept_sec_context *res) + void *data) { + struct gssx_res_accept_sec_context *res = data; u32 value_follows; int err; struct page *scratch; diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.h b/net/sunrpc/auth_gss/gss_rpc_xdr.h index 9d88c6239f01..146c31032917 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.h +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.h @@ -179,10 +179,10 @@ struct gssx_res_accept_sec_context { #define gssx_dec_init_sec_context NULL void gssx_enc_accept_sec_context(struct rpc_rqst *req, struct xdr_stream *xdr, - struct gssx_arg_accept_sec_context *args); + const void *data); int gssx_dec_accept_sec_context(struct rpc_rqst *rqstp, struct xdr_stream *xdr, - struct gssx_res_accept_sec_context *res); + void *data); #define gssx_enc_release_handle NULL #define gssx_dec_release_handle NULL #define gssx_enc_get_mic NULL diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index a54a7a3d28f5..7b1ee5a0b03c 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -838,6 +838,14 @@ unwrap_integ_data(struct svc_rqst *rqstp, struct xdr_buf *buf, u32 seq, struct g struct xdr_netobj mic; struct xdr_buf integ_buf; + /* NFS READ normally uses splice to send data in-place. However + * the data in cache can change after the reply's MIC is computed + * but before the RPC reply is sent. To prevent the client from + * rejecting the server-computed MIC in this somewhat rare case, + * do not use splice with the GSS integrity service. + */ + clear_bit(RQ_SPLICE_OK, &rqstp->rq_flags); + /* Did we already verify the signature on the original pass through? */ if (rqstp->rq_deferred) return 0; diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index b5cb921775a0..2e49d1f892b7 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1517,14 +1517,16 @@ static void call_start(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; + int idx = task->tk_msg.rpc_proc->p_statidx; dprintk("RPC: %5u call_start %s%d proc %s (%s)\n", task->tk_pid, clnt->cl_program->name, clnt->cl_vers, rpc_proc_name(task), (RPC_IS_ASYNC(task) ? "async" : "sync")); - /* Increment call count */ - task->tk_msg.rpc_proc->p_count++; + /* Increment call count (version might not be valid for ping) */ + if (clnt->cl_program->version[clnt->cl_vers]) + clnt->cl_program->version[clnt->cl_vers]->counts[idx]++; clnt->cl_stats->rpccnt++; task->tk_action = call_reserve; } @@ -1672,7 +1674,7 @@ call_allocate(struct rpc_task *task) unsigned int slack = task->tk_rqstp->rq_cred->cr_auth->au_cslack; struct rpc_rqst *req = task->tk_rqstp; struct rpc_xprt *xprt = req->rq_xprt; - struct rpc_procinfo *proc = task->tk_msg.rpc_proc; + const struct rpc_procinfo *proc = task->tk_msg.rpc_proc; int status; dprint_status(task); @@ -2476,16 +2478,18 @@ out_overflow: goto out_garbage; } -static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) +static void rpcproc_encode_null(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + const void *obj) { } -static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj) +static int rpcproc_decode_null(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + void *obj) { return 0; } -static struct rpc_procinfo rpcproc_null = { +static const struct rpc_procinfo rpcproc_null = { .p_encode = rpcproc_encode_null, .p_decode = rpcproc_decode_null, }; diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 5b30603596d0..ea0676f199c8 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -128,13 +128,13 @@ struct rpcbind_args { int r_status; }; -static struct rpc_procinfo rpcb_procedures2[]; -static struct rpc_procinfo rpcb_procedures3[]; -static struct rpc_procinfo rpcb_procedures4[]; +static const struct rpc_procinfo rpcb_procedures2[]; +static const struct rpc_procinfo rpcb_procedures3[]; +static const struct rpc_procinfo rpcb_procedures4[]; struct rpcb_info { u32 rpc_vers; - struct rpc_procinfo * rpc_proc; + const struct rpc_procinfo *rpc_proc; }; static const struct rpcb_info rpcb_next_version[]; @@ -620,7 +620,8 @@ int rpcb_v4_register(struct net *net, const u32 program, const u32 version, return -EAFNOSUPPORT; } -static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, struct rpcbind_args *map, struct rpc_procinfo *proc) +static struct rpc_task *rpcb_call_async(struct rpc_clnt *rpcb_clnt, + struct rpcbind_args *map, const struct rpc_procinfo *proc) { struct rpc_message msg = { .rpc_proc = proc, @@ -671,7 +672,7 @@ static struct rpc_clnt *rpcb_find_transport_owner(struct rpc_clnt *clnt) void rpcb_getport_async(struct rpc_task *task) { struct rpc_clnt *clnt; - struct rpc_procinfo *proc; + const struct rpc_procinfo *proc; u32 bind_version; struct rpc_xprt *xprt; struct rpc_clnt *rpcb_clnt; @@ -843,8 +844,9 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) */ static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct rpcbind_args *rpcb) + const void *data) { + const struct rpcbind_args *rpcb = data; __be32 *p; dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", @@ -860,8 +862,9 @@ static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr, } static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr, - struct rpcbind_args *rpcb) + void *data) { + struct rpcbind_args *rpcb = data; unsigned long port; __be32 *p; @@ -882,8 +885,9 @@ static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr, } static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr, - unsigned int *boolp) + void *data) { + unsigned int *boolp = data; __be32 *p; p = xdr_inline_decode(xdr, 4); @@ -917,8 +921,9 @@ static void encode_rpcb_string(struct xdr_stream *xdr, const char *string, } static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, - const struct rpcbind_args *rpcb) + const void *data) { + const struct rpcbind_args *rpcb = data; __be32 *p; dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", @@ -937,8 +942,9 @@ static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, } static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, - struct rpcbind_args *rpcb) + void *data) { + struct rpcbind_args *rpcb = data; struct sockaddr_storage address; struct sockaddr *sap = (struct sockaddr *)&address; __be32 *p; @@ -989,11 +995,11 @@ out_fail: * since the Linux kernel RPC code requires only these. */ -static struct rpc_procinfo rpcb_procedures2[] = { +static const struct rpc_procinfo rpcb_procedures2[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, - .p_encode = (kxdreproc_t)rpcb_enc_mapping, - .p_decode = (kxdrdproc_t)rpcb_dec_set, + .p_encode = rpcb_enc_mapping, + .p_decode = rpcb_dec_set, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_SET, @@ -1002,8 +1008,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { }, [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, - .p_encode = (kxdreproc_t)rpcb_enc_mapping, - .p_decode = (kxdrdproc_t)rpcb_dec_set, + .p_encode = rpcb_enc_mapping, + .p_decode = rpcb_dec_set, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_UNSET, @@ -1012,8 +1018,8 @@ static struct rpc_procinfo rpcb_procedures2[] = { }, [RPCBPROC_GETPORT] = { .p_proc = RPCBPROC_GETPORT, - .p_encode = (kxdreproc_t)rpcb_enc_mapping, - .p_decode = (kxdrdproc_t)rpcb_dec_getport, + .p_encode = rpcb_enc_mapping, + .p_decode = rpcb_dec_getport, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_getportres_sz, .p_statidx = RPCBPROC_GETPORT, @@ -1022,11 +1028,11 @@ static struct rpc_procinfo rpcb_procedures2[] = { }, }; -static struct rpc_procinfo rpcb_procedures3[] = { +static const struct rpc_procinfo rpcb_procedures3[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, - .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrdproc_t)rpcb_dec_set, + .p_encode = rpcb_enc_getaddr, + .p_decode = rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_SET, @@ -1035,8 +1041,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { }, [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, - .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrdproc_t)rpcb_dec_set, + .p_encode = rpcb_enc_getaddr, + .p_decode = rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_UNSET, @@ -1045,8 +1051,8 @@ static struct rpc_procinfo rpcb_procedures3[] = { }, [RPCBPROC_GETADDR] = { .p_proc = RPCBPROC_GETADDR, - .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, + .p_encode = rpcb_enc_getaddr, + .p_decode = rpcb_dec_getaddr, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_getaddrres_sz, .p_statidx = RPCBPROC_GETADDR, @@ -1055,11 +1061,11 @@ static struct rpc_procinfo rpcb_procedures3[] = { }, }; -static struct rpc_procinfo rpcb_procedures4[] = { +static const struct rpc_procinfo rpcb_procedures4[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, - .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrdproc_t)rpcb_dec_set, + .p_encode = rpcb_enc_getaddr, + .p_decode = rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_SET, @@ -1068,8 +1074,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { }, [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, - .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrdproc_t)rpcb_dec_set, + .p_encode = rpcb_enc_getaddr, + .p_decode = rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_UNSET, @@ -1078,8 +1084,8 @@ static struct rpc_procinfo rpcb_procedures4[] = { }, [RPCBPROC_GETADDR] = { .p_proc = RPCBPROC_GETADDR, - .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, + .p_encode = rpcb_enc_getaddr, + .p_decode = rpcb_dec_getaddr, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_getaddrres_sz, .p_statidx = RPCBPROC_GETADDR, @@ -1112,22 +1118,28 @@ static const struct rpcb_info rpcb_next_version6[] = { }, }; +static unsigned int rpcb_version2_counts[ARRAY_SIZE(rpcb_procedures2)]; static const struct rpc_version rpcb_version2 = { .number = RPCBVERS_2, .nrprocs = ARRAY_SIZE(rpcb_procedures2), - .procs = rpcb_procedures2 + .procs = rpcb_procedures2, + .counts = rpcb_version2_counts, }; +static unsigned int rpcb_version3_counts[ARRAY_SIZE(rpcb_procedures3)]; static const struct rpc_version rpcb_version3 = { .number = RPCBVERS_3, .nrprocs = ARRAY_SIZE(rpcb_procedures3), - .procs = rpcb_procedures3 + .procs = rpcb_procedures3, + .counts = rpcb_version3_counts, }; +static unsigned int rpcb_version4_counts[ARRAY_SIZE(rpcb_procedures4)]; static const struct rpc_version rpcb_version4 = { .number = RPCBVERS_4, .nrprocs = ARRAY_SIZE(rpcb_procedures4), - .procs = rpcb_procedures4 + .procs = rpcb_procedures4, + .counts = rpcb_version4_counts, }; static const struct rpc_version *rpcb_version[] = { diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index caeb01ad2b5a..1e671333c3d5 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c @@ -55,8 +55,7 @@ static int rpc_proc_show(struct seq_file *seq, void *v) { seq_printf(seq, "proc%u %u", vers->number, vers->nrprocs); for (j = 0; j < vers->nrprocs; j++) - seq_printf(seq, " %u", - vers->procs[j].p_count); + seq_printf(seq, " %u", vers->counts[j]); seq_putc(seq, '\n'); } return 0; @@ -78,9 +77,9 @@ static const struct file_operations rpc_proc_fops = { /* * Get RPC server stats */ -void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) { +void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) +{ const struct svc_program *prog = statp->program; - const struct svc_procedure *proc; const struct svc_version *vers; unsigned int i, j; @@ -99,11 +98,12 @@ void svc_seq_show(struct seq_file *seq, const struct svc_stat *statp) { statp->rpcbadclnt); for (i = 0; i < prog->pg_nvers; i++) { - if (!(vers = prog->pg_vers[i]) || !(proc = vers->vs_proc)) + vers = prog->pg_vers[i]; + if (!vers) continue; seq_printf(seq, "proc%d %u", i, vers->vs_nproc); - for (j = 0; j < vers->vs_nproc; j++, proc++) - seq_printf(seq, " %u", proc->pc_count); + for (j = 0; j < vers->vs_nproc; j++) + seq_printf(seq, " %u", vers->vs_count[j]); seq_putc(seq, '\n'); } } @@ -192,7 +192,7 @@ void rpc_count_iostats(const struct rpc_task *task, struct rpc_iostats *stats) EXPORT_SYMBOL_GPL(rpc_count_iostats); static void _print_name(struct seq_file *seq, unsigned int op, - struct rpc_procinfo *procs) + const struct rpc_procinfo *procs) { if (procs[op].p_name) seq_printf(seq, "\t%12s: ", procs[op].p_name); diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index bc0f5a0ecbdc..85ce0db5b0a6 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c @@ -1008,7 +1008,7 @@ int svc_register(const struct svc_serv *serv, struct net *net, const unsigned short port) { struct svc_program *progp; - struct svc_version *vers; + const struct svc_version *vers; unsigned int i; int error = 0; @@ -1151,10 +1151,9 @@ static int svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) { struct svc_program *progp; - struct svc_version *versp = NULL; /* compiler food */ - struct svc_procedure *procp = NULL; + const struct svc_version *versp = NULL; /* compiler food */ + const struct svc_procedure *procp = NULL; struct svc_serv *serv = rqstp->rq_server; - kxdrproc_t xdr; __be32 *statp; u32 prog, vers, proc; __be32 auth_stat, rpc_stat; @@ -1166,7 +1165,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) if (argv->iov_len < 6*4) goto err_short_len; - /* Will be turned off only in gss privacy case: */ + /* Will be turned off by GSS integrity and privacy services */ set_bit(RQ_SPLICE_OK, &rqstp->rq_flags); /* Will be turned off only when NFSv4 Sessions are used */ set_bit(RQ_USEDEFERRAL, &rqstp->rq_flags); @@ -1262,7 +1261,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) svc_putnl(resv, RPC_SUCCESS); /* Bump per-procedure stats counter */ - procp->pc_count++; + versp->vs_count[proc]++; /* Initialize storage for argp and resp */ memset(rqstp->rq_argp, 0, procp->pc_argsize); @@ -1276,28 +1275,30 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) /* Call the function that processes the request. */ if (!versp->vs_dispatch) { - /* Decode arguments */ - xdr = procp->pc_decode; - if (xdr && !xdr(rqstp, argv->iov_base, rqstp->rq_argp)) + /* + * Decode arguments + * XXX: why do we ignore the return value? + */ + if (procp->pc_decode && + !procp->pc_decode(rqstp, argv->iov_base)) goto err_garbage; - *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); + *statp = procp->pc_func(rqstp); /* Encode reply */ if (*statp == rpc_drop_reply || test_bit(RQ_DROPME, &rqstp->rq_flags)) { if (procp->pc_release) - procp->pc_release(rqstp, NULL, rqstp->rq_resp); + procp->pc_release(rqstp); goto dropit; } if (*statp == rpc_autherr_badcred) { if (procp->pc_release) - procp->pc_release(rqstp, NULL, rqstp->rq_resp); + procp->pc_release(rqstp); goto err_bad_auth; } - if (*statp == rpc_success && - (xdr = procp->pc_encode) && - !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { + if (*statp == rpc_success && procp->pc_encode && + !procp->pc_encode(rqstp, resv->iov_base + resv->iov_len)) { dprintk("svc: failed to encode reply\n"); /* serv->sv_stats->rpcsystemerr++; */ *statp = rpc_system_err; @@ -1307,7 +1308,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) if (!versp->vs_dispatch(rqstp, statp)) { /* Release reply info */ if (procp->pc_release) - procp->pc_release(rqstp, NULL, rqstp->rq_resp); + procp->pc_release(rqstp); goto dropit; } } @@ -1318,7 +1319,7 @@ svc_process_common(struct svc_rqst *rqstp, struct kvec *argv, struct kvec *resv) /* Release reply info */ if (procp->pc_release) - procp->pc_release(rqstp, NULL, rqstp->rq_resp); + procp->pc_release(rqstp); if (procp->pc_encode == NULL) goto dropit; diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 7bfe1fb42add..d16a8b423c20 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -659,11 +659,13 @@ static int svc_alloc_arg(struct svc_rqst *rqstp) int i; /* now allocate needed pages. If we get a failure, sleep briefly */ - pages = (serv->sv_max_mesg + PAGE_SIZE) / PAGE_SIZE; - WARN_ON_ONCE(pages >= RPCSVC_MAXPAGES); - if (pages >= RPCSVC_MAXPAGES) + pages = (serv->sv_max_mesg + 2 * PAGE_SIZE) >> PAGE_SHIFT; + if (pages > RPCSVC_MAXPAGES) { + pr_warn_once("svc: warning: pages=%u > RPCSVC_MAXPAGES=%lu\n", + pages, RPCSVC_MAXPAGES); /* use as many pages as possible */ - pages = RPCSVC_MAXPAGES - 1; + pages = RPCSVC_MAXPAGES; + } for (i = 0; i < pages ; i++) while (rqstp->rq_pages[i] == NULL) { struct page *p = alloc_page(GFP_KERNEL); diff --git a/net/sunrpc/xprtrdma/Makefile b/net/sunrpc/xprtrdma/Makefile index c1ae8142ab73..b8213ddce2f2 100644 --- a/net/sunrpc/xprtrdma/Makefile +++ b/net/sunrpc/xprtrdma/Makefile @@ -3,6 +3,6 @@ obj-$(CONFIG_SUNRPC_XPRT_RDMA) += rpcrdma.o rpcrdma-y := transport.o rpc_rdma.o verbs.o \ fmr_ops.o frwr_ops.o \ svc_rdma.o svc_rdma_backchannel.o svc_rdma_transport.o \ - svc_rdma_marshal.o svc_rdma_sendto.o svc_rdma_recvfrom.o \ - svc_rdma_rw.o module.o + svc_rdma_sendto.o svc_rdma_recvfrom.o svc_rdma_rw.o \ + module.o rpcrdma-$(CONFIG_SUNRPC_BACKCHANNEL) += backchannel.o diff --git a/net/sunrpc/xprtrdma/svc_rdma_marshal.c b/net/sunrpc/xprtrdma/svc_rdma_marshal.c deleted file mode 100644 index bdcf7d85a3dc..000000000000 --- a/net/sunrpc/xprtrdma/svc_rdma_marshal.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2016 Oracle. All rights reserved. - * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. - * - * This software is available to you under a choice of one of two - * licenses. You may choose to be licensed under the terms of the GNU - * General Public License (GPL) Version 2, available from the file - * COPYING in the main directory of this source tree, or the BSD-type - * license below: - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * Neither the name of the Network Appliance, Inc. nor the names of - * its contributors may be used to endorse or promote products - * derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Tom Tucker <tom@opengridcomputing.com> - */ - -#include <linux/sunrpc/xdr.h> -#include <linux/sunrpc/debug.h> -#include <asm/unaligned.h> -#include <linux/sunrpc/rpc_rdma.h> -#include <linux/sunrpc/svc_rdma.h> - -#define RPCDBG_FACILITY RPCDBG_SVCXPRT - -static __be32 *xdr_check_read_list(__be32 *p, __be32 *end) -{ - __be32 *next; - - while (*p++ != xdr_zero) { - next = p + rpcrdma_readchunk_maxsz - 1; - if (next > end) - return NULL; - p = next; - } - return p; -} - -static __be32 *xdr_check_write_list(__be32 *p, __be32 *end) -{ - __be32 *next; - - while (*p++ != xdr_zero) { - next = p + 1 + be32_to_cpup(p) * rpcrdma_segment_maxsz; - if (next > end) - return NULL; - p = next; - } - return p; -} - -static __be32 *xdr_check_reply_chunk(__be32 *p, __be32 *end) -{ - __be32 *next; - - if (*p++ != xdr_zero) { - next = p + 1 + be32_to_cpup(p) * rpcrdma_segment_maxsz; - if (next > end) - return NULL; - p = next; - } - return p; -} - -/** - * svc_rdma_xdr_decode_req - Parse incoming RPC-over-RDMA header - * @rq_arg: Receive buffer - * - * On entry, xdr->head[0].iov_base points to first byte in the - * RPC-over-RDMA header. - * - * On successful exit, head[0] points to first byte past the - * RPC-over-RDMA header. For RDMA_MSG, this is the RPC message. - * The length of the RPC-over-RDMA header is returned. - */ -int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg) -{ - __be32 *p, *end, *rdma_argp; - unsigned int hdr_len; - - /* Verify that there's enough bytes for header + something */ - if (rq_arg->len <= RPCRDMA_HDRLEN_ERR) - goto out_short; - - rdma_argp = rq_arg->head[0].iov_base; - if (*(rdma_argp + 1) != rpcrdma_version) - goto out_version; - - switch (*(rdma_argp + 3)) { - case rdma_msg: - case rdma_nomsg: - break; - - case rdma_done: - goto out_drop; - - case rdma_error: - goto out_drop; - - default: - goto out_proc; - } - - end = (__be32 *)((unsigned long)rdma_argp + rq_arg->len); - p = xdr_check_read_list(rdma_argp + 4, end); - if (!p) - goto out_inval; - p = xdr_check_write_list(p, end); - if (!p) - goto out_inval; - p = xdr_check_reply_chunk(p, end); - if (!p) - goto out_inval; - if (p > end) - goto out_inval; - - rq_arg->head[0].iov_base = p; - hdr_len = (unsigned long)p - (unsigned long)rdma_argp; - rq_arg->head[0].iov_len -= hdr_len; - return hdr_len; - -out_short: - dprintk("svcrdma: header too short = %d\n", rq_arg->len); - return -EINVAL; - -out_version: - dprintk("svcrdma: bad xprt version: %u\n", - be32_to_cpup(rdma_argp + 1)); - return -EPROTONOSUPPORT; - -out_drop: - dprintk("svcrdma: dropping RDMA_DONE/ERROR message\n"); - return 0; - -out_proc: - dprintk("svcrdma: bad rdma procedure (%u)\n", - be32_to_cpup(rdma_argp + 3)); - return -EINVAL; - -out_inval: - dprintk("svcrdma: failed to parse transport header\n"); - return -EINVAL; -} diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c index 27a99bf5b1a6..ad4bd62eebf1 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c +++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2016, 2017 Oracle. All rights reserved. * Copyright (c) 2014 Open Grid Computing, Inc. All rights reserved. * Copyright (c) 2005-2006 Network Appliance, Inc. All rights reserved. * @@ -40,12 +41,66 @@ * Author: Tom Tucker <tom@opengridcomputing.com> */ -#include <linux/sunrpc/debug.h> -#include <linux/sunrpc/rpc_rdma.h> -#include <linux/spinlock.h> +/* Operation + * + * The main entry point is svc_rdma_recvfrom. This is called from + * svc_recv when the transport indicates there is incoming data to + * be read. "Data Ready" is signaled when an RDMA Receive completes, + * or when a set of RDMA Reads complete. + * + * An svc_rqst is passed in. This structure contains an array of + * free pages (rq_pages) that will contain the incoming RPC message. + * + * Short messages are moved directly into svc_rqst::rq_arg, and + * the RPC Call is ready to be processed by the Upper Layer. + * svc_rdma_recvfrom returns the length of the RPC Call message, + * completing the reception of the RPC Call. + * + * However, when an incoming message has Read chunks, + * svc_rdma_recvfrom must post RDMA Reads to pull the RPC Call's + * data payload from the client. svc_rdma_recvfrom sets up the + * RDMA Reads using pages in svc_rqst::rq_pages, which are + * transferred to an svc_rdma_op_ctxt for the duration of the + * I/O. svc_rdma_recvfrom then returns zero, since the RPC message + * is still not yet ready. + * + * When the Read chunk payloads have become available on the + * server, "Data Ready" is raised again, and svc_recv calls + * svc_rdma_recvfrom again. This second call may use a different + * svc_rqst than the first one, thus any information that needs + * to be preserved across these two calls is kept in an + * svc_rdma_op_ctxt. + * + * The second call to svc_rdma_recvfrom performs final assembly + * of the RPC Call message, using the RDMA Read sink pages kept in + * the svc_rdma_op_ctxt. The xdr_buf is copied from the + * svc_rdma_op_ctxt to the second svc_rqst. The second call returns + * the length of the completed RPC Call message. + * + * Page Management + * + * Pages under I/O must be transferred from the first svc_rqst to an + * svc_rdma_op_ctxt before the first svc_rdma_recvfrom call returns. + * + * The first svc_rqst supplies pages for RDMA Reads. These are moved + * from rqstp::rq_pages into ctxt::pages. The consumed elements of + * the rq_pages array are set to NULL and refilled with the first + * svc_rdma_recvfrom call returns. + * + * During the second svc_rdma_recvfrom call, RDMA Read sink pages + * are transferred from the svc_rdma_op_ctxt to the second svc_rqst + * (see rdma_read_complete() below). + */ + #include <asm/unaligned.h> #include <rdma/ib_verbs.h> #include <rdma/rdma_cm.h> + +#include <linux/spinlock.h> + +#include <linux/sunrpc/xdr.h> +#include <linux/sunrpc/debug.h> +#include <linux/sunrpc/rpc_rdma.h> #include <linux/sunrpc/svc_rdma.h> #define RPCDBG_FACILITY RPCDBG_SVCXPRT @@ -59,7 +114,6 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp, struct svc_rdma_op_ctxt *ctxt, u32 byte_count) { - struct rpcrdma_msg *rmsgp; struct page *page; u32 bc; int sge_no; @@ -83,20 +137,12 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp, rqstp->rq_arg.page_len = bc; rqstp->rq_arg.page_base = 0; - /* RDMA_NOMSG: RDMA READ data should land just after RDMA RECV data */ - rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; - if (rmsgp->rm_type == rdma_nomsg) - rqstp->rq_arg.pages = &rqstp->rq_pages[0]; - else - rqstp->rq_arg.pages = &rqstp->rq_pages[1]; - sge_no = 1; while (bc && sge_no < ctxt->count) { page = ctxt->pages[sge_no]; put_page(rqstp->rq_pages[sge_no]); rqstp->rq_pages[sge_no] = page; bc -= min_t(u32, bc, ctxt->sge[sge_no].length); - rqstp->rq_arg.buflen += ctxt->sge[sge_no].length; sge_no++; } rqstp->rq_respages = &rqstp->rq_pages[sge_no]; @@ -115,406 +161,208 @@ static void rdma_build_arg_xdr(struct svc_rqst *rqstp, rqstp->rq_arg.tail[0].iov_len = 0; } -/* Issue an RDMA_READ using the local lkey to map the data sink */ -int rdma_read_chunk_lcl(struct svcxprt_rdma *xprt, - struct svc_rqst *rqstp, - struct svc_rdma_op_ctxt *head, - int *page_no, - u32 *page_offset, - u32 rs_handle, - u32 rs_length, - u64 rs_offset, - bool last) -{ - struct ib_rdma_wr read_wr; - int pages_needed = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT; - struct svc_rdma_op_ctxt *ctxt = svc_rdma_get_context(xprt); - int ret, read, pno; - u32 pg_off = *page_offset; - u32 pg_no = *page_no; - - ctxt->direction = DMA_FROM_DEVICE; - ctxt->read_hdr = head; - pages_needed = min_t(int, pages_needed, xprt->sc_max_sge_rd); - read = min_t(int, (pages_needed << PAGE_SHIFT) - *page_offset, - rs_length); - - for (pno = 0; pno < pages_needed; pno++) { - int len = min_t(int, rs_length, PAGE_SIZE - pg_off); - - head->arg.pages[pg_no] = rqstp->rq_arg.pages[pg_no]; - head->arg.page_len += len; - - head->arg.len += len; - if (!pg_off) - head->count++; - rqstp->rq_respages = &rqstp->rq_arg.pages[pg_no+1]; - rqstp->rq_next_page = rqstp->rq_respages + 1; - ctxt->sge[pno].addr = - ib_dma_map_page(xprt->sc_cm_id->device, - head->arg.pages[pg_no], pg_off, - PAGE_SIZE - pg_off, - DMA_FROM_DEVICE); - ret = ib_dma_mapping_error(xprt->sc_cm_id->device, - ctxt->sge[pno].addr); - if (ret) - goto err; - svc_rdma_count_mappings(xprt, ctxt); - - ctxt->sge[pno].lkey = xprt->sc_pd->local_dma_lkey; - ctxt->sge[pno].length = len; - ctxt->count++; - - /* adjust offset and wrap to next page if needed */ - pg_off += len; - if (pg_off == PAGE_SIZE) { - pg_off = 0; - pg_no++; - } - rs_length -= len; - } - - if (last && rs_length == 0) - set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); - else - clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); - - memset(&read_wr, 0, sizeof(read_wr)); - ctxt->cqe.done = svc_rdma_wc_read; - read_wr.wr.wr_cqe = &ctxt->cqe; - read_wr.wr.opcode = IB_WR_RDMA_READ; - read_wr.wr.send_flags = IB_SEND_SIGNALED; - read_wr.rkey = rs_handle; - read_wr.remote_addr = rs_offset; - read_wr.wr.sg_list = ctxt->sge; - read_wr.wr.num_sge = pages_needed; - - ret = svc_rdma_send(xprt, &read_wr.wr); - if (ret) { - pr_err("svcrdma: Error %d posting RDMA_READ\n", ret); - set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); - goto err; - } +/* This accommodates the largest possible Write chunk, + * in one segment. + */ +#define MAX_BYTES_WRITE_SEG ((u32)(RPCSVC_MAXPAGES << PAGE_SHIFT)) - /* return current location in page array */ - *page_no = pg_no; - *page_offset = pg_off; - ret = read; - atomic_inc(&rdma_stat_read); - return ret; - err: - svc_rdma_unmap_dma(ctxt); - svc_rdma_put_context(ctxt, 0); - return ret; -} +/* This accommodates the largest possible Position-Zero + * Read chunk or Reply chunk, in one segment. + */ +#define MAX_BYTES_SPECIAL_SEG ((u32)((RPCSVC_MAXPAGES + 2) << PAGE_SHIFT)) -/* Issue an RDMA_READ using an FRMR to map the data sink */ -int rdma_read_chunk_frmr(struct svcxprt_rdma *xprt, - struct svc_rqst *rqstp, - struct svc_rdma_op_ctxt *head, - int *page_no, - u32 *page_offset, - u32 rs_handle, - u32 rs_length, - u64 rs_offset, - bool last) +/* Sanity check the Read list. + * + * Implementation limits: + * - This implementation supports only one Read chunk. + * + * Sanity checks: + * - Read list does not overflow buffer. + * - Segment size limited by largest NFS data payload. + * + * The segment count is limited to how many segments can + * fit in the transport header without overflowing the + * buffer. That's about 40 Read segments for a 1KB inline + * threshold. + * + * Returns pointer to the following Write list. + */ +static __be32 *xdr_check_read_list(__be32 *p, const __be32 *end) { - struct ib_rdma_wr read_wr; - struct ib_send_wr inv_wr; - struct ib_reg_wr reg_wr; - u8 key; - int nents = PAGE_ALIGN(*page_offset + rs_length) >> PAGE_SHIFT; - struct svc_rdma_op_ctxt *ctxt = svc_rdma_get_context(xprt); - struct svc_rdma_fastreg_mr *frmr = svc_rdma_get_frmr(xprt); - int ret, read, pno, dma_nents, n; - u32 pg_off = *page_offset; - u32 pg_no = *page_no; - - if (IS_ERR(frmr)) - return -ENOMEM; - - ctxt->direction = DMA_FROM_DEVICE; - ctxt->frmr = frmr; - nents = min_t(unsigned int, nents, xprt->sc_frmr_pg_list_len); - read = min_t(int, (nents << PAGE_SHIFT) - *page_offset, rs_length); - - frmr->direction = DMA_FROM_DEVICE; - frmr->access_flags = (IB_ACCESS_LOCAL_WRITE|IB_ACCESS_REMOTE_WRITE); - frmr->sg_nents = nents; - - for (pno = 0; pno < nents; pno++) { - int len = min_t(int, rs_length, PAGE_SIZE - pg_off); - - head->arg.pages[pg_no] = rqstp->rq_arg.pages[pg_no]; - head->arg.page_len += len; - head->arg.len += len; - if (!pg_off) - head->count++; - - sg_set_page(&frmr->sg[pno], rqstp->rq_arg.pages[pg_no], - len, pg_off); - - rqstp->rq_respages = &rqstp->rq_arg.pages[pg_no+1]; - rqstp->rq_next_page = rqstp->rq_respages + 1; - - /* adjust offset and wrap to next page if needed */ - pg_off += len; - if (pg_off == PAGE_SIZE) { - pg_off = 0; - pg_no++; + u32 position; + bool first; + + first = true; + while (*p++ != xdr_zero) { + if (first) { + position = be32_to_cpup(p++); + first = false; + } else if (be32_to_cpup(p++) != position) { + return NULL; } - rs_length -= len; - } + p++; /* handle */ + if (be32_to_cpup(p++) > MAX_BYTES_SPECIAL_SEG) + return NULL; + p += 2; /* offset */ - if (last && rs_length == 0) - set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); - else - clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags); - - dma_nents = ib_dma_map_sg(xprt->sc_cm_id->device, - frmr->sg, frmr->sg_nents, - frmr->direction); - if (!dma_nents) { - pr_err("svcrdma: failed to dma map sg %p\n", - frmr->sg); - return -ENOMEM; + if (p > end) + return NULL; } + return p; +} - n = ib_map_mr_sg(frmr->mr, frmr->sg, frmr->sg_nents, NULL, PAGE_SIZE); - if (unlikely(n != frmr->sg_nents)) { - pr_err("svcrdma: failed to map mr %p (%d/%d elements)\n", - frmr->mr, n, frmr->sg_nents); - return n < 0 ? n : -EINVAL; - } +/* The segment count is limited to how many segments can + * fit in the transport header without overflowing the + * buffer. That's about 60 Write segments for a 1KB inline + * threshold. + */ +static __be32 *xdr_check_write_chunk(__be32 *p, const __be32 *end, + u32 maxlen) +{ + u32 i, segcount; - /* Bump the key */ - key = (u8)(frmr->mr->lkey & 0x000000FF); - ib_update_fast_reg_key(frmr->mr, ++key); - - ctxt->sge[0].addr = frmr->mr->iova; - ctxt->sge[0].lkey = frmr->mr->lkey; - ctxt->sge[0].length = frmr->mr->length; - ctxt->count = 1; - ctxt->read_hdr = head; - - /* Prepare REG WR */ - ctxt->reg_cqe.done = svc_rdma_wc_reg; - reg_wr.wr.wr_cqe = &ctxt->reg_cqe; - reg_wr.wr.opcode = IB_WR_REG_MR; - reg_wr.wr.send_flags = IB_SEND_SIGNALED; - reg_wr.wr.num_sge = 0; - reg_wr.mr = frmr->mr; - reg_wr.key = frmr->mr->lkey; - reg_wr.access = frmr->access_flags; - reg_wr.wr.next = &read_wr.wr; - - /* Prepare RDMA_READ */ - memset(&read_wr, 0, sizeof(read_wr)); - ctxt->cqe.done = svc_rdma_wc_read; - read_wr.wr.wr_cqe = &ctxt->cqe; - read_wr.wr.send_flags = IB_SEND_SIGNALED; - read_wr.rkey = rs_handle; - read_wr.remote_addr = rs_offset; - read_wr.wr.sg_list = ctxt->sge; - read_wr.wr.num_sge = 1; - if (xprt->sc_dev_caps & SVCRDMA_DEVCAP_READ_W_INV) { - read_wr.wr.opcode = IB_WR_RDMA_READ_WITH_INV; - read_wr.wr.ex.invalidate_rkey = ctxt->frmr->mr->lkey; - } else { - read_wr.wr.opcode = IB_WR_RDMA_READ; - read_wr.wr.next = &inv_wr; - /* Prepare invalidate */ - memset(&inv_wr, 0, sizeof(inv_wr)); - ctxt->inv_cqe.done = svc_rdma_wc_inv; - inv_wr.wr_cqe = &ctxt->inv_cqe; - inv_wr.opcode = IB_WR_LOCAL_INV; - inv_wr.send_flags = IB_SEND_SIGNALED | IB_SEND_FENCE; - inv_wr.ex.invalidate_rkey = frmr->mr->lkey; - } + segcount = be32_to_cpup(p++); + for (i = 0; i < segcount; i++) { + p++; /* handle */ + if (be32_to_cpup(p++) > maxlen) + return NULL; + p += 2; /* offset */ - /* Post the chain */ - ret = svc_rdma_send(xprt, ®_wr.wr); - if (ret) { - pr_err("svcrdma: Error %d posting RDMA_READ\n", ret); - set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); - goto err; + if (p > end) + return NULL; } - /* return current location in page array */ - *page_no = pg_no; - *page_offset = pg_off; - ret = read; - atomic_inc(&rdma_stat_read); - return ret; - err: - svc_rdma_put_context(ctxt, 0); - svc_rdma_put_frmr(xprt, frmr); - return ret; -} - -static unsigned int -rdma_rcl_chunk_count(struct rpcrdma_read_chunk *ch) -{ - unsigned int count; - - for (count = 0; ch->rc_discrim != xdr_zero; ch++) - count++; - return count; + return p; } -/* If there was additional inline content, append it to the end of arg.pages. - * Tail copy has to be done after the reader function has determined how many - * pages are needed for RDMA READ. +/* Sanity check the Write list. + * + * Implementation limits: + * - This implementation supports only one Write chunk. + * + * Sanity checks: + * - Write list does not overflow buffer. + * - Segment size limited by largest NFS data payload. + * + * Returns pointer to the following Reply chunk. */ -static int -rdma_copy_tail(struct svc_rqst *rqstp, struct svc_rdma_op_ctxt *head, - u32 position, u32 byte_count, u32 page_offset, int page_no) +static __be32 *xdr_check_write_list(__be32 *p, const __be32 *end) { - char *srcp, *destp; - - srcp = head->arg.head[0].iov_base + position; - byte_count = head->arg.head[0].iov_len - position; - if (byte_count > PAGE_SIZE) { - dprintk("svcrdma: large tail unsupported\n"); - return 0; - } - - /* Fit as much of the tail on the current page as possible */ - if (page_offset != PAGE_SIZE) { - destp = page_address(rqstp->rq_arg.pages[page_no]); - destp += page_offset; - while (byte_count--) { - *destp++ = *srcp++; - page_offset++; - if (page_offset == PAGE_SIZE && byte_count) - goto more; - } - goto done; + u32 chcount; + + chcount = 0; + while (*p++ != xdr_zero) { + p = xdr_check_write_chunk(p, end, MAX_BYTES_WRITE_SEG); + if (!p) + return NULL; + if (chcount++ > 1) + return NULL; } - -more: - /* Fit the rest on the next page */ - page_no++; - destp = page_address(rqstp->rq_arg.pages[page_no]); - while (byte_count--) - *destp++ = *srcp++; - - rqstp->rq_respages = &rqstp->rq_arg.pages[page_no+1]; - rqstp->rq_next_page = rqstp->rq_respages + 1; - -done: - byte_count = head->arg.head[0].iov_len - position; - head->arg.page_len += byte_count; - head->arg.len += byte_count; - head->arg.buflen += byte_count; - return 1; + return p; } -/* Returns the address of the first read chunk or <nul> if no read chunk - * is present +/* Sanity check the Reply chunk. + * + * Sanity checks: + * - Reply chunk does not overflow buffer. + * - Segment size limited by largest NFS data payload. + * + * Returns pointer to the following RPC header. */ -static struct rpcrdma_read_chunk * -svc_rdma_get_read_chunk(struct rpcrdma_msg *rmsgp) +static __be32 *xdr_check_reply_chunk(__be32 *p, const __be32 *end) { - struct rpcrdma_read_chunk *ch = - (struct rpcrdma_read_chunk *)&rmsgp->rm_body.rm_chunks[0]; - - if (ch->rc_discrim == xdr_zero) - return NULL; - return ch; + if (*p++ != xdr_zero) { + p = xdr_check_write_chunk(p, end, MAX_BYTES_SPECIAL_SEG); + if (!p) + return NULL; + } + return p; } -static int rdma_read_chunks(struct svcxprt_rdma *xprt, - struct rpcrdma_msg *rmsgp, - struct svc_rqst *rqstp, - struct svc_rdma_op_ctxt *head) +/* On entry, xdr->head[0].iov_base points to first byte in the + * RPC-over-RDMA header. + * + * On successful exit, head[0] points to first byte past the + * RPC-over-RDMA header. For RDMA_MSG, this is the RPC message. + * The length of the RPC-over-RDMA header is returned. + * + * Assumptions: + * - The transport header is entirely contained in the head iovec. + */ +static int svc_rdma_xdr_decode_req(struct xdr_buf *rq_arg) { - int page_no, ret; - struct rpcrdma_read_chunk *ch; - u32 handle, page_offset, byte_count; - u32 position; - u64 rs_offset; - bool last; - - /* If no read list is present, return 0 */ - ch = svc_rdma_get_read_chunk(rmsgp); - if (!ch) - return 0; + __be32 *p, *end, *rdma_argp; + unsigned int hdr_len; + char *proc; + + /* Verify that there's enough bytes for header + something */ + if (rq_arg->len <= RPCRDMA_HDRLEN_ERR) + goto out_short; + + rdma_argp = rq_arg->head[0].iov_base; + if (*(rdma_argp + 1) != rpcrdma_version) + goto out_version; + + switch (*(rdma_argp + 3)) { + case rdma_msg: + proc = "RDMA_MSG"; + break; + case rdma_nomsg: + proc = "RDMA_NOMSG"; + break; + + case rdma_done: + goto out_drop; - if (rdma_rcl_chunk_count(ch) > RPCSVC_MAXPAGES) - return -EINVAL; - - /* The request is completed when the RDMA_READs complete. The - * head context keeps all the pages that comprise the - * request. - */ - head->arg.head[0] = rqstp->rq_arg.head[0]; - head->arg.tail[0] = rqstp->rq_arg.tail[0]; - head->hdr_count = head->count; - head->arg.page_base = 0; - head->arg.page_len = 0; - head->arg.len = rqstp->rq_arg.len; - head->arg.buflen = rqstp->rq_arg.buflen; - - /* RDMA_NOMSG: RDMA READ data should land just after RDMA RECV data */ - position = be32_to_cpu(ch->rc_position); - if (position == 0) { - head->arg.pages = &head->pages[0]; - page_offset = head->byte_len; - } else { - head->arg.pages = &head->pages[head->count]; - page_offset = 0; - } + case rdma_error: + goto out_drop; - ret = 0; - page_no = 0; - for (; ch->rc_discrim != xdr_zero; ch++) { - if (be32_to_cpu(ch->rc_position) != position) - goto err; - - handle = be32_to_cpu(ch->rc_target.rs_handle), - byte_count = be32_to_cpu(ch->rc_target.rs_length); - xdr_decode_hyper((__be32 *)&ch->rc_target.rs_offset, - &rs_offset); - - while (byte_count > 0) { - last = (ch + 1)->rc_discrim == xdr_zero; - ret = xprt->sc_reader(xprt, rqstp, head, - &page_no, &page_offset, - handle, byte_count, - rs_offset, last); - if (ret < 0) - goto err; - byte_count -= ret; - rs_offset += ret; - head->arg.buflen += ret; - } + default: + goto out_proc; } - /* Read list may need XDR round-up (see RFC 5666, s. 3.7) */ - if (page_offset & 3) { - u32 pad = 4 - (page_offset & 3); - - head->arg.tail[0].iov_len += pad; - head->arg.len += pad; - head->arg.buflen += pad; - page_offset += pad; - } + end = (__be32 *)((unsigned long)rdma_argp + rq_arg->len); + p = xdr_check_read_list(rdma_argp + 4, end); + if (!p) + goto out_inval; + p = xdr_check_write_list(p, end); + if (!p) + goto out_inval; + p = xdr_check_reply_chunk(p, end); + if (!p) + goto out_inval; + if (p > end) + goto out_inval; + + rq_arg->head[0].iov_base = p; + hdr_len = (unsigned long)p - (unsigned long)rdma_argp; + rq_arg->head[0].iov_len -= hdr_len; + rq_arg->len -= hdr_len; + dprintk("svcrdma: received %s request for XID 0x%08x, hdr_len=%u\n", + proc, be32_to_cpup(rdma_argp), hdr_len); + return hdr_len; + +out_short: + dprintk("svcrdma: header too short = %d\n", rq_arg->len); + return -EINVAL; + +out_version: + dprintk("svcrdma: bad xprt version: %u\n", + be32_to_cpup(rdma_argp + 1)); + return -EPROTONOSUPPORT; - ret = 1; - if (position && position < head->arg.head[0].iov_len) - ret = rdma_copy_tail(rqstp, head, position, - byte_count, page_offset, page_no); - head->arg.head[0].iov_len = position; - head->position = position; +out_drop: + dprintk("svcrdma: dropping RDMA_DONE/ERROR message\n"); + return 0; - err: - /* Detach arg pages. svc_recv will replenish them */ - for (page_no = 0; - &rqstp->rq_pages[page_no] < rqstp->rq_respages; page_no++) - rqstp->rq_pages[page_no] = NULL; +out_proc: + dprintk("svcrdma: bad rdma procedure (%u)\n", + be32_to_cpup(rdma_argp + 3)); + return -EINVAL; - return ret; +out_inval: + dprintk("svcrdma: failed to parse transport header\n"); + return -EINVAL; } static void rdma_read_complete(struct svc_rqst *rqstp, @@ -528,24 +376,9 @@ static void rdma_read_complete(struct svc_rqst *rqstp, rqstp->rq_pages[page_no] = head->pages[page_no]; } - /* Adjustments made for RDMA_NOMSG type requests */ - if (head->position == 0) { - if (head->arg.len <= head->sge[0].length) { - head->arg.head[0].iov_len = head->arg.len - - head->byte_len; - head->arg.page_len = 0; - } else { - head->arg.head[0].iov_len = head->sge[0].length - - head->byte_len; - head->arg.page_len = head->arg.len - - head->sge[0].length; - } - } - /* Point rq_arg.pages past header */ rqstp->rq_arg.pages = &rqstp->rq_pages[head->hdr_count]; rqstp->rq_arg.page_len = head->arg.page_len; - rqstp->rq_arg.page_base = head->arg.page_base; /* rq_respages starts after the last arg page */ rqstp->rq_respages = &rqstp->rq_pages[page_no]; @@ -642,21 +475,44 @@ static bool svc_rdma_is_backchannel_reply(struct svc_xprt *xprt, return true; } -/* - * Set up the rqstp thread context to point to the RQ buffer. If - * necessary, pull additional data from the client with an RDMA_READ - * request. +/** + * svc_rdma_recvfrom - Receive an RPC call + * @rqstp: request structure into which to receive an RPC Call + * + * Returns: + * The positive number of bytes in the RPC Call message, + * %0 if there were no Calls ready to return, + * %-EINVAL if the Read chunk data is too large, + * %-ENOMEM if rdma_rw context pool was exhausted, + * %-ENOTCONN if posting failed (connection is lost), + * %-EIO if rdma_rw initialization failed (DMA mapping, etc). + * + * Called in a loop when XPT_DATA is set. XPT_DATA is cleared only + * when there are no remaining ctxt's to process. + * + * The next ctxt is removed from the "receive" lists. + * + * - If the ctxt completes a Read, then finish assembling the Call + * message and return the number of bytes in the message. + * + * - If the ctxt completes a Receive, then construct the Call + * message from the contents of the Receive buffer. + * + * - If there are no Read chunks in this message, then finish + * assembling the Call message and return the number of bytes + * in the message. + * + * - If there are Read chunks in this message, post Read WRs to + * pull that payload and return 0. */ int svc_rdma_recvfrom(struct svc_rqst *rqstp) { struct svc_xprt *xprt = rqstp->rq_xprt; struct svcxprt_rdma *rdma_xprt = container_of(xprt, struct svcxprt_rdma, sc_xprt); - struct svc_rdma_op_ctxt *ctxt = NULL; - struct rpcrdma_msg *rmsgp; - int ret = 0; - - dprintk("svcrdma: rqstp=%p\n", rqstp); + struct svc_rdma_op_ctxt *ctxt; + __be32 *p; + int ret; spin_lock(&rdma_xprt->sc_rq_dto_lock); if (!list_empty(&rdma_xprt->sc_read_complete_q)) { @@ -671,22 +527,14 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) struct svc_rdma_op_ctxt, list); list_del(&ctxt->list); } else { - atomic_inc(&rdma_stat_rq_starve); + /* No new incoming requests, terminate the loop */ clear_bit(XPT_DATA, &xprt->xpt_flags); - ctxt = NULL; + spin_unlock(&rdma_xprt->sc_rq_dto_lock); + return 0; } spin_unlock(&rdma_xprt->sc_rq_dto_lock); - if (!ctxt) { - /* This is the EAGAIN path. The svc_recv routine will - * return -EAGAIN, the nfsd thread will go to call into - * svc_recv again and we shouldn't be on the active - * transport list - */ - if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) - goto defer; - goto out; - } - dprintk("svcrdma: processing ctxt=%p on xprt=%p, rqstp=%p\n", + + dprintk("svcrdma: recvfrom: ctxt=%p on xprt=%p, rqstp=%p\n", ctxt, rdma_xprt, rqstp); atomic_inc(&rdma_stat_recv); @@ -694,7 +542,7 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) rdma_build_arg_xdr(rqstp, ctxt, ctxt->byte_len); /* Decode the RDMA header. */ - rmsgp = (struct rpcrdma_msg *)rqstp->rq_arg.head[0].iov_base; + p = (__be32 *)rqstp->rq_arg.head[0].iov_base; ret = svc_rdma_xdr_decode_req(&rqstp->rq_arg); if (ret < 0) goto out_err; @@ -702,9 +550,8 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) goto out_drop; rqstp->rq_xprt_hlen = ret; - if (svc_rdma_is_backchannel_reply(xprt, &rmsgp->rm_xid)) { - ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, - &rmsgp->rm_xid, + if (svc_rdma_is_backchannel_reply(xprt, p)) { + ret = svc_rdma_handle_bc_reply(xprt->xpt_bc_xprt, p, &rqstp->rq_arg); svc_rdma_put_context(ctxt, 0); if (ret) @@ -712,39 +559,34 @@ int svc_rdma_recvfrom(struct svc_rqst *rqstp) return ret; } - /* Read read-list data. */ - ret = rdma_read_chunks(rdma_xprt, rmsgp, rqstp, ctxt); - if (ret > 0) { - /* read-list posted, defer until data received from client. */ - goto defer; - } else if (ret < 0) { - /* Post of read-list failed, free context. */ - svc_rdma_put_context(ctxt, 1); - return 0; - } + p += rpcrdma_fixed_maxsz; + if (*p != xdr_zero) + goto out_readchunk; complete: - ret = rqstp->rq_arg.head[0].iov_len - + rqstp->rq_arg.page_len - + rqstp->rq_arg.tail[0].iov_len; svc_rdma_put_context(ctxt, 0); - out: - dprintk("svcrdma: ret=%d, rq_arg.len=%u, " - "rq_arg.head[0].iov_base=%p, rq_arg.head[0].iov_len=%zd\n", - ret, rqstp->rq_arg.len, - rqstp->rq_arg.head[0].iov_base, - rqstp->rq_arg.head[0].iov_len); + dprintk("svcrdma: recvfrom: xprt=%p, rqstp=%p, rq_arg.len=%u\n", + rdma_xprt, rqstp, rqstp->rq_arg.len); rqstp->rq_prot = IPPROTO_MAX; svc_xprt_copy_addrs(rqstp, xprt); - return ret; + return rqstp->rq_arg.len; + +out_readchunk: + ret = svc_rdma_recv_read_chunk(rdma_xprt, rqstp, ctxt, p); + if (ret < 0) + goto out_postfail; + return 0; out_err: - svc_rdma_send_error(rdma_xprt, &rmsgp->rm_xid, ret); + svc_rdma_send_error(rdma_xprt, p, ret); svc_rdma_put_context(ctxt, 0); return 0; -defer: - return 0; +out_postfail: + if (ret == -EINVAL) + svc_rdma_send_error(rdma_xprt, p, ret); + svc_rdma_put_context(ctxt, 1); + return ret; out_drop: svc_rdma_put_context(ctxt, 1); diff --git a/net/sunrpc/xprtrdma/svc_rdma_rw.c b/net/sunrpc/xprtrdma/svc_rdma_rw.c index 0cf620277693..933f79bed270 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_rw.c +++ b/net/sunrpc/xprtrdma/svc_rdma_rw.c @@ -12,6 +12,9 @@ #define RPCDBG_FACILITY RPCDBG_SVCXPRT +static void svc_rdma_write_done(struct ib_cq *cq, struct ib_wc *wc); +static void svc_rdma_wc_read_done(struct ib_cq *cq, struct ib_wc *wc); + /* Each R/W context contains state for one chain of RDMA Read or * Write Work Requests. * @@ -113,22 +116,20 @@ struct svc_rdma_chunk_ctxt { struct svcxprt_rdma *cc_rdma; struct list_head cc_rwctxts; int cc_sqecount; - enum dma_data_direction cc_dir; }; static void svc_rdma_cc_init(struct svcxprt_rdma *rdma, - struct svc_rdma_chunk_ctxt *cc, - enum dma_data_direction dir) + struct svc_rdma_chunk_ctxt *cc) { cc->cc_rdma = rdma; svc_xprt_get(&rdma->sc_xprt); INIT_LIST_HEAD(&cc->cc_rwctxts); cc->cc_sqecount = 0; - cc->cc_dir = dir; } -static void svc_rdma_cc_release(struct svc_rdma_chunk_ctxt *cc) +static void svc_rdma_cc_release(struct svc_rdma_chunk_ctxt *cc, + enum dma_data_direction dir) { struct svcxprt_rdma *rdma = cc->cc_rdma; struct svc_rdma_rw_ctxt *ctxt; @@ -138,7 +139,7 @@ static void svc_rdma_cc_release(struct svc_rdma_chunk_ctxt *cc) rdma_rw_ctx_destroy(&ctxt->rw_ctx, rdma->sc_qp, rdma->sc_port_num, ctxt->rw_sg_table.sgl, - ctxt->rw_nents, cc->cc_dir); + ctxt->rw_nents, dir); svc_rdma_put_rw_ctxt(rdma, ctxt); } svc_xprt_put(&rdma->sc_xprt); @@ -176,13 +177,14 @@ svc_rdma_write_info_alloc(struct svcxprt_rdma *rdma, __be32 *chunk) info->wi_seg_no = 0; info->wi_nsegs = be32_to_cpup(++chunk); info->wi_segs = ++chunk; - svc_rdma_cc_init(rdma, &info->wi_cc, DMA_TO_DEVICE); + svc_rdma_cc_init(rdma, &info->wi_cc); + info->wi_cc.cc_cqe.done = svc_rdma_write_done; return info; } static void svc_rdma_write_info_free(struct svc_rdma_write_info *info) { - svc_rdma_cc_release(&info->wi_cc); + svc_rdma_cc_release(&info->wi_cc, DMA_TO_DEVICE); kfree(info); } @@ -216,6 +218,76 @@ static void svc_rdma_write_done(struct ib_cq *cq, struct ib_wc *wc) svc_rdma_write_info_free(info); } +/* State for pulling a Read chunk. + */ +struct svc_rdma_read_info { + struct svc_rdma_op_ctxt *ri_readctxt; + unsigned int ri_position; + unsigned int ri_pageno; + unsigned int ri_pageoff; + unsigned int ri_chunklen; + + struct svc_rdma_chunk_ctxt ri_cc; +}; + +static struct svc_rdma_read_info * +svc_rdma_read_info_alloc(struct svcxprt_rdma *rdma) +{ + struct svc_rdma_read_info *info; + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return info; + + svc_rdma_cc_init(rdma, &info->ri_cc); + info->ri_cc.cc_cqe.done = svc_rdma_wc_read_done; + return info; +} + +static void svc_rdma_read_info_free(struct svc_rdma_read_info *info) +{ + svc_rdma_cc_release(&info->ri_cc, DMA_FROM_DEVICE); + kfree(info); +} + +/** + * svc_rdma_wc_read_done - Handle completion of an RDMA Read ctx + * @cq: controlling Completion Queue + * @wc: Work Completion + * + */ +static void svc_rdma_wc_read_done(struct ib_cq *cq, struct ib_wc *wc) +{ + struct ib_cqe *cqe = wc->wr_cqe; + struct svc_rdma_chunk_ctxt *cc = + container_of(cqe, struct svc_rdma_chunk_ctxt, cc_cqe); + struct svcxprt_rdma *rdma = cc->cc_rdma; + struct svc_rdma_read_info *info = + container_of(cc, struct svc_rdma_read_info, ri_cc); + + atomic_add(cc->cc_sqecount, &rdma->sc_sq_avail); + wake_up(&rdma->sc_send_wait); + + if (unlikely(wc->status != IB_WC_SUCCESS)) { + set_bit(XPT_CLOSE, &rdma->sc_xprt.xpt_flags); + if (wc->status != IB_WC_WR_FLUSH_ERR) + pr_err("svcrdma: read ctx: %s (%u/0x%x)\n", + ib_wc_status_msg(wc->status), + wc->status, wc->vendor_err); + svc_rdma_put_context(info->ri_readctxt, 1); + } else { + spin_lock(&rdma->sc_rq_dto_lock); + list_add_tail(&info->ri_readctxt->list, + &rdma->sc_read_complete_q); + spin_unlock(&rdma->sc_rq_dto_lock); + + set_bit(XPT_DATA, &rdma->sc_xprt.xpt_flags); + svc_xprt_enqueue(&rdma->sc_xprt); + } + + svc_rdma_read_info_free(info); +} + /* This function sleeps when the transport's Send Queue is congested. * * Assumptions: @@ -232,6 +304,9 @@ static int svc_rdma_post_chunk_ctxt(struct svc_rdma_chunk_ctxt *cc) struct ib_cqe *cqe; int ret; + if (cc->cc_sqecount > rdma->sc_sq_depth) + return -EINVAL; + first_wr = NULL; cqe = &cc->cc_cqe; list_for_each(tmp, &cc->cc_rwctxts) { @@ -295,8 +370,9 @@ static void svc_rdma_pagelist_to_sg(struct svc_rdma_write_info *info, struct scatterlist *sg; struct page **page; - page_off = (info->wi_next_off + xdr->page_base) & ~PAGE_MASK; - page_no = (info->wi_next_off + xdr->page_base) >> PAGE_SHIFT; + page_off = info->wi_next_off + xdr->page_base; + page_no = page_off >> PAGE_SHIFT; + page_off = offset_in_page(page_off); page = xdr->pages + page_no; info->wi_next_off += remaining; sg = ctxt->rw_sg_table.sgl; @@ -332,7 +408,6 @@ svc_rdma_build_writes(struct svc_rdma_write_info *info, __be32 *seg; int ret; - cc->cc_cqe.done = svc_rdma_write_done; seg = info->wi_segs + info->wi_seg_no * rpcrdma_segment_maxsz; do { unsigned int write_len; @@ -425,6 +500,7 @@ static int svc_rdma_send_xdr_pagelist(struct svc_rdma_write_info *info, * * Returns a non-negative number of bytes the chunk consumed, or * %-E2BIG if the payload was larger than the Write chunk, + * %-EINVAL if client provided too many segments, * %-ENOMEM if rdma_rw context pool was exhausted, * %-ENOTCONN if posting failed (connection is lost), * %-EIO if rdma_rw initialization failed (DMA mapping, etc). @@ -465,6 +541,7 @@ out_err: * * Returns a non-negative number of bytes the chunk consumed, or * %-E2BIG if the payload was larger than the Reply chunk, + * %-EINVAL if client provided too many segments, * %-ENOMEM if rdma_rw context pool was exhausted, * %-ENOTCONN if posting failed (connection is lost), * %-EIO if rdma_rw initialization failed (DMA mapping, etc). @@ -510,3 +587,353 @@ out_err: svc_rdma_write_info_free(info); return ret; } + +static int svc_rdma_build_read_segment(struct svc_rdma_read_info *info, + struct svc_rqst *rqstp, + u32 rkey, u32 len, u64 offset) +{ + struct svc_rdma_op_ctxt *head = info->ri_readctxt; + struct svc_rdma_chunk_ctxt *cc = &info->ri_cc; + struct svc_rdma_rw_ctxt *ctxt; + unsigned int sge_no, seg_len; + struct scatterlist *sg; + int ret; + + sge_no = PAGE_ALIGN(info->ri_pageoff + len) >> PAGE_SHIFT; + ctxt = svc_rdma_get_rw_ctxt(cc->cc_rdma, sge_no); + if (!ctxt) + goto out_noctx; + ctxt->rw_nents = sge_no; + + dprintk("svcrdma: reading segment %u@0x%016llx:0x%08x (%u sges)\n", + len, offset, rkey, sge_no); + + sg = ctxt->rw_sg_table.sgl; + for (sge_no = 0; sge_no < ctxt->rw_nents; sge_no++) { + seg_len = min_t(unsigned int, len, + PAGE_SIZE - info->ri_pageoff); + + head->arg.pages[info->ri_pageno] = + rqstp->rq_pages[info->ri_pageno]; + if (!info->ri_pageoff) + head->count++; + + sg_set_page(sg, rqstp->rq_pages[info->ri_pageno], + seg_len, info->ri_pageoff); + sg = sg_next(sg); + + info->ri_pageoff += seg_len; + if (info->ri_pageoff == PAGE_SIZE) { + info->ri_pageno++; + info->ri_pageoff = 0; + } + len -= seg_len; + + /* Safety check */ + if (len && + &rqstp->rq_pages[info->ri_pageno + 1] > rqstp->rq_page_end) + goto out_overrun; + } + + ret = rdma_rw_ctx_init(&ctxt->rw_ctx, cc->cc_rdma->sc_qp, + cc->cc_rdma->sc_port_num, + ctxt->rw_sg_table.sgl, ctxt->rw_nents, + 0, offset, rkey, DMA_FROM_DEVICE); + if (ret < 0) + goto out_initerr; + + list_add(&ctxt->rw_list, &cc->cc_rwctxts); + cc->cc_sqecount += ret; + return 0; + +out_noctx: + dprintk("svcrdma: no R/W ctxs available\n"); + return -ENOMEM; + +out_overrun: + dprintk("svcrdma: request overruns rq_pages\n"); + return -EINVAL; + +out_initerr: + svc_rdma_put_rw_ctxt(cc->cc_rdma, ctxt); + pr_err("svcrdma: failed to map pagelist (%d)\n", ret); + return -EIO; +} + +static int svc_rdma_build_read_chunk(struct svc_rqst *rqstp, + struct svc_rdma_read_info *info, + __be32 *p) +{ + int ret; + + info->ri_chunklen = 0; + while (*p++ != xdr_zero) { + u32 rs_handle, rs_length; + u64 rs_offset; + + if (be32_to_cpup(p++) != info->ri_position) + break; + rs_handle = be32_to_cpup(p++); + rs_length = be32_to_cpup(p++); + p = xdr_decode_hyper(p, &rs_offset); + + ret = svc_rdma_build_read_segment(info, rqstp, + rs_handle, rs_length, + rs_offset); + if (ret < 0) + break; + + info->ri_chunklen += rs_length; + } + + return ret; +} + +/* If there is inline content following the Read chunk, append it to + * the page list immediately following the data payload. This has to + * be done after the reader function has determined how many pages + * were consumed for RDMA Read. + * + * On entry, ri_pageno and ri_pageoff point directly to the end of the + * page list. On exit, both have been updated to the new "next byte". + * + * Assumptions: + * - Inline content fits entirely in rq_pages[0] + * - Trailing content is only a handful of bytes + */ +static int svc_rdma_copy_tail(struct svc_rqst *rqstp, + struct svc_rdma_read_info *info) +{ + struct svc_rdma_op_ctxt *head = info->ri_readctxt; + unsigned int tail_length, remaining; + u8 *srcp, *destp; + + /* Assert that all inline content fits in page 0. This is an + * implementation limit, not a protocol limit. + */ + if (head->arg.head[0].iov_len > PAGE_SIZE) { + pr_warn_once("svcrdma: too much trailing inline content\n"); + return -EINVAL; + } + + srcp = head->arg.head[0].iov_base; + srcp += info->ri_position; + tail_length = head->arg.head[0].iov_len - info->ri_position; + remaining = tail_length; + + /* If there is room on the last page in the page list, try to + * fit the trailing content there. + */ + if (info->ri_pageoff > 0) { + unsigned int len; + + len = min_t(unsigned int, remaining, + PAGE_SIZE - info->ri_pageoff); + destp = page_address(rqstp->rq_pages[info->ri_pageno]); + destp += info->ri_pageoff; + + memcpy(destp, srcp, len); + srcp += len; + destp += len; + info->ri_pageoff += len; + remaining -= len; + + if (info->ri_pageoff == PAGE_SIZE) { + info->ri_pageno++; + info->ri_pageoff = 0; + } + } + + /* Otherwise, a fresh page is needed. */ + if (remaining) { + head->arg.pages[info->ri_pageno] = + rqstp->rq_pages[info->ri_pageno]; + head->count++; + + destp = page_address(rqstp->rq_pages[info->ri_pageno]); + memcpy(destp, srcp, remaining); + info->ri_pageoff += remaining; + } + + head->arg.page_len += tail_length; + head->arg.len += tail_length; + head->arg.buflen += tail_length; + return 0; +} + +/* Construct RDMA Reads to pull over a normal Read chunk. The chunk + * data lands in the page list of head->arg.pages. + * + * Currently NFSD does not look at the head->arg.tail[0] iovec. + * Therefore, XDR round-up of the Read chunk and trailing + * inline content must both be added at the end of the pagelist. + */ +static int svc_rdma_build_normal_read_chunk(struct svc_rqst *rqstp, + struct svc_rdma_read_info *info, + __be32 *p) +{ + struct svc_rdma_op_ctxt *head = info->ri_readctxt; + int ret; + + dprintk("svcrdma: Reading Read chunk at position %u\n", + info->ri_position); + + info->ri_pageno = head->hdr_count; + info->ri_pageoff = 0; + + ret = svc_rdma_build_read_chunk(rqstp, info, p); + if (ret < 0) + goto out; + + /* Read chunk may need XDR round-up (see RFC 5666, s. 3.7). + */ + if (info->ri_chunklen & 3) { + u32 padlen = 4 - (info->ri_chunklen & 3); + + info->ri_chunklen += padlen; + + /* NB: data payload always starts on XDR alignment, + * thus the pad can never contain a page boundary. + */ + info->ri_pageoff += padlen; + if (info->ri_pageoff == PAGE_SIZE) { + info->ri_pageno++; + info->ri_pageoff = 0; + } + } + + head->arg.page_len = info->ri_chunklen; + head->arg.len += info->ri_chunklen; + head->arg.buflen += info->ri_chunklen; + + if (info->ri_position < head->arg.head[0].iov_len) { + ret = svc_rdma_copy_tail(rqstp, info); + if (ret < 0) + goto out; + } + head->arg.head[0].iov_len = info->ri_position; + +out: + return ret; +} + +/* Construct RDMA Reads to pull over a Position Zero Read chunk. + * The start of the data lands in the first page just after + * the Transport header, and the rest lands in the page list of + * head->arg.pages. + * + * Assumptions: + * - A PZRC has an XDR-aligned length (no implicit round-up). + * - There can be no trailing inline content (IOW, we assume + * a PZRC is never sent in an RDMA_MSG message, though it's + * allowed by spec). + */ +static int svc_rdma_build_pz_read_chunk(struct svc_rqst *rqstp, + struct svc_rdma_read_info *info, + __be32 *p) +{ + struct svc_rdma_op_ctxt *head = info->ri_readctxt; + int ret; + + dprintk("svcrdma: Reading Position Zero Read chunk\n"); + + info->ri_pageno = head->hdr_count - 1; + info->ri_pageoff = offset_in_page(head->byte_len); + + ret = svc_rdma_build_read_chunk(rqstp, info, p); + if (ret < 0) + goto out; + + head->arg.len += info->ri_chunklen; + head->arg.buflen += info->ri_chunklen; + + if (head->arg.buflen <= head->sge[0].length) { + /* Transport header and RPC message fit entirely + * in page where head iovec resides. + */ + head->arg.head[0].iov_len = info->ri_chunklen; + } else { + /* Transport header and part of RPC message reside + * in the head iovec's page. + */ + head->arg.head[0].iov_len = + head->sge[0].length - head->byte_len; + head->arg.page_len = + info->ri_chunklen - head->arg.head[0].iov_len; + } + +out: + return ret; +} + +/** + * svc_rdma_recv_read_chunk - Pull a Read chunk from the client + * @rdma: controlling RDMA transport + * @rqstp: set of pages to use as Read sink buffers + * @head: pages under I/O collect here + * @p: pointer to start of Read chunk + * + * Returns: + * %0 if all needed RDMA Reads were posted successfully, + * %-EINVAL if client provided too many segments, + * %-ENOMEM if rdma_rw context pool was exhausted, + * %-ENOTCONN if posting failed (connection is lost), + * %-EIO if rdma_rw initialization failed (DMA mapping, etc). + * + * Assumptions: + * - All Read segments in @p have the same Position value. + */ +int svc_rdma_recv_read_chunk(struct svcxprt_rdma *rdma, struct svc_rqst *rqstp, + struct svc_rdma_op_ctxt *head, __be32 *p) +{ + struct svc_rdma_read_info *info; + struct page **page; + int ret; + + /* The request (with page list) is constructed in + * head->arg. Pages involved with RDMA Read I/O are + * transferred there. + */ + head->hdr_count = head->count; + head->arg.head[0] = rqstp->rq_arg.head[0]; + head->arg.tail[0] = rqstp->rq_arg.tail[0]; + head->arg.pages = head->pages; + head->arg.page_base = 0; + head->arg.page_len = 0; + head->arg.len = rqstp->rq_arg.len; + head->arg.buflen = rqstp->rq_arg.buflen; + + info = svc_rdma_read_info_alloc(rdma); + if (!info) + return -ENOMEM; + info->ri_readctxt = head; + + info->ri_position = be32_to_cpup(p + 1); + if (info->ri_position) + ret = svc_rdma_build_normal_read_chunk(rqstp, info, p); + else + ret = svc_rdma_build_pz_read_chunk(rqstp, info, p); + + /* Mark the start of the pages that can be used for the reply */ + if (info->ri_pageoff > 0) + info->ri_pageno++; + rqstp->rq_respages = &rqstp->rq_pages[info->ri_pageno]; + rqstp->rq_next_page = rqstp->rq_respages + 1; + + if (ret < 0) + goto out; + + ret = svc_rdma_post_chunk_ctxt(&info->ri_cc); + +out: + /* Read sink pages have been moved from rqstp->rq_pages to + * head->arg.pages. Force svc_recv to refill those slots + * in rq_pages. + */ + for (page = rqstp->rq_pages; page < rqstp->rq_respages; page++) + *page = NULL; + + if (ret < 0) + svc_rdma_read_info_free(info); + return ret; +} diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c index 1736337f3a55..7c3a211e0e9a 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c +++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c @@ -313,13 +313,17 @@ static int svc_rdma_dma_map_buf(struct svcxprt_rdma *rdma, dma_addr = ib_dma_map_page(dev, virt_to_page(base), offset, len, DMA_TO_DEVICE); if (ib_dma_mapping_error(dev, dma_addr)) - return -EIO; + goto out_maperr; ctxt->sge[sge_no].addr = dma_addr; ctxt->sge[sge_no].length = len; ctxt->sge[sge_no].lkey = rdma->sc_pd->local_dma_lkey; svc_rdma_count_mappings(rdma, ctxt); return 0; + +out_maperr: + pr_err("svcrdma: failed to map buffer\n"); + return -EIO; } static int svc_rdma_dma_map_page(struct svcxprt_rdma *rdma, @@ -334,13 +338,17 @@ static int svc_rdma_dma_map_page(struct svcxprt_rdma *rdma, dma_addr = ib_dma_map_page(dev, page, offset, len, DMA_TO_DEVICE); if (ib_dma_mapping_error(dev, dma_addr)) - return -EIO; + goto out_maperr; ctxt->sge[sge_no].addr = dma_addr; ctxt->sge[sge_no].length = len; ctxt->sge[sge_no].lkey = rdma->sc_pd->local_dma_lkey; svc_rdma_count_mappings(rdma, ctxt); return 0; + +out_maperr: + pr_err("svcrdma: failed to map page\n"); + return -EIO; } /** @@ -547,7 +555,6 @@ static int svc_rdma_send_reply_msg(struct svcxprt_rdma *rdma, return 0; err: - pr_err("svcrdma: failed to post Send WR (%d)\n", ret); svc_rdma_unmap_dma(ctxt); svc_rdma_put_context(ctxt, 1); return ret; @@ -677,7 +684,7 @@ int svc_rdma_sendto(struct svc_rqst *rqstp) return 0; err2: - if (ret != -E2BIG) + if (ret != -E2BIG && ret != -EINVAL) goto err1; ret = svc_rdma_post_recv(rdma, GFP_KERNEL); diff --git a/net/sunrpc/xprtrdma/svc_rdma_transport.c b/net/sunrpc/xprtrdma/svc_rdma_transport.c index a9d9cb1ba4c6..e660d4965b18 100644 --- a/net/sunrpc/xprtrdma/svc_rdma_transport.c +++ b/net/sunrpc/xprtrdma/svc_rdma_transport.c @@ -202,7 +202,6 @@ struct svc_rdma_op_ctxt *svc_rdma_get_context(struct svcxprt_rdma *xprt) out: ctxt->count = 0; ctxt->mapped_sges = 0; - ctxt->frmr = NULL; return ctxt; out_empty: @@ -226,22 +225,13 @@ void svc_rdma_unmap_dma(struct svc_rdma_op_ctxt *ctxt) { struct svcxprt_rdma *xprt = ctxt->xprt; struct ib_device *device = xprt->sc_cm_id->device; - u32 lkey = xprt->sc_pd->local_dma_lkey; unsigned int i; - for (i = 0; i < ctxt->mapped_sges; i++) { - /* - * Unmap the DMA addr in the SGE if the lkey matches - * the local_dma_lkey, otherwise, ignore it since it is - * an FRMR lkey and will be unmapped later when the - * last WR that uses it completes. - */ - if (ctxt->sge[i].lkey == lkey) - ib_dma_unmap_page(device, - ctxt->sge[i].addr, - ctxt->sge[i].length, - ctxt->direction); - } + for (i = 0; i < ctxt->mapped_sges; i++) + ib_dma_unmap_page(device, + ctxt->sge[i].addr, + ctxt->sge[i].length, + ctxt->direction); ctxt->mapped_sges = 0; } @@ -346,36 +336,6 @@ out: svc_xprt_put(&xprt->sc_xprt); } -static void svc_rdma_send_wc_common(struct svcxprt_rdma *xprt, - struct ib_wc *wc, - const char *opname) -{ - if (wc->status != IB_WC_SUCCESS) - goto err; - -out: - atomic_inc(&xprt->sc_sq_avail); - wake_up(&xprt->sc_send_wait); - return; - -err: - set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); - if (wc->status != IB_WC_WR_FLUSH_ERR) - pr_err("svcrdma: %s: %s (%u/0x%x)\n", - opname, ib_wc_status_msg(wc->status), - wc->status, wc->vendor_err); - goto out; -} - -static void svc_rdma_send_wc_common_put(struct ib_cq *cq, struct ib_wc *wc, - const char *opname) -{ - struct svcxprt_rdma *xprt = cq->cq_context; - - svc_rdma_send_wc_common(xprt, wc, opname); - svc_xprt_put(&xprt->sc_xprt); -} - /** * svc_rdma_wc_send - Invoked by RDMA provider for each polled Send WC * @cq: completion queue @@ -384,73 +344,28 @@ static void svc_rdma_send_wc_common_put(struct ib_cq *cq, struct ib_wc *wc, */ void svc_rdma_wc_send(struct ib_cq *cq, struct ib_wc *wc) { - struct ib_cqe *cqe = wc->wr_cqe; - struct svc_rdma_op_ctxt *ctxt; - - svc_rdma_send_wc_common_put(cq, wc, "send"); - - ctxt = container_of(cqe, struct svc_rdma_op_ctxt, cqe); - svc_rdma_unmap_dma(ctxt); - svc_rdma_put_context(ctxt, 1); -} - -/** - * svc_rdma_wc_reg - Invoked by RDMA provider for each polled FASTREG WC - * @cq: completion queue - * @wc: completed WR - * - */ -void svc_rdma_wc_reg(struct ib_cq *cq, struct ib_wc *wc) -{ - svc_rdma_send_wc_common_put(cq, wc, "fastreg"); -} - -/** - * svc_rdma_wc_read - Invoked by RDMA provider for each polled Read WC - * @cq: completion queue - * @wc: completed WR - * - */ -void svc_rdma_wc_read(struct ib_cq *cq, struct ib_wc *wc) -{ struct svcxprt_rdma *xprt = cq->cq_context; struct ib_cqe *cqe = wc->wr_cqe; struct svc_rdma_op_ctxt *ctxt; - svc_rdma_send_wc_common(xprt, wc, "read"); + atomic_inc(&xprt->sc_sq_avail); + wake_up(&xprt->sc_send_wait); ctxt = container_of(cqe, struct svc_rdma_op_ctxt, cqe); svc_rdma_unmap_dma(ctxt); - svc_rdma_put_frmr(xprt, ctxt->frmr); - - if (test_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags)) { - struct svc_rdma_op_ctxt *read_hdr; - - read_hdr = ctxt->read_hdr; - spin_lock(&xprt->sc_rq_dto_lock); - list_add_tail(&read_hdr->list, - &xprt->sc_read_complete_q); - spin_unlock(&xprt->sc_rq_dto_lock); + svc_rdma_put_context(ctxt, 1); - set_bit(XPT_DATA, &xprt->sc_xprt.xpt_flags); - svc_xprt_enqueue(&xprt->sc_xprt); + if (unlikely(wc->status != IB_WC_SUCCESS)) { + set_bit(XPT_CLOSE, &xprt->sc_xprt.xpt_flags); + if (wc->status != IB_WC_WR_FLUSH_ERR) + pr_err("svcrdma: Send: %s (%u/0x%x)\n", + ib_wc_status_msg(wc->status), + wc->status, wc->vendor_err); } - svc_rdma_put_context(ctxt, 0); svc_xprt_put(&xprt->sc_xprt); } -/** - * svc_rdma_wc_inv - Invoked by RDMA provider for each polled LOCAL_INV WC - * @cq: completion queue - * @wc: completed WR - * - */ -void svc_rdma_wc_inv(struct ib_cq *cq, struct ib_wc *wc) -{ - svc_rdma_send_wc_common_put(cq, wc, "localInv"); -} - static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv, int listener) { @@ -462,14 +377,12 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv, INIT_LIST_HEAD(&cma_xprt->sc_accept_q); INIT_LIST_HEAD(&cma_xprt->sc_rq_dto_q); INIT_LIST_HEAD(&cma_xprt->sc_read_complete_q); - INIT_LIST_HEAD(&cma_xprt->sc_frmr_q); INIT_LIST_HEAD(&cma_xprt->sc_ctxts); INIT_LIST_HEAD(&cma_xprt->sc_rw_ctxts); init_waitqueue_head(&cma_xprt->sc_send_wait); spin_lock_init(&cma_xprt->sc_lock); spin_lock_init(&cma_xprt->sc_rq_dto_lock); - spin_lock_init(&cma_xprt->sc_frmr_q_lock); spin_lock_init(&cma_xprt->sc_ctxt_lock); spin_lock_init(&cma_xprt->sc_rw_ctxt_lock); @@ -780,86 +693,6 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, return ERR_PTR(ret); } -static struct svc_rdma_fastreg_mr *rdma_alloc_frmr(struct svcxprt_rdma *xprt) -{ - struct ib_mr *mr; - struct scatterlist *sg; - struct svc_rdma_fastreg_mr *frmr; - u32 num_sg; - - frmr = kmalloc(sizeof(*frmr), GFP_KERNEL); - if (!frmr) - goto err; - - num_sg = min_t(u32, RPCSVC_MAXPAGES, xprt->sc_frmr_pg_list_len); - mr = ib_alloc_mr(xprt->sc_pd, IB_MR_TYPE_MEM_REG, num_sg); - if (IS_ERR(mr)) - goto err_free_frmr; - - sg = kcalloc(RPCSVC_MAXPAGES, sizeof(*sg), GFP_KERNEL); - if (!sg) - goto err_free_mr; - - sg_init_table(sg, RPCSVC_MAXPAGES); - - frmr->mr = mr; - frmr->sg = sg; - INIT_LIST_HEAD(&frmr->frmr_list); - return frmr; - - err_free_mr: - ib_dereg_mr(mr); - err_free_frmr: - kfree(frmr); - err: - return ERR_PTR(-ENOMEM); -} - -static void rdma_dealloc_frmr_q(struct svcxprt_rdma *xprt) -{ - struct svc_rdma_fastreg_mr *frmr; - - while (!list_empty(&xprt->sc_frmr_q)) { - frmr = list_entry(xprt->sc_frmr_q.next, - struct svc_rdma_fastreg_mr, frmr_list); - list_del_init(&frmr->frmr_list); - kfree(frmr->sg); - ib_dereg_mr(frmr->mr); - kfree(frmr); - } -} - -struct svc_rdma_fastreg_mr *svc_rdma_get_frmr(struct svcxprt_rdma *rdma) -{ - struct svc_rdma_fastreg_mr *frmr = NULL; - - spin_lock(&rdma->sc_frmr_q_lock); - if (!list_empty(&rdma->sc_frmr_q)) { - frmr = list_entry(rdma->sc_frmr_q.next, - struct svc_rdma_fastreg_mr, frmr_list); - list_del_init(&frmr->frmr_list); - frmr->sg_nents = 0; - } - spin_unlock(&rdma->sc_frmr_q_lock); - if (frmr) - return frmr; - - return rdma_alloc_frmr(rdma); -} - -void svc_rdma_put_frmr(struct svcxprt_rdma *rdma, - struct svc_rdma_fastreg_mr *frmr) -{ - if (frmr) { - ib_dma_unmap_sg(rdma->sc_cm_id->device, - frmr->sg, frmr->sg_nents, frmr->direction); - spin_lock(&rdma->sc_frmr_q_lock); - WARN_ON_ONCE(!list_empty(&frmr->frmr_list)); - list_add(&frmr->frmr_list, &rdma->sc_frmr_q); - spin_unlock(&rdma->sc_frmr_q_lock); - } -} - /* * This is the xpo_recvfrom function for listening endpoints. Its * purpose is to accept incoming connections. The CMA callback handler @@ -908,8 +741,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) * capabilities of this particular device */ newxprt->sc_max_sge = min((size_t)dev->attrs.max_sge, (size_t)RPCSVC_MAXPAGES); - newxprt->sc_max_sge_rd = min_t(size_t, dev->attrs.max_sge_rd, - RPCSVC_MAXPAGES); newxprt->sc_max_req_size = svcrdma_max_req_size; newxprt->sc_max_requests = min_t(u32, dev->attrs.max_qp_wr, svcrdma_max_requests); @@ -952,7 +783,7 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) memset(&qp_attr, 0, sizeof qp_attr); qp_attr.event_handler = qp_event_handler; qp_attr.qp_context = &newxprt->sc_xprt; - qp_attr.port_num = newxprt->sc_cm_id->port_num; + qp_attr.port_num = newxprt->sc_port_num; qp_attr.cap.max_rdma_ctxs = newxprt->sc_max_requests; qp_attr.cap.max_send_wr = newxprt->sc_sq_depth; qp_attr.cap.max_recv_wr = newxprt->sc_rq_depth; @@ -976,47 +807,12 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) } newxprt->sc_qp = newxprt->sc_cm_id->qp; - /* - * Use the most secure set of MR resources based on the - * transport type and available memory management features in - * the device. Here's the table implemented below: - * - * Fast Global DMA Remote WR - * Reg LKEY MR Access - * Sup'd Sup'd Needed Needed - * - * IWARP N N Y Y - * N Y Y Y - * Y N Y N - * Y Y N - - * - * IB N N Y N - * N Y N - - * Y N Y N - * Y Y N - - * - * NB: iWARP requires remote write access for the data sink - * of an RDMA_READ. IB does not. - */ - newxprt->sc_reader = rdma_read_chunk_lcl; - if (dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) { - newxprt->sc_frmr_pg_list_len = - dev->attrs.max_fast_reg_page_list_len; - newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_FAST_REG; - newxprt->sc_reader = rdma_read_chunk_frmr; - } else + if (!(dev->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS)) newxprt->sc_snd_w_inv = false; - - /* - * Determine if a DMA MR is required and if so, what privs are required - */ - if (!rdma_protocol_iwarp(dev, newxprt->sc_cm_id->port_num) && - !rdma_ib_or_roce(dev, newxprt->sc_cm_id->port_num)) + if (!rdma_protocol_iwarp(dev, newxprt->sc_port_num) && + !rdma_ib_or_roce(dev, newxprt->sc_port_num)) goto errout; - if (rdma_protocol_iwarp(dev, newxprt->sc_cm_id->port_num)) - newxprt->sc_dev_caps |= SVCRDMA_DEVCAP_READ_W_INV; - /* Post receive buffers */ for (i = 0; i < newxprt->sc_max_requests; i++) { ret = svc_rdma_post_recv(newxprt, GFP_KERNEL); @@ -1056,7 +852,6 @@ static struct svc_xprt *svc_rdma_accept(struct svc_xprt *xprt) sap = (struct sockaddr *)&newxprt->sc_cm_id->route.addr.dst_addr; dprintk(" remote address : %pIS:%u\n", sap, rpc_get_port(sap)); dprintk(" max_sge : %d\n", newxprt->sc_max_sge); - dprintk(" max_sge_rd : %d\n", newxprt->sc_max_sge_rd); dprintk(" sq_depth : %d\n", newxprt->sc_sq_depth); dprintk(" max_requests : %d\n", newxprt->sc_max_requests); dprintk(" ord : %d\n", newxprt->sc_ord); @@ -1117,12 +912,6 @@ static void __svc_rdma_free(struct work_struct *work) pr_err("svcrdma: sc_xprt still in use? (%d)\n", kref_read(&xprt->xpt_ref)); - /* - * Destroy queued, but not processed read completions. Note - * that this cleanup has to be done before destroying the - * cm_id because the device ptr is needed to unmap the dma in - * svc_rdma_put_context. - */ while (!list_empty(&rdma->sc_read_complete_q)) { struct svc_rdma_op_ctxt *ctxt; ctxt = list_first_entry(&rdma->sc_read_complete_q, @@ -1130,8 +919,6 @@ static void __svc_rdma_free(struct work_struct *work) list_del(&ctxt->list); svc_rdma_put_context(ctxt, 1); } - - /* Destroy queued, but not processed recv completions */ while (!list_empty(&rdma->sc_rq_dto_q)) { struct svc_rdma_op_ctxt *ctxt; ctxt = list_first_entry(&rdma->sc_rq_dto_q, @@ -1151,7 +938,6 @@ static void __svc_rdma_free(struct work_struct *work) xprt->xpt_bc_xprt = NULL; } - rdma_dealloc_frmr_q(rdma); svc_rdma_destroy_rw_ctxts(rdma); svc_rdma_destroy_ctxts(rdma); |