Deleted Added
full compact
35c35
< __FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clrpcops.c 192337 2009-05-18 21:22:03Z rmacklem $");
---
> __FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clrpcops.c 195510 2009-07-09 19:00:29Z rmacklem $");
84,85d83
< static void nfsrpc_doclose(struct nfsmount *, struct nfsclopenhead *,
< NFSPROC_T *);
556d553
< struct nfsclopenhead oh;
562c559
< error = nfscl_getclose(vp, &clp, &oh);
---
> error = nfscl_doclose(vp, &clp, p);
564c561
< error = nfscl_getclose(vp, &clp, NULL);
---
> error = nfscl_getclose(vp, &clp);
568,569d564
< if (doclose && !LIST_EMPTY(&oh))
< nfsrpc_doclose(VFSTONFS(vnode_mount(vp)), &oh, p);
575c570
< * Close/free all the opens in the list.
---
> * Close the open.
577,578c572,573
< static void
< nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopenhead *ohp, NFSPROC_T *p)
---
> APPLESTATIC void
> nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
581d575
< struct nfsclopen *op, *nop;
587c581
< int error;
---
> int error, do_unlock, trycnt;
590,608c584,605
< op = LIST_FIRST(ohp);
< while (op != NULL) {
< nop = LIST_NEXT(op, nfso_list);
< newnfs_copycred(&op->nfso_cred, tcred);
< /*
< * (Theoretically this could be done in the same
< * compound as the close, but having multiple
< * sequenced Ops in the same compound might be
< * too scary for some servers.)
< */
< if (op->nfso_posixlock) {
< off = 0;
< len = NFS64BITSSET;
< type = NFSV4LOCKT_READ;
< }
< LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) {
< lop = LIST_FIRST(&lp->nfsl_lock);
< while (lop != NULL) {
< nlop = LIST_NEXT(lop, nfslo_list);
---
> newnfs_copycred(&op->nfso_cred, tcred);
> /*
> * (Theoretically this could be done in the same
> * compound as the close, but having multiple
> * sequenced Ops in the same compound might be
> * too scary for some servers.)
> */
> if (op->nfso_posixlock) {
> off = 0;
> len = NFS64BITSSET;
> type = NFSV4LOCKT_READ;
> }
>
> /*
> * Since this function is only called from VOP_INACTIVE(), no
> * other thread will be manipulating this Open. As such, the
> * lock lists are not being changed by other threads, so it should
> * be safe to do this without locking.
> */
> LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) {
> do_unlock = 1;
> LIST_FOREACH_SAFE(lop, &lp->nfsl_lock, nfslo_list, nlop) {
610,615c607,612
< off = lop->nfslo_first;
< len = lop->nfslo_end - lop->nfslo_first;
< if (lop->nfslo_type == F_WRLCK)
< type = NFSV4LOCKT_WRITE;
< else
< type = NFSV4LOCKT_READ;
---
> off = lop->nfslo_first;
> len = lop->nfslo_end - lop->nfslo_first;
> if (lop->nfslo_type == F_WRLCK)
> type = NFSV4LOCKT_WRITE;
> else
> type = NFSV4LOCKT_READ;
617,634c614,628
< if (lop == LIST_FIRST(&lp->nfsl_lock) ||
< op->nfso_posixlock == 0) {
< NFSLOCKCLSTATE();
< nfscl_lockexcl(&lp->nfsl_rwlock,
< NFSCLSTATEMUTEXPTR);
< NFSUNLOCKCLSTATE();
< do {
< error = nfsrpc_locku(nd, nmp, lp, off, len,
< type, tcred, p, 0);
< if ((nd->nd_repstat == NFSERR_GRACE ||
< nd->nd_repstat == NFSERR_DELAY) &&
< error == 0)
< (void) nfs_catnap(PZERO, "nfs_close");
< } while ((nd->nd_repstat == NFSERR_GRACE ||
< nd->nd_repstat == NFSERR_DELAY) && error == 0);
< NFSLOCKCLSTATE();
< nfscl_lockunlock(&lp->nfsl_rwlock);
< NFSUNLOCKCLSTATE();
---
> if (do_unlock) {
> trycnt = 0;
> do {
> error = nfsrpc_locku(nd, nmp, lp, off,
> len, type, tcred, p, 0);
> if ((nd->nd_repstat == NFSERR_GRACE ||
> nd->nd_repstat == NFSERR_DELAY) &&
> error == 0)
> (void) nfs_catnap(PZERO,
> "nfs_close");
> } while ((nd->nd_repstat == NFSERR_GRACE ||
> nd->nd_repstat == NFSERR_DELAY) &&
> error == 0 && trycnt++ < 5);
> if (op->nfso_posixlock)
> do_unlock = 0;
637,638d630
< lop = nlop;
< }
640,650c632
< NFSLOCKCLSTATE();
< nfscl_lockexcl(&op->nfso_own->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
< NFSUNLOCKCLSTATE();
< do {
< error = nfscl_tryclose(op, tcred, nmp, p);
< if (error == NFSERR_GRACE)
< (void) nfs_catnap(PZERO, "nfs_close");
< } while (error == NFSERR_GRACE);
< NFSLOCKCLSTATE();
< nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
< NFSUNLOCKCLSTATE();
---
> }
652,660c634,657
< /*
< * Move the lockowner to nfsc_defunctlockowner,
< * so the Renew thread will do the ReleaseLockOwner
< * Op on it later. There might still be other
< * opens using the same lockowner name.
< */
< lp = LIST_FIRST(&op->nfso_lock);
< if (lp != NULL) {
< while (LIST_NEXT(lp, nfsl_list) != NULL)
---
> /*
> * There could be other Opens for different files on the same
> * OpenOwner, so locking is required.
> */
> NFSLOCKCLSTATE();
> nfscl_lockexcl(&op->nfso_own->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
> NFSUNLOCKCLSTATE();
> do {
> error = nfscl_tryclose(op, tcred, nmp, p);
> if (error == NFSERR_GRACE)
> (void) nfs_catnap(PZERO, "nfs_close");
> } while (error == NFSERR_GRACE);
> NFSLOCKCLSTATE();
> nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
>
> /*
> * Move the lockowner to nfsc_defunctlockowner,
> * so the Renew thread will do the ReleaseLockOwner
> * Op on it later. There might still be other
> * opens using the same lockowner name.
> */
> lp = LIST_FIRST(&op->nfso_lock);
> if (lp != NULL) {
> while (LIST_NEXT(lp, nfsl_list) != NULL)
662,667c659,661
< LIST_PREPEND(&nmp->nm_clp->nfsc_defunctlockowner,
< &op->nfso_lock, lp, nfsl_list);
< LIST_INIT(&op->nfso_lock);
< }
< nfscl_freeopen(op, 0);
< op = nop;
---
> LIST_PREPEND(&nmp->nm_clp->nfsc_defunctlockowner,
> &op->nfso_lock, lp, nfsl_list);
> LIST_INIT(&op->nfso_lock);
668a663,664
> nfscl_freeopen(op, 0);
> NFSUNLOCKCLSTATE();