* [PATCH 0/3] nfs41: layoutreturn on last of close/delegation_return @ 2014-07-03 5:04 Peng Tao 2014-07-03 5:05 ` [PATCH 1/3] nfs4: add nfs4_check_delegation Peng Tao 0 siblings, 1 reply; 4+ messages in thread From: Peng Tao @ 2014-07-03 5:04 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs, Peng Tao Following patches changed client to do layout return on the last of file close and delegation return, per Errata ID 3226. Peng Tao (3): nfs4: add nfs4_check_delegation nfs41: return layout on last close nfs41: layout return on close in delegation return fs/nfs/delegation.c | 34 +++++++++++++++++++++-------- fs/nfs/delegation.h | 1 + fs/nfs/nfs4proc.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 11 deletions(-) -- 1.9.1 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/3] nfs4: add nfs4_check_delegation 2014-07-03 5:04 [PATCH 0/3] nfs41: layoutreturn on last of close/delegation_return Peng Tao @ 2014-07-03 5:05 ` Peng Tao 2014-07-03 5:05 ` [PATCH 2/3] nfs41: return layout on last close Peng Tao 0 siblings, 1 reply; 4+ messages in thread From: Peng Tao @ 2014-07-03 5:05 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs, Peng Tao Signed-off-by: Peng Tao <tao.peng@primarydata.com> --- fs/nfs/delegation.c | 34 +++++++++++++++++++++++++--------- fs/nfs/delegation.h | 1 + 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 5d8ccec..5853f53 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c @@ -41,14 +41,8 @@ void nfs_mark_delegation_referenced(struct nfs_delegation *delegation) set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags); } -/** - * nfs_have_delegation - check if inode has a delegation - * @inode: inode to check - * @flags: delegation types to check for - * - * Returns one if inode has the indicated delegation, otherwise zero. - */ -int nfs4_have_delegation(struct inode *inode, fmode_t flags) +static int +nfs4_do_check_delegation(struct inode *inode, fmode_t flags, bool mark) { struct nfs_delegation *delegation; int ret = 0; @@ -58,12 +52,34 @@ int nfs4_have_delegation(struct inode *inode, fmode_t flags) delegation = rcu_dereference(NFS_I(inode)->delegation); if (delegation != NULL && (delegation->type & flags) == flags && !test_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) { - nfs_mark_delegation_referenced(delegation); + if (mark) + nfs_mark_delegation_referenced(delegation); ret = 1; } rcu_read_unlock(); return ret; } +/** + * nfs_have_delegation - check if inode has a delegation, mark it + * NFS_DELEGATION_REFERENCED if there is one. + * @inode: inode to check + * @flags: delegation types to check for + * + * Returns one if inode has the indicated delegation, otherwise zero. + */ +int nfs4_have_delegation(struct inode *inode, fmode_t flags) +{ + return nfs4_do_check_delegation(inode, flags, true); +} + +/* + * nfs4_check_delegation - check if inode has a delegation, do not mark + * NFS_DELEGATION_REFERENCED if it has one. + */ +int nfs4_check_delegation(struct inode *inode, fmode_t flags) +{ + return nfs4_do_check_delegation(inode, flags, false); +} static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_state *state, const nfs4_stateid *stateid) { diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h index 9a79c7a..5c1cce3 100644 --- a/fs/nfs/delegation.h +++ b/fs/nfs/delegation.h @@ -59,6 +59,7 @@ bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_ void nfs_mark_delegation_referenced(struct nfs_delegation *delegation); int nfs4_have_delegation(struct inode *inode, fmode_t flags); +int nfs4_check_delegation(struct inode *inode, fmode_t flags); #endif -- 1.9.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/3] nfs41: return layout on last close 2014-07-03 5:05 ` [PATCH 1/3] nfs4: add nfs4_check_delegation Peng Tao @ 2014-07-03 5:05 ` Peng Tao 2014-07-03 5:05 ` [PATCH 3/3] nfs41: layout return on close in delegation return Peng Tao 0 siblings, 1 reply; 4+ messages in thread From: Peng Tao @ 2014-07-03 5:05 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs, Peng Tao If client has valid delegation, do not return layout on close at all. Signed-off-by: Peng Tao <tao.peng@primarydata.com> --- fs/nfs/nfs4proc.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index b0e5705..81c0d2e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -2647,6 +2647,48 @@ static const struct rpc_call_ops nfs4_close_ops = { .rpc_release = nfs4_free_closedata, }; +static bool nfs4_state_has_opener(struct nfs4_state *state) +{ + /* first check existing openers */ + if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0 && + state->n_rdonly != 0) + return true; + + if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0 && + state->n_wronly != 0) + return true; + + if (test_bit(NFS_O_RDWR_STATE, &state->flags) != 0 && + state->n_rdwr != 0) + return true; + + return false; +} + +static bool nfs4_roc(struct inode *inode) +{ + struct nfs_inode *nfsi = NFS_I(inode); + struct nfs_open_context *ctx; + struct nfs4_state *state; + + spin_lock(&inode->i_lock); + list_for_each_entry(ctx, &nfsi->open_files, list) { + state = ctx->state; + if (state == NULL) + continue; + if (nfs4_state_has_opener(state)) { + spin_unlock(&inode->i_lock); + return false; + } + } + spin_unlock(&inode->i_lock); + + if (nfs4_check_delegation(inode, FMODE_READ)) + return false; + + return pnfs_roc(inode); +} + /* * It is possible for data to be read/written from a mem-mapped file * after the sys_close call (which hits the vfs layer as a flush). @@ -2697,7 +2739,7 @@ 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 = pnfs_roc(state->inode); + calldata->roc = nfs4_roc(state->inode); nfs_sb_active(calldata->inode->i_sb); msg.rpc_argp = &calldata->arg; -- 1.9.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/3] nfs41: layout return on close in delegation return 2014-07-03 5:05 ` [PATCH 2/3] nfs41: return layout on last close Peng Tao @ 2014-07-03 5:05 ` Peng Tao 0 siblings, 0 replies; 4+ messages in thread From: Peng Tao @ 2014-07-03 5:05 UTC (permalink / raw) To: Trond Myklebust; +Cc: linux-nfs, Peng Tao If file is not opened by anyone, we do layout return on close in delegation return. Signed-off-by: Peng Tao <tao.peng@primarydata.com> --- fs/nfs/nfs4proc.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 81c0d2e..70a623c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -5022,6 +5022,9 @@ struct nfs4_delegreturndata { unsigned long timestamp; struct nfs_fattr fattr; int rpc_status; + struct inode *inode; + bool roc; + u32 roc_barrier; }; static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) @@ -5035,7 +5038,6 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) switch (task->tk_status) { case 0: renew_lease(data->res.server, data->timestamp); - break; case -NFS4ERR_ADMIN_REVOKED: case -NFS4ERR_DELEG_REVOKED: case -NFS4ERR_BAD_STATEID: @@ -5043,6 +5045,8 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) case -NFS4ERR_STALE_STATEID: case -NFS4ERR_EXPIRED: task->tk_status = 0; + if (data->roc) + pnfs_roc_set_barrier(data->inode, data->roc_barrier); break; default: if (nfs4_async_handle_error(task, data->res.server, NULL) == @@ -5056,6 +5060,10 @@ static void nfs4_delegreturn_done(struct rpc_task *task, void *calldata) static void nfs4_delegreturn_release(void *calldata) { + struct nfs4_delegreturndata *data = calldata; + + if (data->roc) + pnfs_roc_release(data->inode); kfree(calldata); } @@ -5065,6 +5073,10 @@ static void nfs4_delegreturn_prepare(struct rpc_task *task, void *data) d_data = (struct nfs4_delegreturndata *)data; + if (d_data->roc && + pnfs_roc_drain(d_data->inode, &d_data->roc_barrier, task)) + return; + nfs4_setup_sequence(d_data->res.server, &d_data->args.seq_args, &d_data->res.seq_res, @@ -5108,6 +5120,9 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co nfs_fattr_init(data->res.fattr); data->timestamp = jiffies; data->rpc_status = 0; + data->inode = inode; + data->roc = list_empty(&NFS_I(inode)->open_files) ? + pnfs_roc(inode) : false; task_setup_data.callback_data = data; msg.rpc_argp = &data->args; -- 1.9.1 ^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2014-07-03 5:05 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2014-07-03 5:04 [PATCH 0/3] nfs41: layoutreturn on last of close/delegation_return Peng Tao 2014-07-03 5:05 ` [PATCH 1/3] nfs4: add nfs4_check_delegation Peng Tao 2014-07-03 5:05 ` [PATCH 2/3] nfs41: return layout on last close Peng Tao 2014-07-03 5:05 ` [PATCH 3/3] nfs41: layout return on close in delegation return Peng Tao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox