mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
More RDMA work and some op-structure constification from Chuck Lever,
and a small cleanup to our xdr encoding. -----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJZst0LAAoJECebzXlCjuG+o30QALbchoIvs7BiDrUxYMfJ2nCa 7UW69STwX79B3NZTg7RrScFTLPEFW9DMpb/Og7AYTH3/wdgGYQNM1UxGUYe7IxSN xemH7BSmQzJ7ryaxouO/jskUw5nvNRXhY0PMxJApjrCs837vTjduIVw9zUa8EDeH 9toxpTM4k3z/1myj60PuHnuQF9EyLDL6W581loDF04nQB3pVRbAZOh1lUeqMgLUd 7IF+CDECFcjL7oZSA3wDGpsVySLdZ+GYxloFIDO/d8kHEsZD3OaN2MdfRki8EOSQ qibTYO0284VeyNLUOIHjspqbDh0Lr2F7VolMmlM5GF1IuApih0/QYidqsH6/As3U JIAK53vgqZfK2qI0ud7dGGFEnT/vlE7pQiXiza36xI8YZu4Xz6uGbM41p38RU8jO 3fr38xdPqqO7YE6F7ZUHYyrmW81Vi0lFdQkw1DBEipHV8UquuCmdtAeR9xgDsdQ/ LsMVevM1mF+19krOIGbBnENq1GX78ecfHEYGxlTjf/MeO4JYl+8/x7Ow2e/ZbwSa 7hpUeCiVuVmy1hqOEtraBl5caAG0hCE8PeGRrdr5dA6ZS9YTm0ANgtxndKabwDh2 CjXF3gRnQNUGdFGCi/fmvfb89tVNj1tL52pbQqfgOb/VFrrL328vyNNg/1p2VY4Q qzmKtxZhi/XBewQjaSQl =E3UQ -----END PGP SIGNATURE----- Merge tag 'nfsd-4.14' of git://linux-nfs.org/~bfields/linux Pull nfsd updates from Bruce Fields: "More RDMA work and some op-structure constification from Chuck Lever, and a small cleanup to our xdr encoding" * tag 'nfsd-4.14' of git://linux-nfs.org/~bfields/linux: svcrdma: Estimate Send Queue depth properly rdma core: Add rdma_rw_mr_payload() svcrdma: Limit RQ depth svcrdma: Populate tail iovec when receiving nfsd: Incoming xdr_bufs may have content in tail buffer svcrdma: Clean up svc_rdma_build_read_chunk() sunrpc: Const-ify struct sv_serv_ops nfsd: Const-ify NFSv4 encoding and decoding ops arrays sunrpc: Const-ify instances of struct svc_xprt_ops nfsd4: individual encoders no longer see error cases nfsd4: skip encoder in trivial error cases nfsd4: define ->op_release for compound ops nfsd4: opdesc will be useful outside nfs4proc.c nfsd4: move some nfsd4 op definitions to xdr4.h
This commit is contained in:
commit
ad9a19d003
14 changed files with 323 additions and 401 deletions
|
|
@ -784,6 +784,14 @@ out:
|
|||
return status;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nfsd4_read_release(union nfsd4_op_u *u)
|
||||
{
|
||||
if (u->read.rd_filp)
|
||||
fput(u->read.rd_filp);
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_readdir(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
union nfsd4_op_u *u)
|
||||
|
|
@ -912,6 +920,13 @@ nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstat
|
|||
return nfs_ok;
|
||||
}
|
||||
|
||||
static void
|
||||
nfsd4_secinfo_release(union nfsd4_op_u *u)
|
||||
{
|
||||
if (u->secinfo.si_exp)
|
||||
exp_put(u->secinfo.si_exp);
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
||||
union nfsd4_op_u *u)
|
||||
|
|
@ -1335,6 +1350,12 @@ out:
|
|||
return nfserr;
|
||||
}
|
||||
|
||||
static void
|
||||
nfsd4_getdeviceinfo_release(union nfsd4_op_u *u)
|
||||
{
|
||||
kfree(u->getdeviceinfo.gd_device);
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_layoutget(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
|
||||
|
|
@ -1415,6 +1436,12 @@ out:
|
|||
return nfserr;
|
||||
}
|
||||
|
||||
static void
|
||||
nfsd4_layoutget_release(union nfsd4_op_u *u)
|
||||
{
|
||||
kfree(u->layoutget.lg_content);
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_layoutcommit(struct svc_rqst *rqstp,
|
||||
struct nfsd4_compound_state *cstate, union nfsd4_op_u *u)
|
||||
|
|
@ -1541,49 +1568,6 @@ static inline void nfsd4_increment_op_stats(u32 opnum)
|
|||
nfsdstats.nfs4_opcount[opnum]++;
|
||||
}
|
||||
|
||||
enum nfsd4_op_flags {
|
||||
ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
|
||||
ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */
|
||||
ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */
|
||||
/* For rfc 5661 section 2.6.3.1.1: */
|
||||
OP_HANDLES_WRONGSEC = 1 << 3,
|
||||
OP_IS_PUTFH_LIKE = 1 << 4,
|
||||
/*
|
||||
* These are the ops whose result size we estimate before
|
||||
* encoding, to avoid performing an op then not being able to
|
||||
* respond or cache a response. This includes writes and setattrs
|
||||
* as well as the operations usually called "nonidempotent":
|
||||
*/
|
||||
OP_MODIFIES_SOMETHING = 1 << 5,
|
||||
/*
|
||||
* Cache compounds containing these ops in the xid-based drc:
|
||||
* We use the DRC for compounds containing non-idempotent
|
||||
* operations, *except* those that are 4.1-specific (since
|
||||
* sessions provide their own EOS), and except for stateful
|
||||
* operations other than setclientid and setclientid_confirm
|
||||
* (since sequence numbers provide EOS for open, lock, etc in
|
||||
* the v4.0 case).
|
||||
*/
|
||||
OP_CACHEME = 1 << 6,
|
||||
/*
|
||||
* These are ops which clear current state id.
|
||||
*/
|
||||
OP_CLEAR_STATEID = 1 << 7,
|
||||
};
|
||||
|
||||
struct nfsd4_operation {
|
||||
__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 */
|
||||
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 const struct nfsd4_operation nfsd4_ops[];
|
||||
|
||||
static const char *nfsd4_op_name(unsigned opnum);
|
||||
|
|
@ -1621,7 +1605,7 @@ static __be32 nfs41_check_op_ordering(struct nfsd4_compoundargs *args)
|
|||
return nfs_ok;
|
||||
}
|
||||
|
||||
static inline const struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
|
||||
const struct nfsd4_operation *OPDESC(struct nfsd4_op *op)
|
||||
{
|
||||
return &nfsd4_ops[op->opnum];
|
||||
}
|
||||
|
|
@ -1694,7 +1678,6 @@ 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;
|
||||
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;
|
||||
|
|
@ -1747,15 +1730,13 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
|
|||
goto encode_op;
|
||||
}
|
||||
|
||||
opdesc = OPDESC(op);
|
||||
|
||||
if (!current_fh->fh_dentry) {
|
||||
if (!(opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
|
||||
if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
|
||||
op->status = nfserr_nofilehandle;
|
||||
goto encode_op;
|
||||
}
|
||||
} else if (current_fh->fh_export->ex_fslocs.migrated &&
|
||||
!(opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
|
||||
!(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
|
||||
op->status = nfserr_moved;
|
||||
goto encode_op;
|
||||
}
|
||||
|
|
@ -1763,12 +1744,12 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
|
|||
fh_clear_wcc(current_fh);
|
||||
|
||||
/* If op is non-idempotent */
|
||||
if (opdesc->op_flags & OP_MODIFIES_SOMETHING) {
|
||||
if (op->opdesc->op_flags & OP_MODIFIES_SOMETHING) {
|
||||
/*
|
||||
* Don't execute this op if we couldn't encode a
|
||||
* succesful reply:
|
||||
*/
|
||||
u32 plen = opdesc->op_rsize_bop(rqstp, op);
|
||||
u32 plen = op->opdesc->op_rsize_bop(rqstp, op);
|
||||
/*
|
||||
* Plus if there's another operation, make sure
|
||||
* we'll have space to at least encode an error:
|
||||
|
|
@ -1781,9 +1762,9 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
|
|||
if (op->status)
|
||||
goto encode_op;
|
||||
|
||||
if (opdesc->op_get_currentstateid)
|
||||
opdesc->op_get_currentstateid(cstate, &op->u);
|
||||
op->status = opdesc->op_func(rqstp, cstate, &op->u);
|
||||
if (op->opdesc->op_get_currentstateid)
|
||||
op->opdesc->op_get_currentstateid(cstate, &op->u);
|
||||
op->status = op->opdesc->op_func(rqstp, cstate, &op->u);
|
||||
|
||||
/* Only from SEQUENCE */
|
||||
if (cstate->status == nfserr_replay_cache) {
|
||||
|
|
@ -1792,10 +1773,10 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
|
|||
goto out;
|
||||
}
|
||||
if (!op->status) {
|
||||
if (opdesc->op_set_currentstateid)
|
||||
opdesc->op_set_currentstateid(cstate, &op->u);
|
||||
if (op->opdesc->op_set_currentstateid)
|
||||
op->opdesc->op_set_currentstateid(cstate, &op->u);
|
||||
|
||||
if (opdesc->op_flags & OP_CLEAR_STATEID)
|
||||
if (op->opdesc->op_flags & OP_CLEAR_STATEID)
|
||||
clear_current_stateid(cstate);
|
||||
|
||||
if (need_wrongsec_check(rqstp))
|
||||
|
|
@ -2160,13 +2141,15 @@ static const struct nfsd4_operation nfsd4_ops[] = {
|
|||
},
|
||||
[OP_LOCK] = {
|
||||
.op_func = nfsd4_lock,
|
||||
.op_flags = OP_MODIFIES_SOMETHING,
|
||||
.op_flags = OP_MODIFIES_SOMETHING |
|
||||
OP_NONTRIVIAL_ERROR_ENCODE,
|
||||
.op_name = "OP_LOCK",
|
||||
.op_rsize_bop = nfsd4_lock_rsize,
|
||||
.op_set_currentstateid = nfsd4_set_lockstateid,
|
||||
},
|
||||
[OP_LOCKT] = {
|
||||
.op_func = nfsd4_lockt,
|
||||
.op_flags = OP_NONTRIVIAL_ERROR_ENCODE,
|
||||
.op_name = "OP_LOCKT",
|
||||
.op_rsize_bop = nfsd4_lock_rsize,
|
||||
},
|
||||
|
|
@ -2238,6 +2221,7 @@ static const struct nfsd4_operation nfsd4_ops[] = {
|
|||
},
|
||||
[OP_READ] = {
|
||||
.op_func = nfsd4_read,
|
||||
.op_release = nfsd4_read_release,
|
||||
.op_name = "OP_READ",
|
||||
.op_rsize_bop = nfsd4_read_rsize,
|
||||
.op_get_currentstateid = nfsd4_get_readstateid,
|
||||
|
|
@ -2287,6 +2271,7 @@ static const struct nfsd4_operation nfsd4_ops[] = {
|
|||
},
|
||||
[OP_SECINFO] = {
|
||||
.op_func = nfsd4_secinfo,
|
||||
.op_release = nfsd4_secinfo_release,
|
||||
.op_flags = OP_HANDLES_WRONGSEC,
|
||||
.op_name = "OP_SECINFO",
|
||||
.op_rsize_bop = nfsd4_secinfo_rsize,
|
||||
|
|
@ -2294,14 +2279,16 @@ static const struct nfsd4_operation nfsd4_ops[] = {
|
|||
[OP_SETATTR] = {
|
||||
.op_func = nfsd4_setattr,
|
||||
.op_name = "OP_SETATTR",
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME
|
||||
| OP_NONTRIVIAL_ERROR_ENCODE,
|
||||
.op_rsize_bop = nfsd4_setattr_rsize,
|
||||
.op_get_currentstateid = nfsd4_get_setattrstateid,
|
||||
},
|
||||
[OP_SETCLIENTID] = {
|
||||
.op_func = nfsd4_setclientid,
|
||||
.op_flags = ALLOWED_WITHOUT_FH | ALLOWED_ON_ABSENT_FS
|
||||
| OP_MODIFIES_SOMETHING | OP_CACHEME,
|
||||
| OP_MODIFIES_SOMETHING | OP_CACHEME
|
||||
| OP_NONTRIVIAL_ERROR_ENCODE,
|
||||
.op_name = "OP_SETCLIENTID",
|
||||
.op_rsize_bop = nfsd4_setclientid_rsize,
|
||||
},
|
||||
|
|
@ -2388,6 +2375,7 @@ static const struct nfsd4_operation nfsd4_ops[] = {
|
|||
},
|
||||
[OP_SECINFO_NO_NAME] = {
|
||||
.op_func = nfsd4_secinfo_no_name,
|
||||
.op_release = nfsd4_secinfo_release,
|
||||
.op_flags = OP_HANDLES_WRONGSEC,
|
||||
.op_name = "OP_SECINFO_NO_NAME",
|
||||
.op_rsize_bop = nfsd4_secinfo_rsize,
|
||||
|
|
@ -2408,12 +2396,14 @@ static const struct nfsd4_operation nfsd4_ops[] = {
|
|||
#ifdef CONFIG_NFSD_PNFS
|
||||
[OP_GETDEVICEINFO] = {
|
||||
.op_func = nfsd4_getdeviceinfo,
|
||||
.op_release = nfsd4_getdeviceinfo_release,
|
||||
.op_flags = ALLOWED_WITHOUT_FH,
|
||||
.op_name = "OP_GETDEVICEINFO",
|
||||
.op_rsize_bop = nfsd4_getdeviceinfo_rsize,
|
||||
},
|
||||
[OP_LAYOUTGET] = {
|
||||
.op_func = nfsd4_layoutget,
|
||||
.op_release = nfsd4_layoutget_release,
|
||||
.op_flags = OP_MODIFIES_SOMETHING,
|
||||
.op_name = "OP_LAYOUTGET",
|
||||
.op_rsize_bop = nfsd4_layoutget_rsize,
|
||||
|
|
|
|||
|
|
@ -159,6 +159,25 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
|
|||
*/
|
||||
unsigned int avail = (char *)argp->end - (char *)argp->p;
|
||||
__be32 *p;
|
||||
|
||||
if (argp->pagelen == 0) {
|
||||
struct kvec *vec = &argp->rqstp->rq_arg.tail[0];
|
||||
|
||||
if (!argp->tail) {
|
||||
argp->tail = true;
|
||||
avail = vec->iov_len;
|
||||
argp->p = vec->iov_base;
|
||||
argp->end = vec->iov_base + avail;
|
||||
}
|
||||
|
||||
if (avail < nbytes)
|
||||
return NULL;
|
||||
|
||||
p = argp->p;
|
||||
argp->p += XDR_QUADLEN(nbytes);
|
||||
return p;
|
||||
}
|
||||
|
||||
if (avail + argp->pagelen < nbytes)
|
||||
return NULL;
|
||||
if (avail + PAGE_SIZE < nbytes) /* need more than a page !! */
|
||||
|
|
@ -1778,7 +1797,7 @@ nfsd4_decode_notsupp(struct nfsd4_compoundargs *argp, void *p)
|
|||
|
||||
typedef __be32(*nfsd4_dec)(struct nfsd4_compoundargs *argp, void *);
|
||||
|
||||
static nfsd4_dec nfsd4_dec_ops[] = {
|
||||
static const nfsd4_dec nfsd4_dec_ops[] = {
|
||||
[OP_ACCESS] = (nfsd4_dec)nfsd4_decode_access,
|
||||
[OP_CLOSE] = (nfsd4_dec)nfsd4_decode_close,
|
||||
[OP_COMMIT] = (nfsd4_dec)nfsd4_decode_commit,
|
||||
|
|
@ -1927,6 +1946,7 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
|
|||
op->opnum = OP_ILLEGAL;
|
||||
op->status = nfserr_op_illegal;
|
||||
}
|
||||
op->opdesc = OPDESC(op);
|
||||
/*
|
||||
* We'll try to cache the result in the DRC if any one
|
||||
* op in the compound wants to be cached:
|
||||
|
|
@ -3102,14 +3122,12 @@ nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, 8);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(access->ac_supported);
|
||||
*p++ = cpu_to_be32(access->ac_resp_access);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, 8);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(access->ac_supported);
|
||||
*p++ = cpu_to_be32(access->ac_resp_access);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_bind_conn_to_session *bcts)
|
||||
|
|
@ -3117,17 +3135,15 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
|
||||
NFS4_MAX_SESSIONID_LEN);
|
||||
*p++ = cpu_to_be32(bcts->dir);
|
||||
/* Upshifting from TCP to RDMA is not supported */
|
||||
*p++ = cpu_to_be32(0);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
|
||||
NFS4_MAX_SESSIONID_LEN);
|
||||
*p++ = cpu_to_be32(bcts->dir);
|
||||
/* Upshifting from TCP to RDMA is not supported */
|
||||
*p++ = cpu_to_be32(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3135,10 +3151,7 @@ nfsd4_encode_close(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_c
|
|||
{
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
|
||||
if (!nfserr)
|
||||
nfserr = nfsd4_encode_stateid(xdr, &close->cl_stateid);
|
||||
|
||||
return nfserr;
|
||||
return nfsd4_encode_stateid(xdr, &close->cl_stateid);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3148,14 +3161,12 @@ nfsd4_encode_commit(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
|
||||
p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = xdr_encode_opaque_fixed(p, commit->co_verf.data,
|
||||
NFS4_VERIFIER_SIZE);
|
||||
}
|
||||
return nfserr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3164,15 +3175,13 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, 20);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
encode_cinfo(p, &create->cr_cinfo);
|
||||
nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
|
||||
create->cr_bmval[1], create->cr_bmval[2]);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, 20);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
encode_cinfo(p, &create->cr_cinfo);
|
||||
nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
|
||||
create->cr_bmval[1], create->cr_bmval[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3181,13 +3190,8 @@ nfsd4_encode_getattr(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
|
|||
struct svc_fh *fhp = getattr->ga_fhp;
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
nfserr = nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
|
||||
getattr->ga_bmval,
|
||||
resp->rqstp, 0);
|
||||
return nfserr;
|
||||
return nfsd4_encode_fattr(xdr, fhp, fhp->fh_export, fhp->fh_dentry,
|
||||
getattr->ga_bmval, resp->rqstp, 0);
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3198,14 +3202,12 @@ nfsd4_encode_getfh(struct nfsd4_compoundres *resp, __be32 nfserr, struct svc_fh
|
|||
unsigned int len;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
len = fhp->fh_handle.fh_size;
|
||||
p = xdr_reserve_space(xdr, len + 4);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len);
|
||||
}
|
||||
return nfserr;
|
||||
len = fhp->fh_handle.fh_size;
|
||||
p = xdr_reserve_space(xdr, len + 4);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = xdr_encode_opaque(p, &fhp->fh_handle.fh_base, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3275,10 +3277,7 @@ nfsd4_encode_locku(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_l
|
|||
{
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
|
||||
if (!nfserr)
|
||||
nfserr = nfsd4_encode_stateid(xdr, &locku->lu_stateid);
|
||||
|
||||
return nfserr;
|
||||
return nfsd4_encode_stateid(xdr, &locku->lu_stateid);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3288,13 +3287,11 @@ nfsd4_encode_link(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_li
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, 20);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = encode_cinfo(p, &link->li_cinfo);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, 20);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = encode_cinfo(p, &link->li_cinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3304,12 +3301,9 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
goto out;
|
||||
|
||||
nfserr = nfsd4_encode_stateid(xdr, &open->op_stateid);
|
||||
if (nfserr)
|
||||
goto out;
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, 24);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
|
@ -3319,7 +3313,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
|
|||
nfserr = nfsd4_encode_bitmap(xdr, open->op_bmval[0], open->op_bmval[1],
|
||||
open->op_bmval[2]);
|
||||
if (nfserr)
|
||||
goto out;
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
|
|
@ -3392,8 +3386,7 @@ nfsd4_encode_open(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_op
|
|||
BUG();
|
||||
}
|
||||
/* XXX save filehandle here */
|
||||
out:
|
||||
return nfserr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3401,10 +3394,7 @@ nfsd4_encode_open_confirm(struct nfsd4_compoundres *resp, __be32 nfserr, struct
|
|||
{
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
|
||||
if (!nfserr)
|
||||
nfserr = nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
|
||||
|
||||
return nfserr;
|
||||
return nfsd4_encode_stateid(xdr, &oc->oc_resp_stateid);
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3412,10 +3402,7 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, struc
|
|||
{
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
|
||||
if (!nfserr)
|
||||
nfserr = nfsd4_encode_stateid(xdr, &od->od_stateid);
|
||||
|
||||
return nfserr;
|
||||
return nfsd4_encode_stateid(xdr, &od->od_stateid);
|
||||
}
|
||||
|
||||
static __be32 nfsd4_encode_splice_read(
|
||||
|
|
@ -3552,20 +3539,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
struct raparms *ra = NULL;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
goto out;
|
||||
|
||||
p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
|
||||
if (!p) {
|
||||
WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags));
|
||||
nfserr = nfserr_resource;
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
}
|
||||
if (resp->xdr.buf->page_len &&
|
||||
test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags)) {
|
||||
WARN_ON_ONCE(1);
|
||||
nfserr = nfserr_resource;
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
}
|
||||
xdr_commit_encode(xdr);
|
||||
|
||||
|
|
@ -3589,9 +3571,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
if (nfserr)
|
||||
xdr_truncate_encode(xdr, starting_len);
|
||||
|
||||
out:
|
||||
if (file)
|
||||
fput(file);
|
||||
return nfserr;
|
||||
}
|
||||
|
||||
|
|
@ -3605,9 +3584,6 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
|
|||
int length_offset = xdr->buf->len;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
|
@ -3651,9 +3627,6 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
|
|||
int starting_len = xdr->buf->len;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, NFS4_VERIFIER_SIZE);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
|
@ -3739,13 +3712,11 @@ nfsd4_encode_remove(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, 20);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = encode_cinfo(p, &remove->rm_cinfo);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, 20);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = encode_cinfo(p, &remove->rm_cinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3754,19 +3725,16 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, 40);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = encode_cinfo(p, &rename->rn_sinfo);
|
||||
p = encode_cinfo(p, &rename->rn_tinfo);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, 40);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
p = encode_cinfo(p, &rename->rn_sinfo);
|
||||
p = encode_cinfo(p, &rename->rn_tinfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
|
||||
__be32 nfserr, struct svc_export *exp)
|
||||
nfsd4_do_encode_secinfo(struct xdr_stream *xdr, struct svc_export *exp)
|
||||
{
|
||||
u32 i, nflavs, supported;
|
||||
struct exp_flavor_info *flavs;
|
||||
|
|
@ -3774,9 +3742,6 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
|
|||
__be32 *p, *flavorsp;
|
||||
static bool report = true;
|
||||
|
||||
if (nfserr)
|
||||
goto out;
|
||||
nfserr = nfserr_resource;
|
||||
if (exp->ex_nflavors) {
|
||||
flavs = exp->ex_flavors;
|
||||
nflavs = exp->ex_nflavors;
|
||||
|
|
@ -3800,7 +3765,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
|
|||
supported = 0;
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
flavorsp = p++; /* to be backfilled later */
|
||||
|
||||
for (i = 0; i < nflavs; i++) {
|
||||
|
|
@ -3812,7 +3777,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
|
|||
p = xdr_reserve_space(xdr, 4 + 4 +
|
||||
XDR_LEN(info.oid.len) + 4 + 4);
|
||||
if (!p)
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(RPC_AUTH_GSS);
|
||||
p = xdr_encode_opaque(p, info.oid.data, info.oid.len);
|
||||
*p++ = cpu_to_be32(info.qop);
|
||||
|
|
@ -3821,7 +3786,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
|
|||
supported++;
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(pf);
|
||||
} else {
|
||||
if (report)
|
||||
|
|
@ -3833,11 +3798,7 @@ nfsd4_do_encode_secinfo(struct xdr_stream *xdr,
|
|||
if (nflavs != supported)
|
||||
report = false;
|
||||
*flavorsp = htonl(supported);
|
||||
nfserr = 0;
|
||||
out:
|
||||
if (exp)
|
||||
exp_put(exp);
|
||||
return nfserr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3846,7 +3807,7 @@ nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
{
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
|
||||
return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->si_exp);
|
||||
return nfsd4_do_encode_secinfo(xdr, secinfo->si_exp);
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3855,7 +3816,7 @@ nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
{
|
||||
struct xdr_stream *xdr = &resp->xdr;
|
||||
|
||||
return nfsd4_do_encode_secinfo(xdr, nfserr, secinfo->sin_exp);
|
||||
return nfsd4_do_encode_secinfo(xdr, secinfo->sin_exp);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -3916,16 +3877,14 @@ nfsd4_encode_write(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_w
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
p = xdr_reserve_space(xdr, 16);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(write->wr_bytes_written);
|
||||
*p++ = cpu_to_be32(write->wr_how_written);
|
||||
p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
|
||||
NFS4_VERIFIER_SIZE);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(xdr, 16);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(write->wr_bytes_written);
|
||||
*p++ = cpu_to_be32(write->wr_how_written);
|
||||
p = xdr_encode_opaque_fixed(p, write->wr_verifier.data,
|
||||
NFS4_VERIFIER_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -3938,12 +3897,8 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
char *server_scope;
|
||||
int major_id_sz;
|
||||
int server_scope_sz;
|
||||
int status = 0;
|
||||
uint64_t minor_id = 0;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
major_id = utsname()->nodename;
|
||||
major_id_sz = strlen(major_id);
|
||||
server_scope = utsname()->nodename;
|
||||
|
|
@ -3968,19 +3923,19 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
break;
|
||||
case SP4_MACH_CRED:
|
||||
/* spo_must_enforce bitmap: */
|
||||
status = nfsd4_encode_bitmap(xdr,
|
||||
nfserr = nfsd4_encode_bitmap(xdr,
|
||||
exid->spo_must_enforce[0],
|
||||
exid->spo_must_enforce[1],
|
||||
exid->spo_must_enforce[2]);
|
||||
if (status)
|
||||
goto out;
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
/* spo_must_allow bitmap: */
|
||||
status = nfsd4_encode_bitmap(xdr,
|
||||
nfserr = nfsd4_encode_bitmap(xdr,
|
||||
exid->spo_must_allow[0],
|
||||
exid->spo_must_allow[1],
|
||||
exid->spo_must_allow[2]);
|
||||
if (status)
|
||||
goto out;
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
break;
|
||||
default:
|
||||
WARN_ON_ONCE(1);
|
||||
|
|
@ -4007,8 +3962,6 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
/* Implementation id */
|
||||
*p++ = cpu_to_be32(0); /* zero length nfs_impl_id4 array */
|
||||
return 0;
|
||||
out:
|
||||
return status;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -4018,9 +3971,6 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, 24);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
|
@ -4074,9 +4024,6 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
|
@ -4101,9 +4048,6 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
struct nfsd4_test_stateid_id *stateid, *next;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, 4 + (4 * test_stateid->ts_num_ids));
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
|
@ -4113,7 +4057,7 @@ nfsd4_encode_test_stateid(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
*p++ = stateid->ts_id_status;
|
||||
}
|
||||
|
||||
return nfserr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NFSD_PNFS
|
||||
|
|
@ -4126,14 +4070,9 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
u32 starting_len = xdr->buf->len, needed_len;
|
||||
__be32 *p;
|
||||
|
||||
dprintk("%s: err %d\n", __func__, be32_to_cpu(nfserr));
|
||||
if (nfserr)
|
||||
goto out;
|
||||
|
||||
nfserr = nfserr_resource;
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
|
||||
*p++ = cpu_to_be32(gdev->gd_layout_type);
|
||||
|
||||
|
|
@ -4149,42 +4088,33 @@ nfsd4_encode_getdeviceinfo(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
*/
|
||||
if (xdr->buf->len + 4 > gdev->gd_maxcount)
|
||||
goto toosmall;
|
||||
goto out;
|
||||
return nfserr;
|
||||
}
|
||||
}
|
||||
|
||||
nfserr = nfserr_resource;
|
||||
if (gdev->gd_notify_types) {
|
||||
p = xdr_reserve_space(xdr, 4 + 4);
|
||||
if (!p)
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(1); /* bitmap length */
|
||||
*p++ = cpu_to_be32(gdev->gd_notify_types);
|
||||
} else {
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
*p++ = 0;
|
||||
}
|
||||
|
||||
nfserr = 0;
|
||||
out:
|
||||
kfree(gdev->gd_device);
|
||||
dprintk("%s: done: %d\n", __func__, be32_to_cpu(nfserr));
|
||||
return nfserr;
|
||||
|
||||
return 0;
|
||||
toosmall:
|
||||
dprintk("%s: maxcount too small\n", __func__);
|
||||
needed_len = xdr->buf->len + 4 /* notifications */;
|
||||
xdr_truncate_encode(xdr, starting_len);
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p) {
|
||||
nfserr = nfserr_resource;
|
||||
} else {
|
||||
*p++ = cpu_to_be32(needed_len);
|
||||
nfserr = nfserr_toosmall;
|
||||
}
|
||||
goto out;
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(needed_len);
|
||||
return nfserr_toosmall;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -4195,14 +4125,9 @@ nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
const struct nfsd4_layout_ops *ops;
|
||||
__be32 *p;
|
||||
|
||||
dprintk("%s: err %d\n", __func__, nfserr);
|
||||
if (nfserr)
|
||||
goto out;
|
||||
|
||||
nfserr = nfserr_resource;
|
||||
p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t));
|
||||
if (!p)
|
||||
goto out;
|
||||
return nfserr_resource;
|
||||
|
||||
*p++ = cpu_to_be32(1); /* we always set return-on-close */
|
||||
*p++ = cpu_to_be32(lgp->lg_sid.si_generation);
|
||||
|
|
@ -4216,10 +4141,7 @@ nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
*p++ = cpu_to_be32(lgp->lg_layout_type);
|
||||
|
||||
ops = nfsd4_layout_ops[lgp->lg_layout_type];
|
||||
nfserr = ops->encode_layoutget(xdr, lgp);
|
||||
out:
|
||||
kfree(lgp->lg_content);
|
||||
return nfserr;
|
||||
return ops->encode_layoutget(xdr, lgp);
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -4229,9 +4151,6 @@ nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
|
|
@ -4243,7 +4162,7 @@ nfsd4_encode_layoutcommit(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
p = xdr_encode_hyper(p, lcp->lc_newsize);
|
||||
}
|
||||
|
||||
return nfs_ok;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -4253,16 +4172,13 @@ nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(xdr, 4);
|
||||
if (!p)
|
||||
return nfserr_resource;
|
||||
*p++ = cpu_to_be32(lrp->lrs_present);
|
||||
if (lrp->lrs_present)
|
||||
return nfsd4_encode_stateid(xdr, &lrp->lr_sid);
|
||||
return nfs_ok;
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_NFSD_PNFS */
|
||||
|
||||
|
|
@ -4289,16 +4205,14 @@ nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
{
|
||||
__be32 *p;
|
||||
|
||||
if (!nfserr) {
|
||||
nfserr = nfsd42_encode_write_res(resp, ©->cp_res);
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
nfserr = nfsd42_encode_write_res(resp, ©->cp_res);
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(&resp->xdr, 4 + 4);
|
||||
*p++ = cpu_to_be32(copy->cp_consecutive);
|
||||
*p++ = cpu_to_be32(copy->cp_synchronous);
|
||||
}
|
||||
return nfserr;
|
||||
p = xdr_reserve_space(&resp->xdr, 4 + 4);
|
||||
*p++ = cpu_to_be32(copy->cp_consecutive);
|
||||
*p++ = cpu_to_be32(copy->cp_synchronous);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -4307,14 +4221,11 @@ nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
|
|||
{
|
||||
__be32 *p;
|
||||
|
||||
if (nfserr)
|
||||
return nfserr;
|
||||
|
||||
p = xdr_reserve_space(&resp->xdr, 4 + 8);
|
||||
*p++ = cpu_to_be32(seek->seek_eof);
|
||||
p = xdr_encode_hyper(p, seek->seek_pos);
|
||||
|
||||
return nfserr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static __be32
|
||||
|
|
@ -4330,7 +4241,7 @@ typedef __be32(* nfsd4_enc)(struct nfsd4_compoundres *, __be32, void *);
|
|||
* since we don't need to filter out obsolete ops as this is
|
||||
* done in the decoding phase.
|
||||
*/
|
||||
static nfsd4_enc nfsd4_enc_ops[] = {
|
||||
static const nfsd4_enc nfsd4_enc_ops[] = {
|
||||
[OP_ACCESS] = (nfsd4_enc)nfsd4_encode_access,
|
||||
[OP_CLOSE] = (nfsd4_enc)nfsd4_encode_close,
|
||||
[OP_COMMIT] = (nfsd4_enc)nfsd4_encode_commit,
|
||||
|
|
@ -4449,6 +4360,7 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
|
|||
struct xdr_stream *xdr = &resp->xdr;
|
||||
struct nfs4_stateowner *so = resp->cstate.replay_owner;
|
||||
struct svc_rqst *rqstp = resp->rqstp;
|
||||
const struct nfsd4_operation *opdesc = op->opdesc;
|
||||
int post_err_offset;
|
||||
nfsd4_enc encoder;
|
||||
__be32 *p;
|
||||
|
|
@ -4463,10 +4375,15 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
|
|||
|
||||
if (op->opnum == OP_ILLEGAL)
|
||||
goto status;
|
||||
if (op->status && opdesc &&
|
||||
!(opdesc->op_flags & OP_NONTRIVIAL_ERROR_ENCODE))
|
||||
goto status;
|
||||
BUG_ON(op->opnum < 0 || op->opnum >= ARRAY_SIZE(nfsd4_enc_ops) ||
|
||||
!nfsd4_enc_ops[op->opnum]);
|
||||
encoder = nfsd4_enc_ops[op->opnum];
|
||||
op->status = encoder(resp, op->status, &op->u);
|
||||
if (opdesc && opdesc->op_release)
|
||||
opdesc->op_release(&op->u);
|
||||
xdr_commit_encode(xdr);
|
||||
|
||||
/* nfsd4_check_resp_size guarantees enough room for error status */
|
||||
|
|
@ -4573,6 +4490,7 @@ nfs4svc_decode_compoundargs(struct svc_rqst *rqstp, __be32 *p)
|
|||
args->end = rqstp->rq_arg.head[0].iov_base + rqstp->rq_arg.head[0].iov_len;
|
||||
args->pagelist = rqstp->rq_arg.pages;
|
||||
args->pagelen = rqstp->rq_arg.page_len;
|
||||
args->tail = false;
|
||||
args->tmpp = NULL;
|
||||
args->to_free = NULL;
|
||||
args->ops = args->iops;
|
||||
|
|
|
|||
|
|
@ -475,7 +475,7 @@ static int nfsd_get_default_max_blksize(void)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct svc_serv_ops nfsd_thread_sv_ops = {
|
||||
static const struct svc_serv_ops nfsd_thread_sv_ops = {
|
||||
.svo_shutdown = nfsd_last_thread,
|
||||
.svo_function = nfsd,
|
||||
.svo_enqueue_xprt = svc_xprt_do_enqueue,
|
||||
|
|
|
|||
|
|
@ -538,6 +538,7 @@ struct nfsd4_seek {
|
|||
|
||||
struct nfsd4_op {
|
||||
int opnum;
|
||||
const struct nfsd4_operation * opdesc;
|
||||
__be32 status;
|
||||
union nfsd4_op_u {
|
||||
struct nfsd4_access access;
|
||||
|
|
@ -614,6 +615,7 @@ struct nfsd4_compoundargs {
|
|||
__be32 * end;
|
||||
struct page ** pagelist;
|
||||
int pagelen;
|
||||
bool tail;
|
||||
__be32 tmp[8];
|
||||
__be32 * tmpp;
|
||||
struct svcxdr_tmpbuf *to_free;
|
||||
|
|
@ -661,6 +663,7 @@ static inline bool nfsd4_last_compound_op(struct svc_rqst *rqstp)
|
|||
return argp->opcnt == resp->opcnt;
|
||||
}
|
||||
|
||||
const struct nfsd4_operation *OPDESC(struct nfsd4_op *op);
|
||||
int nfsd4_max_reply(struct svc_rqst *rqstp, struct nfsd4_op *op);
|
||||
void warn_on_nonidempotent_op(struct nfsd4_op *op);
|
||||
|
||||
|
|
@ -748,6 +751,53 @@ extern __be32 nfsd4_free_stateid(struct svc_rqst *rqstp,
|
|||
struct nfsd4_compound_state *, union nfsd4_op_u *);
|
||||
extern void nfsd4_bump_seqid(struct nfsd4_compound_state *, __be32 nfserr);
|
||||
|
||||
enum nfsd4_op_flags {
|
||||
ALLOWED_WITHOUT_FH = 1 << 0, /* No current filehandle required */
|
||||
ALLOWED_ON_ABSENT_FS = 1 << 1, /* ops processed on absent fs */
|
||||
ALLOWED_AS_FIRST_OP = 1 << 2, /* ops reqired first in compound */
|
||||
/* For rfc 5661 section 2.6.3.1.1: */
|
||||
OP_HANDLES_WRONGSEC = 1 << 3,
|
||||
OP_IS_PUTFH_LIKE = 1 << 4,
|
||||
/*
|
||||
* These are the ops whose result size we estimate before
|
||||
* encoding, to avoid performing an op then not being able to
|
||||
* respond or cache a response. This includes writes and setattrs
|
||||
* as well as the operations usually called "nonidempotent":
|
||||
*/
|
||||
OP_MODIFIES_SOMETHING = 1 << 5,
|
||||
/*
|
||||
* Cache compounds containing these ops in the xid-based drc:
|
||||
* We use the DRC for compounds containing non-idempotent
|
||||
* operations, *except* those that are 4.1-specific (since
|
||||
* sessions provide their own EOS), and except for stateful
|
||||
* operations other than setclientid and setclientid_confirm
|
||||
* (since sequence numbers provide EOS for open, lock, etc in
|
||||
* the v4.0 case).
|
||||
*/
|
||||
OP_CACHEME = 1 << 6,
|
||||
/*
|
||||
* These are ops which clear current state id.
|
||||
*/
|
||||
OP_CLEAR_STATEID = 1 << 7,
|
||||
/* Most ops return only an error on failure; some may do more: */
|
||||
OP_NONTRIVIAL_ERROR_ENCODE = 1 << 8,
|
||||
};
|
||||
|
||||
struct nfsd4_operation {
|
||||
__be32 (*op_func)(struct svc_rqst *, struct nfsd4_compound_state *,
|
||||
union nfsd4_op_u *);
|
||||
void (*op_release)(union nfsd4_op_u *);
|
||||
u32 op_flags;
|
||||
char *op_name;
|
||||
/* Try to get response size before operation */
|
||||
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 *);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue