diff options
Diffstat (limited to 'fs/nfs/callback_proc.c')
| -rw-r--r-- | fs/nfs/callback_proc.c | 61 |
1 files changed, 8 insertions, 53 deletions
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index 264d1aa935f2..2960512792c2 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
| @@ -183,60 +183,15 @@ static u32 initiate_file_draining(struct nfs_client *clp, | |||
| 183 | static u32 initiate_bulk_draining(struct nfs_client *clp, | 183 | static u32 initiate_bulk_draining(struct nfs_client *clp, |
| 184 | struct cb_layoutrecallargs *args) | 184 | struct cb_layoutrecallargs *args) |
| 185 | { | 185 | { |
| 186 | struct nfs_server *server; | 186 | int stat; |
| 187 | struct pnfs_layout_hdr *lo; | ||
| 188 | struct inode *ino; | ||
| 189 | u32 rv = NFS4ERR_NOMATCHING_LAYOUT; | ||
| 190 | struct pnfs_layout_hdr *tmp; | ||
| 191 | LIST_HEAD(recall_list); | ||
| 192 | LIST_HEAD(free_me_list); | ||
| 193 | struct pnfs_layout_range range = { | ||
| 194 | .iomode = IOMODE_ANY, | ||
| 195 | .offset = 0, | ||
| 196 | .length = NFS4_MAX_UINT64, | ||
| 197 | }; | ||
| 198 | |||
| 199 | spin_lock(&clp->cl_lock); | ||
| 200 | rcu_read_lock(); | ||
| 201 | list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { | ||
| 202 | if ((args->cbl_recall_type == RETURN_FSID) && | ||
| 203 | memcmp(&server->fsid, &args->cbl_fsid, | ||
| 204 | sizeof(struct nfs_fsid))) | ||
| 205 | continue; | ||
| 206 | 187 | ||
| 207 | list_for_each_entry(lo, &server->layouts, plh_layouts) { | 188 | if (args->cbl_recall_type == RETURN_FSID) |
| 208 | ino = igrab(lo->plh_inode); | 189 | stat = pnfs_destroy_layouts_byfsid(clp, &args->cbl_fsid, true); |
| 209 | if (!ino) | 190 | else |
| 210 | continue; | 191 | stat = pnfs_destroy_layouts_byclid(clp, true); |
| 211 | spin_lock(&ino->i_lock); | 192 | if (stat != 0) |
| 212 | /* Is this layout in the process of being freed? */ | 193 | return NFS4ERR_DELAY; |
| 213 | if (NFS_I(ino)->layout != lo) { | 194 | return NFS4ERR_NOMATCHING_LAYOUT; |
| 214 | spin_unlock(&ino->i_lock); | ||
| 215 | iput(ino); | ||
| 216 | continue; | ||
| 217 | } | ||
| 218 | pnfs_get_layout_hdr(lo); | ||
| 219 | spin_unlock(&ino->i_lock); | ||
| 220 | list_add(&lo->plh_bulk_recall, &recall_list); | ||
| 221 | } | ||
| 222 | } | ||
| 223 | rcu_read_unlock(); | ||
| 224 | spin_unlock(&clp->cl_lock); | ||
| 225 | |||
| 226 | list_for_each_entry_safe(lo, tmp, | ||
| 227 | &recall_list, plh_bulk_recall) { | ||
| 228 | ino = lo->plh_inode; | ||
| 229 | spin_lock(&ino->i_lock); | ||
| 230 | set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); | ||
| 231 | if (pnfs_mark_matching_lsegs_invalid(lo, &free_me_list, &range)) | ||
| 232 | rv = NFS4ERR_DELAY; | ||
| 233 | list_del_init(&lo->plh_bulk_recall); | ||
| 234 | spin_unlock(&ino->i_lock); | ||
| 235 | pnfs_free_lseg_list(&free_me_list); | ||
| 236 | pnfs_put_layout_hdr(lo); | ||
| 237 | iput(ino); | ||
| 238 | } | ||
| 239 | return rv; | ||
| 240 | } | 195 | } |
| 241 | 196 | ||
| 242 | static u32 do_callback_layoutrecall(struct nfs_client *clp, | 197 | static u32 do_callback_layoutrecall(struct nfs_client *clp, |
