[pnfs] [PATCH 22/38] [v1] pnfs: client layout cache: unlock layout around call to get_layout
Benny Halevy
bhalevy at panasas.com
Fri Jan 4 05:52:50 EST 2008
get_layout sends an rpc to the server so the layout spinlock should be
released around the call.
Signed-off-by: Benny Halevy <bhalevy at panasas.com>
---
fs/nfs/pnfs.c | 21 ++++++++++++++-------
1 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 81d9800..c95659b 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -594,8 +594,6 @@ pnfs_update_layout(struct inode *ino,
return 0; /* Already have layout information */
}
- res.layout.buf = NULL;
-
/* if get layout already failed once goto out */
if (nfsi->pnfs_layout_state & NFS_INO_LAYOUT_FAILED) {
if (unlikely(nfsi->pnfs_layout_suspend &&
@@ -609,7 +607,16 @@ pnfs_update_layout(struct inode *ino,
}
}
+ res.layout.buf = NULL;
+ spin_unlock(&nfsi->lo_lock);
result = get_layout(ino, ctx, &arg, &res);
+ spin_lock(&nfsi->lo_lock);
+
+ /* we got a reference on nfsi->current_layout hence it must never
+ * change, even while nfsi->lo_lock was not held.
+ */
+ BUG_ON(nfsi->current_layout != layout_new);
+
if (result) {
printk(KERN_ERR "%s: ERROR retrieving layout %d\n",
__FUNCTION__, result);
@@ -636,14 +643,14 @@ pnfs_update_layout(struct inode *ino,
/* mark with NFS_INO_LAYOUT_FAILED */
break;
}
- goto out;
+ goto get_out;
}
if (res.layout.len <= 0) {
printk(KERN_ERR
"%s: ERROR! Layout size is ZERO!\n", __FUNCTION__);
result = -EIO;
- goto out;
+ goto get_out;
}
/* Inject layout blob into I/O device driver */
@@ -653,7 +660,7 @@ pnfs_update_layout(struct inode *ino,
printk(KERN_ERR "%s: ERROR! Could not inject layout (%d)\n",
__FUNCTION__, result);
result = -EIO;
- goto out;
+ goto get_out;
}
if (res.return_on_close) {
@@ -664,14 +671,14 @@ pnfs_update_layout(struct inode *ino,
nfsi->current_layout = layout_new;
result = 0;
-out:
-
+get_out:
/* remember that get layout failed and don't try again */
if (result < 0)
nfsi->pnfs_layout_state |= NFS_INO_LAYOUT_FAILED;
/* res.layout.buf kalloc'ed by the xdr decoder? */
kfree(res.layout.buf);
+out:
put_unlock_current_layout(nfsi, layout_new);
ret:
dprintk("%s end (err:%d) state 0x%lx\n",
--
1.5.3.3
More information about the pNFS
mailing list