1/* 2 * Coda: an Experimental Distributed File System 3 * Release 3.1 4 * 5 * Copyright (c) 1987-1998 Carnegie Mellon University 6 * All Rights Reserved 7 * 8 * Permission to use, copy, modify and distribute this software and its --- 28 unchanged lines hidden (view full) --- 37 38/* 39 * This code was written for the Coda filesystem at Carnegie Mellon 40 * University. Contributers include David Steere, James Kistler, and 41 * M. Satyanarayanan. 42 */ 43 44#include <sys/cdefs.h> |
45__FBSDID("$FreeBSD: head/sys/fs/coda/coda_vnops.c 119832 2003-09-07 07:43:10Z tjr $"); |
46 47#include <sys/param.h> 48#include <sys/systm.h> 49#include <sys/acct.h> 50#include <sys/errno.h> 51#include <sys/fcntl.h> 52#include <sys/kernel.h> 53#include <sys/lock.h> --- 430 unchanged lines hidden (view full) --- 484 MARK_INT_FAIL(CODA_RDWR_STATS); 485 return(error); 486 } 487 cfvp = cp->c_ovp; 488 } 489 } 490 491 /* Have UFS handle the call. */ |
492 CODADEBUG(CODA_RDWR, myprintf(("indirect rdwr: fid = %s, refcnt = %d\n", 493 coda_f2s(&cp->c_fid), CTOV(cp)->v_usecount)); ) |
494 if (rw == UIO_READ) { 495 error = VOP_READ(cfvp, uiop, ioflag, cred); 496 } else { 497 error = VOP_WRITE(cfvp, uiop, ioflag, cred); 498 /* ufs_write updates the vnode_pager_setsize for the vnode/object */ 499 500 { struct vattr attr; 501 --- 130 unchanged lines hidden (view full) --- 632 /* Check for getattr of control object. */ 633 if (IS_CTL_VP(vp)) { 634 MARK_INT_FAIL(CODA_GETATTR_STATS); 635 return(ENOENT); 636 } 637 638 /* Check to see if the attributes have already been cached */ 639 if (VALID_VATTR(cp)) { |
640 CODADEBUG(CODA_GETATTR, { myprintf(("attr cache hit: %s\n", 641 coda_f2s(&cp->c_fid)));}); |
642 CODADEBUG(CODA_GETATTR, if (!(codadebug & ~CODA_GETATTR)) 643 print_vattr(&cp->c_vattr); ); 644 645 *vap = cp->c_vattr; 646 MARK_INT_SAT(CODA_GETATTR_STATS); 647 return(0); 648 } 649 650 error = venus_getattr(vtomi(vp), &cp->c_fid, cred, td->td_proc, vap); 651 652 if (!error) { |
653 CODADEBUG(CODA_GETATTR, myprintf(("getattr miss %s: result %d\n", 654 coda_f2s(&cp->c_fid), error)); ) |
655 656 CODADEBUG(CODA_GETATTR, if (!(codadebug & ~CODA_GETATTR)) 657 print_vattr(vap); ); 658 659 { int size = vap->va_size; 660 struct vnode *convp = cp->c_ovp; 661 if (convp != (struct vnode *)0) { 662 vnode_pager_setsize(convp, size); --- 230 unchanged lines hidden (view full) --- 893 /* We don't need to send inactive to venus - DCS */ 894 MARK_ENTRY(CODA_INACTIVE_STATS); 895 896 if (IS_CTL_VP(vp)) { 897 MARK_INT_SAT(CODA_INACTIVE_STATS); 898 return 0; 899 } 900 |
901 CODADEBUG(CODA_INACTIVE, myprintf(("in inactive, %s, vfsp %p\n", 902 coda_f2s(&cp->c_fid), vp->v_mount));) 903 |
904 /* If an array has been allocated to hold the symlink, deallocate it */ 905 if ((coda_symlink_cache) && (VALID_SYMLINK(cp))) { 906 if (cp->c_symlink == NULL) 907 panic("coda_inactive: null symlink pointer in cnode"); 908 909 CODA_FREE(cp->c_symlink, cp->c_symlen); 910 cp->c_flags &= ~C_SYMLINK; 911 cp->c_symlen = 0; --- 55 unchanged lines hidden (view full) --- 967 */ 968 struct componentname *cnp = ap->a_cnp; 969 struct ucred *cred = cnp->cn_cred; 970 struct thread *td = cnp->cn_thread; 971/* locals */ 972 struct cnode *cp; 973 const char *nm = cnp->cn_nameptr; 974 int len = cnp->cn_namelen; |
975 CodaFid VFid; |
976 int vtype; 977 int error = 0; 978 979 MARK_ENTRY(CODA_LOOKUP_STATS); 980 |
981 CODADEBUG(CODA_LOOKUP, myprintf(("lookup: %s in %s\n", 982 nm, coda_f2s(&dcp->c_fid)));); |
983 984 /* Check for lookup of control object. */ 985 if (IS_CTL_NAME(dvp, nm, len)) { 986 *vpp = coda_ctlvp; 987 vref(*vpp); 988 MARK_INT_SAT(CODA_LOOKUP_STATS); 989 goto exit; 990 } 991 992 if (len+1 > CODA_MAXNAMLEN) { 993 MARK_INT_FAIL(CODA_LOOKUP_STATS); |
994 995 CODADEBUG(CODA_LOOKUP, myprintf(("name too long: lookup, %s (%s)\n", 996 coda_f2s(&dcp->c_fid), nm));); |
997 *vpp = (struct vnode *)0; 998 error = EINVAL; 999 goto exit; 1000 } 1001 /* First try to look the file up in the cfs name cache */ 1002 /* lock the parent vnode? */ 1003 cp = coda_nc_lookup(dcp, nm, len, cred); 1004 if (cp) { 1005 *vpp = CTOV(cp); 1006 vref(*vpp); 1007 CODADEBUG(CODA_LOOKUP, 1008 myprintf(("lookup result %d vpp %p\n",error,*vpp));) 1009 } else { 1010 1011 /* The name wasn't cached, so we need to contact Venus */ 1012 error = venus_lookup(vtomi(dvp), &dcp->c_fid, nm, len, cred, td->td_proc, &VFid, &vtype); 1013 1014 if (error) { 1015 MARK_INT_FAIL(CODA_LOOKUP_STATS); |
1016 1017 CODADEBUG(CODA_LOOKUP, myprintf(("lookup error on %s (%s)%d\n", 1018 coda_f2s(&dcp->c_fid), nm, error));) |
1019 *vpp = (struct vnode *)0; 1020 } else { 1021 MARK_INT_SAT(CODA_LOOKUP_STATS); 1022 CODADEBUG(CODA_LOOKUP, |
1023 myprintf(("lookup: %s type %o result %d\n", 1024 coda_f2s(&VFid), vtype, error)); ) |
1025 cp = make_coda_node(&VFid, dvp->v_mount, vtype); 1026 *vpp = CTOV(cp); 1027 1028 /* enter the new vnode in the Name Cache only if the top bit isn't set */ 1029 /* And don't enter a new vnode for an invalid one! */ 1030 if (!(vtype & CODA_NOCACHE)) 1031 coda_nc_enter(VTOC(dvp), nm, len, cred, VTOC(*vpp)); 1032 } --- 93 unchanged lines hidden (view full) --- 1126 struct componentname *cnp = ap->a_cnp; 1127 struct ucred *cred = cnp->cn_cred; 1128 struct thread *td = cnp->cn_thread; 1129/* locals */ 1130 int error; 1131 struct cnode *cp; 1132 const char *nm = cnp->cn_nameptr; 1133 int len = cnp->cn_namelen; |
1134 CodaFid VFid; |
1135 struct vattr attr; 1136 1137 MARK_ENTRY(CODA_CREATE_STATS); 1138 1139 /* All creates are exclusive XXX */ 1140 /* I'm assuming the 'mode' argument is the file mode bits XXX */ 1141 1142 /* Check for create of control object. */ --- 28 unchanged lines hidden (view full) --- 1171 1172 /* Invalidate the parent's attr cache, the modification time has changed */ 1173 VTOC(dvp)->c_flags &= ~C_VATTR; 1174 1175 /* enter the new vnode in the Name Cache */ 1176 coda_nc_enter(VTOC(dvp), nm, len, cred, VTOC(*vpp)); 1177 1178 CODADEBUG(CODA_CREATE, |
1179 myprintf(("create: %s, result %d\n", 1180 coda_f2s(&VFid), error)); ) |
1181 } else { 1182 *vpp = (struct vnode *)0; 1183 CODADEBUG(CODA_CREATE, myprintf(("create error %d\n", error));) 1184 } 1185 1186 if (!error) { 1187 if (cnp->cn_flags & LOCKLEAF) { 1188 if ((error = VOP_LOCK(*ap->a_vpp, LK_EXCLUSIVE, td))) { --- 24 unchanged lines hidden (view full) --- 1213/* locals */ 1214 int error; 1215 const char *nm = cnp->cn_nameptr; 1216 int len = cnp->cn_namelen; 1217 struct cnode *tp; 1218 1219 MARK_ENTRY(CODA_REMOVE_STATS); 1220 |
1221 CODADEBUG(CODA_REMOVE, myprintf(("remove: %s in %s\n", 1222 nm, coda_f2s(&cp->c_fid)));); |
1223 /* Remove the file's entry from the CODA Name Cache */ 1224 /* We're being conservative here, it might be that this person 1225 * doesn't really have sufficient access to delete the file 1226 * but we feel zapping the entry won't really hurt anyone -- dcs 1227 */ 1228 /* I'm gonna go out on a limb here. If a file and a hardlink to it 1229 * exist, and one is removed, the link count on the other will be 1230 * off by 1. We could either invalidate the attrs if cached, or --- 42 unchanged lines hidden (view full) --- 1273/* locals */ 1274 int error; 1275 const char *nm = cnp->cn_nameptr; 1276 int len = cnp->cn_namelen; 1277 1278 MARK_ENTRY(CODA_LINK_STATS); 1279 1280 if (codadebug & CODADBGMSK(CODA_LINK)) { |
1281 myprintf(("nb_link: vp fid: %s\n", 1282 coda_f2s(&cp->c_fid))); 1283 myprintf(("nb_link: tdvp fid: %s)\n", 1284 coda_f2s(&tdcp->c_fid))); |
1285 } 1286 if (codadebug & CODADBGMSK(CODA_LINK)) { |
1287 myprintf(("link: vp fid: %s\n", 1288 coda_f2s(&cp->c_fid))); 1289 myprintf(("link: tdvp fid: %s\n", 1290 coda_f2s(&tdcp->c_fid))); |
1291 } 1292 1293 /* Check for link to/from control object. */ 1294 if (IS_CTL_NAME(tdvp, nm, len) || IS_CTL_VP(vp)) { 1295 MARK_INT_FAIL(CODA_LINK_STATS); 1296 return(EACCES); 1297 } 1298 --- 116 unchanged lines hidden (view full) --- 1415 struct vnode **vpp = ap->a_vpp; 1416 struct ucred *cred = cnp->cn_cred; 1417 struct thread *td = cnp->cn_thread; 1418/* locals */ 1419 int error; 1420 const char *nm = cnp->cn_nameptr; 1421 int len = cnp->cn_namelen; 1422 struct cnode *cp; |
1423 CodaFid VFid; |
1424 struct vattr ova; 1425 1426 MARK_ENTRY(CODA_MKDIR_STATS); 1427 1428 /* Check for mkdir of target object. */ 1429 if (IS_CTL_NAME(dvp, nm, len)) { 1430 *vpp = (struct vnode *)0; 1431 MARK_INT_FAIL(CODA_MKDIR_STATS); --- 26 unchanged lines hidden (view full) --- 1458 if (coda_attr_cache) { 1459 VTOC(*vpp)->c_vattr = ova; /* update the attr cache */ 1460 VTOC(*vpp)->c_flags |= C_VATTR; /* Valid attributes in cnode */ 1461 } 1462 1463 /* Invalidate the parent's attr cache, the modification time has changed */ 1464 VTOC(dvp)->c_flags &= ~C_VATTR; 1465 |
1466 CODADEBUG( CODA_MKDIR, myprintf(("mkdir: %s result %d\n", 1467 coda_f2s(&VFid), error)); ) 1468 } else { |
1469 *vpp = (struct vnode *)0; 1470 CODADEBUG(CODA_MKDIR, myprintf(("mkdir error %d\n",error));) 1471 } 1472 1473 return(error); 1474} 1475 1476int --- 166 unchanged lines hidden (view full) --- 1643 printf("coda_readdir: vfs_object_create() returns %d\n", error); 1644 vput(vp); 1645 } 1646 } 1647 if (error) return(error); 1648 } 1649 1650 /* Have UFS handle the call. */ |
1651 CODADEBUG(CODA_READDIR, myprintf(("indirect readdir: fid = %s, refcnt = %d\n", coda_f2s(&cp->c_fid), vp->v_usecount)); ) |
1652 error = VOP_READDIR(cp->c_ovp, uiop, cred, eofflag, ncookies, 1653 cookies); 1654 1655 if (error) 1656 MARK_INT_FAIL(CODA_READDIR_STATS); 1657 else 1658 MARK_INT_SAT(CODA_READDIR_STATS); 1659 --- 94 unchanged lines hidden (view full) --- 1754 struct cnode *cp = VTOC(vp); 1755 struct thread *td = ap->a_td; 1756/* upcall decl */ 1757/* locals */ 1758 1759 ENTRY; 1760 1761 if (coda_lockdebug) { |
1762 myprintf(("Attempting lock on %s\n", 1763 coda_f2s(&cp->c_fid))); |
1764 } 1765 1766#ifndef DEBUG_LOCKS 1767 return (lockmgr(&cp->c_lock, ap->a_flags, &vp->v_interlock, td)); 1768#else 1769 return (debuglockmgr(&cp->c_lock, ap->a_flags, &vp->v_interlock, td, 1770 "coda_lock", vp->filename, vp->line)); 1771#endif --- 8 unchanged lines hidden (view full) --- 1780 struct vnode *vp = ap->a_vp; 1781 struct cnode *cp = VTOC(vp); 1782 struct thread *td = ap->a_td; 1783/* upcall decl */ 1784/* locals */ 1785 1786 ENTRY; 1787 if (coda_lockdebug) { |
1788 myprintf(("Attempting unlock on %s\n", 1789 coda_f2s(&cp->c_fid))); |
1790 } 1791 1792 return (lockmgr(&cp->c_lock, ap->a_flags | LK_RELEASE, &vp->v_interlock, td)); 1793} 1794 1795int 1796coda_islocked(v) 1797 void *v; --- 102 unchanged lines hidden (view full) --- 1900 myprintf(("\tgroup %d: (%d)\n",i,cred->cr_groups[i])); 1901 myprintf(("\n")); 1902 1903} 1904 1905/* 1906 * Return a vnode for the given fid. 1907 * If no cnode exists for this fid create one and put it |
1908 * in a table hashed by coda_f2i(). If the cnode for |
1909 * this fid is already in the table return it (ref count is 1910 * incremented by coda_find. The cnode will be flushed from the 1911 * table when coda_inactive calls coda_unsave. 1912 */ 1913struct cnode * 1914make_coda_node(fid, vfsp, type) |
1915 CodaFid *fid; struct mount *vfsp; short type; |
1916{ 1917 struct cnode *cp; 1918 int err; 1919 1920 if ((cp = coda_find(fid)) == NULL) { 1921 struct vnode *vp; 1922 1923 cp = coda_alloc(); --- 45 unchanged lines hidden --- |