aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/pnfs.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 59ed68bf79fa..c00b673261f9 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -469,14 +469,6 @@ pnfs_insert_layout(struct pnfs_layout_hdr *lo,
469 dprintk("%s:Begin\n", __func__); 469 dprintk("%s:Begin\n", __func__);
470 470
471 assert_spin_locked(&lo->plh_inode->i_lock); 471 assert_spin_locked(&lo->plh_inode->i_lock);
472 if (list_empty(&lo->plh_segs)) {
473 struct nfs_client *clp = NFS_SERVER(lo->plh_inode)->nfs_client;
474
475 spin_lock(&clp->cl_lock);
476 BUG_ON(!list_empty(&lo->plh_layouts));
477 list_add_tail(&lo->plh_layouts, &clp->cl_layouts);
478 spin_unlock(&clp->cl_lock);
479 }
480 list_for_each_entry(lp, &lo->plh_segs, pls_list) { 472 list_for_each_entry(lp, &lo->plh_segs, pls_list) {
481 if (cmp_layout(lp->pls_range.iomode, lseg->pls_range.iomode) > 0) 473 if (cmp_layout(lp->pls_range.iomode, lseg->pls_range.iomode) > 0)
482 continue; 474 continue;
@@ -597,6 +589,7 @@ pnfs_update_layout(struct inode *ino,
597 enum pnfs_iomode iomode) 589 enum pnfs_iomode iomode)
598{ 590{
599 struct nfs_inode *nfsi = NFS_I(ino); 591 struct nfs_inode *nfsi = NFS_I(ino);
592 struct nfs_client *clp = NFS_SERVER(ino)->nfs_client;
600 struct pnfs_layout_hdr *lo; 593 struct pnfs_layout_hdr *lo;
601 struct pnfs_layout_segment *lseg = NULL; 594 struct pnfs_layout_segment *lseg = NULL;
602 595
@@ -626,9 +619,27 @@ pnfs_update_layout(struct inode *ino,
626 atomic_inc(&lo->plh_outstanding); 619 atomic_inc(&lo->plh_outstanding);
627 620
628 get_layout_hdr_locked(lo); 621 get_layout_hdr_locked(lo);
622 if (list_empty(&lo->plh_segs)) {
623 /* The lo must be on the clp list if there is any
624 * chance of a CB_LAYOUTRECALL(FILE) coming in.
625 */
626 spin_lock(&clp->cl_lock);
627 BUG_ON(!list_empty(&lo->plh_layouts));
628 list_add_tail(&lo->plh_layouts, &clp->cl_layouts);
629 spin_unlock(&clp->cl_lock);
630 }
629 spin_unlock(&ino->i_lock); 631 spin_unlock(&ino->i_lock);
630 632
631 lseg = send_layoutget(lo, ctx, iomode); 633 lseg = send_layoutget(lo, ctx, iomode);
634 if (!lseg) {
635 spin_lock(&ino->i_lock);
636 if (list_empty(&lo->plh_segs)) {
637 spin_lock(&clp->cl_lock);
638 list_del_init(&lo->plh_layouts);
639 spin_unlock(&clp->cl_lock);
640 }
641 spin_unlock(&ino->i_lock);
642 }
632 atomic_dec(&lo->plh_outstanding); 643 atomic_dec(&lo->plh_outstanding);
633 put_layout_hdr(ino); 644 put_layout_hdr(ino);
634out: 645out: