aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/callback_proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/callback_proc.c')
-rw-r--r--fs/nfs/callback_proc.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 1b5d809a105e..76b4a7a3e559 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -122,7 +122,15 @@ static struct pnfs_layout_hdr * get_layout_by_fh_locked(struct nfs_client *clp,
122 ino = igrab(lo->plh_inode); 122 ino = igrab(lo->plh_inode);
123 if (!ino) 123 if (!ino)
124 continue; 124 continue;
125 get_layout_hdr(lo); 125 spin_lock(&ino->i_lock);
126 /* Is this layout in the process of being freed? */
127 if (NFS_I(ino)->layout != lo) {
128 spin_unlock(&ino->i_lock);
129 iput(ino);
130 continue;
131 }
132 pnfs_get_layout_hdr(lo);
133 spin_unlock(&ino->i_lock);
126 return lo; 134 return lo;
127 } 135 }
128 } 136 }
@@ -158,7 +166,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
158 ino = lo->plh_inode; 166 ino = lo->plh_inode;
159 spin_lock(&ino->i_lock); 167 spin_lock(&ino->i_lock);
160 if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) || 168 if (test_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags) ||
161 mark_matching_lsegs_invalid(lo, &free_me_list, 169 pnfs_mark_matching_lsegs_invalid(lo, &free_me_list,
162 &args->cbl_range)) 170 &args->cbl_range))
163 rv = NFS4ERR_DELAY; 171 rv = NFS4ERR_DELAY;
164 else 172 else
@@ -166,7 +174,7 @@ static u32 initiate_file_draining(struct nfs_client *clp,
166 pnfs_set_layout_stateid(lo, &args->cbl_stateid, true); 174 pnfs_set_layout_stateid(lo, &args->cbl_stateid, true);
167 spin_unlock(&ino->i_lock); 175 spin_unlock(&ino->i_lock);
168 pnfs_free_lseg_list(&free_me_list); 176 pnfs_free_lseg_list(&free_me_list);
169 put_layout_hdr(lo); 177 pnfs_put_layout_hdr(lo);
170 iput(ino); 178 iput(ino);
171 return rv; 179 return rv;
172} 180}
@@ -196,9 +204,18 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
196 continue; 204 continue;
197 205
198 list_for_each_entry(lo, &server->layouts, plh_layouts) { 206 list_for_each_entry(lo, &server->layouts, plh_layouts) {
199 if (!igrab(lo->plh_inode)) 207 ino = igrab(lo->plh_inode);
208 if (ino)
209 continue;
210 spin_lock(&ino->i_lock);
211 /* Is this layout in the process of being freed? */
212 if (NFS_I(ino)->layout != lo) {
213 spin_unlock(&ino->i_lock);
214 iput(ino);
200 continue; 215 continue;
201 get_layout_hdr(lo); 216 }
217 pnfs_get_layout_hdr(lo);
218 spin_unlock(&ino->i_lock);
202 BUG_ON(!list_empty(&lo->plh_bulk_recall)); 219 BUG_ON(!list_empty(&lo->plh_bulk_recall));
203 list_add(&lo->plh_bulk_recall, &recall_list); 220 list_add(&lo->plh_bulk_recall, &recall_list);
204 } 221 }
@@ -211,12 +228,12 @@ static u32 initiate_bulk_draining(struct nfs_client *clp,
211 ino = lo->plh_inode; 228 ino = lo->plh_inode;
212 spin_lock(&ino->i_lock); 229 spin_lock(&ino->i_lock);
213 set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); 230 set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags);
214 if (mark_matching_lsegs_invalid(lo, &free_me_list, &range)) 231 if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, &range))
215 rv = NFS4ERR_DELAY; 232 rv = NFS4ERR_DELAY;
216 list_del_init(&lo->plh_bulk_recall); 233 list_del_init(&lo->plh_bulk_recall);
217 spin_unlock(&ino->i_lock); 234 spin_unlock(&ino->i_lock);
218 pnfs_free_lseg_list(&free_me_list); 235 pnfs_free_lseg_list(&free_me_list);
219 put_layout_hdr(lo); 236 pnfs_put_layout_hdr(lo);
220 iput(ino); 237 iput(ino);
221 } 238 }
222 return rv; 239 return rv;