From: Benny Halevy <bhalevy@panasas.com>
To: Fred Isaman <iisaman@netapp.com>
Cc: linux-nfs@vger.kernel.org
Subject: Re: [PATCH 18/22] pnfs-submit: roc add layoutreturn op to close compound
Date: Fri, 12 Nov 2010 18:31:33 +0200 [thread overview]
Message-ID: <4CDD6BE5.1000502@panasas.com> (raw)
In-Reply-To: <1289551724-18575-19-git-send-email-iisaman@netapp.com>
On 2010-11-12 10:48, Fred Isaman wrote:
> From: Andy Adamson <andros@netapp.com>
>
> Signed-off-by: Andy Adamson <andros@netapp.com>
> ---
> fs/nfs/nfs4proc.c | 73 +++++++++++++++++++++++++++++++++-------------
> fs/nfs/nfs4state.c | 18 +-----------
> fs/nfs/nfs4xdr.c | 14 ++++++++-
> fs/nfs/pnfs.c | 64 +++++++++++++++++++++++++++++++++++++----
> fs/nfs/pnfs.h | 1 +
> include/linux/nfs_xdr.h | 19 ++++++++++++
> 6 files changed, 143 insertions(+), 46 deletions(-)
>
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index 6223c6a..2b47c59 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -74,6 +74,8 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
> static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
> struct nfs_fattr *fattr, struct iattr *sattr,
> struct nfs4_state *state);
> +static void nfs4_layoutreturn_set_stateid(struct inode *ino,
> + struct nfs4_layoutreturn_res *res);
>
> /* Prevent leaks of NFSv4 errors into userland */
> static int nfs4_map_errors(int err)
> @@ -1821,16 +1823,6 @@ static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
> return err;
> }
>
> -struct nfs4_closedata {
> - struct path path;
> - struct inode *inode;
> - struct nfs4_state *state;
> - struct nfs_closeargs arg;
> - struct nfs_closeres res;
> - struct nfs_fattr fattr;
> - unsigned long timestamp;
> -};
> -
> static void nfs4_free_closedata(void *data)
> {
> struct nfs4_closedata *calldata = data;
> @@ -1840,6 +1832,17 @@ static void nfs4_free_closedata(void *data)
> nfs_free_seqid(calldata->arg.seqid);
> nfs4_put_state_owner(sp);
> path_put(&calldata->path);
> + if (calldata->res.op_bitmask & NFS4_HAS_LAYOUTRETURN) {
> + struct pnfs_layout_hdr *lo = NFS_I(calldata->inode)->layout;
> +
> + spin_lock(&lo->inode->i_lock);
> + lo->plh_block_lgets--;
> + lo->plh_outstanding--;
> + if (!pnfs_layoutgets_blocked(lo, NULL))
> + rpc_wake_up(&NFS_I(lo->inode)->lo_rpcwaitq_stateid);
> + spin_unlock(&lo->inode->i_lock);
> + put_layout_hdr(lo->inode);
> + }
> kfree(calldata);
> }
>
> @@ -1869,6 +1872,9 @@ static void nfs4_close_done(struct rpc_task *task, void *data)
> switch (task->tk_status) {
> case 0:
> nfs_set_open_stateid(state, &calldata->res.stateid, 0);
> + if (calldata->res.op_bitmask & NFS4_HAS_LAYOUTRETURN)
> + nfs4_layoutreturn_set_stateid(calldata->inode,
> + &calldata->res.lr_res);
> renew_lease(server, calldata->timestamp);
> nfs4_close_clear_stateid_flags(state,
> calldata->arg.fmode);
> @@ -1920,8 +1926,27 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data)
> return;
> }
>
> - if (calldata->arg.fmode == 0)
> + if (calldata->arg.fmode == 0) {
> task->tk_msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_CLOSE];
> + /* Are there layout segments to return on close? */
> + if (pnfs_roc(calldata)) {
> + struct nfs_inode *nfsi = NFS_I(calldata->inode);
> + if (pnfs_return_layout_barrier(nfsi,
> + &calldata->arg.lr_args.range)) {
> + dprintk("%s: waiting on barrier\n", __func__);
> + /* FIXME race with wake here */
> + rpc_sleep_on(&nfsi->lo_rpcwaitq, task, NULL);
> + spin_lock(&calldata->inode->i_lock);
> + nfsi->layout->plh_block_lgets--;
> + nfsi->layout->plh_outstanding--;
> + if (!pnfs_layoutgets_blocked(nfsi->layout, NULL))
> + rpc_wake_up(&nfsi->lo_rpcwaitq_stateid);
> + spin_unlock(&calldata->inode->i_lock);
> + put_layout_hdr(calldata->inode);
> + return;
> + }
> + }
> + }
>
> nfs_fattr_init(calldata->res.fattr);
> calldata->timestamp = jiffies;
> @@ -5587,6 +5612,7 @@ nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
>
> if (pnfs_return_layout_barrier(nfsi, &lrp->args.range)) {
> dprintk("%s: waiting on barrier\n", __func__);
> + /* FIXME race with wake here */
> rpc_sleep_on(&nfsi->lo_rpcwaitq, task, NULL);
> return;
> }
> @@ -5602,6 +5628,19 @@ nfs4_layoutreturn_prepare(struct rpc_task *task, void *calldata)
> rpc_call_start(task);
> }
>
> +static void nfs4_layoutreturn_set_stateid(struct inode *ino,
> + struct nfs4_layoutreturn_res *res)
> +{
> + struct pnfs_layout_hdr *lo = NFS_I(ino)->layout;
> +
> + spin_lock(&ino->i_lock);
> + if (res->lrs_present)
> + pnfs_set_layout_stateid(lo, &res->stateid, true);
> + else
> + BUG_ON(!list_empty(&lo->segs));
> + spin_unlock(&ino->i_lock);
> +}
> +
> static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
> {
> struct nfs4_layoutreturn *lrp = calldata;
> @@ -5620,16 +5659,8 @@ static void nfs4_layoutreturn_done(struct rpc_task *task, void *calldata)
> nfs_restart_rpc(task, lrp->clp);
> return;
> }
> - if ((task->tk_status == 0) && (lrp->args.return_type == RETURN_FILE)) {
> - struct pnfs_layout_hdr *lo = NFS_I(lrp->args.inode)->layout;
> -
> - spin_lock(&lo->inode->i_lock);
> - if (lrp->res.lrs_present)
> - pnfs_set_layout_stateid(lo, &lrp->res.stateid, true);
> - else
> - BUG_ON(!list_empty(&lo->segs));
> - spin_unlock(&lo->inode->i_lock);
> - }
> + if ((task->tk_status == 0) && (lrp->args.return_type == RETURN_FILE))
> + nfs4_layoutreturn_set_stateid(lrp->args.inode, &lrp->res);
> dprintk("<-- %s\n", __func__);
> }
>
> diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
> index ceb0d66..784f122 100644
> --- a/fs/nfs/nfs4state.c
> +++ b/fs/nfs/nfs4state.c
> @@ -601,24 +601,8 @@ static void __nfs4_close(struct path *path, struct nfs4_state *state,
> if (!call_close) {
> nfs4_put_open_state(state);
> nfs4_put_state_owner(owner);
> - } else {
> - u32 roc_iomode;
> - struct nfs_inode *nfsi = NFS_I(state->inode);
> -
> - if (has_layout(nfsi) &&
> - (roc_iomode = pnfs_layout_roc_iomode(nfsi)) != 0) {
> - struct pnfs_layout_range range = {
> - .iomode = roc_iomode,
> - .offset = 0,
> - .length = NFS4_MAX_UINT64,
> - };
> -
> - pnfs_return_layout(state->inode, &range, NULL,
> - RETURN_FILE, wait);
> - }
> -
> + } else
> nfs4_do_close(path, state, gfp_mask, wait);
> - }
> }
>
> void nfs4_close_state(struct path *path, struct nfs4_state *state, fmode_t fmode)
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index f530c7e..adb4c47 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -438,12 +438,14 @@ static int nfs4_stat_to_errno(int);
> encode_sequence_maxsz + \
> encode_putfh_maxsz + \
> encode_close_maxsz + \
> - encode_getattr_maxsz)
> + encode_getattr_maxsz + \
> + encode_layoutreturn_maxsz)
> #define NFS4_dec_close_sz (compound_decode_hdr_maxsz + \
> decode_sequence_maxsz + \
> decode_putfh_maxsz + \
> decode_close_maxsz + \
> - decode_getattr_maxsz)
> + decode_getattr_maxsz + \
> + decode_layoutreturn_maxsz)
> #define NFS4_enc_setattr_sz (compound_encode_hdr_maxsz + \
> encode_sequence_maxsz + \
> encode_putfh_maxsz + \
> @@ -2143,6 +2145,8 @@ static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closea
> encode_putfh(&xdr, args->fh, &hdr);
> encode_close(&xdr, args, &hdr);
> encode_getfattr(&xdr, args->bitmask, &hdr);
> + if (args->op_bitmask & NFS4_HAS_LAYOUTRETURN) /* layoutreturn set */
> + encode_layoutreturn(&xdr, &args->lr_args, &hdr);
Sorry, I just noticed, but if there's no object I'll move the layoutreturn op
before close in the compound.
Benny
> encode_nops(&hdr);
> return 0;
> }
> @@ -5719,6 +5723,12 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos
> */
> decode_getfattr(&xdr, res->fattr, res->server,
> !RPC_IS_ASYNC(rqstp->rq_task));
> + /*
> + * With the forgetful model, we pay no attention to the
> + * layoutreturn status.
> + */
> + if (res->op_bitmask & NFS4_HAS_LAYOUTRETURN)
> + decode_layoutreturn(&xdr, &res->lr_res);
> out:
> return status;
> }
> diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
> index 22abf83..76cfb11 100644
> --- a/fs/nfs/pnfs.c
> +++ b/fs/nfs/pnfs.c
> @@ -623,6 +623,63 @@ pnfs_return_layout_barrier(struct nfs_inode *nfsi,
> return ret;
> }
>
> +/*
> + * Return on close
> + *
> + * No LAYOUTRETURNS can be sent when BULK RECALL flag is set.
> + * FIXME: add layoutcommit operation if layoutcommit_needed is true.
> + */
> +bool
> +pnfs_roc(struct nfs4_closedata *data)
> +{
> + struct nfs4_layoutreturn_args *lr_args = &data->arg.lr_args;
> + struct pnfs_layout_hdr *lo;
> + struct pnfs_layout_segment *lseg, *tmp;
> + struct pnfs_layout_range range = {
> + .length = NFS4_MAX_UINT64,
> + };
> + LIST_HEAD(tmp_list);
> + bool found = false;
> +
> + spin_lock(&data->inode->i_lock);
> + lo = NFS_I(data->inode)->layout;
> + if (!lo || lo->roc_iomode == 0 ||
> + test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags))
> + goto out_nolayout;
> +
> + range.iomode = lo->roc_iomode;
> + list_for_each_entry_safe(lseg, tmp, &lo->segs, fi_list)
> + if (should_free_lseg(&lseg->range, &range)) {
> + mark_lseg_invalid(lseg, &tmp_list);
> + found = true;
> + }
> + if (found == false)
> + goto out_nolayout;
> + /* Stop new and drop response to outstanding LAYOUTGETS */
> + lo->plh_block_lgets++;
> + lo->plh_outstanding++;
> + /* Reference matched in pnfs_layoutreturn_release */
> + get_layout_hdr(lo);
> +
> + spin_unlock(&data->inode->i_lock);
> +
> + pnfs_free_lseg_list(&tmp_list);
> +
> + lr_args->reclaim = 0;
> + lr_args->layout_type = NFS_SERVER(data->inode)->pnfs_curr_ld->id;
> + lr_args->return_type = RETURN_FILE;
> + lr_args->range = range;
> + lr_args->inode = data->inode;
> + data->res.op_bitmask |= NFS4_HAS_LAYOUTRETURN;
> + data->arg.op_bitmask |= NFS4_HAS_LAYOUTRETURN;
> +
> + return true;
> +
> +out_nolayout:
> + spin_unlock(&data->inode->i_lock);
> + return false;
> +}
> +
> static int
> return_layout(struct inode *ino, struct pnfs_layout_range *range,
> enum pnfs_layoutreturn_type type, struct pnfs_layout_hdr *lo,
> @@ -997,13 +1054,8 @@ pnfs_layout_process(struct nfs4_layoutget *lgp)
> *lgp->lsegpp = lseg;
> pnfs_insert_layout(lo, lseg);
>
> - if (res->return_on_close) {
> - /* FI: This needs to be re-examined. At lo level,
> - * all it needs is a bit indicating whether any of
> - * the lsegs in the list have the flags set.
> - */
> + if (res->return_on_close)
> lo->roc_iomode |= res->range.iomode;
> - }
>
> /* Done processing layoutget. Set the layout stateid */
> pnfs_set_layout_stateid(lo, &res->stateid, false);
> diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
> index 7fd1f5d..916a057 100644
> --- a/fs/nfs/pnfs.h
> +++ b/fs/nfs/pnfs.h
> @@ -234,6 +234,7 @@ void nfs4_asynch_forget_layouts(struct pnfs_layout_hdr *lo,
> struct pnfs_layout_range *range,
> int notify_bit, atomic_t *notify_count,
> struct list_head *tmp_list);
> +bool pnfs_roc(struct nfs4_closedata *data);
>
> static inline bool
> has_layout(struct nfs_inode *nfsi)
> diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
> index f472405..6c4ba71 100644
> --- a/include/linux/nfs_xdr.h
> +++ b/include/linux/nfs_xdr.h
> @@ -351,12 +351,18 @@ struct nfs_open_confirmres {
> /*
> * Arguments to the close call.
> */
> +
> +/* op_bitmask bits */
> +#define NFS4_HAS_LAYOUTRETURN 0x01
> +
> struct nfs_closeargs {
> struct nfs_fh * fh;
> nfs4_stateid * stateid;
> struct nfs_seqid * seqid;
> fmode_t fmode;
> const u32 * bitmask;
> + u32 op_bitmask; /* which optional ops to encode */
> + struct nfs4_layoutreturn_args lr_args; /* optional */
> struct nfs4_sequence_args seq_args;
> };
>
> @@ -365,8 +371,21 @@ struct nfs_closeres {
> struct nfs_fattr * fattr;
> struct nfs_seqid * seqid;
> const struct nfs_server *server;
> + u32 op_bitmask; /* which optional ops encoded */
> + struct nfs4_layoutreturn_res lr_res; /* optional */
> struct nfs4_sequence_res seq_res;
> };
> +
> +struct nfs4_closedata {
> + struct path path;
> + struct inode *inode;
> + struct nfs4_state *state;
> + struct nfs_closeargs arg;
> + struct nfs_closeres res;
> + struct nfs_fattr fattr;
> + unsigned long timestamp;
> +};
> +
> /*
> * * Arguments to the lock,lockt, and locku call.
> * */
next prev parent reply other threads:[~2010-11-12 16:31 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-12 8:48 [PATCH 00/22] rewrite of CB_LAYOUTRECALL and layoutstate code, try 2 Fred Isaman
2010-11-12 8:48 ` [PATCH 01/22] pnfs-submit: remove RPC_ASSASSINATED(task) checks Fred Isaman
2010-11-12 8:48 ` [PATCH 02/22] pnfs-submit: remove unnecessary field lgp->status Fred Isaman
2010-11-12 8:48 ` [PATCH 03/22] pnfs-submit: layoutreturn's rpc_call_op functions need to handle bulk returns Fred Isaman
2010-11-12 8:48 ` [PATCH 04/22] pnfs-submit: argument to should_free_lseg changed from lseg to range Fred Isaman
2010-11-12 8:48 ` [PATCH 05/22] pnfs-submit: change layout state seqlock to a spinlock Fred Isaman
2010-11-12 8:48 ` [PATCH 06/22] NFSv4.1: Callback share session between ops Fred Isaman
2010-11-12 8:48 ` [PATCH 07/22] SQUASHME: pnfs-submit: fixups for nfsv4.1 callbacks Fred Isaman
2010-11-12 8:48 ` [PATCH 08/22] SQUASHME: allow cb_sequence changes to compile without v4.1 Fred Isaman
2010-11-14 12:05 ` Benny Halevy
2010-11-15 15:07 ` Fred Isaman
2010-11-12 8:48 ` [PATCH 09/22] pnfs-submit: change pnfs_layout_segment refcounting from kref to atomic_t Fred Isaman
2010-11-12 8:48 ` [PATCH 10/22] pnfs-submit: Have LAYOUTGETS wait when lo->plh_block_lgets is set Fred Isaman
2010-11-12 8:48 ` [PATCH 11/22] pnfs-submit: remove _pnfs_can_return_lseg call from pnfs_clear_lseg_list Fred Isaman
2010-11-12 8:48 ` [PATCH 12/22] pnfs_submit: nfs4_layoutreturn_release should not reference results Fred Isaman
2010-11-12 8:48 ` [PATCH 13/22] pnfs-submit: reorganize struct cb_layoutrecallargs Fred Isaman
2010-11-12 8:48 ` [PATCH 14/22] pnfs-submit: rename lo->state to lo->plh_flags Fred Isaman
2010-11-12 8:48 ` [PATCH 15/22] pnfs-submit: change pnfs_layout_hdr refcount to atomic_t Fred Isaman
2010-11-12 8:48 ` [PATCH 16/22] pnfs-submit: rewrite of layout state handling and cb_layoutrecall Fred Isaman
2010-11-13 9:11 ` Trond Myklebust
2010-11-14 11:44 ` Benny Halevy
2010-11-14 11:50 ` Benny Halevy
2010-11-15 14:28 ` Fred Isaman
2010-11-14 15:43 ` Benny Halevy
2010-11-15 14:51 ` Fred Isaman
2010-11-15 16:17 ` Benny Halevy
2010-11-15 17:53 ` [nfsv4] " Fred Isaman
2010-11-15 19:19 ` Boaz Harrosh
2010-11-15 20:40 ` Fred Isaman
2010-11-16 9:54 ` Boaz Harrosh
2010-11-16 11:12 ` Boaz Harrosh
2010-11-17 17:53 ` Benny Halevy
2010-11-12 8:48 ` [PATCH 17/22] pnfs-submit: increase number of outstanding CB_LAYOUTRECALLS we can handle Fred Isaman
2010-11-12 8:48 ` [PATCH 18/22] pnfs-submit: roc add layoutreturn op to close compound Fred Isaman
2010-11-12 16:31 ` Benny Halevy [this message]
2010-11-12 16:56 ` Fred Isaman
2010-11-14 10:54 ` Benny Halevy
2010-11-14 14:21 ` [PATCH] SQUASHME: pnfs-submit: encode layoutreturn on close before close Benny Halevy
2010-11-14 18:12 ` [PATCH 2/2] pnfs-submit: handle NFS4ERR_DELEG_REVOKED for LAYOUTRETURN Benny Halevy
2010-11-15 12:54 ` [PATCH 2/2 v2] " Benny Halevy
2010-11-15 15:02 ` [PATCH] SQUASHME: pnfs-submit: encode layoutreturn on close before close Fred Isaman
2010-11-15 15:34 ` Benny Halevy
2010-11-12 8:48 ` [PATCH 19/22] pnfs-submit refactor layoutcommit xdr structures Fred Isaman
2010-11-12 8:48 ` [PATCH 20/22] pnfs-submit refactor pnfs_layoutcommit_setup Fred Isaman
2010-11-12 8:48 ` [PATCH 21/22] pnfs_submit: roc add layoutcommit op to close compound Fred Isaman
2010-11-12 8:48 ` [PATCH 22/22] SQUASHME: make roc patches compile without v4.1 Fred Isaman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4CDD6BE5.1000502@panasas.com \
--to=bhalevy@panasas.com \
--cc=iisaman@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).