Deleted Added
full compact
nfs_clrpcops.c (192337) nfs_clrpcops.c (195510)
1/*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 18 unchanged lines hidden (view full) ---

27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 18 unchanged lines hidden (view full) ---

27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 */
33
34#include <sys/cdefs.h>
35__FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clrpcops.c 192337 2009-05-18 21:22:03Z rmacklem $");
35__FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clrpcops.c 195510 2009-07-09 19:00:29Z rmacklem $");
36
37/*
38 * Rpc op calls, generally called from the vnode op calls or through the
39 * buffer cache, for NFS v2, 3 and 4.
40 * These do not normally make any changes to vnode arguments or use
41 * structures that might change between the VFS variants. The returned
42 * arguments are all at the end, after the NFSPROC_T *p one.
43 */

--- 32 unchanged lines hidden (view full) ---

76 struct nfsvattr *, struct nfsfh **, int *, int *, void *);
77static int nfsrpc_createv4(vnode_t , char *, int, struct vattr *,
78 nfsquad_t, int, struct nfsclowner *, struct nfscldeleg **, struct ucred *,
79 NFSPROC_T *, struct nfsvattr *, struct nfsvattr *, struct nfsfh **, int *,
80 int *, void *, int *);
81static int nfsrpc_locku(struct nfsrv_descript *, struct nfsmount *,
82 struct nfscllockowner *, u_int64_t, u_int64_t,
83 u_int32_t, struct ucred *, NFSPROC_T *, int);
36
37/*
38 * Rpc op calls, generally called from the vnode op calls or through the
39 * buffer cache, for NFS v2, 3 and 4.
40 * These do not normally make any changes to vnode arguments or use
41 * structures that might change between the VFS variants. The returned
42 * arguments are all at the end, after the NFSPROC_T *p one.
43 */

--- 32 unchanged lines hidden (view full) ---

76 struct nfsvattr *, struct nfsfh **, int *, int *, void *);
77static int nfsrpc_createv4(vnode_t , char *, int, struct vattr *,
78 nfsquad_t, int, struct nfsclowner *, struct nfscldeleg **, struct ucred *,
79 NFSPROC_T *, struct nfsvattr *, struct nfsvattr *, struct nfsfh **, int *,
80 int *, void *, int *);
81static int nfsrpc_locku(struct nfsrv_descript *, struct nfsmount *,
82 struct nfscllockowner *, u_int64_t, u_int64_t,
83 u_int32_t, struct ucred *, NFSPROC_T *, int);
84static void nfsrpc_doclose(struct nfsmount *, struct nfsclopenhead *,
85 NFSPROC_T *);
86#ifdef NFS4_ACL_EXTATTR_NAME
87static int nfsrpc_setaclrpc(vnode_t, struct ucred *, NFSPROC_T *,
88 struct acl *, nfsv4stateid_t *, void *);
89#endif
90
91/*
92 * nfs null call from vfs.
93 */

--- 454 unchanged lines hidden (view full) ---

