Lines 139-145
static void nfsrv_dumpaclient(struct nfsclient *clp,
Link Here
|
139 |
struct nfsd_dumpclients *dumpp); |
139 |
struct nfsd_dumpclients *dumpp); |
140 |
static void nfsrv_freeopenowner(struct nfsstate *stp, int cansleep, |
140 |
static void nfsrv_freeopenowner(struct nfsstate *stp, int cansleep, |
141 |
NFSPROC_T *p); |
141 |
NFSPROC_T *p); |
142 |
static int nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, |
142 |
static void nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, |
143 |
NFSPROC_T *p); |
143 |
NFSPROC_T *p); |
144 |
static void nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep, |
144 |
static void nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp, int cansleep, |
145 |
NFSPROC_T *p); |
145 |
NFSPROC_T *p); |
Lines 1566-1572
nfsrv_freeopenowner(struct nfsstate *stp, int cansleep
Link Here
|
1566 |
while (nstp != LIST_END(&stp->ls_open)) { |
1566 |
while (nstp != LIST_END(&stp->ls_open)) { |
1567 |
tstp = nstp; |
1567 |
tstp = nstp; |
1568 |
nstp = LIST_NEXT(nstp, ls_list); |
1568 |
nstp = LIST_NEXT(nstp, ls_list); |
1569 |
(void) nfsrv_freeopen(tstp, NULL, cansleep, p); |
1569 |
nfsrv_freeopen(tstp, NULL, cansleep, p); |
1570 |
} |
1570 |
} |
1571 |
if (stp->ls_op) |
1571 |
if (stp->ls_op) |
1572 |
nfsrvd_derefcache(stp->ls_op); |
1572 |
nfsrvd_derefcache(stp->ls_op); |
Lines 1581-1592
nfsrv_freeopenowner(struct nfsstate *stp, int cansleep
Link Here
|
1581 |
* are no other opens on the file. |
1581 |
* are no other opens on the file. |
1582 |
* Returns 1 if it free'd the nfslockfile, 0 otherwise. |
1582 |
* Returns 1 if it free'd the nfslockfile, 0 otherwise. |
1583 |
*/ |
1583 |
*/ |
1584 |
static int |
1584 |
static void |
1585 |
nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, NFSPROC_T *p) |
1585 |
nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int cansleep, NFSPROC_T *p) |
1586 |
{ |
1586 |
{ |
1587 |
struct nfsstate *nstp, *tstp; |
1587 |
struct nfsstate *nstp, *tstp; |
1588 |
struct nfslockfile *lfp; |
1588 |
struct nfslockfile *lfp; |
1589 |
int ret; |
|
|
1590 |
|
1589 |
|
1591 |
LIST_REMOVE(stp, ls_hash); |
1590 |
LIST_REMOVE(stp, ls_hash); |
1592 |
LIST_REMOVE(stp, ls_list); |
1591 |
LIST_REMOVE(stp, ls_list); |
Lines 1595-1629
nfsrv_freeopen(struct nfsstate *stp, vnode_t vp, int c
Link Here
|
1595 |
lfp = stp->ls_lfp; |
1594 |
lfp = stp->ls_lfp; |
1596 |
/* |
1595 |
/* |
1597 |
* Now, free all lockowners associated with this open. |
1596 |
* Now, free all lockowners associated with this open. |
|
|
1597 |
* Note that, if vp != NULL, nfsrv_freelockowner() will |
1598 |
* not call nfsrv_freeallnfslocks(), so it needs to be called, below. |
1598 |
*/ |
1599 |
*/ |
1599 |
LIST_FOREACH_SAFE(tstp, &stp->ls_open, ls_list, nstp) |
1600 |
LIST_FOREACH_SAFE(tstp, &stp->ls_open, ls_list, nstp) |
1600 |
nfsrv_freelockowner(tstp, vp, cansleep, p); |
1601 |
nfsrv_freelockowner(tstp, vp, cansleep, p); |
1601 |
|
1602 |
|
|
|
1603 |
if (vp != NULL) { |
1604 |
KASSERT(cansleep != 0, ("nfsrv_freeopen: cansleep == 0")); |
1605 |
mtx_assert(NFSSTATEMUTEXPTR, MA_OWNED); |
1606 |
/* |
1607 |
* Only called with vp != NULL for Close when |
1608 |
* vfs.nfsd.enable_locallocks != 0. |
1609 |
* Lock the lfp so that it will not go away and do the |
1610 |
* nfsrv_freeallnfslocks() call that was not done by |
1611 |
* nfsrv_freelockowner(). |
1612 |
*/ |
1613 |
nfsrv_locklf(lfp); |
1614 |
NFSUNLOCKSTATE(); |
1615 |
NFSVOPUNLOCK(vp); |
1616 |
nfsrv_freeallnfslocks(stp, vp, cansleep, p); |
1617 |
NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); |
1618 |
NFSLOCKSTATE(); |
1619 |
nfsrv_unlocklf(lfp); |
1620 |
} |
1621 |
|
1602 |
/* |
1622 |
/* |
1603 |
* The nfslockfile is freed here if there are no locks |
1623 |
* The nfslockfile is freed here if there are no locks |
1604 |
* associated with the open. |
1624 |
* associated with the open. |
1605 |
* If there are locks associated with the open, the |
1625 |
* If there are locks associated with the open, the |
1606 |
* nfslockfile structure can be freed via nfsrv_freelockowner(). |
1626 |
* nfslockfile structure can be freed via nfsrv_freelockowner(). |
1607 |
* Acquire the state mutex to avoid races with calls to |
|
|
1608 |
* nfsrv_getlockfile(). |
1609 |
*/ |
1627 |
*/ |
1610 |
if (cansleep != 0) |
|
|
1611 |
NFSLOCKSTATE(); |
1612 |
if (lfp != NULL && LIST_EMPTY(&lfp->lf_open) && |
1628 |
if (lfp != NULL && LIST_EMPTY(&lfp->lf_open) && |
1613 |
LIST_EMPTY(&lfp->lf_deleg) && LIST_EMPTY(&lfp->lf_lock) && |
1629 |
LIST_EMPTY(&lfp->lf_deleg) && LIST_EMPTY(&lfp->lf_lock) && |
1614 |
LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) && |
1630 |
LIST_EMPTY(&lfp->lf_locallock) && LIST_EMPTY(&lfp->lf_rollback) && |
1615 |
lfp->lf_usecount == 0 && |
1631 |
lfp->lf_usecount == 0 && |
1616 |
(cansleep != 0 || nfsv4_testlock(&lfp->lf_locallock_lck) == 0)) { |
1632 |
nfsv4_testlock(&lfp->lf_locallock_lck) == 0) |
1617 |
nfsrv_freenfslockfile(lfp); |
1633 |
nfsrv_freenfslockfile(lfp); |
1618 |
ret = 1; |
|
|
1619 |
} else |
1620 |
ret = 0; |
1621 |
if (cansleep != 0) |
1622 |
NFSUNLOCKSTATE(); |
1623 |
free(stp, M_NFSDSTATE); |
1634 |
free(stp, M_NFSDSTATE); |
1624 |
NFSD_VNET(nfsstatsv1_p)->srvopens--; |
1635 |
NFSD_VNET(nfsstatsv1_p)->srvopens--; |
1625 |
nfsrv_openpluslock--; |
1636 |
nfsrv_openpluslock--; |
1626 |
return (ret); |
|
|
1627 |
} |
1637 |
} |
1628 |
|
1638 |
|
1629 |
/* |
1639 |
/* |
Lines 1636-1642
nfsrv_freelockowner(struct nfsstate *stp, vnode_t vp,
Link Here
|
1636 |
|
1646 |
|
1637 |
LIST_REMOVE(stp, ls_hash); |
1647 |
LIST_REMOVE(stp, ls_hash); |
1638 |
LIST_REMOVE(stp, ls_list); |
1648 |
LIST_REMOVE(stp, ls_list); |
1639 |
nfsrv_freeallnfslocks(stp, vp, cansleep, p); |
1649 |
if (vp == NULL) |
|
|
1650 |
nfsrv_freeallnfslocks(stp, vp, cansleep, p); |
1640 |
if (stp->ls_op) |
1651 |
if (stp->ls_op) |
1641 |
nfsrvd_derefcache(stp->ls_op); |
1652 |
nfsrvd_derefcache(stp->ls_op); |
1642 |
free(stp, M_NFSDSTATE); |
1653 |
free(stp, M_NFSDSTATE); |
Lines 3431-3437
nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp,
Link Here
|
3431 |
{ |
3442 |
{ |
3432 |
struct nfsstate *stp; |
3443 |
struct nfsstate *stp; |
3433 |
struct nfsclient *clp; |
3444 |
struct nfsclient *clp; |
3434 |
struct nfslockfile *lfp; |
|
|
3435 |
u_int32_t bits; |
3445 |
u_int32_t bits; |
3436 |
int error = 0, gotstate = 0, len = 0; |
3446 |
int error = 0, gotstate = 0, len = 0; |
3437 |
u_char *clidp = NULL; |
3447 |
u_char *clidp = NULL; |
Lines 3526-3534
nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp,
Link Here
|
3526 |
NFSBCOPY(clp->lc_id, clidp, len); |
3536 |
NFSBCOPY(clp->lc_id, clidp, len); |
3527 |
gotstate = 1; |
3537 |
gotstate = 1; |
3528 |
} |
3538 |
} |
3529 |
NFSUNLOCKSTATE(); |
|
|
3530 |
} else if (new_stp->ls_flags & NFSLCK_CLOSE) { |
3539 |
} else if (new_stp->ls_flags & NFSLCK_CLOSE) { |
3531 |
lfp = stp->ls_lfp; |
|
|
3532 |
if (retwriteaccessp != NULL) { |
3540 |
if (retwriteaccessp != NULL) { |
3533 |
if ((stp->ls_flags & NFSLCK_WRITEACCESS) != 0) |
3541 |
if ((stp->ls_flags & NFSLCK_WRITEACCESS) != 0) |
3534 |
*retwriteaccessp = 1; |
3542 |
*retwriteaccessp = 1; |
Lines 3536-3555
nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp,
Link Here
|
3536 |
*retwriteaccessp = 0; |
3544 |
*retwriteaccessp = 0; |
3537 |
} |
3545 |
} |
3538 |
if (nfsrv_dolocallocks != 0 && !LIST_EMPTY(&stp->ls_open)) { |
3546 |
if (nfsrv_dolocallocks != 0 && !LIST_EMPTY(&stp->ls_open)) { |
3539 |
/* Get the lf lock */ |
|
|
3540 |
nfsrv_locklf(lfp); |
3541 |
NFSUNLOCKSTATE(); |
3542 |
ASSERT_VOP_ELOCKED(vp, "nfsrv_openupdate"); |
3547 |
ASSERT_VOP_ELOCKED(vp, "nfsrv_openupdate"); |
3543 |
NFSVOPUNLOCK(vp); |
3548 |
nfsrv_freeopen(stp, vp, 1, p); |
3544 |
if (nfsrv_freeopen(stp, vp, 1, p) == 0) { |
|
|
3545 |
NFSLOCKSTATE(); |
3546 |
nfsrv_unlocklf(lfp); |
3547 |
NFSUNLOCKSTATE(); |
3548 |
} |
3549 |
NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY); |
3550 |
} else { |
3549 |
} else { |
3551 |
(void) nfsrv_freeopen(stp, NULL, 0, p); |
3550 |
nfsrv_freeopen(stp, NULL, 0, p); |
3552 |
NFSUNLOCKSTATE(); |
|
|
3553 |
} |
3551 |
} |
3554 |
} else { |
3552 |
} else { |
3555 |
/* |
3553 |
/* |
Lines 3567-3574
nfsrv_openupdate(vnode_t vp, struct nfsstate *new_stp,
Link Here
|
3567 |
if ((nd->nd_flag & ND_NFSV41) != 0 && |
3565 |
if ((nd->nd_flag & ND_NFSV41) != 0 && |
3568 |
stp->ls_stateid.seqid == 0) |
3566 |
stp->ls_stateid.seqid == 0) |
3569 |
stp->ls_stateid.seqid = 1; |
3567 |
stp->ls_stateid.seqid = 1; |
3570 |
NFSUNLOCKSTATE(); |
|
|
3571 |
} |
3568 |
} |
|
|
3569 |
NFSUNLOCKSTATE(); |
3572 |
|
3570 |
|
3573 |
/* |
3571 |
/* |
3574 |
* If the client just confirmed its first open, write a timestamp |
3572 |
* If the client just confirmed its first open, write a timestamp |