aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c99
1 files changed, 35 insertions, 64 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index dc792b6b4513..b92dc9e08973 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1429,90 +1429,61 @@ static struct lock_manager_operations nfsd_lease_mng_ops = {
1429}; 1429};
1430 1430
1431 1431
1432/*
1433 * nfsd4_process_open1()
1434 * lookup stateowner.
1435 * found:
1436 * check confirmed
1437 * confirmed:
1438 * check seqid
1439 * not confirmed:
1440 * delete owner
1441 * create new owner
1442 * notfound:
1443 * verify clientid
1444 * create new owner
1445 *
1446 * called with nfs4_lock_state() held.
1447 */
1448int 1432int
1449nfsd4_process_open1(struct nfsd4_open *open) 1433nfsd4_process_open1(struct nfsd4_open *open)
1450{ 1434{
1451 int status;
1452 clientid_t *clientid = &open->op_clientid; 1435 clientid_t *clientid = &open->op_clientid;
1453 struct nfs4_client *clp = NULL; 1436 struct nfs4_client *clp = NULL;
1454 unsigned int strhashval; 1437 unsigned int strhashval;
1455 struct nfs4_stateowner *sop = NULL; 1438 struct nfs4_stateowner *sop = NULL;
1456 1439
1457 status = nfserr_inval;
1458 if (!check_name(open->op_owner)) 1440 if (!check_name(open->op_owner))
1459 goto out; 1441 return nfserr_inval;
1460 1442
1461 if (STALE_CLIENTID(&open->op_clientid)) 1443 if (STALE_CLIENTID(&open->op_clientid))
1462 return nfserr_stale_clientid; 1444 return nfserr_stale_clientid;
1463 1445
1464 strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner); 1446 strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner);
1465 sop = find_openstateowner_str(strhashval, open); 1447 sop = find_openstateowner_str(strhashval, open);
1466 if (sop) { 1448 open->op_stateowner = sop;
1467 open->op_stateowner = sop; 1449 if (!sop) {
1468 if (!sop->so_confirmed) { 1450 /* Make sure the client's lease hasn't expired. */
1469 /* Replace any unconfirmed stateowner without
1470 * even checking for replays */
1471 clp = sop->so_client;
1472 release_stateowner(sop);
1473 } else if (open->op_seqid == sop->so_seqid) {
1474 /* normal case */
1475 goto renew;
1476 } else if (open->op_seqid == sop->so_seqid - 1) {
1477 /* replay */
1478 if (sop->so_replay.rp_buflen)
1479 return NFSERR_REPLAY_ME;
1480 else {
1481 /* The original OPEN failed so spectacularly
1482 * that we don't even have replay data saved!
1483 * Therefore, we have no choice but to continue
1484 * processing this OPEN; presumably, we'll
1485 * fail again for the same reason.
1486 */
1487 dprintk("nfsd4_process_open1:"
1488 " replay with no replay cache\n");
1489 goto renew;
1490 }
1491 } else {
1492 status = nfserr_bad_seqid;
1493 goto out;
1494 }
1495 } else {
1496 /* nfs4_stateowner not found.
1497 * Verify clientid and instantiate new nfs4_stateowner.
1498 * If verify fails this is presumably the result of the
1499 * client's lease expiring.
1500 */
1501 status = nfserr_expired;
1502 clp = find_confirmed_client(clientid); 1451 clp = find_confirmed_client(clientid);
1503 if (clp == NULL) 1452 if (clp == NULL)
1504 goto out; 1453 return nfserr_expired;
1454 goto renew;
1505 } 1455 }
1506 status = nfserr_resource; 1456 if (!sop->so_confirmed) {
1507 sop = alloc_init_open_stateowner(strhashval, clp, open); 1457 /* Replace unconfirmed owners without checking for replay. */
1508 if (sop == NULL) 1458 clp = sop->so_client;
1509 goto out; 1459 release_stateowner(sop);
1510 open->op_stateowner = sop; 1460 open->op_stateowner = NULL;
1461 goto renew;
1462 }
1463 if (open->op_seqid == sop->so_seqid - 1) {
1464 if (sop->so_replay.rp_buflen)
1465 return NFSERR_REPLAY_ME;
1466 /* The original OPEN failed so spectacularly
1467 * that we don't even have replay data saved!
1468 * Therefore, we have no choice but to continue
1469 * processing this OPEN; presumably, we'll
1470 * fail again for the same reason.
1471 */
1472 dprintk("nfsd4_process_open1: replay with no replay cache\n");
1473 goto renew;
1474 }
1475 if (open->op_seqid != sop->so_seqid)
1476 return nfserr_bad_seqid;
1511renew: 1477renew:
1512 status = nfs_ok; 1478 if (open->op_stateowner == NULL) {
1479 sop = alloc_init_open_stateowner(strhashval, clp, open);
1480 if (sop == NULL)
1481 return nfserr_resource;
1482 open->op_stateowner = sop;
1483 }
1484 list_del_init(&sop->so_close_lru);
1513 renew_client(sop->so_client); 1485 renew_client(sop->so_client);
1514out: 1486 return nfs_ok;
1515 return status;
1516} 1487}
1517 1488
1518static inline int 1489static inline int