All of lore.kernel.org
 help / color / mirror / Atom feed
From: Benny Halevy <bhalevy@primarydata.com>
To: " J. Bruce Fields" <bfields@redhat.com>
Cc: linux-nfs@vger.kernel.org
Subject: [PATCH RFC v0 46/49] pnfsd: layout return generic implementation
Date: Thu, 26 Sep 2013 14:43:03 -0400	[thread overview]
Message-ID: <1380220983-14807-1-git-send-email-bhalevy@primarydata.com> (raw)
In-Reply-To: <52447EA0.7070004@primarydata.com>

Handle layout return by the generic layer for RETURN_{FILE,FSID,ALL}.
Keep track of the layout state sequence and remaining outstanding layout.
lrs_present set to false when the client returns all of its layout for the file.

Signed-off-by: Benny Halevy <bhalevy@primarydata.com>
---
 fs/nfsd/nfs4pnfsd.c             | 284 ++++++++++++++++++++++++++++++++++++++++
 fs/nfsd/nfs4proc.c              |  58 ++++++++
 fs/nfsd/nfs4state.c             |  10 +-
 fs/nfsd/nfs4xdr.c               |  49 ++++++-
 fs/nfsd/pnfsd.h                 |   1 +
 fs/nfsd/state.h                 |   3 +
 fs/nfsd/xdr4.h                  |   7 +
 include/linux/nfsd/nfsd4_pnfs.h |  10 ++
 8 files changed, 416 insertions(+), 6 deletions(-)

diff --git a/fs/nfsd/nfs4pnfsd.c b/fs/nfsd/nfs4pnfsd.c
index 1807455..2ba4a29 100644
--- a/fs/nfsd/nfs4pnfsd.c
+++ b/fs/nfsd/nfs4pnfsd.c
@@ -289,6 +289,54 @@ static void update_layout_stateid_locked(struct nfs4_layout_state *ls, stateid_t
 	dprintk("pNFS %s end\n", __func__);
 }
 
+/*
+ * Note: must be called under the layout_lock.
+ */
+static void
+dequeue_layout_for_return(struct nfs4_layout *lo,
+                          struct list_head *lo_destroy_list)
+{
+	ASSERT_LAYOUT_LOCKED();
+	list_del_init(&lo->lo_perstate);
+	list_add_tail(&lo->lo_perstate, lo_destroy_list);
+	if (list_empty(&lo->lo_state->ls_layouts)) {
+		unhash_layout_state(lo->lo_state);
+		nfsd4_unhash_stid(&lo->lo_state->ls_stid);
+	}
+}
+
+/*
+ * Note: must be called under the state lock
+ */
+static void
+destroy_layout(struct nfs4_layout *lp)
+{
+	struct nfs4_layout_state *ls;
+
+	ls = lp->lo_state;
+	dprintk("pNFS %s: lp %p ls %p ino %lu\n",
+		__func__, lp, ls, ls->ls_file->fi_inode->i_ino);
+
+	free_layout(lp);
+	/* release references taken by init_layout */
+	put_layout_state(ls);
+}
+
+/*
+ * Note: must be called under the state lock
+ */
+static void
+destroy_layout_list(struct list_head *lo_destroy_list)
+{
+	struct nfs4_layout *lp;
+
+	while (!list_empty(lo_destroy_list)) {
+		lp = list_first_entry(lo_destroy_list, struct nfs4_layout, lo_perstate);
+		list_del(&lp->lo_perstate);
+		destroy_layout(lp);
+	}
+}
+
 static u64
 alloc_init_sbid(struct super_block *sb)
 {
@@ -367,6 +415,35 @@ struct super_block *
 }
 
 /*
+ * are two octet ranges overlapping?
+ * start1            last1
+ *   |-----------------|
+ *                start2            last2
+ *                  |----------------|
+ */
+static int
+lo_seg_overlapping(struct nfsd4_layout_seg *l1, struct nfsd4_layout_seg *l2)
+{
+	u64 start1 = l1->offset;
+	u64 last1 = last_byte_offset(start1, l1->length);
+	u64 start2 = l2->offset;
+	u64 last2 = last_byte_offset(start2, l2->length);
+	int ret;
+
+	/* if last1 == start2 there's a single byte overlap */
+	ret = (last2 >= start1) && (last1 >= start2);
+	dprintk("%s: l1 %llu:%lld l2 %llu:%lld ret=%d\n", __func__,
+		l1->offset, l1->length, l2->offset, l2->length, ret);
+	return ret;
+}
+
+static int
+same_fsid_major(struct nfs4_fsid *fsid, u64 major)
+{
+	return fsid->major == major;
+}
+
+/*
  * are two octet ranges overlapping or adjacent?
  */
 static bool
