aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-01-28 14:50:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2017-01-28 14:50:17 -0500
commitd56a5ca366e785f463b4782f65daac883612a2b2 (patch)
tree26ff9bf940fc911e81ab22717d9e6c3258c74bf8
parentdd553962675ab5747e887f89aea1ece90e6a802e (diff)
parentee6625a948d2e47267ec8fd97307fdd67d0f8a5b (diff)
Merge tag 'nfs-for-4.10-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull NFS client bugfixes from Trond Myklebust: "Stable patches: - NFSv4.1: Fix a deadlock in layoutget - NFSv4 must not bump sequence ids on NFS4ERR_MOVED errors - NFSv4 Fix a regression with OPEN EXCLUSIVE4 mode - Fix a memory leak when removing the SUNRPC module Bugfixes: - Fix a reference leak in _pnfs_return_layout" * tag 'nfs-for-4.10-4' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: pNFS: Fix a reference leak in _pnfs_return_layout nfs: Fix "Don't increment lock sequence ID after NFS4ERR_MOVED" SUNRPC: cleanup ida information when removing sunrpc module NFSv4.0: always send mode in SETATTR after EXCLUSIVE4 nfs: Don't increment lock sequence ID after NFS4ERR_MOVED NFSv4.1: Fix a deadlock in layoutget
-rw-r--r--fs/nfs/nfs4proc.c4
-rw-r--r--fs/nfs/nfs4state.c1
-rw-r--r--fs/nfs/pnfs.c2
-rw-r--r--include/linux/nfs4.h3
-rw-r--r--include/linux/sunrpc/clnt.h1
-rw-r--r--net/sunrpc/clnt.c5
-rw-r--r--net/sunrpc/sunrpc_syms.c1
7 files changed, 14 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index ecc151697fd4..0a0eaecf9676 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -2700,7 +2700,8 @@ static inline void nfs4_exclusive_attrset(struct nfs4_opendata *opendata,
2700 sattr->ia_valid |= ATTR_MTIME; 2700 sattr->ia_valid |= ATTR_MTIME;
2701 2701
2702 /* Except MODE, it seems harmless of setting twice. */ 2702 /* Except MODE, it seems harmless of setting twice. */
2703 if ((attrset[1] & FATTR4_WORD1_MODE)) 2703 if (opendata->o_arg.createmode != NFS4_CREATE_EXCLUSIVE &&
2704 attrset[1] & FATTR4_WORD1_MODE)
2704 sattr->ia_valid &= ~ATTR_MODE; 2705 sattr->ia_valid &= ~ATTR_MODE;
2705 2706
2706 if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL) 2707 if (attrset[2] & FATTR4_WORD2_SECURITY_LABEL)
@@ -8490,6 +8491,7 @@ nfs4_layoutget_handle_exception(struct rpc_task *task,
8490 goto out; 8491 goto out;
8491 } 8492 }
8492 8493
8494 nfs4_sequence_free_slot(&lgp->res.seq_res);
8493 err = nfs4_handle_exception(server, nfs4err, exception); 8495 err = nfs4_handle_exception(server, nfs4err, exception);
8494 if (!status) { 8496 if (!status) {
8495 if (exception->retry) 8497 if (exception->retry)
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 90e6193ce6be..daeb94e3acd4 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1091,6 +1091,7 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
1091 case -NFS4ERR_BADXDR: 1091 case -NFS4ERR_BADXDR:
1092 case -NFS4ERR_RESOURCE: 1092 case -NFS4ERR_RESOURCE:
1093 case -NFS4ERR_NOFILEHANDLE: 1093 case -NFS4ERR_NOFILEHANDLE:
1094 case -NFS4ERR_MOVED:
1094 /* Non-seqid mutating errors */ 1095 /* Non-seqid mutating errors */
1095 return; 1096 return;
1096 }; 1097 };
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 59554f3adf29..dd042498ce7c 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1200,10 +1200,10 @@ _pnfs_return_layout(struct inode *ino)
1200 1200
1201 send = pnfs_prepare_layoutreturn(lo, &stateid, NULL); 1201 send = pnfs_prepare_layoutreturn(lo, &stateid, NULL);
1202 spin_unlock(&ino->i_lock); 1202 spin_unlock(&ino->i_lock);
1203 pnfs_free_lseg_list(&tmp_list);
1204 if (send) 1203 if (send)
1205 status = pnfs_send_layoutreturn(lo, &stateid, IOMODE_ANY, true); 1204 status = pnfs_send_layoutreturn(lo, &stateid, IOMODE_ANY, true);
1206out_put_layout_hdr: 1205out_put_layout_hdr:
1206 pnfs_free_lseg_list(&tmp_list);
1207 pnfs_put_layout_hdr(lo); 1207 pnfs_put_layout_hdr(lo);
1208out: 1208out:
1209 dprintk("<-- %s status: %d\n", __func__, status); 1209 dprintk("<-- %s status: %d\n", __func__, status);
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index bca536341d1a..1b1ca04820a3 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -282,7 +282,7 @@ enum nfsstat4 {
282 282
283static inline bool seqid_mutating_err(u32 err) 283static inline bool seqid_mutating_err(u32 err)
284{ 284{
285 /* rfc 3530 section 8.1.5: */ 285 /* See RFC 7530, section 9.1.7 */
286 switch (err) { 286 switch (err) {
287 case NFS4ERR_STALE_CLIENTID: 287 case NFS4ERR_STALE_CLIENTID:
288 case NFS4ERR_STALE_STATEID: 288 case NFS4ERR_STALE_STATEID:
@@ -291,6 +291,7 @@ static inline bool seqid_mutating_err(u32 err)
291 case NFS4ERR_BADXDR: 291 case NFS4ERR_BADXDR:
292 case NFS4ERR_RESOURCE: 292 case NFS4ERR_RESOURCE:
293 case NFS4ERR_NOFILEHANDLE: 293 case NFS4ERR_NOFILEHANDLE:
294 case NFS4ERR_MOVED:
294 return false; 295 return false;
295 }; 296 };
296 return true; 297 return true;
diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h
index 85cc819676e8..333ad11b3dd9 100644
--- a/include/linux/sunrpc/clnt.h
+++ b/include/linux/sunrpc/clnt.h
@@ -216,5 +216,6 @@ void rpc_clnt_xprt_switch_put(struct rpc_clnt *);
216void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *); 216void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *, struct rpc_xprt *);
217bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt, 217bool rpc_clnt_xprt_switch_has_addr(struct rpc_clnt *clnt,
218 const struct sockaddr *sap); 218 const struct sockaddr *sap);
219void rpc_cleanup_clids(void);
219#endif /* __KERNEL__ */ 220#endif /* __KERNEL__ */
220#endif /* _LINUX_SUNRPC_CLNT_H */ 221#endif /* _LINUX_SUNRPC_CLNT_H */
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c
index 1efbe48e794f..1dc9f3bac099 100644
--- a/net/sunrpc/clnt.c
+++ b/net/sunrpc/clnt.c
@@ -336,6 +336,11 @@ out:
336 336
337static DEFINE_IDA(rpc_clids); 337static DEFINE_IDA(rpc_clids);
338 338
339void rpc_cleanup_clids(void)
340{
341 ida_destroy(&rpc_clids);
342}
343
339static int rpc_alloc_clid(struct rpc_clnt *clnt) 344static int rpc_alloc_clid(struct rpc_clnt *clnt)
340{ 345{
341 int clid; 346 int clid;
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index d1c330a7953a..c73de181467a 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -119,6 +119,7 @@ out:
119static void __exit 119static void __exit
120cleanup_sunrpc(void) 120cleanup_sunrpc(void)
121{ 121{
122 rpc_cleanup_clids();
122 rpcauth_remove_module(); 123 rpcauth_remove_module();
123 cleanup_socket_xprt(); 124 cleanup_socket_xprt();
124 svc_cleanup_xprt_sock(); 125 svc_cleanup_xprt_sock();