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 --- |