NFSv4.1: Clean up the removal of pnfs_layout_hdr from the server list
[deliverable/linux.git] / fs / nfs / callback_proc.c
index 24252fea2c9cddb3a4640f662d8132b877bf28d4..76b4a7a3e55931e0f9cc79d08c248048cbfaa961 100644 (file)
@@ -122,7 +122,15 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp,
                        ino = igrab(lo->plh_inode);
                        if (!ino)
                                continue;
+                       spin_lock(&ino->i_lock);
+                       /* Is this layout in the process of being freed? */
+                       if (NFS_I(ino)->layout != lo) {
+                               spin_unlock(&ino->i_lock);
+                               iput(ino);
+                               continue;
+                       }
                        pnfs_get_layout_hdr(lo);
+                       spin_unlock(&ino->i_lock);
                        return lo;
                }
        }
@@ -196,9 +204,18 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
                        continue;
 
                list_for_each_entry(lo, &server->layouts, plh_layouts) {
-                       if (!igrab(lo->plh_inode))
+                       ino = igrab(lo->plh_inode);
+                       if (ino)
+                               continue;
+                       spin_lock(&ino->i_lock);
+                       /* Is this layout in the process of being freed? */
+                       if (NFS_I(ino)->layout != lo) {
+                               spin_unlock(&ino->i_lock);
+                               iput(ino);
                                continue;
+                       }
                        pnfs_get_layout_hdr(lo);
+                       spin_unlock(&ino->i_lock);
                        BUG_ON(!list_empty(&lo->plh_bulk_recall));
                        list_add(&lo->plh_bulk_recall, &recall_list);
                }
This page took 0.03944 seconds and 5 git commands to generate.