diff options
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r-- | fs/nfsd/nfs4proc.c | 53 |
1 files changed, 22 insertions, 31 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 8f029db5d271..5e0dc528a0e8 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -177,7 +177,7 @@ fh_dup2(struct svc_fh *dst, struct svc_fh *src) | |||
177 | fh_put(dst); | 177 | fh_put(dst); |
178 | dget(src->fh_dentry); | 178 | dget(src->fh_dentry); |
179 | if (src->fh_export) | 179 | if (src->fh_export) |
180 | cache_get(&src->fh_export->h); | 180 | exp_get(src->fh_export); |
181 | *dst = *src; | 181 | *dst = *src; |
182 | } | 182 | } |
183 | 183 | ||
@@ -385,8 +385,6 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
385 | if (nfsd4_has_session(cstate)) | 385 | if (nfsd4_has_session(cstate)) |
386 | copy_clientid(&open->op_clientid, cstate->session); | 386 | copy_clientid(&open->op_clientid, cstate->session); |
387 | 387 | ||
388 | nfs4_lock_state(); | ||
389 | |||
390 | /* check seqid for replay. set nfs4_owner */ | 388 | /* check seqid for replay. set nfs4_owner */ |
391 | resp = rqstp->rq_resp; | 389 | resp = rqstp->rq_resp; |
392 | status = nfsd4_process_open1(&resp->cstate, open, nn); | 390 | status = nfsd4_process_open1(&resp->cstate, open, nn); |
@@ -431,8 +429,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
431 | break; | 429 | break; |
432 | case NFS4_OPEN_CLAIM_PREVIOUS: | 430 | case NFS4_OPEN_CLAIM_PREVIOUS: |
433 | status = nfs4_check_open_reclaim(&open->op_clientid, | 431 | status = nfs4_check_open_reclaim(&open->op_clientid, |
434 | cstate->minorversion, | 432 | cstate, nn); |
435 | nn); | ||
436 | if (status) | 433 | if (status) |
437 | goto out; | 434 | goto out; |
438 | open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; | 435 | open->op_openowner->oo_flags |= NFS4_OO_CONFIRMED; |
@@ -461,19 +458,17 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
461 | * set, (2) sets open->op_stateid, (3) sets open->op_delegation. | 458 | * set, (2) sets open->op_stateid, (3) sets open->op_delegation. |
462 | */ | 459 | */ |
463 | status = nfsd4_process_open2(rqstp, resfh, open); | 460 | status = nfsd4_process_open2(rqstp, resfh, open); |
464 | WARN_ON(status && open->op_created); | 461 | WARN(status && open->op_created, |
462 | "nfsd4_process_open2 failed to open newly-created file! status=%u\n", | ||
463 | be32_to_cpu(status)); | ||
465 | out: | 464 | out: |
466 | if (resfh && resfh != &cstate->current_fh) { | 465 | if (resfh && resfh != &cstate->current_fh) { |
467 | fh_dup2(&cstate->current_fh, resfh); | 466 | fh_dup2(&cstate->current_fh, resfh); |
468 | fh_put(resfh); | 467 | fh_put(resfh); |
469 | kfree(resfh); | 468 | kfree(resfh); |
470 | } | 469 | } |
471 | nfsd4_cleanup_open_state(open, status); | 470 | nfsd4_cleanup_open_state(cstate, open, status); |
472 | if (open->op_openowner && !nfsd4_has_session(cstate)) | ||
473 | cstate->replay_owner = &open->op_openowner->oo_owner; | ||
474 | nfsd4_bump_seqid(cstate, status); | 471 | nfsd4_bump_seqid(cstate, status); |
475 | if (!cstate->replay_owner) | ||
476 | nfs4_unlock_state(); | ||
477 | return status; | 472 | return status; |
478 | } | 473 | } |
479 | 474 | ||
@@ -581,8 +576,12 @@ static void gen_boot_verifier(nfs4_verifier *verifier, struct net *net) | |||
581 | __be32 verf[2]; | 576 | __be32 verf[2]; |
582 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); | 577 | struct nfsd_net *nn = net_generic(net, nfsd_net_id); |
583 | 578 | ||
584 | verf[0] = (__be32)nn->nfssvc_boot.tv_sec; | 579 | /* |
585 | verf[1] = (__be32)nn->nfssvc_boot.tv_usec; | 580 | * This is opaque to client, so no need to byte-swap. Use |
581 | * __force to keep sparse happy | ||
582 | */ | ||
583 | verf[0] = (__force __be32)nn->nfssvc_boot.tv_sec; | ||
584 | verf[1] = (__force __be32)nn->nfssvc_boot.tv_usec; | ||
586 | memcpy(verifier->data, verf, sizeof(verifier->data)); | 585 | memcpy(verifier->data, verf, sizeof(verifier->data)); |
587 | } | 586 | } |
588 | 587 | ||
@@ -619,8 +618,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
619 | case NF4LNK: | 618 | case NF4LNK: |
620 | status = nfsd_symlink(rqstp, &cstate->current_fh, | 619 | status = nfsd_symlink(rqstp, &cstate->current_fh, |
621 | create->cr_name, create->cr_namelen, | 620 | create->cr_name, create->cr_namelen, |
622 | create->cr_linkname, create->cr_linklen, | 621 | create->cr_data, &resfh); |
623 | &resfh, &create->cr_iattr); | ||
624 | break; | 622 | break; |
625 | 623 | ||
626 | case NF4BLK: | 624 | case NF4BLK: |
@@ -909,8 +907,8 @@ nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstat | |||
909 | default: | 907 | default: |
910 | return nfserr_inval; | 908 | return nfserr_inval; |
911 | } | 909 | } |
912 | exp_get(cstate->current_fh.fh_export); | 910 | |
913 | sin->sin_exp = cstate->current_fh.fh_export; | 911 | sin->sin_exp = exp_get(cstate->current_fh.fh_export); |
914 | fh_put(&cstate->current_fh); | 912 | fh_put(&cstate->current_fh); |
915 | return nfs_ok; | 913 | return nfs_ok; |
916 | } | 914 | } |
@@ -1289,7 +1287,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp, | |||
1289 | * Don't use the deferral mechanism for NFSv4; compounds make it | 1287 | * Don't use the deferral mechanism for NFSv4; compounds make it |
1290 | * too hard to avoid non-idempotency problems. | 1288 | * too hard to avoid non-idempotency problems. |
1291 | */ | 1289 | */ |
1292 | rqstp->rq_usedeferral = 0; | 1290 | rqstp->rq_usedeferral = false; |
1293 | 1291 | ||
1294 | /* | 1292 | /* |
1295 | * According to RFC3010, this takes precedence over all other errors. | 1293 | * According to RFC3010, this takes precedence over all other errors. |
@@ -1391,10 +1389,7 @@ encode_op: | |||
1391 | args->ops, args->opcnt, resp->opcnt, op->opnum, | 1389 | args->ops, args->opcnt, resp->opcnt, op->opnum, |
1392 | be32_to_cpu(status)); | 1390 | be32_to_cpu(status)); |
1393 | 1391 | ||
1394 | if (cstate->replay_owner) { | 1392 | nfsd4_cstate_clear_replay(cstate); |
1395 | nfs4_unlock_state(); | ||
1396 | cstate->replay_owner = NULL; | ||
1397 | } | ||
1398 | /* XXX Ugh, we need to get rid of this kind of special case: */ | 1393 | /* XXX Ugh, we need to get rid of this kind of special case: */ |
1399 | if (op->opnum == OP_READ && op->u.read.rd_filp) | 1394 | if (op->opnum == OP_READ && op->u.read.rd_filp) |
1400 | fput(op->u.read.rd_filp); | 1395 | fput(op->u.read.rd_filp); |
@@ -1408,7 +1403,7 @@ encode_op: | |||
1408 | BUG_ON(cstate->replay_owner); | 1403 | BUG_ON(cstate->replay_owner); |
1409 | out: | 1404 | out: |
1410 | /* Reset deferral mechanism for RPC deferrals */ | 1405 | /* Reset deferral mechanism for RPC deferrals */ |
1411 | rqstp->rq_usedeferral = 1; | 1406 | rqstp->rq_usedeferral = true; |
1412 | dprintk("nfsv4 compound returned %d\n", ntohl(status)); | 1407 | dprintk("nfsv4 compound returned %d\n", ntohl(status)); |
1413 | return status; | 1408 | return status; |
1414 | } | 1409 | } |
@@ -1520,21 +1515,17 @@ static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) | |||
1520 | u32 maxcount = 0, rlen = 0; | 1515 | u32 maxcount = 0, rlen = 0; |
1521 | 1516 | ||
1522 | maxcount = svc_max_payload(rqstp); | 1517 | maxcount = svc_max_payload(rqstp); |
1523 | rlen = op->u.read.rd_length; | 1518 | rlen = min(op->u.read.rd_length, maxcount); |
1524 | |||
1525 | if (rlen > maxcount) | ||
1526 | rlen = maxcount; | ||
1527 | 1519 | ||
1528 | return (op_encode_hdr_size + 2 + XDR_QUADLEN(rlen)) * sizeof(__be32); | 1520 | return (op_encode_hdr_size + 2 + XDR_QUADLEN(rlen)) * sizeof(__be32); |
1529 | } | 1521 | } |
1530 | 1522 | ||
1531 | static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) | 1523 | static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) |
1532 | { | 1524 | { |
1533 | u32 maxcount = svc_max_payload(rqstp); | 1525 | u32 maxcount = 0, rlen = 0; |
1534 | u32 rlen = op->u.readdir.rd_maxcount; | ||
1535 | 1526 | ||
1536 | if (rlen > maxcount) | 1527 | maxcount = svc_max_payload(rqstp); |
1537 | rlen = maxcount; | 1528 | rlen = min(op->u.readdir.rd_maxcount, maxcount); |
1538 | 1529 | ||
1539 | return (op_encode_hdr_size + op_encode_verifier_maxsz + | 1530 | return (op_encode_hdr_size + op_encode_verifier_maxsz + |
1540 | XDR_QUADLEN(rlen)) * sizeof(__be32); | 1531 | XDR_QUADLEN(rlen)) * sizeof(__be32); |