548
549/*
550 * V4 Close operation.
551 */
552APPLESTATIC int
553nfsrpc_close(vnode_t vp, int doclose, NFSPROC_T *p)
554{
555 struct nfsclclient *clp;
84#ifdef NFS4_ACL_EXTATTR_NAME
85static int nfsrpc_setaclrpc(vnode_t, struct ucred *, NFSPROC_T *,
86 struct acl *, nfsv4stateid_t *, void *);
87#endif
88
89/*
90 * nfs null call from vfs.
91 */

--- 454 unchanged lines hidden (view full) ---

546
547/*
548 * V4 Close operation.
549 */
550APPLESTATIC int
551nfsrpc_close(vnode_t vp, int doclose, NFSPROC_T *p)
552{
553 struct nfsclclient *clp;
556 struct nfsclopenhead oh;
557 int error;
558
559 if (vnode_vtype(vp) != VREG)
560 return (0);
561 if (doclose)
554 int error;
555
556 if (vnode_vtype(vp) != VREG)
557 return (0);
558 if (doclose)
562 error = nfscl_getclose(vp, &clp, &oh);
559 error = nfscl_doclose(vp, &clp, p);
563 else
560 else
564 error = nfscl_getclose(vp, &clp, NULL);
561 error = nfscl_getclose(vp, &clp);
565 if (error)
566 return (error);
567
562 if (error)
563 return (error);
564
568 if (doclose && !LIST_EMPTY(&oh))
569 nfsrpc_doclose(VFSTONFS(vnode_mount(vp)), &oh, p);
570 nfscl_clientrelease(clp);
571 return (0);
572}
573
574/*
565 nfscl_clientrelease(clp);
566 return (0);
567}
568
569/*
575 * Close/free all the opens in the list.
570 * Close the open.
576 */
571 */
577static void
578nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopenhead *ohp, NFSPROC_T *p)
572APPLESTATIC void
573nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
579{
580 struct nfsrv_descript nfsd, *nd = &nfsd;
574{
575 struct nfsrv_descript nfsd, *nd = &nfsd;
581 struct nfsclopen *op, *nop;
582 struct nfscllockowner *lp;
583 struct nfscllock *lop, *nlop;
584 struct ucred *tcred;
585 u_int64_t off = 0, len = 0;
586 u_int32_t type = NFSV4LOCKT_READ;
576 struct nfscllockowner *lp;
577 struct nfscllock *lop, *nlop;
578 struct ucred *tcred;
579 u_int64_t off = 0, len = 0;
580 u_int32_t type = NFSV4LOCKT_READ;
587 int error;
581 int error, do_unlock, trycnt;
588
589 tcred = newnfs_getcred();
582
583 tcred = newnfs_getcred();
590 op = LIST_FIRST(ohp);
591 while (op != NULL) {
592 nop = LIST_NEXT(op, nfso_list);
593 newnfs_copycred(&op->nfso_cred, tcred);
594 /*
595 * (Theoretically this could be done in the same
596 * compound as the close, but having multiple
597 * sequenced Ops in the same compound might be
598 * too scary for some servers.)
599 */
600 if (op->nfso_posixlock) {
601 off = 0;
602 len = NFS64BITSSET;
603 type = NFSV4LOCKT_READ;
604 }
605 LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) {
606 lop = LIST_FIRST(&lp->nfsl_lock);
607 while (lop != NULL) {
608 nlop = LIST_NEXT(lop, nfslo_list);
584 newnfs_copycred(&op->nfso_cred, tcred);
585 /*
586 * (Theoretically this could be done in the same
587 * compound as the close, but having multiple
588 * sequenced Ops in the same compound might be
589 * too scary for some servers.)
590 */
591 if (op->nfso_posixlock) {
592 off = 0;
593 len = NFS64BITSSET;
594 type = NFSV4LOCKT_READ;
595 }
596
597 /*
598 * Since this function is only called from VOP_INACTIVE(), no
599 * other thread will be manipulating this Open. As such, the
600 * lock lists are not being changed by other threads, so it should
601 * be safe to do this without locking.
602 */
603 LIST_FOREACH(lp, &op->nfso_lock, nfsl_list) {
604 do_unlock = 1;
605 LIST_FOREACH_SAFE(lop, &lp->nfsl_lock, nfslo_list, nlop) {
609 if (op->nfso_posixlock == 0) {
606 if (op->nfso_posixlock == 0) {
610 off = lop->nfslo_first;
611 len = lop->nfslo_end - lop->nfslo_first;
612 if (lop->nfslo_type == F_WRLCK)
613 type = NFSV4LOCKT_WRITE;
614 else
615 type = NFSV4LOCKT_READ;
607 off = lop->nfslo_first;
608 len = lop->nfslo_end - lop->nfslo_first;
609 if (lop->nfslo_type == F_WRLCK)
610 type = NFSV4LOCKT_WRITE;
611 else
612 type = NFSV4LOCKT_READ;
616 }
613 }
617 if (lop == LIST_FIRST(&lp->nfsl_lock) ||
618 op->nfso_posixlock == 0) {
619 NFSLOCKCLSTATE();
620 nfscl_lockexcl(&lp->nfsl_rwlock,
621 NFSCLSTATEMUTEXPTR);
622 NFSUNLOCKCLSTATE();
623 do {
624 error = nfsrpc_locku(nd, nmp, lp, off, len,
625 type, tcred, p, 0);
626 if ((nd->nd_repstat == NFSERR_GRACE ||
627 nd->nd_repstat == NFSERR_DELAY) &&
628 error == 0)
629 (void) nfs_catnap(PZERO, "nfs_close");
630 } while ((nd->nd_repstat == NFSERR_GRACE ||
631 nd->nd_repstat == NFSERR_DELAY) && error == 0);
632 NFSLOCKCLSTATE();
633 nfscl_lockunlock(&lp->nfsl_rwlock);
634 NFSUNLOCKCLSTATE();
614 if (do_unlock) {
615 trycnt = 0;
616 do {
617 error = nfsrpc_locku(nd, nmp, lp, off,
618 len, type, tcred, p, 0);
619 if ((nd->nd_repstat == NFSERR_GRACE ||
620 nd->nd_repstat == NFSERR_DELAY) &&
621 error == 0)
622 (void) nfs_catnap(PZERO,
623 "nfs_close");
624 } while ((nd->nd_repstat == NFSERR_GRACE ||
625 nd->nd_repstat == NFSERR_DELAY) &&
626 error == 0 && trycnt++ < 5);
627 if (op->nfso_posixlock)
628 do_unlock = 0;
635 }
636 nfscl_freelock(lop, 0);
629 }
630 nfscl_freelock(lop, 0);
637 lop = nlop;
638 }
639 }
631 }
640 NFSLOCKCLSTATE();
641 nfscl_lockexcl(&op->nfso_own->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
642 NFSUNLOCKCLSTATE();
643 do {
644 error = nfscl_tryclose(op, tcred, nmp, p);
645 if (error == NFSERR_GRACE)
646 (void) nfs_catnap(PZERO, "nfs_close");
647 } while (error == NFSERR_GRACE);
648 NFSLOCKCLSTATE();
649 nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
650 NFSUNLOCKCLSTATE();
632 }
651
633
652 /*
653 * Move the lockowner to nfsc_defunctlockowner,
654 * so the Renew thread will do the ReleaseLockOwner
655 * Op on it later. There might still be other
656 * opens using the same lockowner name.
657 */
658 lp = LIST_FIRST(&op->nfso_lock);
659 if (lp != NULL) {
660 while (LIST_NEXT(lp, nfsl_list) != NULL)
634 /*
635 * There could be other Opens for different files on the same
636 * OpenOwner, so locking is required.
637 */
638 NFSLOCKCLSTATE();
639 nfscl_lockexcl(&op->nfso_own->nfsow_rwlock, NFSCLSTATEMUTEXPTR);
640 NFSUNLOCKCLSTATE();
641 do {
642 error = nfscl_tryclose(op, tcred, nmp, p);
643 if (error == NFSERR_GRACE)
644 (void) nfs_catnap(PZERO, "nfs_close");
645 } while (error == NFSERR_GRACE);
646 NFSLOCKCLSTATE();
647 nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
648
649 /*
650 * Move the lockowner to nfsc_defunctlockowner,
651 * so the Renew thread will do the ReleaseLockOwner
652 * Op on it later. There might still be other
653 * opens using the same lockowner name.
654 */
655 lp = LIST_FIRST(&op->nfso_lock);
656 if (lp != NULL) {
657 while (LIST_NEXT(lp, nfsl_list) != NULL)
661 lp = LIST_NEXT(lp, nfsl_list);
658 lp = LIST_NEXT(lp, nfsl_list);
662 LIST_PREPEND(&nmp->nm_clp->nfsc_defunctlockowner,
663 &op->nfso_lock, lp, nfsl_list);
664 LIST_INIT(&op->nfso_lock);
665 }
666 nfscl_freeopen(op, 0);
667 op = nop;
659 LIST_PREPEND(&nmp->nm_clp->nfsc_defunctlockowner,
660 &op->nfso_lock, lp, nfsl_list);
661 LIST_INIT(&op->nfso_lock);
668 }
662 }
663 nfscl_freeopen(op, 0);
664 NFSUNLOCKCLSTATE();
669 NFSFREECRED(tcred);
670}
671
672/*
673 * The actual Close RPC.
674 */
675APPLESTATIC int
676nfsrpc_closerpc(struct nfsrv_descript *nd, struct nfsmount *nmp,

--- 3500 unchanged lines hidden ---
665 NFSFREECRED(tcred);
666}
667
668/*
669 * The actual Close RPC.
670 */
671APPLESTATIC int
672nfsrpc_closerpc(struct nfsrv_descript *nd, struct nfsmount *nmp,

--- 3500 unchanged lines hidden ---