@@ -578,3 +655,210 @@ struct super_block *
 	free_layout(lp);
 	goto out_unlock;
 }
+
+static void
+trim_layout(struct nfsd4_layout_seg *lo, struct nfsd4_layout_seg *lr)
+{
+	u64 lo_start = lo->offset;
+	u64 lo_end = end_offset(lo_start, lo->length);
+	u64 lr_start = lr->offset;
+	u64 lr_end = end_offset(lr_start, lr->length);
+
+	dprintk("%s:Begin lo %llu:%lld lr %llu:%lld\n", __func__,
+		lo->offset, lo->length, lr->offset, lr->length);
+
+	/* lr fully covers lo? */
+	if (lr_start <= lo_start && lo_end <= lr_end) {
+		lo->length = 0;
+		goto out;
+	}
+
+	/*
+	 * split not supported yet. retain layout segment.
+	 * remains must be returned by the client
+	 * on the final layout return.
+	 */
+	if (lo_start < lr_start && lr_end < lo_end) {
+		dprintk("%s: split not supported\n", __func__);
+		goto out;
+	}
+
+	if (lo_start < lr_start)
+		lo_end = lr_start - 1;
+	else /* lr_end < lo_end */
+		lo_start = lr_end + 1;
+
+	lo->offset = lo_start;
+	lo->length = (lo_end == NFS4_MAX_UINT64) ? lo_end : lo_end - lo_start;
+out:
+	dprintk("%s:End lo %llu:%lld\n", __func__, lo->offset, lo->length);
+}
+
+/*
+ * Note: should be called WITHOUT holding the layout_lock
+ */
+static int
+pnfs_return_file_layouts(struct nfsd4_pnfs_layoutreturn *lrp,
+			 struct nfs4_layout_state *ls,
+			 struct list_head *lo_destroy_list)
+{
+	int layouts_found = 0;
+	struct nfs4_layout *lp, *nextlp;
+
+	dprintk("%s: ls %p\n", __func__, ls);
+	lrp->lrs_present = 0;
+	spin_lock(&layout_lock);
+	list_for_each_entry_safe (lp, nextlp, &ls->ls_layouts, lo_perstate) {
+		dprintk("%s: lp %p ls %p inode %lu lo_type %x,%x iomode %d,%d\n",
+			__func__, lp, lp->lo_state,
+			lp->lo_state->ls_file->fi_inode->i_ino,
+			lp->lo_seg.layout_type, lrp->args.lr_seg.layout_type,
+			lp->lo_seg.iomode, lrp->args.lr_seg.iomode);
+		if ((lp->lo_seg.layout_type != lrp->args.lr_seg.layout_type &&
+		     lrp->args.lr_seg.layout_type) ||
+		    (lp->lo_seg.iomode != lrp->args.lr_seg.iomode &&
+		     lrp->args.lr_seg.iomode != IOMODE_ANY) ||
+		     !lo_seg_overlapping(&lp->lo_seg, &lrp->args.lr_seg)) {
+			lrp->lrs_present = 1;
+			continue;
+		}
+		layouts_found++;
+		trim_layout(&lp->lo_seg, &lrp->args.lr_seg);
+		if (!lp->lo_seg.length)
+			dequeue_layout_for_return(lp, lo_destroy_list);
+		else
+			lrp->lrs_present = 1;
+	}
+	if (ls && layouts_found && lrp->lrs_present)
+		update_layout_stateid_locked(ls, (stateid_t *)&lrp->args.lr_sid);
+	spin_unlock(&layout_lock);
+
+	return layouts_found;
+}
+
+/*
+ * Return layouts for RETURN_FSID or RETURN_ALL
+ *
+ * Note: must be called WITHOUT holding the layout lock
+ */
+static int
+pnfs_return_client_layouts(struct nfs4_client *clp,
+			   struct nfsd4_pnfs_layoutreturn *lrp,
+			   u64 ex_fsid,
+			   struct list_head *lo_destroy_list)
+{
+	int layouts_found = 0;
+	bool state_found;
+	struct nfs4_layout_state *ls, *nextls;
+	struct nfs4_layout *lp, *nextlp;
+
+	spin_lock(&layout_lock);
+	list_for_each_entry_safe (ls, nextls, &clp->cl_lo_states, ls_perclnt) {
+		if (lrp->args.lr_return_type == RETURN_FSID &&
+		    !same_fsid_major(&ls->ls_file->fi_fsid, ex_fsid))
+			continue;
+
+		/* first pass, test only */
+		state_found = false;
+		list_for_each_entry (lp, &ls->ls_layouts, lo_perstate) {
+			if (lrp->args.lr_seg.layout_type != lp->lo_seg.layout_type &&
+			    lrp->args.lr_seg.layout_type)
+				break;
+
+			if (lrp->args.lr_seg.iomode != lp->lo_seg.iomode &&
+			    lrp->args.lr_seg.iomode != IOMODE_ANY)
+				continue;
+
+			state_found = true;
+			break;
+		}
+
+		if (!state_found)
+			continue;
+
+		list_for_each_entry_safe (lp, nextlp, &ls->ls_layouts, lo_perstate) {
+			if (lrp->args.lr_seg.layout_type != lp->lo_seg.layout_type &&
+			    lrp->args.lr_seg.layout_type)
+				break;
+
+			if (lrp->args.lr_seg.iomode != lp->lo_seg.iomode &&
+			    lrp->args.lr_seg.iomode != IOMODE_ANY)
+				continue;
+
+			layouts_found++;
+			dequeue_layout_for_return(lp, lo_destroy_list);
+		}
+	}
+	spin_unlock(&layout_lock);
+	return layouts_found;
+}
+
+int nfs4_pnfs_return_layout(struct svc_rqst *rqstp,
+			    struct super_block *sb,
+			    struct svc_fh *current_fh,
+			    struct nfsd4_pnfs_layoutreturn *lrp)
+{
+	int status = 0;
+	int layouts_found = 0;
+	struct inode *ino = current_fh->fh_dentry->d_inode;
+	struct nfs4_file *fp = NULL;
+	struct nfs4_layout_state *ls = NULL;
+	struct nfs4_client *clp;
+	u64 ex_fsid = current_fh->fh_export->ex_fsid;
+	LIST_HEAD(lo_destroy_list);
+
+	dprintk("NFSD: %s\n", __func__);
+
+	nfs4_lock_state();
+	clp = find_confirmed_client(&lrp->lr_clientid,
+				    true, net_generic(SVC_NET(rqstp), nfsd_net_id));
+	if (!clp)
+		goto out_unlock;
+
+	if (lrp->args.lr_return_type == RETURN_FILE) {
+		LIST_HEAD(lo_destroy_list);
+
+		fp = find_file(ino);
+		if (!fp) {
+			dprintk("%s: RETURN_FILE: no nfs4_file for ino %p:%lu\n",
+				__func__, ino, ino ? ino->i_ino : 0L);
+			/* If we had a layout on the file the nfs4_file would
+			 * be referenced and we should have found it. Since we
+			 * don't then it means all layouts were ROC and at this
+			 * point we returned all of them on file close.
+			 */
+			goto out_unlock;
+		}
+
+		/* Check the stateid */
+		dprintk("%s PROCESS LO_STATEID inode %p\n", __func__, ino);
+		status = nfs4_process_layout_stateid(clp, fp,
+						     (stateid_t *)&lrp->args.lr_sid,
+						     NFS4_LAYOUT_STID, &ls);
+		if (status)
+			goto out_unlock;
+		layouts_found = pnfs_return_file_layouts(lrp, ls, &lo_destroy_list);
+	} else {
+		layouts_found = pnfs_return_client_layouts(clp, lrp, ex_fsid,
+							   &lo_destroy_list);
+	}
+
+	dprintk("pNFS %s: clp %p fp %p layout_type 0x%x iomode %d "
+		"return_type %d fsid 0x%llx offset %llu length %llu: "
+		"layouts_found %d\n",
+		__func__, clp, fp, lrp->args.lr_seg.layout_type,
+		lrp->args.lr_seg.iomode, lrp->args.lr_return_type,
+		ex_fsid,
+		lrp->args.lr_seg.offset, lrp->args.lr_seg.length, layouts_found);
+
+	if (ls)
+		put_layout_state(ls);
+	destroy_layout_list(&lo_destroy_list);
+out_unlock:
+	nfs4_unlock_state();
+	if (fp)
+		put_nfs4_file(fp);
+
+	dprintk("pNFS %s: exit status %d\n", __func__, status);
+	return status;
+}
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 960d8ff..54926cb 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1274,6 +1274,60 @@ static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
 out:
 	return status;
 }
