NFSD: Move copy offload callback arguments into a separate structure
Refactor so that CB_OFFLOAD arguments can be passed without allocating a whole struct nfsd4_copy object. On my system (x86_64) this removes another 96 bytes from struct nfsd4_copy. Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
e72f9bc006
commit
a11ada99ce
@ -679,7 +679,7 @@ static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp,
|
|||||||
* case NFS4_OK:
|
* case NFS4_OK:
|
||||||
* write_response4 coa_resok4;
|
* write_response4 coa_resok4;
|
||||||
* default:
|
* default:
|
||||||
* length4 coa_bytes_copied;
|
* length4 coa_bytes_copied;
|
||||||
* };
|
* };
|
||||||
* struct CB_OFFLOAD4args {
|
* struct CB_OFFLOAD4args {
|
||||||
* nfs_fh4 coa_fh;
|
* nfs_fh4 coa_fh;
|
||||||
@ -688,21 +688,22 @@ static int nfs4_xdr_dec_cb_notify_lock(struct rpc_rqst *rqstp,
|
|||||||
* };
|
* };
|
||||||
*/
|
*/
|
||||||
static void encode_offload_info4(struct xdr_stream *xdr,
|
static void encode_offload_info4(struct xdr_stream *xdr,
|
||||||
__be32 nfserr,
|
const struct nfsd4_cb_offload *cbo)
|
||||||
const struct nfsd4_copy *cp)
|
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
|
|
||||||
p = xdr_reserve_space(xdr, 4);
|
p = xdr_reserve_space(xdr, 4);
|
||||||
*p++ = nfserr;
|
*p = cbo->co_nfserr;
|
||||||
if (!nfserr) {
|
switch (cbo->co_nfserr) {
|
||||||
|
case nfs_ok:
|
||||||
p = xdr_reserve_space(xdr, 4 + 8 + 4 + NFS4_VERIFIER_SIZE);
|
p = xdr_reserve_space(xdr, 4 + 8 + 4 + NFS4_VERIFIER_SIZE);
|
||||||
p = xdr_encode_empty_array(p);
|
p = xdr_encode_empty_array(p);
|
||||||
p = xdr_encode_hyper(p, cp->cp_res.wr_bytes_written);
|
p = xdr_encode_hyper(p, cbo->co_res.wr_bytes_written);
|
||||||
*p++ = cpu_to_be32(cp->cp_res.wr_stable_how);
|
*p++ = cpu_to_be32(cbo->co_res.wr_stable_how);
|
||||||
p = xdr_encode_opaque_fixed(p, cp->cp_res.wr_verifier.data,
|
p = xdr_encode_opaque_fixed(p, cbo->co_res.wr_verifier.data,
|
||||||
NFS4_VERIFIER_SIZE);
|
NFS4_VERIFIER_SIZE);
|
||||||
} else {
|
break;
|
||||||
|
default:
|
||||||
p = xdr_reserve_space(xdr, 8);
|
p = xdr_reserve_space(xdr, 8);
|
||||||
/* We always return success if bytes were written */
|
/* We always return success if bytes were written */
|
||||||
p = xdr_encode_hyper(p, 0);
|
p = xdr_encode_hyper(p, 0);
|
||||||
@ -710,18 +711,16 @@ static void encode_offload_info4(struct xdr_stream *xdr,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void encode_cb_offload4args(struct xdr_stream *xdr,
|
static void encode_cb_offload4args(struct xdr_stream *xdr,
|
||||||
__be32 nfserr,
|
const struct nfsd4_cb_offload *cbo,
|
||||||
const struct knfsd_fh *fh,
|
|
||||||
const struct nfsd4_copy *cp,
|
|
||||||
struct nfs4_cb_compound_hdr *hdr)
|
struct nfs4_cb_compound_hdr *hdr)
|
||||||
{
|
{
|
||||||
__be32 *p;
|
__be32 *p;
|
||||||
|
|
||||||
p = xdr_reserve_space(xdr, 4);
|
p = xdr_reserve_space(xdr, 4);
|
||||||
*p++ = cpu_to_be32(OP_CB_OFFLOAD);
|
*p = cpu_to_be32(OP_CB_OFFLOAD);
|
||||||
encode_nfs_fh4(xdr, fh);
|
encode_nfs_fh4(xdr, &cbo->co_fh);
|
||||||
encode_stateid4(xdr, &cp->cp_res.cb_stateid);
|
encode_stateid4(xdr, &cbo->co_res.cb_stateid);
|
||||||
encode_offload_info4(xdr, nfserr, cp);
|
encode_offload_info4(xdr, cbo);
|
||||||
|
|
||||||
hdr->nops++;
|
hdr->nops++;
|
||||||
}
|
}
|
||||||
@ -731,8 +730,8 @@ static void nfs4_xdr_enc_cb_offload(struct rpc_rqst *req,
|
|||||||
const void *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
const struct nfsd4_callback *cb = data;
|
const struct nfsd4_callback *cb = data;
|
||||||
const struct nfsd4_copy *cp =
|
const struct nfsd4_cb_offload *cbo =
|
||||||
container_of(cb, struct nfsd4_copy, cp_cb);
|
container_of(cb, struct nfsd4_cb_offload, co_cb);
|
||||||
struct nfs4_cb_compound_hdr hdr = {
|
struct nfs4_cb_compound_hdr hdr = {
|
||||||
.ident = 0,
|
.ident = 0,
|
||||||
.minorversion = cb->cb_clp->cl_minorversion,
|
.minorversion = cb->cb_clp->cl_minorversion,
|
||||||
@ -740,7 +739,7 @@ static void nfs4_xdr_enc_cb_offload(struct rpc_rqst *req,
|
|||||||
|
|
||||||
encode_cb_compound4args(xdr, &hdr);
|
encode_cb_compound4args(xdr, &hdr);
|
||||||
encode_cb_sequence4args(xdr, cb, &hdr);
|
encode_cb_sequence4args(xdr, cb, &hdr);
|
||||||
encode_cb_offload4args(xdr, cp->nfserr, &cp->fh, cp, &hdr);
|
encode_cb_offload4args(xdr, cbo, &hdr);
|
||||||
encode_cb_nops(&hdr);
|
encode_cb_nops(&hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1645,9 +1645,10 @@ nfsd4_cleanup_intra_ssc(struct nfsd_file *src, struct nfsd_file *dst)
|
|||||||
|
|
||||||
static void nfsd4_cb_offload_release(struct nfsd4_callback *cb)
|
static void nfsd4_cb_offload_release(struct nfsd4_callback *cb)
|
||||||
{
|
{
|
||||||
struct nfsd4_copy *copy = container_of(cb, struct nfsd4_copy, cp_cb);
|
struct nfsd4_cb_offload *cbo =
|
||||||
|
container_of(cb, struct nfsd4_cb_offload, co_cb);
|
||||||
|
|
||||||
nfs4_put_copy(copy);
|
kfree(cbo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfsd4_cb_offload_done(struct nfsd4_callback *cb,
|
static int nfsd4_cb_offload_done(struct nfsd4_callback *cb,
|
||||||
@ -1763,25 +1764,23 @@ static void cleanup_async_copy(struct nfsd4_copy *copy)
|
|||||||
nfs4_put_copy(copy);
|
nfs4_put_copy(copy);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nfsd4_send_cb_offload(struct nfsd4_copy *copy)
|
static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr)
|
||||||
{
|
{
|
||||||
struct nfsd4_copy *cb_copy;
|
struct nfsd4_cb_offload *cbo;
|
||||||
|
|
||||||
cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL);
|
cbo = kzalloc(sizeof(*cbo), GFP_KERNEL);
|
||||||
if (!cb_copy)
|
if (!cbo)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
refcount_set(&cb_copy->refcount, 1);
|
memcpy(&cbo->co_res, ©->cp_res, sizeof(copy->cp_res));
|
||||||
memcpy(&cb_copy->cp_res, ©->cp_res, sizeof(copy->cp_res));
|
memcpy(&cbo->co_fh, ©->fh, sizeof(copy->fh));
|
||||||
cb_copy->cp_clp = copy->cp_clp;
|
cbo->co_nfserr = nfserr;
|
||||||
cb_copy->nfserr = copy->nfserr;
|
|
||||||
memcpy(&cb_copy->fh, ©->fh, sizeof(copy->fh));
|
|
||||||
|
|
||||||
nfsd4_init_cb(&cb_copy->cp_cb, cb_copy->cp_clp,
|
nfsd4_init_cb(&cbo->co_cb, copy->cp_clp, &nfsd4_cb_offload_ops,
|
||||||
&nfsd4_cb_offload_ops, NFSPROC4_CLNT_CB_OFFLOAD);
|
NFSPROC4_CLNT_CB_OFFLOAD);
|
||||||
trace_nfsd_cb_offload(copy->cp_clp, ©->cp_res.cb_stateid,
|
trace_nfsd_cb_offload(copy->cp_clp, &cbo->co_res.cb_stateid,
|
||||||
©->fh, copy->cp_count, copy->nfserr);
|
&cbo->co_fh, copy->cp_count, nfserr);
|
||||||
nfsd4_run_cb(&cb_copy->cp_cb);
|
nfsd4_run_cb(&cbo->co_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1794,6 +1793,7 @@ static void nfsd4_send_cb_offload(struct nfsd4_copy *copy)
|
|||||||
static int nfsd4_do_async_copy(void *data)
|
static int nfsd4_do_async_copy(void *data)
|
||||||
{
|
{
|
||||||
struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
|
struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
|
||||||
|
__be32 nfserr;
|
||||||
|
|
||||||
if (nfsd4_ssc_is_inter(copy)) {
|
if (nfsd4_ssc_is_inter(copy)) {
|
||||||
struct file *filp;
|
struct file *filp;
|
||||||
@ -1801,21 +1801,21 @@ static int nfsd4_do_async_copy(void *data)
|
|||||||
filp = nfs42_ssc_open(copy->ss_mnt, ©->c_fh,
|
filp = nfs42_ssc_open(copy->ss_mnt, ©->c_fh,
|
||||||
©->stateid);
|
©->stateid);
|
||||||
if (IS_ERR(filp)) {
|
if (IS_ERR(filp)) {
|
||||||
copy->nfserr = nfserr_offload_denied;
|
nfserr = nfserr_offload_denied;
|
||||||
nfsd4_interssc_disconnect(copy->ss_mnt);
|
nfsd4_interssc_disconnect(copy->ss_mnt);
|
||||||
goto do_callback;
|
goto do_callback;
|
||||||
}
|
}
|
||||||
copy->nfserr = nfsd4_do_copy(copy, filp,
|
nfserr = nfsd4_do_copy(copy, filp, copy->nf_dst->nf_file,
|
||||||
copy->nf_dst->nf_file, false);
|
false);
|
||||||
nfsd4_cleanup_inter_ssc(copy->ss_mnt, filp, copy->nf_dst);
|
nfsd4_cleanup_inter_ssc(copy->ss_mnt, filp, copy->nf_dst);
|
||||||
} else {
|
} else {
|
||||||
copy->nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,
|
nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,
|
||||||
copy->nf_dst->nf_file, false);
|
copy->nf_dst->nf_file, false);
|
||||||
nfsd4_cleanup_intra_ssc(copy->nf_src, copy->nf_dst);
|
nfsd4_cleanup_intra_ssc(copy->nf_src, copy->nf_dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
do_callback:
|
do_callback:
|
||||||
nfsd4_send_cb_offload(copy);
|
nfsd4_send_cb_offload(copy, nfserr);
|
||||||
cleanup_async_copy(copy);
|
cleanup_async_copy(copy);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -533,6 +533,13 @@ struct nfsd42_write_res {
|
|||||||
stateid_t cb_stateid;
|
stateid_t cb_stateid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct nfsd4_cb_offload {
|
||||||
|
struct nfsd4_callback co_cb;
|
||||||
|
struct nfsd42_write_res co_res;
|
||||||
|
__be32 co_nfserr;
|
||||||
|
struct knfsd_fh co_fh;
|
||||||
|
};
|
||||||
|
|
||||||
struct nfsd4_copy {
|
struct nfsd4_copy {
|
||||||
/* request */
|
/* request */
|
||||||
stateid_t cp_src_stateid;
|
stateid_t cp_src_stateid;
|
||||||
@ -550,10 +557,6 @@ struct nfsd4_copy {
|
|||||||
|
|
||||||
/* response */
|
/* response */
|
||||||
struct nfsd42_write_res cp_res;
|
struct nfsd42_write_res cp_res;
|
||||||
|
|
||||||
/* for cb_offload */
|
|
||||||
struct nfsd4_callback cp_cb;
|
|
||||||
__be32 nfserr;
|
|
||||||
struct knfsd_fh fh;
|
struct knfsd_fh fh;
|
||||||
|
|
||||||
struct nfs4_client *cp_clp;
|
struct nfs4_client *cp_clp;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user