[prev in list] [next in list] [prev in thread] [next in thread] 

List:       linux-nfs
Subject:    RE: [PATCH 7/8] pnfs-submit: forgetful client model
From:       "Batsakis, Alexandros" <Alexandros.Batsakis () netapp ! com>
Date:       2010-05-27 18:38:19
Message-ID: B9364369CA66BF45806C2CD86EAB8BA60631FAAB () SACMVEXC3-PRD ! hq ! netapp ! com
[Download RAW message or body]

Hi Benny,

Thanks for the review. I ll resend a new version shortly.

-alexandros

> -----Original Message-----
> From: Benny Halevy [mailto:bhalevy@panasas.com]
> Sent: Wednesday, May 26, 2010 2:21 AM
> To: Batsakis, Alexandros
> Cc: linux-nfs@vger.kernel.org
> Subject: Re: [PATCH 7/8] pnfs-submit: forgetful client model
> 
> On 2010-05-17 20:56, Alexandros Batsakis wrote:
> > Forgetful client model:
> >
> > If we receive a CB_LAYOUTRECALL
> > 	- we spawn a thread to handle the recall
> > 	(xxx: now only one recall can be active at a time, else
> NFS4ERR_DELAY)
> > 	- we check the stateid seqid
> > 	if it does not match we return NFS4ERR_DELAY
> > 	- we check for pending I/O
> > 	if there is we return NFS4ERR_DELAY
> > 	Else we return NO_MATCHING_LAYOUT.
> > 	Note that for whole file layouts there is no need to serialize
> LAYOUTGETs/LAYOUTRETURNs
> > For bulk layouts, if there is a layout active, we return NFS4_OK and
> we start
> > cleaning the layouts asynchronously. At the end we send a bulk
> LAYOUTRETURN.
> > Note that there is no need to prevent any new LAYOUTGETs explicitly
> as the server should
> > reject them.
> >
> > Signed-off-by: Alexandros Batsakis <batsakis@netapp.com>
> > ---
> >  fs/nfs/callback_proc.c |  131
++++++++++++++++++++++++++++++++++----
> ----------
> >  fs/nfs/inode.c         |    2 +-
> >  fs/nfs/nfs4_fs.h       |    1 +
> >  fs/nfs/nfs4proc.c      |    4 +-
> >  fs/nfs/nfs4state.c     |    2 +-
> >  fs/nfs/pnfs.c          |   78 +++++++++++++---------------
> >  fs/nfs/pnfs.h          |    8 ++-
> >  7 files changed, 139 insertions(+), 87 deletions(-)
> >
> > diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
> > index 24e2571..419fee7 100644
> > --- a/fs/nfs/callback_proc.c
> > +++ b/fs/nfs/callback_proc.c
> > @@ -129,6 +129,38 @@ int nfs4_validate_delegation_stateid(struct
> nfs_delegation *delegation, const nf
> >
> >  #if defined(CONFIG_NFS_V4_1)
> >
> > +static int
> 
> can return bool
> 
> > +pnfs_is_next_layout_stateid(const struct pnfs_layout_type *lo,
> > +			    const nfs4_stateid stateid)
> > +{
> > +	int seq;
> 
> how about calling it seqlock so it will be less confusing
> with regards to seqid.
> 
> > +	int res;
> 
> and res is "bool" too.
> 
> > +	u32 oldseqid, newseqid;
> > +
> > +	do {
> > +		seq = read_seqbegin(&lo->seqlock);
> > +		oldseqid = ntohl(lo->stateid.u.stateid.seqid);
> > +		newseqid = ntohl(stateid.u.stateid.seqid);
> 
> let's use the more modern be32_to_cpu form...
> 
> > +		res = !memcmp(lo->stateid.u.stateid.other,
> > +			      stateid.u.stateid.other,
> > +			      NFS4_STATEID_OTHER_SIZE);
> > +		if (res) { /* comparing layout stateids */
> > +			if (oldseqid == ~0)
> > +				res = (newseqid == 1);
> > +			else
> > +				res = (newseqid == oldseqid + 1);
> > +		} else { /* open stateid */
> > +			res = !memcmp(lo->stateid.u.data,
> > +				      &zero_stateid,
> > +				      NFS4_STATEID_SIZE);
> > +			if (res)
> > +				res = (newseqid == 1);
> > +		}
> > +	} while (read_seqretry(&lo->seqlock, seq));
> > +
> > +	return res;
> > +}
> > +
> >  /*
> >   * Retrieve an inode based on layout recall parameters
> >   *
> > @@ -190,10 +222,11 @@ static int pnfs_recall_layout(void *data)
> >  {
> >  	struct inode *inode, *ino;
> >  	struct nfs_client *clp;
> > +	struct nfs4_pnfs_layoutreturn *lrp;
> >  	struct cb_pnfs_layoutrecallargs rl;
> >  	struct recall_layout_threadargs *args =
> >  		(struct recall_layout_threadargs *)data;
> > -	int status;
> > +	int status = 0;
> >
> >  	daemonize("nfsv4-layoutreturn");
> >
> > @@ -204,46 +237,57 @@ static int pnfs_recall_layout(void *data)
> >  	clp = args->clp;
> >  	inode = args->inode;
> >  	rl = *args->rl;
> > -	args->result = 0;
> > -	complete(&args->started);
> > -	args = NULL;
> > -	/* Note: args must not be used after this point!!! */
> > -
> > -/* FIXME: need barrier here:
> > -   pause I/O to data servers
> > -   pause layoutgets
> > -   drain all outstanding writes to storage devices
> > -   wait for any outstanding layoutreturns and layoutgets mentioned
> in
> > -   cb_sequence.
> > -   then return layouts, resume after layoutreturns complete
> > - */
> >
> >  	/* support whole file layouts only */
> >  	rl.cbl_seg.offset = 0;
> >  	rl.cbl_seg.length = NFS4_MAX_UINT64;
> >
> >  	if (rl.cbl_recall_type == RETURN_FILE) {
> > -		status = pnfs_return_layout(inode, &rl.cbl_seg,
> &rl.cbl_stateid,
> > -					    RETURN_FILE);
> > +		if (pnfs_is_next_layout_stateid(&NFS_I(inode)->layout,
> rl.cbl_stateid))
> > +			status = pnfs_return_layout(inode, &rl.cbl_seg,
> &rl.cbl_stateid,
> > +						    RETURN_FILE, 0);
> > +		else
> > +			status = htonl(NFS4ERR_DELAY);
> 
> cpu_to_be32?
> 
> > +		/* forgetful client */
> >  		if (status)
> > -			dprintk("%s RETURN_FILE error: %d\n", __func__,
> status);
> > +			dprintk("%s RETURN_FILE : %d\n", __func__,
status);
> > +		else
> > +			status =  htonl(NFS4ERR_NOMATCHING_LAYOUT);
> 
> ditto
> 
> > +		args->result = status;
> > +		complete(&args->started);
> >  		goto out;
> >  	}
> >
> > -	/* FIXME: This loop is inefficient, running in O(|s_inodes|^2)
*/
> 
> Hmm, I would like this to be fixed, eventually.
> Maybe FIXME is too harsh and IMPROVEME would be better :)
> 
> > +	status = htonl(NFS4_OK);
> 
> ditto
> 
> > +	args->result = status;
> > +	complete(&args->started);
> > +	args = NULL;
> > +
> >  	while ((ino = nfs_layoutrecall_find_inode(clp, &rl)) != NULL) {
> >  		/* XXX need to check status on pnfs_return_layout */
> 
> s/XXX/FIXME/
> 
> > -		pnfs_return_layout(ino, &rl.cbl_seg, NULL, RETURN_FILE);
> > +		pnfs_return_layout(ino, &rl.cbl_seg, NULL, RETURN_FILE,
0);
> >  		iput(ino);
> >  	}
> >
> > -	/* send final layoutreturn */
> > -	status = pnfs_return_layout(inode, &rl.cbl_seg, NULL,
> rl.cbl_recall_type);
> > -	if (status)
> > -		printk(KERN_INFO "%s: ignoring pnfs_return_layout
> status=%d\n",
> > -				__func__, status);
> > +	lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
> > +	if (!lrp) {
> > +		dprintk("%s: allocation failed. Cannot send last
> LAYOUTRETURN\n",
> > +			__func__);
> > +		goto out;
> > +	}
> > +
> > +	/* send final layoutreturn (bulk) */
> > +	lrp->args.reclaim = 0;
> > +	lrp->args.layout_type = rl.cbl_layout_type;
> > +	lrp->args.return_type = rl.cbl_recall_type;
> > +	lrp->args.lseg = rl.cbl_seg;
> > +	lrp->args.inode = inode;
> > +	lrp->lo = NULL;
> > +
> > +	pnfs4_proc_layoutreturn(lrp);
> >  out:
> > -	iput(inode);
> > +	clear_bit(NFS4CLNT_LAYOUT_RECALL, &clp->cl_state);
> > +	nfs_put_client(clp);
> >  	module_put_and_exit(0);
> >  	dprintk("%s: exit status %d\n", __func__, 0);
> >  	return 0;
> > @@ -261,15 +305,18 @@ static int pnfs_async_return_layout(struct
> nfs_client *clp, struct inode *inode,
> >  		.rl = rl,
> >  	};
> >  	struct task_struct *t;
> > -	int status;
> > -
> > -	/* should have returned NFS4ERR_NOMATCHING_LAYOUT... */
> > -	BUG_ON(inode == NULL);
> > +	int status = htonl(NFS4ERR_DELAY);
> >
> >  	dprintk("%s: -->\n", __func__);
> >
> > +	/* XXX: do not allow two concurrent layout recalls */
> > +	if (test_and_set_bit(NFS4CLNT_LAYOUT_RECALL, &clp->cl_state))
> > +		return status;
> > +
> >  	init_completion(&data.started);
> >  	__module_get(THIS_MODULE);
> > +	if (!atomic_inc_not_zero(&clp->cl_count))
> > +		goto out_put_no_client;
> >
> >  	t = kthread_run(pnfs_recall_layout, &data, "%s",
> "pnfs_recall_layout");
> >  	if (IS_ERR(t)) {
> > @@ -283,6 +330,9 @@ static int pnfs_async_return_layout(struct
> nfs_client *clp, struct inode *inode,
> >  	wait_for_completion(&data.started);
> >  	return data.result;
> >  out_module_put:
> > +	nfs_put_client(clp);
> > +out_put_no_client:
> > +	clear_bit(NFS4CLNT_LAYOUT_RECALL, &clp->cl_state);
> >  	module_put(THIS_MODULE);
> >  	return status;
> >  }
> > @@ -309,19 +359,24 @@ __be32 pnfs_cb_layoutrecall(struct
> cb_pnfs_layoutrecallargs *args,
> >  	do {
> >  		struct nfs_client *prev = clp;
> >  		num_client++;
> > -		inode = nfs_layoutrecall_find_inode(clp, args);
> > -		if (inode != NULL) {
> > -			if (PNFS_LD(&NFS_I(inode)->layout)->id ==
> > -			    args->cbl_layout_type) {
> > -				/* Set up a helper thread to actually
> > -				 * return the delegation */
> > +		/* the callback must come from the MDS personality */
> > +		if (!(clp->cl_exchange_flags &
EXCHGID4_FLAG_USE_PNFS_MDS))
> > +			goto loop;
> > +		if (args->cbl_recall_type == RETURN_FILE) {
> > +			inode = nfs_layoutrecall_find_inode(clp, args);
> > +			if (inode != NULL) {
> >  				res = pnfs_async_return_layout(clp,
inode,
> args);
> > -				if (res != 0)
> > -					res = htonl(NFS4ERR_RESOURCE);
> > -				break;
> > +				iput(inode);
> >  			}
> > +		} else {
> > +			/* we need the inode to get the nfs_server
struct */
> > +			inode = nfs_layoutrecall_find_inode(clp, args);
> > +			if (!inode)
> > +				goto loop;
> > +			res = pnfs_async_return_layout(clp, inode,
args);
> >  			iput(inode);
> >  		}
> > +loop:
> >  		clp = nfs_find_client_next(prev);
> >  		nfs_put_client(prev);
> >  	} while (clp != NULL);
> > diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
> > index adf3280..584c9b8 100644
> > --- a/fs/nfs/inode.c
> > +++ b/fs/nfs/inode.c
> > @@ -1321,7 +1321,7 @@ void nfs4_clear_inode(struct inode *inode)
> >  	/* First call standard NFS clear_inode() code */
> >  	nfs_clear_inode(inode);
> >  #ifdef CONFIG_NFS_V4_1
> > -	pnfs_return_layout(inode, NULL, NULL, RETURN_FILE);
> > +	pnfs_return_layout(inode, NULL, NULL, RETURN_FILE, 1);
> >  #endif /* CONFIG_NFS_V4_1 */
> >  }
> >  #endif
> > diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
> > index 40ebe1d..90c57b3 100644
> > --- a/fs/nfs/nfs4_fs.h
> > +++ b/fs/nfs/nfs4_fs.h
> > @@ -47,6 +47,7 @@ enum nfs4_client_state {
> >  	NFS4CLNT_SESSION_RESET,
> >  	NFS4CLNT_SESSION_DRAINING,
> >  	NFS4CLNT_RECALL_SLOT,
> > +	NFS4CLNT_LAYOUT_RECALL,
> >  };
> >
> >  /*
> > diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> > index 6739d15..14e90e1 100644
> > --- a/fs/nfs/nfs4proc.c
> > +++ b/fs/nfs/nfs4proc.c
> > @@ -1085,7 +1085,7 @@ static void pnfs4_layout_reclaim(struct
> nfs4_state *state)
> >  	/* FIXME: send gratuitous layout commits and return with the
> reclaim
> >  	 * flag during grace period
> >  	 */
> > -	pnfs_return_layout(state->inode, NULL, &state->open_stateid,
> RETURN_FILE);
> > +	pnfs_return_layout(state->inode, NULL, NULL, RETURN_FILE, 1);
> >  	pnfs_set_layout_stateid(&NFS_I(state->inode)->layout,
> &zero_stateid);
> >  #endif /* CONFIG_NFS_V4_1 */
> >  }
> > @@ -2382,7 +2382,7 @@ pnfs4_proc_setattr(struct dentry *dentry,
> struct nfs_fattr *fattr,
> >
> >  	if (pnfs_enabled_sb(server) && has_layout(nfsi) &&
> >  	    pnfs_ld_layoutret_on_setattr(server->pnfs_curr_ld))
> > -		pnfs_return_layout(inode, NULL, NULL, RETURN_FILE);
> > +		pnfs_return_layout(inode, NULL, NULL, RETURN_FILE, 1);
> >  	return nfs4_proc_setattr(dentry, fattr, sattr);
> >  }
> >  #endif /* CONFIG_NFS_V4_1 */
> > diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
> > index 2d52300..cd2ae83 100644
> > --- a/fs/nfs/nfs4state.c
> > +++ b/fs/nfs/nfs4state.c
> > @@ -598,7 +598,7 @@ static void __nfs4_close(struct path *path,
> struct nfs4_state *state, fmode_t fm
> >  			range.offset = 0;
> >  			range.length = NFS4_MAX_UINT64;
> >  			pnfs_return_layout(state->inode, &range, NULL,
> > -					   RETURN_FILE);
> > +					   RETURN_FILE, 1);
> >  		}
> >  #endif /* CONFIG_NFS_V4_1 */
> >  		nfs4_do_close(path, state, wait);
> > diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
> > index 3b4dea0..2c96723 100644
> > --- a/fs/nfs/pnfs.c
> > +++ b/fs/nfs/pnfs.c
> > @@ -610,7 +610,7 @@ get_layout(struct inode *ino,
> >   */
> >  static inline int
> >  should_free_lseg(struct pnfs_layout_segment *lseg,
> > -		   struct nfs4_pnfs_layout_segment *range)
> > +		 struct nfs4_pnfs_layout_segment *range)
> >  {
> >  	return (range->iomode == IOMODE_ANY ||
> >  		lseg->range.iomode == range->iomode) &&
> > @@ -703,6 +703,8 @@ return_layout(struct inode *ino, struct
> nfs4_pnfs_layout_segment *range,
> >
> >  	dprintk("--> %s\n", __func__);
> >
> > +	BUG_ON(type != RETURN_FILE);
> > +
> >  	lrp = kzalloc(sizeof(*lrp), GFP_KERNEL);
> >  	if (lrp == NULL) {
> >  		if (lo && (type == RETURN_FILE))
> > @@ -729,7 +731,8 @@ out:
> >  int
> >  _pnfs_return_layout(struct inode *ino, struct
> nfs4_pnfs_layout_segment *range,
> >  		    const nfs4_stateid *stateid, /* optional */
> > -		    enum pnfs_layoutreturn_type type)
> > +		    enum pnfs_layoutreturn_type type,
> > +		    int sendreturn)
> 
> s/int/bool/
> and we should use true/false rather than 1/0 in call sites.
> 
> >  {
> >  	struct pnfs_layout_type *lo = NULL;
> >  	struct nfs_inode *nfsi = NFS_I(ino);
> > @@ -739,14 +742,19 @@ _pnfs_return_layout(struct inode *ino, struct
> nfs4_pnfs_layout_segment *range,
> >  	dprintk("--> %s type %d\n", __func__, type);
> >
> >  	if (range)
> > -		arg = *range;
> > -	else {
> > +		arg.iomode = range->iomode;
> > +	else
> >  		arg.iomode = IOMODE_ANY;
> 
> how about
> 	arg.iomode = range ? range->iomode : IOMODE_ANY;
> 
> > -		arg.offset = 0;
> > -		arg.length = ~0;
> > -	}
> > +	arg.offset = 0;
> > +	arg.length = ~0;
> 
> NFS4_MAX_UINT64
> 
> > +
> >  	if (type == RETURN_FILE) {
> >  		if (nfsi->layout.layoutcommit_ctx) {
> > +			if (stateid && !sendreturn) { /* callback */
> > +				dprintk("%s: layoutcommit pending\n",
> __func__);
> > +				status = htonl(NFS4ERR_DELAY);
> 
> this function currently returns system errors, not nfs'p.
> 
> > +				goto out;
> > +			}
> >  			status = pnfs_layoutcommit_inode(ino, 1);
> >  			if (status) {
> >  				dprintk("%s: layoutcommit failed,
status=%d. "
> > @@ -763,11 +771,7 @@ _pnfs_return_layout(struct inode *ino, struct
> nfs4_pnfs_layout_segment *range,
> >  		}
> >  		if (!lo) {
> >  			dprintk("%s: no layout segments to return\n",
> __func__);
> > -			/* must send the LAYOUTRETURN in response to
recall
> */
> > -			if (stateid)
> > -				goto send_return;
> > -			else
> > -				goto out;
> > +			goto out;
> 
> what about the sendreturn case?
> 
> >  		}
> >
> >  		/* unlock w/o put rebalanced by eventual call to
> > @@ -776,13 +780,22 @@ _pnfs_return_layout(struct inode *ino, struct
> nfs4_pnfs_layout_segment *range,
> >  		unlock_current_layout(nfsi);
> >
> >  		if (pnfs_return_layout_barrier(nfsi, &arg)) {
> > +			if (stateid) { /* callback */
> > +				status = htonl(NFS4ERR_DELAY);
> 
> ditto
> 
> > +				lock_current_layout(nfsi);
> > +				put_unlock_current_layout(lo);
> > +				goto out;
> > +			}
> >  			dprintk("%s: waiting\n", __func__);
> >  			wait_event(nfsi->lo_waitq,
> > -				!pnfs_return_layout_barrier(nfsi,
&arg));
> > +				   !pnfs_return_layout_barrier(nfsi,
&arg));
> >  		}
> > +
> > +		if (sendreturn)
> > +			status = return_layout(ino, &arg, stateid, type,
lo);
> > +		else
> > +			pnfs_layout_release(lo, &arg);
> >  	}
> > -send_return:
> > -	status = return_layout(ino, &arg, stateid, type, lo);
> >  out:
> >  	dprintk("<-- %s status: %d\n", __func__, status);
> >  	return status;
> > @@ -1080,31 +1093,12 @@ pnfs_update_layout(struct inode *ino,
> >  	/* Check to see if the layout for the given range already exists
> */
> >  	lseg = pnfs_has_layout(lo, &arg, take_ref, !take_ref);
> >  	if (lseg && !lseg->valid) {
> > -		unlock_current_layout(nfsi);
> >  		if (take_ref)
> >  			put_lseg(lseg);
> > -		for (;;) {
> > -			prepare_to_wait(&nfsi->lo_waitq, &__wait,
> > -					TASK_KILLABLE);
> > -			lock_current_layout(nfsi);
> > -			lseg = pnfs_has_layout(lo, &arg, take_ref,
> !take_ref);
> > -			if (!lseg || lseg->valid)
> > -				break;
> > -			dprintk("%s: invalid lseg %p ref %d\n",
__func__,
> > -				lseg,
atomic_read(&lseg->kref.refcount)-1);
> > -			if (take_ref)
> > -				put_lseg(lseg);
> > -			if (signal_pending(current)) {
> > -				lseg = NULL;
> > -				result = -ERESTARTSYS;
> > -				break;
> > -			}
> > -			unlock_current_layout(nfsi);
> > -			schedule();
> > -		}
> > -		finish_wait(&nfsi->lo_waitq, &__wait);
> > -		if (result)
> > -			goto out_put;
> > +
> > +		/* someone is cleaning the layout */
> > +		result = -EAGAIN;
> 
> Ah well, I'm not sure if this works, did you test that?
> Anyhow, will work properly with the long awaited state machine.
> 
> > +		goto out_put;
> >  	}
> >
> >  	if (lseg) {
> > @@ -1434,7 +1428,7 @@ pnfs_pageio_init_read(struct
> nfs_pageio_descriptor *pgio,
> >
> >  	if (count > 0 && !below_threshold(inode, count, 0)) {
> >  		status = pnfs_update_layout(inode, ctx, count,
> > -						loff, IOMODE_READ,
NULL);
> > +					    loff, IOMODE_READ, NULL);
> >  		dprintk("%s *rsize %Zd virt update returned %d\n",
> >  			__func__, *rsize, status);
> >  		if (status != 0)
> > @@ -1673,7 +1667,7 @@ pnfs_writeback_done(struct nfs_write_data
> *data)
> >  			.length = data->args.count,
> >  		};
> >  		dprintk("%s: retrying\n", __func__);
> > -		_pnfs_return_layout(data->inode, &range, NULL,
> RETURN_FILE);
> > +		_pnfs_return_layout(data->inode, &range, NULL,
RETURN_FILE,
> 1);
> 
> s/1/true/
> 
> >  		pnfs_initiate_write(data, NFS_CLIENT(data->inode),
> >  				    pdata->call_ops, pdata->how);
> >  	}
> > @@ -1804,7 +1798,7 @@ pnfs_read_done(struct nfs_read_data *data)
> >  			.length = data->args.count,
> >  		};
> >  		dprintk("%s: retrying\n", __func__);
> > -		_pnfs_return_layout(data->inode, &range, NULL,
> RETURN_FILE);
> > +		_pnfs_return_layout(data->inode, &range, NULL,
RETURN_FILE,
> 1);
> 
> ditto
> 
> >  		pnfs_initiate_read(data, NFS_CLIENT(data->inode),
> >  				   pdata->call_ops);
> >  	}
> > @@ -2030,7 +2024,7 @@ pnfs_commit_done(struct nfs_write_data *data)
> >  			.length = data->args.count,
> >  		};
> >  		dprintk("%s: retrying\n", __func__);
> > -		_pnfs_return_layout(data->inode, &range, NULL,
> RETURN_FILE);
> > +		_pnfs_return_layout(data->inode, &range, NULL,
RETURN_FILE,
> 1);
> 
> ditto
> 
> >  		pnfs_initiate_commit(data, NFS_CLIENT(data->inode),
> >  				     pdata->call_ops, pdata->how);
> >  	}
> > diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
> > index 9e43973..794a2d3 100644
> > --- a/fs/nfs/pnfs.h
> > +++ b/fs/nfs/pnfs.h
> > @@ -40,7 +40,8 @@ int pnfs_update_layout(struct inode *ino, struct
> nfs_open_context *ctx,
> >
> >  int _pnfs_return_layout(struct inode *, struct
> nfs4_pnfs_layout_segment *,
> >  			const nfs4_stateid *stateid, /* optional */
> > -			enum pnfs_layoutreturn_type);
> > +			enum pnfs_layoutreturn_type,
> > +			int sendreturn);
> 
> bool
> 
> >  void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh
> *mntfh, u32 id);
> >  void unmount_pnfs_layoutdriver(struct nfs_server *);
> >  int pnfs_use_read(struct inode *inode, ssize_t count);
> > @@ -236,14 +237,15 @@ static inline void
> pnfs_modify_new_request(struct nfs_page *req,
> >  static inline int pnfs_return_layout(struct inode *ino,
> >  				     struct nfs4_pnfs_layout_segment
*lseg,
> >  				     const nfs4_stateid *stateid, /*
optional
> */
> > -				     enum pnfs_layoutreturn_type type)
> > +				     enum pnfs_layoutreturn_type type,
> > +				     int sendreturn)
> 
> bool
> 
> Thanks!
> 
> Benny
> 
> >  {
> >  	struct nfs_inode *nfsi = NFS_I(ino);
> >  	struct nfs_server *nfss = NFS_SERVER(ino);
> >
> >  	if (pnfs_enabled_sb(nfss) &&
> >  	    (type != RETURN_FILE || has_layout(nfsi)))
> > -		return _pnfs_return_layout(ino, lseg, stateid, type);
> > +		return _pnfs_return_layout(ino, lseg, stateid, type,
> sendreturn);
> >
> >  	return 0;
> >  }

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic