aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pnfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/pnfs.c')
-rw-r--r--fs/nfs/pnfs.c33
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
758pnfs_layout_bulk_destroy_byserver_locked(struct nfs_client *clp, 758pnfs_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}