diff options
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r-- | fs/nfs/pnfs.c | 33 |
1 files changed, 23 insertions, 10 deletions
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 53726da5c010..8247bd1634cb 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -758,22 +758,35 @@ static int | |||
758 | pnfs_layout_bulk_destroy_byserver_locked(struct nfs_client *clp, | 758 | pnfs_layout_bulk_destroy_byserver_locked(struct nfs_client *clp, |
759 | struct nfs_server *server, | 759 | struct nfs_server *server, |
760 | struct list_head *layout_list) | 760 | struct list_head *layout_list) |
761 | __must_hold(&clp->cl_lock) | ||
762 | __must_hold(RCU) | ||
761 | { | 763 | { |
762 | struct pnfs_layout_hdr *lo, *next; | 764 | struct pnfs_layout_hdr *lo, *next; |
763 | struct inode *inode; | 765 | struct inode *inode; |
764 | 766 | ||
765 | list_for_each_entry_safe(lo, next, &server->layouts, plh_layouts) { | 767 | list_for_each_entry_safe(lo, next, &server->layouts, plh_layouts) { |
766 | if (test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags)) | 768 | if (test_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags) || |
769 | test_bit(NFS_LAYOUT_INODE_FREEING, &lo->plh_flags) || | ||
770 | !list_empty(&lo->plh_bulk_destroy)) | ||
767 | continue; | 771 | continue; |
772 | /* If the sb is being destroyed, just bail */ | ||
773 | if (!nfs_sb_active(server->super)) | ||
774 | break; | ||
768 | inode = igrab(lo->plh_inode); | 775 | inode = igrab(lo->plh_inode); |
769 | if (inode == NULL) | 776 | if (inode != NULL) { |
770 | continue; | 777 | list_del_init(&lo->plh_layouts); |
771 | list_del_init(&lo->plh_layouts); | 778 | if (pnfs_layout_add_bulk_destroy_list(inode, |
772 | if (pnfs_layout_add_bulk_destroy_list(inode, layout_list)) | 779 | layout_list)) |
773 | continue; | 780 | continue; |
774 | rcu_read_unlock(); | 781 | rcu_read_unlock(); |
775 | spin_unlock(&clp->cl_lock); | 782 | spin_unlock(&clp->cl_lock); |
776 | iput(inode); | 783 | iput(inode); |
784 | } else { | ||
785 | rcu_read_unlock(); | ||
786 | spin_unlock(&clp->cl_lock); | ||
787 | set_bit(NFS_LAYOUT_INODE_FREEING, &lo->plh_flags); | ||
788 | } | ||
789 | nfs_sb_deactive(server->super); | ||
777 | spin_lock(&clp->cl_lock); | 790 | spin_lock(&clp->cl_lock); |
778 | rcu_read_lock(); | 791 | rcu_read_lock(); |
779 | return -EAGAIN; | 792 | return -EAGAIN; |
@@ -811,7 +824,7 @@ pnfs_layout_free_bulk_destroy_list(struct list_head *layout_list, | |||
811 | /* Free all lsegs that are attached to commit buckets */ | 824 | /* Free all lsegs that are attached to commit buckets */ |
812 | nfs_commit_inode(inode, 0); | 825 | nfs_commit_inode(inode, 0); |
813 | pnfs_put_layout_hdr(lo); | 826 | pnfs_put_layout_hdr(lo); |
814 | iput(inode); | 827 | nfs_iput_and_deactive(inode); |
815 | } | 828 | } |
816 | return ret; | 829 | return ret; |
817 | } | 830 | } |