[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