aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4proc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4proc.c')
-rw-r--r--fs/nfsd/nfs4proc.c53
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));
465out: 464out:
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);
1409out: 1404out:
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
1531static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) 1523static 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);