Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'nfs-for-3.14-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs

Pull NFS client bugfixes from Trond Myklebust:
"Highlights:

- Fix several races in nfs_revalidate_mapping
- NFSv4.1 slot leakage in the pNFS files driver
- Stable fix for a slot leak in nfs40_sequence_done
- Don't reject NFSv4 servers that support ACLs with only ALLOW aces"

* tag 'nfs-for-3.14-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
nfs: initialize the ACL support bits to zero.
NFSv4.1: Cleanup
NFSv4.1: Clean up nfs41_sequence_done
NFSv4: Fix a slot leak in nfs40_sequence_done
NFSv4.1 free slot before resending I/O to MDS
nfs: add memory barriers around NFS_INO_INVALID_DATA and NFS_INO_INVALIDATING
NFS: Fix races in nfs_revalidate_mapping
sunrpc: turn warn_gssd() log message into a dprintk()
NFS: fix the handling of NFS_INO_INVALID_DATA flag in nfs_revalidate_mapping
nfs: handle servers that support only ALLOW ACE type.

+86 -42
+11 -2
fs/nfs/dir.c
··· 274 274 return -EBADCOOKIE; 275 275 } 276 276 277 + static bool 278 + nfs_readdir_inode_mapping_valid(struct nfs_inode *nfsi) 279 + { 280 + if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) 281 + return false; 282 + smp_rmb(); 283 + return !test_bit(NFS_INO_INVALIDATING, &nfsi->flags); 284 + } 285 + 277 286 static 278 287 int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc) 279 288 { ··· 296 287 struct nfs_open_dir_context *ctx = desc->file->private_data; 297 288 298 289 new_pos = desc->current_index + i; 299 - if (ctx->attr_gencount != nfsi->attr_gencount 300 - || (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA))) { 290 + if (ctx->attr_gencount != nfsi->attr_gencount || 291 + !nfs_readdir_inode_mapping_valid(nfsi)) { 301 292 ctx->duped = 0; 302 293 ctx->attr_gencount = nfsi->attr_gencount; 303 294 } else if (new_pos < desc->ctx->pos) {
+43 -8
fs/nfs/inode.c
··· 977 977 if (ret < 0) 978 978 return ret; 979 979 } 980 - spin_lock(&inode->i_lock); 981 - nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; 982 - if (S_ISDIR(inode->i_mode)) 980 + if (S_ISDIR(inode->i_mode)) { 981 + spin_lock(&inode->i_lock); 983 982 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); 984 - spin_unlock(&inode->i_lock); 983 + spin_unlock(&inode->i_lock); 984 + } 985 985 nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); 986 986 nfs_fscache_wait_on_invalidate(inode); 987 987 ··· 1008 1008 int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) 1009 1009 { 1010 1010 struct nfs_inode *nfsi = NFS_I(inode); 1011 + unsigned long *bitlock = &nfsi->flags; 1011 1012 int ret = 0; 1012 1013 1013 1014 /* swapfiles are not supposed to be shared. */ ··· 1020 1019 if (ret < 0) 1021 1020 goto out; 1022 1021 } 1023 - if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { 1024 - trace_nfs_invalidate_mapping_enter(inode); 1025 - ret = nfs_invalidate_mapping(inode, mapping); 1026 - trace_nfs_invalidate_mapping_exit(inode, ret); 1022 + 1023 + /* 1024 + * We must clear NFS_INO_INVALID_DATA first to ensure that 1025 + * invalidations that come in while we're shooting down the mappings 1026 + * are respected. But, that leaves a race window where one revalidator 1027 + * can clear the flag, and then another checks it before the mapping 1028 + * gets invalidated. Fix that by serializing access to this part of 1029 + * the function. 1030 + * 1031 + * At the same time, we need to allow other tasks to see whether we 1032 + * might be in the middle of invalidating the pages, so we only set 1033 + * the bit lock here if it looks like we're going to be doing that. 1034 + */ 1035 + for (;;) { 1036 + ret = wait_on_bit(bitlock, NFS_INO_INVALIDATING, 1037 + nfs_wait_bit_killable, TASK_KILLABLE); 1038 + if (ret) 1039 + goto out; 1040 + spin_lock(&inode->i_lock); 1041 + if (test_bit(NFS_INO_INVALIDATING, bitlock)) { 1042 + spin_unlock(&inode->i_lock); 1043 + continue; 1044 + } 1045 + if (nfsi->cache_validity & NFS_INO_INVALID_DATA) 1046 + break; 1047 + spin_unlock(&inode->i_lock); 1048 + goto out; 1027 1049 } 1028 1050 1051 + set_bit(NFS_INO_INVALIDATING, bitlock); 1052 + smp_wmb(); 1053 + nfsi->cache_validity &= ~NFS_INO_INVALID_DATA; 1054 + spin_unlock(&inode->i_lock); 1055 + trace_nfs_invalidate_mapping_enter(inode); 1056 + ret = nfs_invalidate_mapping(inode, mapping); 1057 + trace_nfs_invalidate_mapping_exit(inode, ret); 1058 + 1059 + clear_bit_unlock(NFS_INO_INVALIDATING, bitlock); 1060 + smp_mb__after_clear_bit(); 1061 + wake_up_bit(bitlock, NFS_INO_INVALIDATING); 1029 1062 out: 1030 1063 return ret; 1031 1064 }
+1
fs/nfs/nfs4_fs.h
··· 270 270 extern int nfs41_setup_sequence(struct nfs4_session *session, 271 271 struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, 272 272 struct rpc_task *task); 273 + extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *); 273 274 extern int nfs4_proc_create_session(struct nfs_client *, struct rpc_cred *); 274 275 extern int nfs4_proc_destroy_session(struct nfs4_session *, struct rpc_cred *); 275 276 extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
+1 -4
fs/nfs/nfs4client.c
··· 372 372 __set_bit(NFS_CS_DISCRTRY, &clp->cl_flags); 373 373 __set_bit(NFS_CS_NO_RETRANS_TIMEOUT, &clp->cl_flags); 374 374 375 - error = -EINVAL; 376 - if (gssd_running(clp->cl_net)) 377 - error = nfs_create_rpc_client(clp, timeparms, 378 - RPC_AUTH_GSS_KRB5I); 375 + error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_GSS_KRB5I); 379 376 if (error == -EINVAL) 380 377 error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX); 381 378 if (error < 0)
+6 -2
fs/nfs/nfs4filelayout.c
··· 335 335 dprintk("--> %s task->tk_status %d\n", __func__, task->tk_status); 336 336 337 337 if (test_bit(NFS_IOHDR_REDO, &rdata->header->flags) && 338 - task->tk_status == 0) 338 + task->tk_status == 0) { 339 + nfs41_sequence_done(task, &rdata->res.seq_res); 339 340 return; 341 + } 340 342 341 343 /* Note this may cause RPC to be resent */ 342 344 rdata->header->mds_ops->rpc_call_done(task, data); ··· 444 442 struct nfs_write_data *wdata = data; 445 443 446 444 if (test_bit(NFS_IOHDR_REDO, &wdata->header->flags) && 447 - task->tk_status == 0) 445 + task->tk_status == 0) { 446 + nfs41_sequence_done(task, &wdata->res.seq_res); 448 447 return; 448 + } 449 449 450 450 /* Note this may cause RPC to be resent */ 451 451 wdata->header->mds_ops->rpc_call_done(task, data);
+14 -17
fs/nfs/nfs4proc.c
··· 539 539 struct nfs4_slot *slot = res->sr_slot; 540 540 struct nfs4_slot_table *tbl; 541 541 542 - if (!RPC_WAS_SENT(task)) 542 + if (slot == NULL) 543 543 goto out; 544 544 545 545 tbl = slot->table; ··· 559 559 { 560 560 struct nfs4_session *session; 561 561 struct nfs4_slot_table *tbl; 562 + struct nfs4_slot *slot = res->sr_slot; 562 563 bool send_new_highest_used_slotid = false; 563 564 564 - if (!res->sr_slot) { 565 - /* just wake up the next guy waiting since 566 - * we may have not consumed a slot after all */ 567 - dprintk("%s: No slot\n", __func__); 568 - return; 569 - } 570 - tbl = res->sr_slot->table; 565 + tbl = slot->table; 571 566 session = tbl->session; 572 567 573 568 spin_lock(&tbl->slot_tbl_lock); ··· 572 577 if (tbl->highest_used_slotid > tbl->target_highest_slotid) 573 578 send_new_highest_used_slotid = true; 574 579 575 - if (nfs41_wake_and_assign_slot(tbl, res->sr_slot)) { 580 + if (nfs41_wake_and_assign_slot(tbl, slot)) { 576 581 send_new_highest_used_slotid = false; 577 582 goto out_unlock; 578 583 } 579 - nfs4_free_slot(tbl, res->sr_slot); 584 + nfs4_free_slot(tbl, slot); 580 585 581 586 if (tbl->highest_used_slotid != NFS4_NO_SLOT) 582 587 send_new_highest_used_slotid = false; ··· 587 592 nfs41_server_notify_highest_slotid_update(session->clp); 588 593 } 589 594 590 - static int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 595 + int nfs41_sequence_done(struct rpc_task *task, struct nfs4_sequence_res *res) 591 596 { 592 597 struct nfs4_session *session; 593 - struct nfs4_slot *slot; 598 + struct nfs4_slot *slot = res->sr_slot; 594 599 struct nfs_client *clp; 595 600 bool interrupted = false; 596 601 int ret = 1; 597 602 603 + if (slot == NULL) 604 + goto out_noaction; 598 605 /* don't increment the sequence number if the task wasn't sent */ 599 606 if (!RPC_WAS_SENT(task)) 600 607 goto out; 601 608 602 - slot = res->sr_slot; 603 609 session = slot->table->session; 604 610 605 611 if (slot->interrupted) { ··· 675 679 /* The session may be reset by one of the error handlers. */ 676 680 dprintk("%s: Error %d free the slot \n", __func__, res->sr_status); 677 681 nfs41_sequence_free_slot(res); 682 + out_noaction: 678 683 return ret; 679 684 retry_nowait: 680 685 if (rpc_restart_call_prepare(task)) { ··· 689 692 rpc_delay(task, NFS4_POLL_RETRY_MAX); 690 693 return 0; 691 694 } 695 + EXPORT_SYMBOL_GPL(nfs41_sequence_done); 692 696 693 697 static int nfs4_sequence_done(struct rpc_task *task, 694 698 struct nfs4_sequence_res *res) ··· 2742 2744 NFS_CAP_OWNER_GROUP|NFS_CAP_ATIME| 2743 2745 NFS_CAP_CTIME|NFS_CAP_MTIME| 2744 2746 NFS_CAP_SECURITY_LABEL); 2745 - if (res.attr_bitmask[0] & FATTR4_WORD0_ACL) 2747 + if (res.attr_bitmask[0] & FATTR4_WORD0_ACL && 2748 + res.acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) 2746 2749 server->caps |= NFS_CAP_ACLS; 2747 2750 if (res.has_links != 0) 2748 2751 server->caps |= NFS_CAP_HARDLINKS; ··· 4320 4321 4321 4322 static inline int nfs4_server_supports_acls(struct nfs_server *server) 4322 4323 { 4323 - return (server->caps & NFS_CAP_ACLS) 4324 - && (server->acl_bitmask & ACL4_SUPPORT_ALLOW_ACL) 4325 - && (server->acl_bitmask & ACL4_SUPPORT_DENY_ACL); 4324 + return server->caps & NFS_CAP_ACLS; 4326 4325 } 4327 4326 4328 4327 /* Assuming that XATTR_SIZE_MAX is a multiple of PAGE_SIZE, and that
+1 -1
fs/nfs/nfs4xdr.c
··· 3449 3449 { 3450 3450 __be32 *p; 3451 3451 3452 - *res = ACL4_SUPPORT_ALLOW_ACL|ACL4_SUPPORT_DENY_ACL; 3452 + *res = 0; 3453 3453 if (unlikely(bitmap[0] & (FATTR4_WORD0_ACLSUPPORT - 1U))) 3454 3454 return -EIO; 3455 3455 if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) {
+1
fs/nfs/nfstrace.h
··· 36 36 __print_flags(v, "|", \ 37 37 { 1 << NFS_INO_ADVISE_RDPLUS, "ADVISE_RDPLUS" }, \ 38 38 { 1 << NFS_INO_STALE, "STALE" }, \ 39 + { 1 << NFS_INO_INVALIDATING, "INVALIDATING" }, \ 39 40 { 1 << NFS_INO_FLUSHING, "FLUSHING" }, \ 40 41 { 1 << NFS_INO_FSCACHE, "FSCACHE" }, \ 41 42 { 1 << NFS_INO_COMMIT, "COMMIT" }, \
+6 -1
fs/nfs/write.c
··· 909 909 */ 910 910 static bool nfs_write_pageuptodate(struct page *page, struct inode *inode) 911 911 { 912 + struct nfs_inode *nfsi = NFS_I(inode); 913 + 912 914 if (nfs_have_delegated_attributes(inode)) 913 915 goto out; 914 - if (NFS_I(inode)->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE)) 916 + if (nfsi->cache_validity & (NFS_INO_INVALID_DATA|NFS_INO_REVAL_PAGECACHE)) 917 + return false; 918 + smp_rmb(); 919 + if (test_bit(NFS_INO_INVALIDATING, &nfsi->flags)) 915 920 return false; 916 921 out: 917 922 return PageUptodate(page) != 0;
+1
include/linux/nfs_fs.h
··· 211 211 #define NFS_INO_ADVISE_RDPLUS (0) /* advise readdirplus */ 212 212 #define NFS_INO_STALE (1) /* possible stale inode */ 213 213 #define NFS_INO_ACL_LRU_SET (2) /* Inode is on the LRU list */ 214 + #define NFS_INO_INVALIDATING (3) /* inode is being invalidated */ 214 215 #define NFS_INO_FLUSHING (4) /* inode is flushing out data */ 215 216 #define NFS_INO_FSCACHE (5) /* inode can be cached by FS-Cache */ 216 217 #define NFS_INO_FSCACHE_LOCK (6) /* FS-Cache cookie management lock */
+1 -7
net/sunrpc/auth_gss/auth_gss.c
··· 532 532 533 533 static void warn_gssd(void) 534 534 { 535 - static unsigned long ratelimit; 536 - unsigned long now = jiffies; 537 - 538 - if (time_after(now, ratelimit)) { 539 - pr_warn("RPC: AUTH_GSS upcall failed. Please check user daemon is running.\n"); 540 - ratelimit = now + 15*HZ; 541 - } 535 + dprintk("AUTH_GSS upcall failed. Please check user daemon is running.\n"); 542 536 } 543 537 544 538 static inline int