View | Details | Raw Unified | Return to bug 280978
Collapse All | Expand All

(-)sys/fs/nfsserver/nfs_nfsdstate.c (-32 / +30 lines)
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

Return to bug 280978