From: Greg Kroah-Hartman Date: Tue, 18 Nov 2014 20:24:26 +0000 (-0800) Subject: 3.10-stable patches X-Git-Tag: v3.10.61~25 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e30bf88394273a4e8fdcc087f9ed5a5098a83428;p=thirdparty%2Fkernel%2Fstable-queue.git 3.10-stable patches added patches: nfs-don-t-try-to-reclaim-delegation-open-state-if-recovery-failed.patch nfs-fix-use-of-uninitialized-variable-in-nfs_getattr.patch nfsv4-ensure-that-we-remove-nfsv4.0-delegations-when-state-has-expired.patch nfsv4-fix-races-between-nfs_remove_bad_delegation-and-delegation-return.patch --- diff --git a/queue-3.10/nfs-don-t-try-to-reclaim-delegation-open-state-if-recovery-failed.patch b/queue-3.10/nfs-don-t-try-to-reclaim-delegation-open-state-if-recovery-failed.patch new file mode 100644 index 00000000000..6ad4dc1874a --- /dev/null +++ b/queue-3.10/nfs-don-t-try-to-reclaim-delegation-open-state-if-recovery-failed.patch @@ -0,0 +1,31 @@ +From f8ebf7a8ca35dde321f0cd385fee6f1950609367 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 17 Oct 2014 23:02:52 +0300 +Subject: NFS: Don't try to reclaim delegation open state if recovery failed + +From: Trond Myklebust + +commit f8ebf7a8ca35dde321f0cd385fee6f1950609367 upstream. + +If state recovery failed, then we should not attempt to reclaim delegated +state. + +http://lkml.kernel.org/r/CAN-5tyHwG=Cn2Q9KsHWadewjpTTy_K26ee+UnSvHvG4192p-Xw@mail.gmail.com +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/delegation.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -108,6 +108,8 @@ again: + continue; + if (!test_bit(NFS_DELEGATED_STATE, &state->flags)) + continue; ++ if (!nfs4_valid_open_stateid(state)) ++ continue; + if (!nfs4_stateid_match(&state->stateid, stateid)) + continue; + get_nfs_open_context(ctx); diff --git a/queue-3.10/nfs-fix-use-of-uninitialized-variable-in-nfs_getattr.patch b/queue-3.10/nfs-fix-use-of-uninitialized-variable-in-nfs_getattr.patch new file mode 100644 index 00000000000..648601d3853 --- /dev/null +++ b/queue-3.10/nfs-fix-use-of-uninitialized-variable-in-nfs_getattr.patch @@ -0,0 +1,32 @@ +From 16caf5b6101d03335b386e77e9e14136f989be87 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Thu, 23 Oct 2014 14:02:47 +0200 +Subject: nfs: Fix use of uninitialized variable in nfs_getattr() + +From: Jan Kara + +commit 16caf5b6101d03335b386e77e9e14136f989be87 upstream. + +Variable 'err' needn't be initialized when nfs_getattr() uses it to +check whether it should call generic_fillattr() or not. That can result +in spurious error returns. Initialize 'err' properly. + +Signed-off-by: Jan Kara +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/inode.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/fs/nfs/inode.c ++++ b/fs/nfs/inode.c +@@ -519,7 +519,7 @@ int nfs_getattr(struct vfsmount *mnt, st + { + struct inode *inode = dentry->d_inode; + int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; +- int err; ++ int err = 0; + + /* Flush out writes to the server in order to update c/mtime. */ + if (S_ISREG(inode->i_mode)) { diff --git a/queue-3.10/nfsv4-ensure-that-we-remove-nfsv4.0-delegations-when-state-has-expired.patch b/queue-3.10/nfsv4-ensure-that-we-remove-nfsv4.0-delegations-when-state-has-expired.patch new file mode 100644 index 00000000000..65e2ac4913b --- /dev/null +++ b/queue-3.10/nfsv4-ensure-that-we-remove-nfsv4.0-delegations-when-state-has-expired.patch @@ -0,0 +1,61 @@ +From 4dfd4f7af0afd201706ad186352ca423b0f17d4b Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Fri, 17 Oct 2014 15:10:25 +0300 +Subject: NFSv4: Ensure that we remove NFSv4.0 delegations when state has expired + +From: Trond Myklebust + +commit 4dfd4f7af0afd201706ad186352ca423b0f17d4b upstream. + +NFSv4.0 does not have TEST_STATEID/FREE_STATEID functionality, so +unlike NFSv4.1, the recovery procedure when stateids have expired or +have been revoked requires us to just forget the delegation. + +http://lkml.kernel.org/r/CAN-5tyHwG=Cn2Q9KsHWadewjpTTy_K26ee+UnSvHvG4192p-Xw@mail.gmail.com +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/nfs4proc.c | 24 +++++++++++++++++++++++- + 1 file changed, 23 insertions(+), 1 deletion(-) + +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1845,6 +1845,28 @@ static int nfs4_open_expired(struct nfs4 + return ret; + } + ++static void nfs_finish_clear_delegation_stateid(struct nfs4_state *state) ++{ ++ nfs_remove_bad_delegation(state->inode); ++ write_seqlock(&state->seqlock); ++ nfs4_stateid_copy(&state->stateid, &state->open_stateid); ++ write_sequnlock(&state->seqlock); ++ clear_bit(NFS_DELEGATED_STATE, &state->flags); ++} ++ ++static void nfs40_clear_delegation_stateid(struct nfs4_state *state) ++{ ++ if (rcu_access_pointer(NFS_I(state->inode)->delegation) != NULL) ++ nfs_finish_clear_delegation_stateid(state); ++} ++ ++static int nfs40_open_expired(struct nfs4_state_owner *sp, struct nfs4_state *state) ++{ ++ /* NFSv4.0 doesn't allow for delegation recovery on open expire */ ++ nfs40_clear_delegation_stateid(state); ++ return nfs4_open_expired(sp, state); ++} ++ + #if defined(CONFIG_NFS_V4_1) + static void nfs41_clear_delegation_stateid(struct nfs4_state *state) + { +@@ -6974,7 +6996,7 @@ static const struct nfs4_state_recovery_ + static const struct nfs4_state_recovery_ops nfs40_nograce_recovery_ops = { + .owner_flag_bit = NFS_OWNER_RECLAIM_NOGRACE, + .state_flag_bit = NFS_STATE_RECLAIM_NOGRACE, +- .recover_open = nfs4_open_expired, ++ .recover_open = nfs40_open_expired, + .recover_lock = nfs4_lock_expired, + .establish_clid = nfs4_init_clientid, + .get_clid_cred = nfs4_get_setclientid_cred, diff --git a/queue-3.10/nfsv4-fix-races-between-nfs_remove_bad_delegation-and-delegation-return.patch b/queue-3.10/nfsv4-fix-races-between-nfs_remove_bad_delegation-and-delegation-return.patch new file mode 100644 index 00000000000..75896c45e24 --- /dev/null +++ b/queue-3.10/nfsv4-fix-races-between-nfs_remove_bad_delegation-and-delegation-return.patch @@ -0,0 +1,105 @@ +From 869f9dfa4d6d57b79e0afc3af14772c2a023eeb1 Mon Sep 17 00:00:00 2001 +From: Trond Myklebust +Date: Mon, 10 Nov 2014 18:43:56 -0500 +Subject: NFSv4: Fix races between nfs_remove_bad_delegation() and delegation return + +From: Trond Myklebust + +commit 869f9dfa4d6d57b79e0afc3af14772c2a023eeb1 upstream. + +Any attempt to call nfs_remove_bad_delegation() while a delegation is being +returned is currently a no-op. This means that we can end up looping +forever in nfs_end_delegation_return() if something causes the delegation +to be revoked. +This patch adds a mechanism whereby the state recovery code can communicate +to the delegation return code that the delegation is no longer valid and +that it should not be used when reclaiming state. +It also changes the return value for nfs4_handle_delegation_recall_error() +to ensure that nfs_end_delegation_return() does not reattempt the lock +reclaim before state recovery is done. + +http://lkml.kernel.org/r/CAN-5tyHwG=Cn2Q9KsHWadewjpTTy_K26ee+UnSvHvG4192p-Xw@mail.gmail.com +Signed-off-by: Trond Myklebust +Signed-off-by: Greg Kroah-Hartman + +--- + fs/nfs/delegation.c | 23 +++++++++++++++++++++-- + fs/nfs/delegation.h | 1 + + fs/nfs/nfs4proc.c | 2 +- + 3 files changed, 23 insertions(+), 3 deletions(-) + +--- a/fs/nfs/delegation.c ++++ b/fs/nfs/delegation.c +@@ -177,7 +177,11 @@ static int nfs_do_return_delegation(stru + { + int res = 0; + +- res = nfs4_proc_delegreturn(inode, delegation->cred, &delegation->stateid, issync); ++ if (!test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) ++ res = nfs4_proc_delegreturn(inode, ++ delegation->cred, ++ &delegation->stateid, ++ issync); + nfs_free_delegation(delegation); + return res; + } +@@ -363,11 +367,13 @@ static int nfs_end_delegation_return(str + { + struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; + struct nfs_inode *nfsi = NFS_I(inode); +- int err; ++ int err = 0; + + if (delegation == NULL) + return 0; + do { ++ if (test_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) ++ break; + err = nfs_delegation_claim_opens(inode, &delegation->stateid); + if (!issync || err != -EAGAIN) + break; +@@ -588,10 +594,23 @@ static void nfs_client_mark_return_unuse + rcu_read_unlock(); + } + ++static void nfs_revoke_delegation(struct inode *inode) ++{ ++ struct nfs_delegation *delegation; ++ rcu_read_lock(); ++ delegation = rcu_dereference(NFS_I(inode)->delegation); ++ if (delegation != NULL) { ++ set_bit(NFS_DELEGATION_REVOKED, &delegation->flags); ++ nfs_mark_return_delegation(NFS_SERVER(inode), delegation); ++ } ++ rcu_read_unlock(); ++} ++ + void nfs_remove_bad_delegation(struct inode *inode) + { + struct nfs_delegation *delegation; + ++ nfs_revoke_delegation(inode); + delegation = nfs_inode_detach_delegation(inode); + if (delegation) { + nfs_inode_find_state_and_recover(inode, &delegation->stateid); +--- a/fs/nfs/delegation.h ++++ b/fs/nfs/delegation.h +@@ -31,6 +31,7 @@ enum { + NFS_DELEGATION_RETURN_IF_CLOSED, + NFS_DELEGATION_REFERENCED, + NFS_DELEGATION_RETURNING, ++ NFS_DELEGATION_REVOKED, + }; + + int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res); +--- a/fs/nfs/nfs4proc.c ++++ b/fs/nfs/nfs4proc.c +@@ -1416,7 +1416,7 @@ static int nfs4_handle_delegation_recall + nfs_inode_find_state_and_recover(state->inode, + stateid); + nfs4_schedule_stateid_recovery(server, state); +- return 0; ++ return -EAGAIN; + case -NFS4ERR_DELAY: + case -NFS4ERR_GRACE: + set_bit(NFS_DELEGATED_STATE, &state->flags); diff --git a/queue-3.10/series b/queue-3.10/series index d75d862c64b..741834fe71f 100644 --- a/queue-3.10/series +++ b/queue-3.10/series @@ -32,3 +32,7 @@ dm-btree-fix-a-recursion-depth-bug-in-btree-walking-code.patch dm-raid-ensure-superblock-s-size-matches-device-s-logical-block-size.patch input-alps-ignore-potential-bare-packets-when-device-is-out-of-sync.patch input-alps-allow-up-to-2-invalid-packets-without-resetting-device.patch +nfsv4-ensure-that-we-remove-nfsv4.0-delegations-when-state-has-expired.patch +nfs-don-t-try-to-reclaim-delegation-open-state-if-recovery-failed.patch +nfs-fix-use-of-uninitialized-variable-in-nfs_getattr.patch +nfsv4-fix-races-between-nfs_remove_bad_delegation-and-delegation-return.patch