diff options
Diffstat (limited to 'fs/lockd')
-rw-r--r-- | fs/lockd/clntxdr.c | 2 | ||||
-rw-r--r-- | fs/lockd/mon.c | 57 | ||||
-rw-r--r-- | fs/lockd/svcproc.c | 3 |
3 files changed, 35 insertions, 27 deletions
diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index d269ada7670..982d2676e1f 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c | |||
@@ -223,7 +223,7 @@ static void encode_nlm_stat(struct xdr_stream *xdr, | |||
223 | { | 223 | { |
224 | __be32 *p; | 224 | __be32 *p; |
225 | 225 | ||
226 | BUG_ON(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); | 226 | WARN_ON_ONCE(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); |
227 | p = xdr_reserve_space(xdr, 4); | 227 | p = xdr_reserve_space(xdr, 4); |
228 | *p = stat; | 228 | *p = stat; |
229 | } | 229 | } |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index e4fb3ba5a58..3d7e09bcc0e 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
@@ -85,29 +85,38 @@ static struct rpc_clnt *nsm_create(struct net *net) | |||
85 | return rpc_create(&args); | 85 | return rpc_create(&args); |
86 | } | 86 | } |
87 | 87 | ||
88 | static struct rpc_clnt *nsm_client_set(struct lockd_net *ln, | ||
89 | struct rpc_clnt *clnt) | ||
90 | { | ||
91 | spin_lock(&ln->nsm_clnt_lock); | ||
92 | if (ln->nsm_users == 0) { | ||
93 | if (clnt == NULL) | ||
94 | goto out; | ||
95 | ln->nsm_clnt = clnt; | ||
96 | } | ||
97 | clnt = ln->nsm_clnt; | ||
98 | ln->nsm_users++; | ||
99 | out: | ||
100 | spin_unlock(&ln->nsm_clnt_lock); | ||
101 | return clnt; | ||
102 | } | ||
103 | |||
88 | static struct rpc_clnt *nsm_client_get(struct net *net) | 104 | static struct rpc_clnt *nsm_client_get(struct net *net) |
89 | { | 105 | { |
90 | static DEFINE_MUTEX(nsm_create_mutex); | 106 | struct rpc_clnt *clnt, *new; |
91 | struct rpc_clnt *clnt; | ||
92 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 107 | struct lockd_net *ln = net_generic(net, lockd_net_id); |
93 | 108 | ||
94 | spin_lock(&ln->nsm_clnt_lock); | 109 | clnt = nsm_client_set(ln, NULL); |
95 | if (ln->nsm_users) { | 110 | if (clnt != NULL) |
96 | ln->nsm_users++; | ||
97 | clnt = ln->nsm_clnt; | ||
98 | spin_unlock(&ln->nsm_clnt_lock); | ||
99 | goto out; | 111 | goto out; |
100 | } | ||
101 | spin_unlock(&ln->nsm_clnt_lock); | ||
102 | 112 | ||
103 | mutex_lock(&nsm_create_mutex); | 113 | clnt = new = nsm_create(net); |
104 | clnt = nsm_create(net); | 114 | if (IS_ERR(clnt)) |
105 | if (!IS_ERR(clnt)) { | 115 | goto out; |
106 | ln->nsm_clnt = clnt; | 116 | |
107 | smp_wmb(); | 117 | clnt = nsm_client_set(ln, new); |
108 | ln->nsm_users = 1; | 118 | if (clnt != new) |
109 | } | 119 | rpc_shutdown_client(new); |
110 | mutex_unlock(&nsm_create_mutex); | ||
111 | out: | 120 | out: |
112 | return clnt; | 121 | return clnt; |
113 | } | 122 | } |
@@ -115,18 +124,16 @@ out: | |||
115 | static void nsm_client_put(struct net *net) | 124 | static void nsm_client_put(struct net *net) |
116 | { | 125 | { |
117 | struct lockd_net *ln = net_generic(net, lockd_net_id); | 126 | struct lockd_net *ln = net_generic(net, lockd_net_id); |
118 | struct rpc_clnt *clnt = ln->nsm_clnt; | 127 | struct rpc_clnt *clnt = NULL; |
119 | int shutdown = 0; | ||
120 | 128 | ||
121 | spin_lock(&ln->nsm_clnt_lock); | 129 | spin_lock(&ln->nsm_clnt_lock); |
122 | if (ln->nsm_users) { | 130 | ln->nsm_users--; |
123 | if (--ln->nsm_users) | 131 | if (ln->nsm_users == 0) { |
124 | ln->nsm_clnt = NULL; | 132 | clnt = ln->nsm_clnt; |
125 | shutdown = !ln->nsm_users; | 133 | ln->nsm_clnt = NULL; |
126 | } | 134 | } |
127 | spin_unlock(&ln->nsm_clnt_lock); | 135 | spin_unlock(&ln->nsm_clnt_lock); |
128 | 136 | if (clnt != NULL) | |
129 | if (shutdown) | ||
130 | rpc_shutdown_client(clnt); | 137 | rpc_shutdown_client(clnt); |
131 | } | 138 | } |
132 | 139 | ||
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 3009a365e08..21171f0c647 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
@@ -68,7 +68,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
68 | 68 | ||
69 | /* Obtain file pointer. Not used by FREE_ALL call. */ | 69 | /* Obtain file pointer. Not used by FREE_ALL call. */ |
70 | if (filp != NULL) { | 70 | if (filp != NULL) { |
71 | if ((error = nlm_lookup_file(rqstp, &file, &lock->fh)) != 0) | 71 | error = cast_status(nlm_lookup_file(rqstp, &file, &lock->fh)); |
72 | if (error != 0) | ||
72 | goto no_locks; | 73 | goto no_locks; |
73 | *filp = file; | 74 | *filp = file; |
74 | 75 | ||