+
+static __be32
+nfsd4_layoutreturn(struct svc_rqst *rqstp,
+		struct nfsd4_compound_state *cstate,
+		struct nfsd4_pnfs_layoutreturn *lrp)
+{
+	int status;
+	struct super_block *sb;
+	struct svc_fh *current_fh = &cstate->current_fh;
+
+	status = fh_verify(rqstp, current_fh, 0, NFSD_MAY_NOP);
+	if (status)
+		goto out;
+
+	status = nfserr_inval;
+	sb = current_fh->fh_dentry->d_inode->i_sb;
+	if (!sb)
+		goto out;
+
+	/* Ensure underlying file system supports pNFS and,
+	 * if so, the requested layout type
+	 */
+	status = nfsd4_layout_verify(sb, current_fh->fh_export,
+				     lrp->args.lr_seg.layout_type);
+	if (status)
+		goto out;
+
+	status = nfserr_inval;
+	if (lrp->args.lr_return_type != RETURN_FILE &&
+	    lrp->args.lr_return_type != RETURN_FSID &&
+	    lrp->args.lr_return_type != RETURN_ALL) {
+		dprintk("pNFS %s: invalid return_type %d\n", __func__,
+			lrp->args.lr_return_type);
+		goto out;
+	}
+
+	status = nfserr_inval;
+	if (lrp->args.lr_seg.iomode != IOMODE_READ &&
+	    lrp->args.lr_seg.iomode != IOMODE_RW &&
+	    lrp->args.lr_seg.iomode != IOMODE_ANY) {
+		dprintk("pNFS %s: invalid iomode %d\n", __func__,
+			lrp->args.lr_seg.iomode);
+		goto out;
+	}
+
+	/* Set clientid from sessionid */
+	copy_clientid(&lrp->lr_clientid, cstate->session);
+	lrp->lrs_present = 0;
+	status = nfs4_pnfs_return_layout(rqstp, sb, current_fh, lrp);
+out:
+	dprintk("pNFS %s: status %d return_type 0x%x lrs_present %d\n",
+		__func__, status, lrp->args.lr_return_type, lrp->lrs_present);
+	return status;
+}
 #endif /* CONFIG_PNFSD */
 
 /*
@@ -2021,6 +2075,10 @@ static inline u32 nfsd4_create_session_rsize(struct svc_rqst *rqstp, struct nfsd
 		.op_func = (nfsd4op_func)nfsd4_layoutget,
 		.op_name = "OP_LAYOUTGET",
 	},
+	[OP_LAYOUTRETURN] = {
+		.op_func = (nfsd4op_func)nfsd4_layoutreturn,
+		.op_name = "OP_LAYOUTRETURN",
+	},
 #endif /* CONFIG_PNFSD */
 };
 
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 5d5dead..a9bd82b 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -463,7 +463,7 @@ static void nfs4_put_deleg_lease(struct nfs4_file *fp)
 	}
 }
 
