diff options
Diffstat (limited to 'fs/nfs/callback_proc.c')
-rw-r--r-- | fs/nfs/callback_proc.c | 31 |
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; |