Skip to content

Commit

Permalink
NFSv4: Add encode/decode of the layoutreturn op in CLOSE
Browse files Browse the repository at this point in the history
Add XDR encoding for the layoutreturn op, and storage for the layoutreturn
arguments to the CLOSE compound.

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
  • Loading branch information
Trond Myklebust committed Dec 1, 2016
1 parent d8434d4 commit cf80516
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 9 deletions.
49 changes: 40 additions & 9 deletions fs/nfs/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -3035,10 +3035,14 @@ struct nfs4_closedata {
struct nfs4_state *state;
struct nfs_closeargs arg;
struct nfs_closeres res;
struct {
struct nfs4_layoutreturn_args arg;
struct nfs4_layoutreturn_res res;
u32 roc_barrier;
bool roc;
} lr;
struct nfs_fattr fattr;
unsigned long timestamp;
bool roc;
u32 roc_barrier;
};

static void nfs4_free_closedata(void *data)
Expand All @@ -3047,7 +3051,7 @@ static void nfs4_free_closedata(void *data)
struct nfs4_state_owner *sp = calldata->state->owner;
struct super_block *sb = calldata->state->inode->i_sb;

if (calldata->roc)
if (calldata->lr.roc)
pnfs_roc_release(calldata->state->inode);
nfs4_put_open_state(calldata->state);
nfs_free_seqid(calldata->arg.seqid);
Expand All @@ -3067,15 +3071,41 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
if (!nfs4_sequence_done(task, &calldata->res.seq_res))
return;
trace_nfs4_close(state, &calldata->arg, &calldata->res, task->tk_status);

/* Handle Layoutreturn errors */
if (calldata->arg.lr_args && task->tk_status != 0) {
switch (calldata->res.lr_ret) {
default:
calldata->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
break;
case 0:
calldata->arg.lr_args = NULL;
calldata->res.lr_res = NULL;
break;
case -NFS4ERR_ADMIN_REVOKED:
case -NFS4ERR_DELEG_REVOKED:
case -NFS4ERR_EXPIRED:
case -NFS4ERR_BAD_STATEID:
case -NFS4ERR_OLD_STATEID:
case -NFS4ERR_UNKNOWN_LAYOUTTYPE:
case -NFS4ERR_WRONG_CRED:
calldata->arg.lr_args = NULL;
calldata->res.lr_res = NULL;
calldata->res.lr_ret = 0;
rpc_restart_call_prepare(task);
return;
}
}

/* hmm. we are done with the inode, and in the process of freeing
* the state_owner. we keep this around to process errors
*/
switch (task->tk_status) {
case 0:
res_stateid = &calldata->res.stateid;
if (calldata->roc)
if (calldata->lr.roc)
pnfs_roc_set_barrier(state->inode,
calldata->roc_barrier);
calldata->lr.roc_barrier);
renew_lease(server, calldata->timestamp);
break;
case -NFS4ERR_ADMIN_REVOKED:
Expand Down Expand Up @@ -3151,7 +3181,7 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
goto out_no_action;
}

if (nfs4_wait_on_layoutreturn(inode, task)) {
if (!calldata->arg.lr_args && nfs4_wait_on_layoutreturn(inode, task)) {
nfs_release_seqid(calldata->arg.seqid);
goto out_wait;
}
Expand All @@ -3165,8 +3195,8 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
else
calldata->arg.bitmask = NULL;
}
if (calldata->roc)
pnfs_roc_get_barrier(inode, &calldata->roc_barrier);
if (calldata->lr.roc)
pnfs_roc_get_barrier(inode, &calldata->lr.roc_barrier);

