1 /* 2 * Copyright (c) 1991, 1993, 1994 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * %sccs.include.redist.c% 11 * 12 * @(#)ufs_vfsops.c 8.6 (Berkeley) 03/30/95 13 */ 14 15 #include <sys/param.h> 16 #include <sys/mbuf.h> 17 #include <sys/mount.h> 18 #include <sys/proc.h> 19 #include <sys/buf.h> 20 #include <sys/vnode.h> 21 #include <sys/malloc.h> 22 23 #include <miscfs/specfs/specdev.h> 24 25 #include <ufs/ufs/quota.h> 26 #include <ufs/ufs/inode.h> 27 #include <ufs/ufs/ufsmount.h> 28 #include <ufs/ufs/ufs_extern.h> 29 30 /* 31 * Flag to permit forcible unmounting. 32 */ 33 int doforce = 1; 34 35 /* 36 * Make a filesystem operational. 37 * Nothing to do at the moment. 38 */ 39 /* ARGSUSED */ 40 int 41 ufs_start(mp, flags, p) 42 struct mount *mp; 43 int flags; 44 struct proc *p; 45 { 46 47 return (0); 48 } 49 50 /* 51 * Return the root of a filesystem. 52 */ 53 int 54 ufs_root(mp, vpp) 55 struct mount *mp; 56 struct vnode **vpp; 57 { 58 struct vnode *nvp; 59 int error; 60 61 if (error = VFS_VGET(mp, (ino_t)ROOTINO, &nvp)) 62 return (error); 63 *vpp = nvp; 64 return (0); 65 } 66 67 /* 68 * Do operations associated with quotas 69 */ 70 int 71 ufs_quotactl(mp, cmds, uid, arg, p) 72 struct mount *mp; 73 int cmds; 74 uid_t uid; 75 caddr_t arg; 76 struct proc *p; 77 { 78 int cmd, type, error; 79 80 #ifndef QUOTA 81 return (EOPNOTSUPP); 82 #else 83 if (uid == -1) 84 uid = p->p_cred->p_ruid; 85 cmd = cmds >> SUBCMDSHIFT; 86 87 switch (cmd) { 88 case Q_SYNC: 89 break; 90 case Q_GETQUOTA: 91 if (uid == p->p_cred->p_ruid) 92 break; 93 /* fall through */ 94 default: 95 if (error = suser(p->p_ucred, &p->p_acflag)) 96 return (error); 97 } 98 99 type = cmds & SUBCMDMASK; 100 if ((u_int)type >= MAXQUOTAS) 101 return (EINVAL); 102 103 switch (cmd) { 104 105 case Q_QUOTAON: 106 return (quotaon(p, mp, type, arg)); 107 108 case Q_QUOTAOFF: 109 if (vfs_busy(mp)) 110 return (0); 111 error = quotaoff(p, mp, type); 112 vfs_unbusy(mp); 113 return (error); 114 115 case Q_SETQUOTA: 116 return (setquota(mp, uid, type, arg)); 117 118 case Q_SETUSE: 119 return (setuse(mp, uid, type, arg)); 120 121 case Q_GETQUOTA: 122 return (getquota(mp, uid, type, arg)); 123 124 case Q_SYNC: 125 if (vfs_busy(mp)) 126 return (0); 127 error = qsync(mp); 128 vfs_unbusy(mp); 129 return (error); 130 131 default: 132 return (EINVAL); 133 } 134 /* NOTREACHED */ 135 #endif 136 } 137 138 /* 139 * Initial UFS filesystems, done only once. 140 */ 141 int 142 ufs_init(vfsp) 143 struct vfsconf *vfsp; 144 { 145 static int done; 146 147 if (done) 148 return (0); 149 done = 1; 150 ufs_ihashinit(); 151 #ifdef QUOTA 152 dqinit(); 153 #endif 154 return (0); 155 } 156 157 /* 158 * This is the generic part of fhtovp called after the underlying 159 * filesystem has validated the file handle. 160 * 161 * Verify that a host should have access to a filesystem, and if so 162 * return a vnode for the presented file handle. 163 */ 164 int 165 ufs_check_export(mp, ufhp, nam, vpp, exflagsp, credanonp) 166 register struct mount *mp; 167 struct ufid *ufhp; 168 struct mbuf *nam; 169 struct vnode **vpp; 170 int *exflagsp; 171 struct ucred **credanonp; 172 { 173 register struct inode *ip; 174 register struct netcred *np; 175 register struct ufsmount *ump = VFSTOUFS(mp); 176 struct vnode *nvp; 177 int error; 178 179 /* 180 * Get the export permission structure for this <mp, client> tuple. 181 */ 182 np = vfs_export_lookup(mp, &ump->um_export, nam); 183 if (np == NULL) 184 return (EACCES); 185 186 if (error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) { 187 *vpp = NULLVP; 188 return (error); 189 } 190 ip = VTOI(nvp); 191 if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen) { 192 vput(nvp); 193 *vpp = NULLVP; 194 return (ESTALE); 195 } 196 *vpp = nvp; 197 *exflagsp = np->netc_exflags; 198 *credanonp = &np->netc_anon; 199 return (0); 200 } 201