[pnfs] [PATCH] pnfs: simplify locking in pnfs_layout_process

Benny Halevy bhalevy at panasas.com
Tue Jul 15 14:03:58 EDT 2008


Embed pnfs_inject in pnfs_layout_process so that the
lo_lock spinlock can be simply taken right before
calling pnfs_insert_layout.

Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
 fs/nfs/pnfs.c |   67 ++++++++++++++++----------------------------------------
 1 files changed, 19 insertions(+), 48 deletions(-)

diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 504f1b1..fa7b08d 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -721,39 +721,6 @@ pnfs_insert_layout(struct pnfs_layout_type *lo,
 	dprintk("%s:Return\n", __func__);
 }
 
-/* DH: Inject layout blob into the I/O module.  This must happen before
- *     the I/O module has its read/write methods called.
- */
-static struct pnfs_layout_segment *
-pnfs_inject_layout(struct pnfs_layout_type *lo,
-		   struct nfs4_pnfs_layoutget_res *lgr,
-		   int take_ref)
-{
-	struct nfs_inode *nfsi = NFS_I(lo->inode);
-	struct pnfs_layout_segment *lseg;
-
-	dprintk("%s Begin\n", __func__);
-	BUG_ON_UNLOCKED_LO(lo);
-	spin_unlock(&nfsi->lo_lock);
-	lseg = PNFS_LD_IO_OPS(lo)->alloc_lseg(lo, lgr);
-	spin_lock(&nfsi->lo_lock);
-	if (!lseg || IS_ERR(lseg)) {
-		if (!lseg)
-			lseg = ERR_PTR(-ENOMEM);
-		printk(KERN_ERR "%s: Could not allocate layout: error %ld\n",
-		       __func__, PTR_ERR(lseg));
-		return lseg;
-	}
-
-	init_lseg(lo, lseg);
-	if (take_ref)
-		kref_get(&lseg->kref);
-	lseg->range = lgr->lseg;
-	pnfs_insert_layout(lo, lseg);
-	dprintk("%s Return %p\n", __func__, lseg);
-	return lseg;
-}
-
 static struct pnfs_layout_type *
 alloc_init_layout(struct inode *ino, struct layoutdriver_io_operations *io_ops)
 {
@@ -1053,24 +1020,31 @@ pnfs_layout_process(struct pnfs_layout_type *lo,
 	struct nfs_inode *nfsi = NFS_I(lo->inode);
 	int status = 0;
 
-
-	/* FIXME: This lock is just so wrong... */
-	/* Already have reference */
-	spin_lock(&nfsi->lo_lock);
-
 	/* FIXME: WTF? */
 	BUG_ON(nfsi->current_layout != lo);
 
-
 	/* Inject layout blob into I/O device driver */
-	lseg = pnfs_inject_layout(lo, res, lgp->lsegpp != NULL);
-	if (IS_ERR(lseg)) {
-		status = PTR_ERR(lseg);
-		printk(KERN_ERR "%s: ERROR!  Could not inject layout (%d)\n",
-				__func__, status);
+	lseg = PNFS_LD_IO_OPS(lo)->alloc_lseg(lo, res);
+	if (!lseg || IS_ERR(lseg)) {
+		if (!lseg)
+			status = -ENOMEM;
+		else
+			status = PTR_ERR(lseg);
+		printk(KERN_ERR "%s: Could not allocate layout: error %d\n",
+		       __func__, status);
 		goto out;
 	}
 
+	init_lseg(lo, lseg);
+	lseg->range = res->lseg;
+	if (lgp->lsegpp) {
+		kref_get(&lseg->kref);
+		*lgp->lsegpp = lseg;
+	}
+
+	spin_lock(&nfsi->lo_lock);
+	pnfs_insert_layout(lo, lseg);
+
 	if (res->return_on_close) {
 		lo->roc_iomode |= res->lseg.iomode;
 		if (!lo->roc_iomode)
@@ -1079,11 +1053,8 @@ pnfs_layout_process(struct pnfs_layout_type *lo,
 
 	/* Done processing layoutget. Set the layout stateid */
 	pnfs_set_layout_stateid(lo, &res->stateid);
-
-	if (lgp->lsegpp)
-		*lgp->lsegpp = lseg;
-out:
 	spin_unlock(&nfsi->lo_lock);
+out:
 	return status;
 }
 
-- 
1.5.6.3



More information about the pNFS mailing list