diff options
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/pnfs.c | 27 |
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); |
634 | out: | 645 | out: |