diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-02-23 19:39:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-02-23 19:39:21 -0500 |
commit | 420eb6d7efc4591ef1968106cdaa980ea06fe00e (patch) | |
tree | 28a3215400d9cfe7d5b93313402d023caee5ecbe /fs | |
parent | de9e478b9d49f3a0214310d921450cf5bb4a21e6 (diff) | |
parent | 9fd4b9fc7695a4da1363a0b439853f88fb6a034f (diff) |
Merge tag 'nfs-for-4.5-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust:
"Stable bugfixes:
- Fix nfs_size_to_loff_t
- NFSv4: Fix a dentry leak on alias use
Other bugfixes:
- Don't schedule a layoutreturn if the layout segment can be freed
immediately.
- Always set NFS_LAYOUT_RETURN_REQUESTED with lo->plh_return_iomode
- rpcrdma_bc_receive_call() should init rq_private_buf.len
- fix stateid handling for the NFS v4.2 operations
- pnfs/blocklayout: fix a memeory leak when using,vmalloc_to_page
- fix panic in gss_pipe_downcall() in fips mode
- Fix a race between layoutget and pnfs_destroy_layout
- Fix a race between layoutget and bulk recalls"
* tag 'nfs-for-4.5-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
NFSv4.x/pnfs: Fix a race between layoutget and bulk recalls
NFSv4.x/pnfs: Fix a race between layoutget and pnfs_destroy_layout
auth_gss: fix panic in gss_pipe_downcall() in fips mode
pnfs/blocklayout: fix a memeory leak when using,vmalloc_to_page
nfs4: fix stateid handling for the NFS v4.2 operations
NFSv4: Fix a dentry leak on alias use
xprtrdma: rpcrdma_bc_receive_call() should init rq_private_buf.len
pNFS: Always set NFS_LAYOUT_RETURN_REQUESTED with lo->plh_return_iomode
pNFS: Fix pnfs_mark_matching_lsegs_return()
nfs: fix nfs_size_to_loff_t
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/blocklayout/extent_tree.c | 10 | ||||
-rw-r--r-- | fs/nfs/nfs42proc.c | 119 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 4 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 55 |
4 files changed, 126 insertions, 62 deletions
diff --git a/fs/nfs/blocklayout/extent_tree.c b/fs/nfs/blocklayout/extent_tree.c index c59a59c37f3d..35ab51c04814 100644 --- a/fs/nfs/blocklayout/extent_tree.c +++ b/fs/nfs/blocklayout/extent_tree.c | |||
@@ -476,6 +476,7 @@ static void ext_tree_free_commitdata(struct nfs4_layoutcommit_args *arg, | |||
476 | 476 | ||
477 | for (i = 0; i < nr_pages; i++) | 477 | for (i = 0; i < nr_pages; i++) |
478 | put_page(arg->layoutupdate_pages[i]); | 478 | put_page(arg->layoutupdate_pages[i]); |
479 | vfree(arg->start_p); | ||
479 | kfree(arg->layoutupdate_pages); | 480 | kfree(arg->layoutupdate_pages); |
480 | } else { | 481 | } else { |
481 | put_page(arg->layoutupdate_page); | 482 | put_page(arg->layoutupdate_page); |
@@ -559,10 +560,15 @@ retry: | |||
559 | 560 | ||
560 | if (unlikely(arg->layoutupdate_pages != &arg->layoutupdate_page)) { | 561 | if (unlikely(arg->layoutupdate_pages != &arg->layoutupdate_page)) { |
561 | void *p = start_p, *end = p + arg->layoutupdate_len; | 562 | void *p = start_p, *end = p + arg->layoutupdate_len; |
563 | struct page *page = NULL; | ||
562 | int i = 0; | 564 | int i = 0; |
563 | 565 | ||
564 | for ( ; p < end; p += PAGE_SIZE) | 566 | arg->start_p = start_p; |
565 | arg->layoutupdate_pages[i++] = vmalloc_to_page(p); | 567 | for ( ; p < end; p += PAGE_SIZE) { |
568 | page = vmalloc_to_page(p); | ||
569 | arg->layoutupdate_pages[i++] = page; | ||
570 | get_page(page); | ||
571 | } | ||
566 | } | 572 | } |
567 | 573 | ||
568 | dprintk("%s found %zu ranges\n", __func__, count); | 574 | dprintk("%s found %zu ranges\n", __func__, count); |
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c index bd25dc7077f7..dff83460e5a6 100644 --- a/fs/nfs/nfs42proc.c +++ b/fs/nfs/nfs42proc.c | |||
@@ -16,29 +16,8 @@ | |||
16 | 16 | ||
17 | #define NFSDBG_FACILITY NFSDBG_PROC | 17 | #define NFSDBG_FACILITY NFSDBG_PROC |
18 | 18 | ||
19 | static int nfs42_set_rw_stateid(nfs4_stateid *dst, struct file *file, | ||
20 | fmode_t fmode) | ||
21 | { | ||
22 | struct nfs_open_context *open; | ||
23 | struct nfs_lock_context *lock; | ||
24 | int ret; | ||
25 | |||
26 | open = get_nfs_open_context(nfs_file_open_context(file)); | ||
27 | lock = nfs_get_lock_context(open); | ||
28 | if (IS_ERR(lock)) { | ||
29 | put_nfs_open_context(open); | ||
30 | return PTR_ERR(lock); | ||
31 | } | ||
32 | |||
33 | ret = nfs4_set_rw_stateid(dst, open, lock, fmode); | ||
34 | |||
35 | nfs_put_lock_context(lock); | ||
36 | put_nfs_open_context(open); | ||
37 | return ret; | ||
38 | } | ||
39 | |||
40 | static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, | 19 | static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, |
41 | loff_t offset, loff_t len) | 20 | struct nfs_lock_context *lock, loff_t offset, loff_t len) |
42 | { | 21 | { |
43 | struct inode *inode = file_inode(filep); | 22 | struct inode *inode = file_inode(filep); |
44 | struct nfs_server *server = NFS_SERVER(inode); | 23 | struct nfs_server *server = NFS_SERVER(inode); |
@@ -56,7 +35,8 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, | |||
56 | msg->rpc_argp = &args; | 35 | msg->rpc_argp = &args; |
57 | msg->rpc_resp = &res; | 36 | msg->rpc_resp = &res; |
58 | 37 | ||
59 | status = nfs42_set_rw_stateid(&args.falloc_stateid, filep, FMODE_WRITE); | 38 | status = nfs4_set_rw_stateid(&args.falloc_stateid, lock->open_context, |
39 | lock, FMODE_WRITE); | ||
60 | if (status) | 40 | if (status) |
61 | return status; | 41 | return status; |
62 | 42 | ||
@@ -78,15 +58,26 @@ static int nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep, | |||
78 | { | 58 | { |
79 | struct nfs_server *server = NFS_SERVER(file_inode(filep)); | 59 | struct nfs_server *server = NFS_SERVER(file_inode(filep)); |
80 | struct nfs4_exception exception = { }; | 60 | struct nfs4_exception exception = { }; |
61 | struct nfs_lock_context *lock; | ||
81 | int err; | 62 | int err; |
82 | 63 | ||
64 | lock = nfs_get_lock_context(nfs_file_open_context(filep)); | ||
65 | if (IS_ERR(lock)) | ||
66 | return PTR_ERR(lock); | ||
67 | |||
68 | exception.inode = file_inode(filep); | ||
69 | exception.state = lock->open_context->state; | ||
70 | |||
83 | do { | 71 | do { |
84 | err = _nfs42_proc_fallocate(msg, filep, offset, len); | 72 | err = _nfs42_proc_fallocate(msg, filep, lock, offset, len); |
85 | if (err == -ENOTSUPP) | 73 | if (err == -ENOTSUPP) { |
86 | return -EOPNOTSUPP; | 74 | err = -EOPNOTSUPP; |
75 | break; | ||
76 | } | ||
87 | err = nfs4_handle_exception(server, err, &exception); | 77 | err = nfs4_handle_exception(server, err, &exception); |
88 | } while (exception.retry); | 78 | } while (exception.retry); |
89 | 79 | ||
80 | nfs_put_lock_context(lock); | ||
90 | return err; | 81 | return err; |
91 | } | 82 | } |
92 | 83 | ||
@@ -135,7 +126,8 @@ int nfs42_proc_deallocate(struct file *filep, loff_t offset, loff_t len) | |||
135 | return err; | 126 | return err; |
136 | } | 127 | } |
137 | 128 | ||
138 | static loff_t _nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) | 129 | static loff_t _nfs42_proc_llseek(struct file *filep, |
130 | struct nfs_lock_context *lock, loff_t offset, int whence) | ||
139 | { | 131 | { |
140 | struct inode *inode = file_inode(filep); | 132 | struct inode *inode = file_inode(filep); |
141 | struct nfs42_seek_args args = { | 133 | struct nfs42_seek_args args = { |
@@ -156,7 +148,8 @@ static loff_t _nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) | |||
156 | if (!nfs_server_capable(inode, NFS_CAP_SEEK)) | 148 | if (!nfs_server_capable(inode, NFS_CAP_SEEK)) |
157 | return -ENOTSUPP; | 149 | return -ENOTSUPP; |
158 | 150 | ||
159 | status = nfs42_set_rw_stateid(&args.sa_stateid, filep, FMODE_READ); | 151 | status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context, |
152 | lock, FMODE_READ); | ||
160 | if (status) | 153 | if (status) |
161 | return status; | 154 | return status; |
162 | 155 | ||
@@ -175,17 +168,28 @@ loff_t nfs42_proc_llseek(struct file *filep, loff_t offset, int whence) | |||
175 | { | 168 | { |
176 | struct nfs_server *server = NFS_SERVER(file_inode(filep)); | 169 | struct nfs_server *server = NFS_SERVER(file_inode(filep)); |
177 | struct nfs4_exception exception = { }; | 170 | struct nfs4_exception exception = { }; |
171 | struct nfs_lock_context *lock; | ||
178 | loff_t err; | 172 | loff_t err; |
179 | 173 | ||
174 | lock = nfs_get_lock_context(nfs_file_open_context(filep)); | ||
175 | if (IS_ERR(lock)) | ||
176 | return PTR_ERR(lock); | ||
177 | |||
178 | exception.inode = file_inode(filep); | ||
179 | exception.state = lock->open_context->state; | ||
180 | |||
180 | do { | 181 | do { |
181 | err = _nfs42_proc_llseek(filep, offset, whence); | 182 | err = _nfs42_proc_llseek(filep, lock, offset, whence); |
182 | if (err >= 0) | 183 | if (err >= 0) |
183 | break; | 184 | break; |
184 | if (err == -ENOTSUPP) | 185 | if (err == -ENOTSUPP) { |
185 | return -EOPNOTSUPP; | 186 | err = -EOPNOTSUPP; |
187 | break; | ||
188 | } | ||
186 | err = nfs4_handle_exception(server, err, &exception); | 189 | err = nfs4_handle_exception(server, err, &exception); |
187 | } while (exception.retry); | 190 | } while (exception.retry); |
188 | 191 | ||
192 | nfs_put_lock_context(lock); | ||
189 | return err; | 193 | return err; |
190 | } | 194 | } |
191 | 195 | ||
@@ -298,8 +302,9 @@ int nfs42_proc_layoutstats_generic(struct nfs_server *server, | |||
298 | } | 302 | } |
299 | 303 | ||
300 | static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, | 304 | static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, |
301 | struct file *dst_f, loff_t src_offset, | 305 | struct file *dst_f, struct nfs_lock_context *src_lock, |
302 | loff_t dst_offset, loff_t count) | 306 | struct nfs_lock_context *dst_lock, loff_t src_offset, |
307 | loff_t dst_offset, loff_t count) | ||
303 | { | 308 | { |
304 | struct inode *src_inode = file_inode(src_f); | 309 | struct inode *src_inode = file_inode(src_f); |
305 | struct inode *dst_inode = file_inode(dst_f); | 310 | struct inode *dst_inode = file_inode(dst_f); |
@@ -320,11 +325,13 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f, | |||
320 | msg->rpc_argp = &args; | 325 | msg->rpc_argp = &args; |
321 | msg->rpc_resp = &res; | 326 | msg->rpc_resp = &res; |
322 | 327 | ||
323 | status = nfs42_set_rw_stateid(&args.src_stateid, src_f, FMODE_READ); | 328 | status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context, |
329 | src_lock, FMODE_READ); | ||
324 | if (status) | 330 | if (status) |
325 | return status; | 331 | return status; |
326 | 332 | ||
327 | status = nfs42_set_rw_stateid(&args.dst_stateid, dst_f, FMODE_WRITE); | 333 | status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context, |
334 | dst_lock, FMODE_WRITE); | ||
328 | if (status) | 335 | if (status) |
329 | return status; | 336 | return status; |
330 | 337 | ||
@@ -349,22 +356,48 @@ int nfs42_proc_clone(struct file *src_f, struct file *dst_f, | |||
349 | }; | 356 | }; |
350 | struct inode *inode = file_inode(src_f); | 357 | struct inode *inode = file_inode(src_f); |
351 | struct nfs_server *server = NFS_SERVER(file_inode(src_f)); | 358 | struct nfs_server *server = NFS_SERVER(file_inode(src_f)); |
352 | struct nfs4_exception exception = { }; | 359 | struct nfs_lock_context *src_lock; |
353 | int err; | 360 | struct nfs_lock_context *dst_lock; |
361 | struct nfs4_exception src_exception = { }; | ||
362 | struct nfs4_exception dst_exception = { }; | ||
363 | int err, err2; | ||
354 | 364 | ||
355 | if (!nfs_server_capable(inode, NFS_CAP_CLONE)) | 365 | if (!nfs_server_capable(inode, NFS_CAP_CLONE)) |
356 | return -EOPNOTSUPP; | 366 | return -EOPNOTSUPP; |
357 | 367 | ||
368 | src_lock = nfs_get_lock_context(nfs_file_open_context(src_f)); | ||
369 | if (IS_ERR(src_lock)) | ||
370 | return PTR_ERR(src_lock); | ||
371 | |||
372 | src_exception.inode = file_inode(src_f); | ||
373 | src_exception.state = src_lock->open_context->state; | ||
374 | |||
375 | dst_lock = nfs_get_lock_context(nfs_file_open_context(dst_f)); | ||
376 | if (IS_ERR(dst_lock)) { | ||
377 | err = PTR_ERR(dst_lock); | ||
378 | goto out_put_src_lock; | ||
379 | } | ||
380 | |||
381 | dst_exception.inode = file_inode(dst_f); | ||
382 | dst_exception.state = dst_lock->open_context->state; | ||
383 | |||
358 | do { | 384 | do { |
359 | err = _nfs42_proc_clone(&msg, src_f, dst_f, src_offset, | 385 | err = _nfs42_proc_clone(&msg, src_f, dst_f, src_lock, dst_lock, |
360 | dst_offset, count); | 386 | src_offset, dst_offset, count); |
361 | if (err == -ENOTSUPP || err == -EOPNOTSUPP) { | 387 | if (err == -ENOTSUPP || err == -EOPNOTSUPP) { |
362 | NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE; | 388 | NFS_SERVER(inode)->caps &= ~NFS_CAP_CLONE; |
363 | return -EOPNOTSUPP; | 389 | err = -EOPNOTSUPP; |
390 | break; | ||
364 | } | 391 | } |
365 | err = nfs4_handle_exception(server, err, &exception); | ||
366 | } while (exception.retry); | ||
367 | 392 | ||
368 | return err; | 393 | err2 = nfs4_handle_exception(server, err, &src_exception); |
394 | err = nfs4_handle_exception(server, err, &dst_exception); | ||
395 | if (!err) | ||
396 | err = err2; | ||
397 | } while (src_exception.retry || dst_exception.retry); | ||
369 | 398 | ||
399 | nfs_put_lock_context(dst_lock); | ||
400 | out_put_src_lock: | ||
401 | nfs_put_lock_context(src_lock); | ||
402 | return err; | ||
370 | } | 403 | } |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4bfc33ad0563..14881594dd07 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -2466,9 +2466,9 @@ static int _nfs4_open_and_get_state(struct nfs4_opendata *opendata, | |||
2466 | dentry = d_add_unique(dentry, igrab(state->inode)); | 2466 | dentry = d_add_unique(dentry, igrab(state->inode)); |
2467 | if (dentry == NULL) { | 2467 | if (dentry == NULL) { |
2468 | dentry = opendata->dentry; | 2468 | dentry = opendata->dentry; |
2469 | } else if (dentry != ctx->dentry) { | 2469 | } else { |
2470 | dput(ctx->dentry); | 2470 | dput(ctx->dentry); |
2471 | ctx->dentry = dget(dentry); | 2471 | ctx->dentry = dentry; |
2472 | } | 2472 | } |
2473 | nfs_set_verifier(dentry, | 2473 | nfs_set_verifier(dentry, |
2474 | nfs_save_change_attribute(d_inode(opendata->dir))); | 2474 | nfs_save_change_attribute(d_inode(opendata->dir))); |
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 482b6e94bb37..2fa483e6dbe2 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -252,6 +252,27 @@ pnfs_put_layout_hdr(struct pnfs_layout_hdr *lo) | |||
252 | } | 252 | } |
253 | } | 253 | } |
254 | 254 | ||
255 | /* | ||
256 | * Mark a pnfs_layout_hdr and all associated layout segments as invalid | ||
257 | * | ||
258 | * In order to continue using the pnfs_layout_hdr, a full recovery | ||
259 | * is required. | ||
260 | * Note that caller must hold inode->i_lock. | ||
261 | */ | ||
262 | static int | ||
263 | pnfs_mark_layout_stateid_invalid(struct pnfs_layout_hdr *lo, | ||
264 | struct list_head *lseg_list) | ||
265 | { | ||
266 | struct pnfs_layout_range range = { | ||
267 | .iomode = IOMODE_ANY, | ||
268 | .offset = 0, | ||
269 | .length = NFS4_MAX_UINT64, | ||
270 | }; | ||
271 | |||
272 | set_bit(NFS_LAYOUT_INVALID_STID, &lo->plh_flags); | ||
273 | return pnfs_mark_matching_lsegs_invalid(lo, lseg_list, &range); | ||
274 | } | ||
275 | |||
255 | static int | 276 | static int |
256 | pnfs_iomode_to_fail_bit(u32 iomode) | 277 | pnfs_iomode_to_fail_bit(u32 iomode) |
257 | { | 278 | { |
@@ -554,9 +575,8 @@ pnfs_destroy_layout(struct nfs_inode *nfsi) | |||
554 | spin_lock(&nfsi->vfs_inode.i_lock); | 575 | spin_lock(&nfsi->vfs_inode.i_lock); |
555 | lo = nfsi->layout; | 576 | lo = nfsi->layout; |
556 | if (lo) { | 577 | if (lo) { |
557 | lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */ | ||
558 | pnfs_mark_matching_lsegs_invalid(lo, &tmp_list, NULL); | ||
559 | pnfs_get_layout_hdr(lo); | 578 | pnfs_get_layout_hdr(lo); |
579 | pnfs_mark_layout_stateid_invalid(lo, &tmp_list); | ||
560 | pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED); | 580 | pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RO_FAILED); |
561 | pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED); | 581 | pnfs_layout_clear_fail_bit(lo, NFS_LAYOUT_RW_FAILED); |
562 | spin_unlock(&nfsi->vfs_inode.i_lock); | 582 | spin_unlock(&nfsi->vfs_inode.i_lock); |
@@ -617,11 +637,6 @@ pnfs_layout_free_bulk_destroy_list(struct list_head *layout_list, | |||
617 | { | 637 | { |
618 | struct pnfs_layout_hdr *lo; | 638 | struct pnfs_layout_hdr *lo; |
619 | struct inode *inode; | 639 | struct inode *inode; |
620 | struct pnfs_layout_range range = { | ||
621 | .iomode = IOMODE_ANY, | ||
622 | .offset = 0, | ||
623 | .length = NFS4_MAX_UINT64, | ||
624 | }; | ||
625 | LIST_HEAD(lseg_list); | 640 | LIST_HEAD(lseg_list); |
626 | int ret = 0; | 641 | int ret = 0; |
627 | 642 | ||
@@ -636,11 +651,11 @@ pnfs_layout_free_bulk_destroy_list(struct list_head *layout_list, | |||
636 | 651 | ||
637 | spin_lock(&inode->i_lock); | 652 | spin_lock(&inode->i_lock); |
638 | list_del_init(&lo->plh_bulk_destroy); | 653 | list_del_init(&lo->plh_bulk_destroy); |
639 | lo->plh_block_lgets++; /* permanently block new LAYOUTGETs */ | 654 | if (pnfs_mark_layout_stateid_invalid(lo, &lseg_list)) { |
640 | if (is_bulk_recall) | 655 | if (is_bulk_recall) |
641 | set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); | 656 | set_bit(NFS_LAYOUT_BULK_RECALL, &lo->plh_flags); |
642 | if (pnfs_mark_matching_lsegs_invalid(lo, &lseg_list, &range)) | ||
643 | ret = -EAGAIN; | 657 | ret = -EAGAIN; |
658 | } | ||
644 | spin_unlock(&inode->i_lock); | 659 | spin_unlock(&inode->i_lock); |
645 | pnfs_free_lseg_list(&lseg_list); | 660 | pnfs_free_lseg_list(&lseg_list); |
646 | /* Free all lsegs that are attached to commit buckets */ | 661 | /* Free all lsegs that are attached to commit buckets */ |
@@ -1738,8 +1753,19 @@ pnfs_set_plh_return_iomode(struct pnfs_layout_hdr *lo, enum pnfs_iomode iomode) | |||
1738 | if (lo->plh_return_iomode != 0) | 1753 | if (lo->plh_return_iomode != 0) |
1739 | iomode = IOMODE_ANY; | 1754 | iomode = IOMODE_ANY; |
1740 | lo->plh_return_iomode = iomode; | 1755 | lo->plh_return_iomode = iomode; |
1756 | set_bit(NFS_LAYOUT_RETURN_REQUESTED, &lo->plh_flags); | ||
1741 | } | 1757 | } |
1742 | 1758 | ||
1759 | /** | ||
1760 | * pnfs_mark_matching_lsegs_return - Free or return matching layout segments | ||
1761 | * @lo: pointer to layout header | ||
1762 | * @tmp_list: list header to be used with pnfs_free_lseg_list() | ||
1763 | * @return_range: describe layout segment ranges to be returned | ||
1764 | * | ||
1765 | * This function is mainly intended for use by layoutrecall. It attempts | ||
1766 | * to free the layout segment immediately, or else to mark it for return | ||
1767 | * as soon as its reference count drops to zero. | ||
1768 | */ | ||
1743 | int | 1769 | int |
1744 | pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, | 1770 | pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, |
1745 | struct list_head *tmp_list, | 1771 | struct list_head *tmp_list, |
@@ -1762,12 +1788,11 @@ pnfs_mark_matching_lsegs_return(struct pnfs_layout_hdr *lo, | |||
1762 | lseg, lseg->pls_range.iomode, | 1788 | lseg, lseg->pls_range.iomode, |
1763 | lseg->pls_range.offset, | 1789 | lseg->pls_range.offset, |
1764 | lseg->pls_range.length); | 1790 | lseg->pls_range.length); |
1791 | if (mark_lseg_invalid(lseg, tmp_list)) | ||
1792 | continue; | ||
1793 | remaining++; | ||
1765 | set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags); | 1794 | set_bit(NFS_LSEG_LAYOUTRETURN, &lseg->pls_flags); |
1766 | pnfs_set_plh_return_iomode(lo, return_range->iomode); | 1795 | pnfs_set_plh_return_iomode(lo, return_range->iomode); |
1767 | if (!mark_lseg_invalid(lseg, tmp_list)) | ||
1768 | remaining++; | ||
1769 | set_bit(NFS_LAYOUT_RETURN_REQUESTED, | ||
1770 | &lo->plh_flags); | ||
1771 | } | 1796 | } |
1772 | return remaining; | 1797 | return remaining; |
1773 | } | 1798 | } |