calldata->arg.share_access =
nfs4_map_atomic_open_share(NFS_SERVER(inode),
Expand Down Expand Up @@ -3250,7 +3280,8 @@ int nfs4_do_close(struct nfs4_state *state, gfp_t gfp_mask, int wait)
calldata->res.fattr = &calldata->fattr;
calldata->res.seqid = calldata->arg.seqid;
calldata->res.server = server;
calldata->roc = nfs4_roc(state->inode);
calldata->res.lr_ret = -NFS4ERR_NOMATCHING_LAYOUT;
calldata->lr.roc = nfs4_roc(state->inode);
nfs_sb_active(calldata->inode->i_sb);

msg.rpc_argp = &calldata->arg;
Expand Down
26 changes: 26 additions & 0 deletions fs/nfs/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,8 @@ static int nfs4_stat_to_errno(int);
#else /* CONFIG_NFS_V4_1 */
#define encode_sequence_maxsz 0
#define decode_sequence_maxsz 0
#define encode_layoutreturn_maxsz 0
#define decode_layoutreturn_maxsz 0
#endif /* CONFIG_NFS_V4_1 */

#define NFS4_enc_compound_sz (1024) /* XXX: large enough? */
Expand Down Expand Up @@ -508,11 +510,13 @@ static int nfs4_stat_to_errno(int);
#define NFS4_enc_close_sz (compound_encode_hdr_maxsz + \
encode_sequence_maxsz + \
encode_putfh_maxsz + \
encode_layoutreturn_maxsz + \
encode_close_maxsz + \
encode_getattr_maxsz)
#define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
decode_sequence_maxsz + \
decode_putfh_maxsz + \
decode_layoutreturn_maxsz + \
decode_close_maxsz + \
decode_getattr_maxsz)
#define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
Expand Down Expand Up @@ -2061,6 +2065,13 @@ static void encode_free_stateid(struct xdr_stream *xdr,
encode_op_hdr(xdr, OP_FREE_STATEID, decode_free_stateid_maxsz, hdr);
encode_nfs4_stateid(xdr, &args->stateid);
}
#else
static inline void
encode_layoutreturn(struct xdr_stream *xdr,
const struct nfs4_layoutreturn_args *args,
struct compound_hdr *hdr)
{
}
#endif /* CONFIG_NFS_V4_1 */

/*
Expand Down Expand Up @@ -2248,6 +2259,8 @@ static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr,
encode_compound_hdr(xdr, req, &hdr);
encode_sequence(xdr, &args->seq_args, &hdr);
encode_putfh(xdr, args->fh, &hdr);
if (args->lr_args)
encode_layoutreturn(xdr, args->lr_args, &hdr);
encode_close(xdr, args, &hdr);
if (args->bitmask != NULL)
encode_getfattr(xdr, args->bitmask, &hdr);
Expand Down Expand Up @@ -6088,6 +6101,13 @@ static int decode_free_stateid(struct xdr_stream *xdr,
res->status = decode_op_hdr(xdr, OP_FREE_STATEID);
return res->status;
}
#else
static inline
int decode_layoutreturn(struct xdr_stream *xdr,
struct nfs4_layoutreturn_res *res)
{
return 0;
}
#endif /* CONFIG_NFS_V4_1 */

/*
Expand Down Expand Up @@ -6440,6 +6460,12 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
status = decode_putfh(xdr);
if (status)
goto out;
if (res->lr_res) {
status = decode_layoutreturn(xdr, res->lr_res);
res->lr_ret = status;
if (status)
goto out;
}
status = decode_close(xdr, res);
if (status != 0)
goto out;
Expand Down
3 changes: 3 additions & 0 deletions include/linux/nfs_xdr.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,7 @@ struct nfs_closeargs {
fmode_t fmode;
u32 share_access;
const u32 * bitmask;
struct nfs4_layoutreturn_args *lr_args;
};

struct nfs_closeres {
Expand All @@ -477,6 +478,8 @@ struct nfs_closeres {
struct nfs_fattr * fattr;
struct nfs_seqid * seqid;
const struct nfs_server *server;
struct nfs4_layoutreturn_res *lr_res;
int lr_ret;
};
/*
* * Arguments to the lock,lockt, and locku call.
Expand Down

0 comments on commit cf80516

Please sign in to comment.