-static void unhash_stid(struct nfs4_stid *s)
+void nfsd4_unhash_stid(struct nfs4_stid *s)
 {
 	s->sc_type = 0;
 }
@@ -660,7 +660,7 @@ static void release_lock_stateid(struct nfs4_ol_stateid *stp)
 	struct file *file;
 
 	unhash_generic_stateid(stp);
-	unhash_stid(&stp->st_stid);
+	nfsd4_unhash_stid(&stp->st_stid);
 	file = find_any_file(stp->st_file);
 	if (file)
 		locks_remove_posix(file, (fl_owner_t)lockowner(stp->st_stateowner));
@@ -2539,6 +2539,8 @@ static void nfsd4_init_file(struct nfs4_file *fp, struct inode *ino,
 	memset(fp->fi_access, 0, sizeof(fp->fi_access));
 #if defined(CONFIG_PNFSD)
 	INIT_LIST_HEAD(&fp->fi_lo_states);
+	fp->fi_fsid.major = current_fh->fh_export->ex_fsid;
+	fp->fi_fsid.minor = 0;
 #endif /* CONFIG_PNFSD */
 	spin_lock(&recall_lock);
 	hlist_add_head(&fp->fi_hash, &file_hashtbl[hashval]);
@@ -2725,7 +2727,7 @@ static void init_open_stateid(struct nfs4_ol_stateid *stp, struct nfs4_file *fp,
 }
 
 /* search file_hashtbl[] for file */
-static struct nfs4_file *
+struct nfs4_file *
 find_file(struct inode *ino)
 {
 	unsigned int hashval = file_hashval(ino);
@@ -3233,7 +3235,7 @@ static void nfsd4_open_deleg_none_ext(struct nfsd4_open *open, int status)
 	open->op_delegate_type = NFS4_OPEN_DELEGATE_READ;
 	return;
 out_free:
-	unhash_stid(&dp->dl_stid);
+	nfsd4_unhash_stid(&dp->dl_stid);
 	nfs4_put_delegation(dp);
 out_no_deleg:
 	open->op_delegate_type = NFS4_OPEN_DELEGATE_NONE;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 1a50467..fc10dd7 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -1541,6 +1541,33 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
 
 	DECODE_TAIL;
 }
+
+static __be32
+nfsd4_decode_layoutreturn(struct nfsd4_compoundargs *argp,
+			  struct nfsd4_pnfs_layoutreturn *lrp)
+{
+	DECODE_HEAD;
+
+	READ_BUF(16);
+	READ32(lrp->args.lr_reclaim);
+	READ32(lrp->args.lr_seg.layout_type);
+	READ32(lrp->args.lr_seg.iomode);
+	READ32(lrp->args.lr_return_type);
+	if (lrp->args.lr_return_type == RETURN_FILE) {
+		READ_BUF(16);
+		READ64(lrp->args.lr_seg.offset);
+		READ64(lrp->args.lr_seg.length);
+		nfsd4_decode_stateid(argp, (stateid_t *)&lrp->args.lr_sid);
+		READ_BUF(4);
+		READ32(lrp->args.lrf_body_len);
+		if (lrp->args.lrf_body_len > 0) {
+			READ_BUF(lrp->args.lrf_body_len);
+			READMEM(lrp->args.lrf_body, lrp->args.lrf_body_len);
+		}
+	}
+
+	DECODE_TAIL;
+}
 #endif /* CONFIG_PNFSD */
 
 static __be32
@@ -1649,7 +1676,7 @@ static __be32 nfsd4_decode_reclaim_complete(struct nfsd4_compoundargs *argp, str
 	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_getdevlist,
 	[OP_LAYOUTCOMMIT]	= (nfsd4_dec)nfsd4_decode_notsupp,
 	[OP_LAYOUTGET]		= (nfsd4_dec)nfsd4_decode_layoutget,
-	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_notsupp,
+	[OP_LAYOUTRETURN]	= (nfsd4_dec)nfsd4_decode_layoutreturn,
 #else  /* CONFIG_PNFSD */
 	[OP_GETDEVICEINFO]	= (nfsd4_dec)nfsd4_decode_notsupp,
 	[OP_GETDEVICELIST]	= (nfsd4_dec)nfsd4_decode_notsupp,
@@ -3903,6 +3930,24 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
 	resp->p = p_start;
 	return nfserr;
 }
+
+static __be32
+nfsd4_encode_layoutreturn(struct nfsd4_compoundres *resp, __be32 nfserr,
+			  struct nfsd4_pnfs_layoutreturn *lrp)
+{
+	__be32 *p;
+
+	if (nfserr)
+		goto out;
+
+	RESERVE_SPACE(4);
+	WRITE32(lrp->lrs_present != 0);    /* got stateid? */
+	ADJUST_ARGS();
+	if (lrp->lrs_present)
+		nfsd4_encode_stateid(resp, (stateid_t *)&lrp->args.lr_sid);
+out:
+	return nfserr;
+}
 #endif /* CONFIG_PNFSD */
 
 static __be32
@@ -3970,7 +4015,7 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
 	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_getdevlist,
 	[OP_LAYOUTCOMMIT]	= (nfsd4_enc)nfsd4_encode_noop,
 	[OP_LAYOUTGET]		= (nfsd4_enc)nfsd4_encode_layoutget,
-	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_noop,
+	[OP_LAYOUTRETURN]	= (nfsd4_enc)nfsd4_encode_layoutreturn,
 #else  /* CONFIG_PNFSD */
 	[OP_GETDEVICEINFO]	= (nfsd4_enc)nfsd4_encode_noop,
 	[OP_GETDEVICELIST]	= (nfsd4_enc)nfsd4_encode_noop,
diff --git a/fs/nfsd/pnfsd.h b/fs/nfsd/pnfsd.h
index 1cd7a87..7ced4f3 100644
--- a/fs/nfsd/pnfsd.h
+++ b/fs/nfsd/pnfsd.h
@@ -61,6 +61,7 @@ struct nfs4_layout {
 u64 find_create_sbid(struct super_block *);
 struct super_block *find_sbid_id(u64);
 __be32 nfs4_pnfs_get_layout(struct svc_rqst *, struct nfsd4_pnfs_layoutget *, struct exp_xdr_stream *);
+int nfs4_pnfs_return_layout(struct svc_rqst *, struct super_block *, struct svc_fh *, struct nfsd4_pnfs_layoutreturn *);
 
 static inline struct nfs4_layout_state *layoutstateid(struct nfs4_stid *s)
 {
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h
index 3be7507..d2c75c5 100644
--- a/fs/nfsd/state.h
+++ b/fs/nfsd/state.h
@@ -407,6 +407,7 @@ struct nfs4_file {
 	bool			fi_had_conflict;
 #if defined(CONFIG_PNFSD)
 	struct list_head	fi_lo_states;
+	struct nfs4_fsid	fi_fsid;
 #endif /* CONFIG_PNFSD */
 };
 
@@ -489,6 +490,7 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
 extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn);
 extern void put_client_renew(struct nfs4_client *clp);
 extern void nfsd4_free_slab(struct kmem_cache **);
+extern struct nfs4_file *find_file(struct inode *);
 extern struct nfs4_file *find_alloc_file(struct inode *, struct svc_fh *);
 extern void put_nfs4_file(struct nfs4_file *);
 extern void put_nfs4_file_locked(struct nfs4_file *);
@@ -497,6 +499,7 @@ extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name,
 extern struct nfs4_stid *nfsd4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab);
 extern void nfsd4_free_stid(struct kmem_cache *slab, struct nfs4_stid *s);
 extern void nfsd4_remove_stid(struct nfs4_stid *s);
+extern void nfsd4_unhash_stid(struct nfs4_stid *s);
 extern struct nfs4_stid *nfsd4_find_stateid(struct nfs4_client *, stateid_t *);
 extern __be32 nfsd4_lookup_stateid(stateid_t *, unsigned char typemask, struct nfs4_stid **, bool sessions, struct nfsd_net *);
 
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 727288b..cfa0bcf 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -458,6 +458,12 @@ struct nfsd4_pnfs_layoutget {
 	u32			lg_roc;		/* response */
 };
 
+struct nfsd4_pnfs_layoutreturn {
+	struct nfsd4_pnfs_layoutreturn_arg args;
+	clientid_t		lr_clientid;	/* request */
+	u32			lrs_present;	/* response */
+};
+
 struct nfsd4_op {
 	int					opnum;
 	__be32					status;
@@ -507,6 +513,7 @@ struct nfsd4_op {
 		struct nfsd4_pnfs_getdevlist	pnfs_getdevlist;
 		struct nfsd4_pnfs_getdevinfo	pnfs_getdevinfo;
 		struct nfsd4_pnfs_layoutget	pnfs_layoutget;
+		struct nfsd4_pnfs_layoutreturn	pnfs_layoutreturn;
 #endif /* CONFIG_PNFSD */
 	} u;
 	struct nfs4_replay *			replay;
diff --git a/include/linux/nfsd/nfsd4_pnfs.h b/include/linux/nfsd/nfsd4_pnfs.h
index a680085..e198979 100644
--- a/include/linux/nfsd/nfsd4_pnfs.h
+++ b/include/linux/nfsd/nfsd4_pnfs.h
@@ -36,6 +36,7 @@
 
 #include <linux/exportfs.h>
 #include <linux/exp_xdr.h>
+#include <linux/nfs_xdr.h>
 
 struct nfsd4_pnfs_deviceid {
 	u64	sbid;			/* per-superblock unique ID */
@@ -86,6 +87,15 @@ struct nfsd4_pnfs_layoutget_res {
 	u32			lg_return_on_close;
 };
 
+struct nfsd4_pnfs_layoutreturn_arg {
+	u32			lr_return_type;	/* request */
+	struct nfsd4_layout_seg	lr_seg;		/* request */
+	u32			lr_reclaim;	/* request */
+	u32			lrf_body_len;	/* request */
+	void			*lrf_body;	/* request */
+	nfs4_stateid		lr_sid;		/* request/response */
+};
+
 /*
  * pNFS export operations vector.
  *
-- 
1.8.3.1


  parent reply	other threads:[~2013-09-26 18:43 UTC|newest]

Thread overview: 141+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-26 18:36 [PATCH RFC v0 0/49] pnfsd-dlm Benny Halevy
2013-09-26 18:39 ` [PATCH RFC v0 01/49] pnfsd: Define CONFIG_PNFSD Benny Halevy
2013-09-26 18:39 ` [PATCH RFC v0 02/49] pnfsd: define NFSDDBG_PNFS Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 03/49] pnfsd: return pnfs flags on exchange_id Benny Halevy
2013-09-26 21:55   ` J. Bruce Fields
2013-09-27  1:09     ` Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 04/49] pnfsd: don't set up back channel on create_session for ds Benny Halevy
2013-09-26 22:01   ` J. Bruce Fields
2013-09-27  1:20     ` Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 05/49] pnfsd: introduce pnfsd header files Benny Halevy
2013-09-29 11:43   ` Christoph Hellwig
2013-09-29 12:12     ` Benny Halevy
2013-09-29 12:13       ` Christoph Hellwig
2013-09-29 12:20         ` Benny Halevy
2013-09-29 12:21           ` Christoph Hellwig
2013-09-29 12:35             ` Christoph Hellwig
2013-09-30 15:23               ` Benny Halevy
2013-10-01 13:19                 ` Christoph Hellwig
2013-10-01  1:05               ` Boaz Harrosh
2013-10-01 13:33                 ` Christoph Hellwig
2013-10-02 11:35                   ` Benny Halevy
2013-10-02 16:06                     ` Christoph Hellwig
2013-10-01 20:30               ` J. Bruce Fields
2013-10-02 11:36                 ` Benny Halevy
2013-10-02 16:07                   ` Christoph Hellwig
2013-10-03  6:02                     ` Benny Halevy
2013-10-03  9:55                       ` Christoph Hellwig
2013-10-03 12:29                         ` Benny Halevy
2013-10-03 12:37                           ` Christoph Hellwig
2013-10-03 13:12                           ` Ric Wheeler
2013-10-03 13:17                             ` Christoph Hellwig
2013-10-03 13:18                               ` Ric Wheeler
2013-10-03 14:19                                 ` Benny Halevy
2013-10-03 14:21                                   ` Christoph Hellwig
2013-10-03 14:24                                     ` Ric Wheeler
2013-10-03 14:38                                       ` Benny Halevy
2013-10-01  1:41           ` Boaz Harrosh
2013-10-01 19:43           ` J. Bruce Fields
2013-09-26 18:40 ` [PATCH RFC v0 06/49] pnfsd: define pnfs_export_operations Benny Halevy
2013-09-27 14:39   ` J. Bruce Fields
2013-09-29 10:53     ` Benny Halevy
2013-09-29 12:14   ` Christoph Hellwig
2013-09-26 18:40 ` [PATCH RFC v0 07/49] pnfsd: add pnfs export option Benny Halevy
2013-09-27 14:36   ` J. Bruce Fields
2013-09-29 10:51     ` Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 08/49] pnfsd: layout verify Benny Halevy
2013-09-27 14:44   ` J. Bruce Fields
2013-09-29 11:16     ` Benny Halevy
2013-10-01 20:38       ` J. Bruce Fields
2013-10-02 11:42         ` Benny Halevy
2013-10-01 22:12       ` J. Bruce Fields
2013-09-26 18:40 ` [PATCH RFC v0 09/49] pnfsd: initial stub Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 10/49] pnfsd: use sbid hash table to map super_blocks to devid major identifiers Benny Halevy
2013-10-01 22:14   ` J. Bruce Fields
2013-10-02 14:32     ` Benny Halevy
2013-10-02 15:24       ` J. Bruce Fields
2013-10-11 19:56   ` Christoph Hellwig
2013-10-13  6:11     ` Benny Halevy
2013-10-13 11:08       ` Christoph Hellwig
2013-10-13 12:44         ` Benny Halevy
2013-10-14 14:15           ` Christoph Hellwig
2013-09-26 18:40 ` [PATCH RFC v0 11/49] NFSD: introduce exp_xdr.h Benny Halevy
2013-09-29 12:15   ` Christoph Hellwig
2013-09-30 15:25     ` Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 12/49] pnfsd: get device list/info Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 13/49] pnfsd: filelayout: " Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 14/49] pnfsd: provide helper for xdr encoding of deviceid Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 15/49] pnfsd: add helper functions for identifying DS filehandles Benny Halevy
2013-09-26 18:40 ` [PATCH RFC v0 16/49] pnfsd: accept all ds stateids Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 17/49] DEBUG: nfsd: more client_lock asserts Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 18/49] pnfsd: nfs4_assert_state_locked Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 19/49] pnfsd: layout get Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 20/49] pnfsd: filelayout: layout encoding Benny Halevy
2013-09-29 12:16   ` Christoph Hellwig
2013-10-01  1:15     ` Boaz Harrosh
2013-10-01 13:34       ` Christoph Hellwig
2013-10-01  6:04     ` Benny Halevy
2013-10-02 14:27     ` Benny Halevy
2013-10-02 16:09       ` Christoph Hellwig
2013-09-26 18:41 ` [PATCH RFC v0 21/49] nfsd: no need to unhash_stid before free Benny Halevy
2013-10-11 19:37   ` Christoph Hellwig
2013-10-13  6:23     ` Benny Halevy
2013-10-13 19:28       ` J. Bruce Fields
2013-09-26 18:41 ` [PATCH RFC v0 22/49] nfsd: cleanup free_stid Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 23/49] pnfsd: layout state allocation Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 24/49] pnfsd: process the layout stateid Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 25/49] pnfsd: layout state per client tracking Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 26/49] pnfsd: layout state per file tracking Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 27/49] pnfsd: hash layouts on layout state Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 28/49] pnfsd: support layout segment merging Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 29/49] pnfsd: support layout_type attribute Benny Halevy
2013-09-29 12:17   ` Christoph Hellwig
2013-10-01  1:21     ` Boaz Harrosh
2013-10-01  8:32       ` Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 30/49] pnfsd: make pnfs server return layout_blksize when the client asks for it Benny Halevy
2013-09-26 18:41 ` [PATCH RFC v0 31/49] pnfsd: add support for per-file layout_types attribute Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 32/49] pnfsd: per block device dlm data server list cache Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 33/49] pnfsd: Add IP address validation to nfsd4_set_pnfs_dlm_device() Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 34/49] pnfsd: new nfsd filesystem file: pnfs_dlm_device Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 35/49] pnfsd: nfsd4_pnfs_dlm_getdeviter Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 36/49] pnfsd: nfsd4_pnfs_dlm_getdevinfo Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 37/49] pnfsd: make /proc/fs/nfsd/pnfs_dlm_device report dlm device list Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 38/49] pnfsd: nfsd4_pnfs_dlm_layoutget Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 39/49] pnfsd: DLM file layout only support read iomode layouts Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 40/49] pnfsd: add dlm file layout layout-type Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 41/49] pnfsd: dlm pnfs_export_operations Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 42/49] pnfsd: gfs2: use generic file layout pnfs operations vector Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 43/49] pnfsd: release state lock around iput in put_nfs4_file Benny Halevy
2013-09-29 12:19   ` Christoph Hellwig
2013-10-01 13:31     ` Benny Halevy
2013-10-01 13:37       ` Christoph Hellwig
2013-10-02 14:17         ` Benny Halevy
2013-10-02 15:26         ` J. Bruce Fields
2013-10-11 19:47   ` Christoph Hellwig
2013-10-13  6:26     ` Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 44/49] posix_acl: resolve compile dependency in posix_acl.h Benny Halevy
2013-09-29 12:19   ` Christoph Hellwig
2013-10-02 14:17     ` Benny Halevy
     [not found]   ` <1380220974-14716-1-git-send-email-bhalevy-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
2013-10-02 14:36     ` [PATCH] " Benny Halevy
2013-10-02 14:36       ` Benny Halevy
2013-10-09 22:41       ` Andrew Morton
     [not found]         ` <20131009154109.13c7248c53b97d96194ca8f9-de/tnXTf+JLsfHDXvbKv3WD2FQJk+8+b@public.gmane.org>
2013-10-10  8:49           ` Benny Halevy
2013-10-10  8:49             ` Benny Halevy
2013-09-26 18:42 ` [PATCH RFC v0 45/49] nfs: resolve compile dependency in nfs_xdr.h Benny Halevy
2013-09-29 12:19   ` Christoph Hellwig
2013-10-02 14:19     ` Benny Halevy
2013-09-26 18:43 ` Benny Halevy [this message]
2013-09-26 18:43 ` [PATCH RFC v0 47/49] pnfsd: pnfs_expire_client Benny Halevy
2013-09-26 18:43 ` [PATCH RFC v0 48/49] pnfsd: return on close Benny Halevy
2013-09-26 18:43 ` [PATCH RFC v0 49/49] pnfsd: dlm set return_on_close to true Benny Halevy
2013-09-26 19:44 ` [PATCH RFC v0 0/49] pnfsd-dlm J. Bruce Fields
2013-09-26 20:06   ` Benny Halevy
2013-09-27 13:31 ` Boaz Harrosh
2013-09-27 13:34   ` Benny Halevy
2013-09-27 16:37     ` Boaz Harrosh
2013-09-27 20:19       ` Benny Halevy
2013-10-01  0:23         ` Boaz Harrosh
2013-10-01  0:29           ` Boaz Harrosh
2013-10-02  6:02           ` Benny Halevy
2013-09-29 11:42 ` Christoph Hellwig
2013-09-29 11:54   ` Benny Halevy

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=1380220983-14807-1-git-send-email-bhalevy@primarydata.com \
    --to=bhalevy@primarydata.com \
    --cc=bfields@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.