diff options
Diffstat (limited to 'fs/nfsd/nfs4state.c')
| -rw-r--r-- | fs/nfsd/nfs4state.c | 220 |
1 files changed, 80 insertions, 140 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 6bbefd06f10d..1143cfb64549 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
| @@ -1088,7 +1088,7 @@ alloc_init_open_stateowner(unsigned int strhashval, struct nfs4_client *clp, str | |||
| 1088 | sop->so_seqid = open->op_seqid; | 1088 | sop->so_seqid = open->op_seqid; |
| 1089 | sop->so_confirmed = 0; | 1089 | sop->so_confirmed = 0; |
| 1090 | rp = &sop->so_replay; | 1090 | rp = &sop->so_replay; |
| 1091 | rp->rp_status = NFSERR_SERVERFAULT; | 1091 | rp->rp_status = nfserr_serverfault; |
| 1092 | rp->rp_buflen = 0; | 1092 | rp->rp_buflen = 0; |
| 1093 | rp->rp_buf = rp->rp_ibuf; | 1093 | rp->rp_buf = rp->rp_ibuf; |
| 1094 | return sop; | 1094 | return sop; |
| @@ -1178,7 +1178,6 @@ release_stateid(struct nfs4_stateid *stp, int flags) | |||
| 1178 | locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner); | 1178 | locks_remove_posix(filp, (fl_owner_t) stp->st_stateowner); |
| 1179 | put_nfs4_file(stp->st_file); | 1179 | put_nfs4_file(stp->st_file); |
| 1180 | kmem_cache_free(stateid_slab, stp); | 1180 | kmem_cache_free(stateid_slab, stp); |
| 1181 | stp = NULL; | ||
| 1182 | } | 1181 | } |
| 1183 | 1182 | ||
| 1184 | static void | 1183 | static void |
| @@ -1191,22 +1190,6 @@ move_to_close_lru(struct nfs4_stateowner *sop) | |||
| 1191 | sop->so_time = get_seconds(); | 1190 | sop->so_time = get_seconds(); |
| 1192 | } | 1191 | } |
| 1193 | 1192 | ||
| 1194 | static void | ||
| 1195 | release_state_owner(struct nfs4_stateid *stp, int flag) | ||
| 1196 | { | ||
| 1197 | struct nfs4_stateowner *sop = stp->st_stateowner; | ||
| 1198 | |||
| 1199 | dprintk("NFSD: release_state_owner\n"); | ||
| 1200 | release_stateid(stp, flag); | ||
| 1201 | |||
| 1202 | /* place unused nfs4_stateowners on so_close_lru list to be | ||
| 1203 | * released by the laundromat service after the lease period | ||
| 1204 | * to enable us to handle CLOSE replay | ||
| 1205 | */ | ||
| 1206 | if (sop->so_confirmed && list_empty(&sop->so_stateids)) | ||
| 1207 | move_to_close_lru(sop); | ||
| 1208 | } | ||
| 1209 | |||
| 1210 | static int | 1193 | static int |
| 1211 | cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) { | 1194 | cmp_owner_str(struct nfs4_stateowner *sop, struct xdr_netobj *owner, clientid_t *clid) { |
| 1212 | return ((sop->so_owner.len == owner->len) && | 1195 | return ((sop->so_owner.len == owner->len) && |
| @@ -1446,92 +1429,61 @@ static struct lock_manager_operations nfsd_lease_mng_ops = { | |||
| 1446 | }; | 1429 | }; |
| 1447 | 1430 | ||
| 1448 | 1431 | ||
| 1449 | /* | ||
| 1450 | * nfsd4_process_open1() | ||
| 1451 | * lookup stateowner. | ||
| 1452 | * found: | ||
| 1453 | * check confirmed | ||
| 1454 | * confirmed: | ||
| 1455 | * check seqid | ||
| 1456 | * not confirmed: | ||
| 1457 | * delete owner | ||
| 1458 | * create new owner | ||
| 1459 | * notfound: | ||
| 1460 | * verify clientid | ||
| 1461 | * create new owner | ||
| 1462 | * | ||
| 1463 | * called with nfs4_lock_state() held. | ||
| 1464 | */ | ||
| 1465 | int | 1432 | int |
| 1466 | nfsd4_process_open1(struct nfsd4_open *open) | 1433 | nfsd4_process_open1(struct nfsd4_open *open) |
| 1467 | { | 1434 | { |
| 1468 | int status; | ||
| 1469 | clientid_t *clientid = &open->op_clientid; | 1435 | clientid_t *clientid = &open->op_clientid; |
| 1470 | struct nfs4_client *clp = NULL; | 1436 | struct nfs4_client *clp = NULL; |
| 1471 | unsigned int strhashval; | 1437 | unsigned int strhashval; |
| 1472 | struct nfs4_stateowner *sop = NULL; | 1438 | struct nfs4_stateowner *sop = NULL; |
| 1473 | 1439 | ||
| 1474 | status = nfserr_inval; | ||
| 1475 | if (!check_name(open->op_owner)) | 1440 | if (!check_name(open->op_owner)) |
| 1476 | goto out; | 1441 | return nfserr_inval; |
| 1477 | 1442 | ||
| 1478 | if (STALE_CLIENTID(&open->op_clientid)) | 1443 | if (STALE_CLIENTID(&open->op_clientid)) |
| 1479 | return nfserr_stale_clientid; | 1444 | return nfserr_stale_clientid; |
| 1480 | 1445 | ||
| 1481 | strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner); | 1446 | strhashval = ownerstr_hashval(clientid->cl_id, open->op_owner); |
| 1482 | sop = find_openstateowner_str(strhashval, open); | 1447 | sop = find_openstateowner_str(strhashval, open); |
| 1483 | if (sop) { | 1448 | open->op_stateowner = sop; |
| 1484 | open->op_stateowner = sop; | 1449 | if (!sop) { |
| 1485 | /* check for replay */ | 1450 | /* Make sure the client's lease hasn't expired. */ |
| 1486 | if (open->op_seqid == sop->so_seqid - 1){ | ||
| 1487 | if (sop->so_replay.rp_buflen) | ||
| 1488 | return NFSERR_REPLAY_ME; | ||
| 1489 | else { | ||
| 1490 | /* The original OPEN failed so spectacularly | ||
| 1491 | * that we don't even have replay data saved! | ||
| 1492 | * Therefore, we have no choice but to continue | ||
| 1493 | * processing this OPEN; presumably, we'll | ||
| 1494 | * fail again for the same reason. | ||
| 1495 | */ | ||
| 1496 | dprintk("nfsd4_process_open1:" | ||
| 1497 | " replay with no replay cache\n"); | ||
| 1498 | goto renew; | ||
| 1499 | } | ||
| 1500 | } else if (sop->so_confirmed) { | ||
| 1501 | if (open->op_seqid == sop->so_seqid) | ||
| 1502 | goto renew; | ||
| 1503 | status = nfserr_bad_seqid; | ||
| 1504 | goto out; | ||
| 1505 | } else { | ||
| 1506 | /* If we get here, we received an OPEN for an | ||
| 1507 | * unconfirmed nfs4_stateowner. Since the seqid's are | ||
| 1508 | * different, purge the existing nfs4_stateowner, and | ||
| 1509 | * instantiate a new one. | ||
| 1510 | */ | ||
| 1511 | clp = sop->so_client; | ||
| 1512 | release_stateowner(sop); | ||
| 1513 | } | ||
| 1514 | } else { | ||
| 1515 | /* nfs4_stateowner not found. | ||
| 1516 | * Verify clientid and instantiate new nfs4_stateowner. | ||
| 1517 | * If verify fails this is presumably the result of the | ||
| 1518 | * client's lease expiring. | ||
| 1519 | */ | ||
| 1520 | status = nfserr_expired; | ||
| 1521 | clp = find_confirmed_client(clientid); | 1451 | clp = find_confirmed_client(clientid); |
| 1522 | if (clp == NULL) | 1452 | if (clp == NULL) |
| 1523 | goto out; | 1453 | return nfserr_expired; |
| 1454 | goto renew; | ||
| 1524 | } | 1455 | } |
| 1525 | status = nfserr_resource; | 1456 | if (!sop->so_confirmed) { |
| 1526 | sop = alloc_init_open_stateowner(strhashval, clp, open); | 1457 | /* Replace unconfirmed owners without checking for replay. */ |
| 1527 | if (sop == NULL) | 1458 | clp = sop->so_client; |
| 1528 | goto out; | 1459 | release_stateowner(sop); |
| 1529 | 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; | ||
| 1530 | renew: | 1477 | renew: |
| 1531 | 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); | ||
| 1532 | renew_client(sop->so_client); | 1485 | renew_client(sop->so_client); |
| 1533 | out: | 1486 | return nfs_ok; |
| 1534 | return status; | ||
| 1535 | } | 1487 | } |
| 1536 | 1488 | ||
| 1537 | static inline int | 1489 | static inline int |
| @@ -1648,7 +1600,7 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh, | |||
| 1648 | if (!open->op_truncate) | 1600 | if (!open->op_truncate) |
| 1649 | return 0; | 1601 | return 0; |
| 1650 | if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) | 1602 | if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE)) |
| 1651 | return -EINVAL; | 1603 | return nfserr_inval; |
| 1652 | return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0); | 1604 | return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0); |
| 1653 | } | 1605 | } |
| 1654 | 1606 | ||
| @@ -1657,26 +1609,26 @@ nfs4_upgrade_open(struct svc_rqst *rqstp, struct svc_fh *cur_fh, struct nfs4_sta | |||
| 1657 | { | 1609 | { |
| 1658 | struct file *filp = stp->st_vfs_file; | 1610 | struct file *filp = stp->st_vfs_file; |
| 1659 | struct inode *inode = filp->f_dentry->d_inode; | 1611 | struct inode *inode = filp->f_dentry->d_inode; |
| 1660 | unsigned int share_access; | 1612 | unsigned int share_access, new_writer; |
| 1661 | int status; | 1613 | int status; |
| 1662 | 1614 | ||
| 1663 | set_access(&share_access, stp->st_access_bmap); | 1615 | set_access(&share_access, stp->st_access_bmap); |
| 1664 | share_access = ~share_access; | 1616 | new_writer = (~share_access) & open->op_share_access |
| 1665 | share_access &= open->op_share_access; | 1617 | & NFS4_SHARE_ACCESS_WRITE; |
| 1666 | |||
| 1667 | if (!(share_access & NFS4_SHARE_ACCESS_WRITE)) | ||
| 1668 | return nfsd4_truncate(rqstp, cur_fh, open); | ||
| 1669 | 1618 | ||
| 1670 | status = get_write_access(inode); | 1619 | if (new_writer) { |
| 1671 | if (status) | 1620 | status = get_write_access(inode); |
| 1672 | return nfserrno(status); | 1621 | if (status) |
| 1622 | return nfserrno(status); | ||
| 1623 | } | ||
| 1673 | status = nfsd4_truncate(rqstp, cur_fh, open); | 1624 | status = nfsd4_truncate(rqstp, cur_fh, open); |
| 1674 | if (status) { | 1625 | if (status) { |
| 1675 | put_write_access(inode); | 1626 | if (new_writer) |
| 1627 | put_write_access(inode); | ||
| 1676 | return status; | 1628 | return status; |
| 1677 | } | 1629 | } |
| 1678 | /* remember the open */ | 1630 | /* remember the open */ |
| 1679 | filp->f_mode = (filp->f_mode | FMODE_WRITE) & ~FMODE_READ; | 1631 | filp->f_mode |= open->op_share_access; |
| 1680 | set_bit(open->op_share_access, &stp->st_access_bmap); | 1632 | set_bit(open->op_share_access, &stp->st_access_bmap); |
| 1681 | set_bit(open->op_share_deny, &stp->st_deny_bmap); | 1633 | set_bit(open->op_share_deny, &stp->st_deny_bmap); |
| 1682 | 1634 | ||
| @@ -1780,12 +1732,6 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
| 1780 | struct nfs4_delegation *dp = NULL; | 1732 | struct nfs4_delegation *dp = NULL; |
| 1781 | int status; | 1733 | int status; |
| 1782 | 1734 | ||
| 1783 | if (nfs4_in_grace() && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS) | ||
| 1784 | return nfserr_grace; | ||
| 1785 | |||
| 1786 | if (!nfs4_in_grace() && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS) | ||
| 1787 | return nfserr_no_grace; | ||
| 1788 | |||
| 1789 | status = nfserr_inval; | 1735 | status = nfserr_inval; |
| 1790 | if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny)) | 1736 | if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny)) |
| 1791 | goto out; | 1737 | goto out; |
| @@ -2423,15 +2369,19 @@ nfsd4_close(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_clos | |||
| 2423 | CHECK_FH | OPEN_STATE | CLOSE_STATE, | 2369 | CHECK_FH | OPEN_STATE | CLOSE_STATE, |
| 2424 | &close->cl_stateowner, &stp, NULL))) | 2370 | &close->cl_stateowner, &stp, NULL))) |
| 2425 | goto out; | 2371 | goto out; |
| 2426 | /* | ||
| 2427 | * Return success, but first update the stateid. | ||
| 2428 | */ | ||
| 2429 | status = nfs_ok; | 2372 | status = nfs_ok; |
| 2430 | update_stateid(&stp->st_stateid); | 2373 | update_stateid(&stp->st_stateid); |
| 2431 | memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); | 2374 | memcpy(&close->cl_stateid, &stp->st_stateid, sizeof(stateid_t)); |
| 2432 | 2375 | ||
| 2433 | /* release_state_owner() calls nfsd_close() if needed */ | 2376 | /* release_stateid() calls nfsd_close() if needed */ |
| 2434 | release_state_owner(stp, OPEN_STATE); | 2377 | release_stateid(stp, OPEN_STATE); |
| 2378 | |||
| 2379 | /* place unused nfs4_stateowners on so_close_lru list to be | ||
| 2380 | * released by the laundromat service after the lease period | ||
| 2381 | * to enable us to handle CLOSE replay | ||
| 2382 | */ | ||
| 2383 | if (list_empty(&close->cl_stateowner->so_stateids)) | ||
| 2384 | move_to_close_lru(close->cl_stateowner); | ||
| 2435 | out: | 2385 | out: |
| 2436 | if (close->cl_stateowner) { | 2386 | if (close->cl_stateowner) { |
| 2437 | nfs4_get_stateowner(close->cl_stateowner); | 2387 | nfs4_get_stateowner(close->cl_stateowner); |
| @@ -2633,7 +2583,7 @@ alloc_init_lock_stateowner(unsigned int strhashval, struct nfs4_client *clp, str | |||
| 2633 | sop->so_seqid = lock->lk_new_lock_seqid + 1; | 2583 | sop->so_seqid = lock->lk_new_lock_seqid + 1; |
| 2634 | sop->so_confirmed = 1; | 2584 | sop->so_confirmed = 1; |
| 2635 | rp = &sop->so_replay; | 2585 | rp = &sop->so_replay; |
| 2636 | rp->rp_status = NFSERR_SERVERFAULT; | 2586 | rp->rp_status = nfserr_serverfault; |
| 2637 | rp->rp_buflen = 0; | 2587 | rp->rp_buflen = 0; |
| 2638 | rp->rp_buf = rp->rp_ibuf; | 2588 | rp->rp_buf = rp->rp_ibuf; |
| 2639 | return sop; | 2589 | return sop; |
| @@ -2700,6 +2650,11 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
| 2700 | if (check_lock_length(lock->lk_offset, lock->lk_length)) | 2650 | if (check_lock_length(lock->lk_offset, lock->lk_length)) |
| 2701 | return nfserr_inval; | 2651 | return nfserr_inval; |
| 2702 | 2652 | ||
| 2653 | if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) { | ||
| 2654 | dprintk("NFSD: nfsd4_lock: permission denied!\n"); | ||
| 2655 | return status; | ||
| 2656 | } | ||
| 2657 | |||
| 2703 | nfs4_lock_state(); | 2658 | nfs4_lock_state(); |
| 2704 | 2659 | ||
| 2705 | if (lock->lk_is_new) { | 2660 | if (lock->lk_is_new) { |
| @@ -2720,11 +2675,11 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
| 2720 | lock->lk_new_open_seqid, | 2675 | lock->lk_new_open_seqid, |
| 2721 | &lock->lk_new_open_stateid, | 2676 | &lock->lk_new_open_stateid, |
| 2722 | CHECK_FH | OPEN_STATE, | 2677 | CHECK_FH | OPEN_STATE, |
| 2723 | &lock->lk_stateowner, &open_stp, | 2678 | &lock->lk_replay_owner, &open_stp, |
| 2724 | lock); | 2679 | lock); |
| 2725 | if (status) | 2680 | if (status) |
| 2726 | goto out; | 2681 | goto out; |
| 2727 | open_sop = lock->lk_stateowner; | 2682 | open_sop = lock->lk_replay_owner; |
| 2728 | /* create lockowner and lock stateid */ | 2683 | /* create lockowner and lock stateid */ |
| 2729 | fp = open_stp->st_file; | 2684 | fp = open_stp->st_file; |
| 2730 | strhashval = lock_ownerstr_hashval(fp->fi_inode, | 2685 | strhashval = lock_ownerstr_hashval(fp->fi_inode, |
| @@ -2739,29 +2694,22 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
| 2739 | if (lock_sop == NULL) | 2694 | if (lock_sop == NULL) |
| 2740 | goto out; | 2695 | goto out; |
| 2741 | lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); | 2696 | lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); |
| 2742 | if (lock_stp == NULL) { | 2697 | if (lock_stp == NULL) |
| 2743 | release_stateowner(lock_sop); | ||
| 2744 | goto out; | 2698 | goto out; |
| 2745 | } | ||
| 2746 | } else { | 2699 | } else { |
| 2747 | /* lock (lock owner + lock stateid) already exists */ | 2700 | /* lock (lock owner + lock stateid) already exists */ |
| 2748 | status = nfs4_preprocess_seqid_op(current_fh, | 2701 | status = nfs4_preprocess_seqid_op(current_fh, |
| 2749 | lock->lk_old_lock_seqid, | 2702 | lock->lk_old_lock_seqid, |
| 2750 | &lock->lk_old_lock_stateid, | 2703 | &lock->lk_old_lock_stateid, |
| 2751 | CHECK_FH | LOCK_STATE, | 2704 | CHECK_FH | LOCK_STATE, |
| 2752 | &lock->lk_stateowner, &lock_stp, lock); | 2705 | &lock->lk_replay_owner, &lock_stp, lock); |
| 2753 | if (status) | 2706 | if (status) |
| 2754 | goto out; | 2707 | goto out; |
| 2755 | lock_sop = lock->lk_stateowner; | 2708 | lock_sop = lock->lk_replay_owner; |
| 2756 | } | 2709 | } |
| 2757 | /* lock->lk_stateowner and lock_stp have been created or found */ | 2710 | /* lock->lk_replay_owner and lock_stp have been created or found */ |
| 2758 | filp = lock_stp->st_vfs_file; | 2711 | filp = lock_stp->st_vfs_file; |
| 2759 | 2712 | ||
| 2760 | if ((status = fh_verify(rqstp, current_fh, S_IFREG, MAY_LOCK))) { | ||
| 2761 | dprintk("NFSD: nfsd4_lock: permission denied!\n"); | ||
| 2762 | goto out; | ||
| 2763 | } | ||
| 2764 | |||
| 2765 | status = nfserr_grace; | 2713 | status = nfserr_grace; |
| 2766 | if (nfs4_in_grace() && !lock->lk_reclaim) | 2714 | if (nfs4_in_grace() && !lock->lk_reclaim) |
| 2767 | goto out; | 2715 | goto out; |
| @@ -2802,8 +2750,6 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
| 2802 | */ | 2750 | */ |
| 2803 | 2751 | ||
| 2804 | status = posix_lock_file(filp, &file_lock); | 2752 | status = posix_lock_file(filp, &file_lock); |
| 2805 | if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private) | ||
| 2806 | file_lock.fl_ops->fl_release_private(&file_lock); | ||
| 2807 | dprintk("NFSD: nfsd4_lock: posix_lock_file status %d\n",status); | 2753 | dprintk("NFSD: nfsd4_lock: posix_lock_file status %d\n",status); |
| 2808 | switch (-status) { | 2754 | switch (-status) { |
| 2809 | case 0: /* success! */ | 2755 | case 0: /* success! */ |
| @@ -2815,9 +2761,12 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
| 2815 | goto conflicting_lock; | 2761 | goto conflicting_lock; |
| 2816 | case (EDEADLK): | 2762 | case (EDEADLK): |
| 2817 | status = nfserr_deadlock; | 2763 | status = nfserr_deadlock; |
| 2764 | dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); | ||
| 2765 | goto out; | ||
| 2818 | default: | 2766 | default: |
| 2767 | status = nfserrno(status); | ||
| 2819 | dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); | 2768 | dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); |
| 2820 | goto out_destroy_new_stateid; | 2769 | goto out; |
| 2821 | } | 2770 | } |
| 2822 | 2771 | ||
| 2823 | conflicting_lock: | 2772 | conflicting_lock: |
| @@ -2831,20 +2780,12 @@ conflicting_lock: | |||
| 2831 | goto out; | 2780 | goto out; |
| 2832 | } | 2781 | } |
| 2833 | nfs4_set_lock_denied(conflock, &lock->lk_denied); | 2782 | nfs4_set_lock_denied(conflock, &lock->lk_denied); |
| 2834 | |||
| 2835 | out_destroy_new_stateid: | ||
| 2836 | if (lock->lk_is_new) { | ||
| 2837 | dprintk("NFSD: nfsd4_lock: destroy new stateid!\n"); | ||
| 2838 | /* | ||
| 2839 | * An error encountered after instantiation of the new | ||
| 2840 | * stateid has forced us to destroy it. | ||
| 2841 | */ | ||
| 2842 | release_state_owner(lock_stp, LOCK_STATE); | ||
| 2843 | } | ||
| 2844 | out: | 2783 | out: |
| 2845 | if (lock->lk_stateowner) { | 2784 | if (status && lock->lk_is_new && lock_sop) |
| 2846 | nfs4_get_stateowner(lock->lk_stateowner); | 2785 | release_stateowner(lock_sop); |
| 2847 | *replay_owner = lock->lk_stateowner; | 2786 | if (lock->lk_replay_owner) { |
| 2787 | nfs4_get_stateowner(lock->lk_replay_owner); | ||
| 2788 | *replay_owner = lock->lk_replay_owner; | ||
| 2848 | } | 2789 | } |
| 2849 | nfs4_unlock_state(); | 2790 | nfs4_unlock_state(); |
| 2850 | return status; | 2791 | return status; |
| @@ -2977,8 +2918,6 @@ nfsd4_locku(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
| 2977 | * Try to unlock the file in the VFS. | 2918 | * Try to unlock the file in the VFS. |
| 2978 | */ | 2919 | */ |
| 2979 | status = posix_lock_file(filp, &file_lock); | 2920 | status = posix_lock_file(filp, &file_lock); |
| 2980 | if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private) | ||
| 2981 | file_lock.fl_ops->fl_release_private(&file_lock); | ||
| 2982 | if (status) { | 2921 | if (status) { |
| 2983 | dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n"); | 2922 | dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n"); |
| 2984 | goto out_nfserr; | 2923 | goto out_nfserr; |
| @@ -3016,9 +2955,10 @@ check_for_locks(struct file *filp, struct nfs4_stateowner *lowner) | |||
| 3016 | 2955 | ||
| 3017 | lock_kernel(); | 2956 | lock_kernel(); |
| 3018 | for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { | 2957 | for (flpp = &inode->i_flock; *flpp != NULL; flpp = &(*flpp)->fl_next) { |
| 3019 | if ((*flpp)->fl_owner == (fl_owner_t)lowner) | 2958 | if ((*flpp)->fl_owner == (fl_owner_t)lowner) { |
| 3020 | status = 1; | 2959 | status = 1; |
| 3021 | goto out; | 2960 | goto out; |
| 2961 | } | ||
| 3022 | } | 2962 | } |
| 3023 | out: | 2963 | out: |
| 3024 | unlock_kernel(); | 2964 | unlock_kernel(); |
