diff options
Diffstat (limited to 'net/sunrpc/clnt.c')
| -rw-r--r-- | net/sunrpc/clnt.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index d6409e757219..3e19d321067a 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -183,8 +183,7 @@ rpc_new_client(struct rpc_xprt *xprt, char *servname, | |||
| 183 | 183 | ||
| 184 | out_no_auth: | 184 | out_no_auth: |
| 185 | if (!IS_ERR(clnt->cl_dentry)) { | 185 | if (!IS_ERR(clnt->cl_dentry)) { |
| 186 | rpc_rmdir(clnt->cl_pathname); | 186 | rpc_rmdir(clnt->cl_dentry); |
| 187 | dput(clnt->cl_dentry); | ||
| 188 | rpc_put_mount(); | 187 | rpc_put_mount(); |
| 189 | } | 188 | } |
| 190 | out_no_path: | 189 | out_no_path: |
| @@ -251,10 +250,8 @@ rpc_clone_client(struct rpc_clnt *clnt) | |||
| 251 | new->cl_autobind = 0; | 250 | new->cl_autobind = 0; |
| 252 | new->cl_oneshot = 0; | 251 | new->cl_oneshot = 0; |
| 253 | new->cl_dead = 0; | 252 | new->cl_dead = 0; |
| 254 | if (!IS_ERR(new->cl_dentry)) { | 253 | if (!IS_ERR(new->cl_dentry)) |
| 255 | dget(new->cl_dentry); | 254 | dget(new->cl_dentry); |
| 256 | rpc_get_mount(); | ||
| 257 | } | ||
| 258 | rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); | 255 | rpc_init_rtt(&new->cl_rtt_default, clnt->cl_xprt->timeout.to_initval); |
| 259 | if (new->cl_auth) | 256 | if (new->cl_auth) |
| 260 | atomic_inc(&new->cl_auth->au_count); | 257 | atomic_inc(&new->cl_auth->au_count); |
| @@ -317,11 +314,15 @@ rpc_destroy_client(struct rpc_clnt *clnt) | |||
| 317 | clnt->cl_auth = NULL; | 314 | clnt->cl_auth = NULL; |
| 318 | } | 315 | } |
| 319 | if (clnt->cl_parent != clnt) { | 316 | if (clnt->cl_parent != clnt) { |
| 317 | if (!IS_ERR(clnt->cl_dentry)) | ||
| 318 | dput(clnt->cl_dentry); | ||
| 320 | rpc_destroy_client(clnt->cl_parent); | 319 | rpc_destroy_client(clnt->cl_parent); |
| 321 | goto out_free; | 320 | goto out_free; |
| 322 | } | 321 | } |
| 323 | if (clnt->cl_pathname[0]) | 322 | if (!IS_ERR(clnt->cl_dentry)) { |
| 324 | rpc_rmdir(clnt->cl_pathname); | 323 | rpc_rmdir(clnt->cl_dentry); |
| 324 | rpc_put_mount(); | ||
| 325 | } | ||
| 325 | if (clnt->cl_xprt) { | 326 | if (clnt->cl_xprt) { |
| 326 | xprt_destroy(clnt->cl_xprt); | 327 | xprt_destroy(clnt->cl_xprt); |
| 327 | clnt->cl_xprt = NULL; | 328 | clnt->cl_xprt = NULL; |
| @@ -331,10 +332,6 @@ rpc_destroy_client(struct rpc_clnt *clnt) | |||
| 331 | out_free: | 332 | out_free: |
| 332 | rpc_free_iostats(clnt->cl_metrics); | 333 | rpc_free_iostats(clnt->cl_metrics); |
| 333 | clnt->cl_metrics = NULL; | 334 | clnt->cl_metrics = NULL; |
| 334 | if (!IS_ERR(clnt->cl_dentry)) { | ||
| 335 | dput(clnt->cl_dentry); | ||
| 336 | rpc_put_mount(); | ||
| 337 | } | ||
| 338 | kfree(clnt); | 335 | kfree(clnt); |
| 339 | return 0; | 336 | return 0; |
| 340 | } | 337 | } |
| @@ -1184,6 +1181,17 @@ call_verify(struct rpc_task *task) | |||
| 1184 | u32 *p = iov->iov_base, n; | 1181 | u32 *p = iov->iov_base, n; |
| 1185 | int error = -EACCES; | 1182 | int error = -EACCES; |
| 1186 | 1183 | ||
| 1184 | if ((task->tk_rqstp->rq_rcv_buf.len & 3) != 0) { | ||
| 1185 | /* RFC-1014 says that the representation of XDR data must be a | ||
| 1186 | * multiple of four bytes | ||
| 1187 | * - if it isn't pointer subtraction in the NFS client may give | ||
| 1188 | * undefined results | ||
| 1189 | */ | ||
| 1190 | printk(KERN_WARNING | ||
| 1191 | "call_verify: XDR representation not a multiple of" | ||
| 1192 | " 4 bytes: 0x%x\n", task->tk_rqstp->rq_rcv_buf.len); | ||
| 1193 | goto out_eio; | ||
| 1194 | } | ||
| 1187 | if ((len -= 3) < 0) | 1195 | if ((len -= 3) < 0) |
| 1188 | goto out_overflow; | 1196 | goto out_overflow; |
| 1189 | p += 1; /* skip XID */ | 1197 | p += 1; /* skip XID */ |
