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 | |
| 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
| -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 | ||||
| -rw-r--r-- | include/linux/nfs_fs.h | 4 | ||||
| -rw-r--r-- | include/linux/nfs_xdr.h | 1 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/auth_gss.c | 2 | ||||
| -rw-r--r-- | net/sunrpc/xprtrdma/backchannel.c | 2 |
8 files changed, 131 insertions, 66 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 | } |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 48e0320cd643..67300f8e5f2f 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
| @@ -550,9 +550,7 @@ extern int nfs_readpage_async(struct nfs_open_context *, struct inode *, | |||
| 550 | 550 | ||
| 551 | static inline loff_t nfs_size_to_loff_t(__u64 size) | 551 | static inline loff_t nfs_size_to_loff_t(__u64 size) |
| 552 | { | 552 | { |
| 553 | if (size > (__u64) OFFSET_MAX - 1) | 553 | return min_t(u64, size, OFFSET_MAX); |
| 554 | return OFFSET_MAX - 1; | ||
| 555 | return (loff_t) size; | ||
| 556 | } | 554 | } |
| 557 | 555 | ||
| 558 | static inline ino_t | 556 | static inline ino_t |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 791098a08a87..d320906cf13e 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -275,6 +275,7 @@ struct nfs4_layoutcommit_args { | |||
| 275 | size_t layoutupdate_len; | 275 | size_t layoutupdate_len; |
| 276 | struct page *layoutupdate_page; | 276 | struct page *layoutupdate_page; |
| 277 | struct page **layoutupdate_pages; | 277 | struct page **layoutupdate_pages; |
| 278 | __be32 *start_p; | ||
| 278 | }; | 279 | }; |
| 279 | 280 | ||
| 280 | struct nfs4_layoutcommit_res { | 281 | struct nfs4_layoutcommit_res { |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 799e65b944b9..cabf586f47d7 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
| @@ -740,7 +740,7 @@ gss_pipe_downcall(struct file *filp, const char __user *src, size_t mlen) | |||
| 740 | default: | 740 | default: |
| 741 | printk(KERN_CRIT "%s: bad return from " | 741 | printk(KERN_CRIT "%s: bad return from " |
| 742 | "gss_fill_context: %zd\n", __func__, err); | 742 | "gss_fill_context: %zd\n", __func__, err); |
| 743 | BUG(); | 743 | gss_msg->msg.errno = -EIO; |
| 744 | } | 744 | } |
| 745 | goto err_release_msg; | 745 | goto err_release_msg; |
| 746 | } | 746 | } |
diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index cc1251d07297..2dcd7640eeb5 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c | |||
| @@ -341,6 +341,8 @@ void rpcrdma_bc_receive_call(struct rpcrdma_xprt *r_xprt, | |||
| 341 | rqst->rq_reply_bytes_recvd = 0; | 341 | rqst->rq_reply_bytes_recvd = 0; |
| 342 | rqst->rq_bytes_sent = 0; | 342 | rqst->rq_bytes_sent = 0; |
| 343 | rqst->rq_xid = headerp->rm_xid; | 343 | rqst->rq_xid = headerp->rm_xid; |
| 344 | |||
| 345 | rqst->rq_private_buf.len = size; | ||
| 344 | set_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state); | 346 | set_bit(RPC_BC_PA_IN_USE, &rqst->rq_bc_pa_state); |
| 345 | 347 | ||
| 346 | buf = &rqst->rq_rcv_buf; | 348 | buf = &rqst->rq_rcv_buf; |
