1139825Simp/*-
21541Srgrimes * Copyright (c) 1991, 1993, 1994
31541Srgrimes *	The Regents of the University of California.  All rights reserved.
41541Srgrimes * (c) UNIX System Laboratories, Inc.
51541Srgrimes * All or some portions of this file are derived from material licensed
61541Srgrimes * to the University of California by American Telephone and Telegraph
71541Srgrimes * Co. or Unix System Laboratories, Inc. and are reproduced herein with
81541Srgrimes * the permission of UNIX System Laboratories, Inc.
91541Srgrimes *
101541Srgrimes * Redistribution and use in source and binary forms, with or without
111541Srgrimes * modification, are permitted provided that the following conditions
121541Srgrimes * are met:
131541Srgrimes * 1. Redistributions of source code must retain the above copyright
141541Srgrimes *    notice, this list of conditions and the following disclaimer.
151541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
161541Srgrimes *    notice, this list of conditions and the following disclaimer in the
171541Srgrimes *    documentation and/or other materials provided with the distribution.
181541Srgrimes * 4. Neither the name of the University nor the names of its contributors
191541Srgrimes *    may be used to endorse or promote products derived from this software
201541Srgrimes *    without specific prior written permission.
211541Srgrimes *
221541Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
231541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
241541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
251541Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
261541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
271541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
281541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
291541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
301541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
311541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
321541Srgrimes * SUCH DAMAGE.
331541Srgrimes *
3422521Sdyson *	@(#)ufs_vfsops.c	8.8 (Berkeley) 5/20/95
351541Srgrimes */
361541Srgrimes
37116192Sobrien#include <sys/cdefs.h>
38116192Sobrien__FBSDID("$FreeBSD$");
39116192Sobrien
4013260Swollman#include "opt_quota.h"
4199101Siedowse#include "opt_ufs.h"
4213260Swollman
431541Srgrimes#include <sys/param.h>
4476166Smarkm#include <sys/systm.h>
4541059Speter#include <sys/kernel.h>
4676166Smarkm#include <sys/lock.h>
4776166Smarkm#include <sys/malloc.h>
4876166Smarkm#include <sys/mount.h>
4965557Sjasone#include <sys/proc.h>
5076166Smarkm#include <sys/socket.h>
511541Srgrimes#include <sys/vnode.h>
521541Srgrimes
5359241Srwatson#include <ufs/ufs/extattr.h>
541541Srgrimes#include <ufs/ufs/quota.h>
551541Srgrimes#include <ufs/ufs/inode.h>
561541Srgrimes#include <ufs/ufs/ufsmount.h>
571541Srgrimes#include <ufs/ufs/ufs_extern.h>
5899101Siedowse#ifdef UFS_DIRHASH
5999101Siedowse#include <ufs/ufs/dir.h>
6099101Siedowse#include <ufs/ufs/dirhash.h>
6199101Siedowse#endif
621541Srgrimes
63151897SrwatsonMALLOC_DEFINE(M_UFSMNT, "ufs_mount", "UFS mount structure");
641541Srgrimes
651541Srgrimes/*
661541Srgrimes * Return the root of a filesystem.
671541Srgrimes */
681541Srgrimesint
69191990Sattilioufs_root(mp, flags, vpp)
701541Srgrimes	struct mount *mp;
71144056Sjeff	int flags;
721541Srgrimes	struct vnode **vpp;
731541Srgrimes{
741541Srgrimes	struct vnode *nvp;
751541Srgrimes	int error;
761541Srgrimes
77144056Sjeff	error = VFS_VGET(mp, (ino_t)ROOTINO, flags, &nvp);
783427Sphk	if (error)
791541Srgrimes		return (error);
801541Srgrimes	*vpp = nvp;
811541Srgrimes	return (0);
821541Srgrimes}
831541Srgrimes
841541Srgrimes/*
851541Srgrimes * Do operations associated with quotas
861541Srgrimes */
871541Srgrimesint
88191990Sattilioufs_quotactl(mp, cmds, id, arg)
891541Srgrimes	struct mount *mp;
901541Srgrimes	int cmds;
91166381Smpp	uid_t id;
92153400Sdes	void *arg;
931541Srgrimes{
941541Srgrimes#ifndef QUOTA
951541Srgrimes	return (EOPNOTSUPP);
961541Srgrimes#else
97191990Sattilio	struct thread *td;
983427Sphk	int cmd, type, error;
993427Sphk
100191990Sattilio	td = curthread;
1011541Srgrimes	cmd = cmds >> SUBCMDSHIFT;
1026992Sdg	type = cmds & SUBCMDMASK;
103166381Smpp	if (id == -1) {
104166381Smpp		switch (type) {
105166381Smpp
106166381Smpp		case USRQUOTA:
107166381Smpp			id = td->td_ucred->cr_ruid;
108166381Smpp			break;
109166381Smpp
110166381Smpp		case GRPQUOTA:
111166381Smpp			id = td->td_ucred->cr_rgid;
112166381Smpp			break;
113166381Smpp
114166381Smpp		default:
115166381Smpp			return (EINVAL);
116166381Smpp		}
117166381Smpp	}
1181541Srgrimes	if ((u_int)type >= MAXQUOTAS)
1191541Srgrimes		return (EINVAL);
120116384Srwatson
1211541Srgrimes	switch (cmd) {
1221541Srgrimes	case Q_QUOTAON:
12383366Sjulian		error = quotaon(td, mp, type, arg);
12422521Sdyson		break;
1251541Srgrimes
1261541Srgrimes	case Q_QUOTAOFF:
12783366Sjulian		error = quotaoff(td, mp, type);
12822521Sdyson		break;
1291541Srgrimes
130207736Smckusick	case Q_SETQUOTA32:
131207736Smckusick		error = setquota32(td, mp, id, type, arg);
132207736Smckusick		break;
133207736Smckusick
134207736Smckusick	case Q_SETUSE32:
135207736Smckusick		error = setuse32(td, mp, id, type, arg);
136207736Smckusick		break;
137207736Smckusick
138207736Smckusick	case Q_GETQUOTA32:
139207736Smckusick		error = getquota32(td, mp, id, type, arg);
140207736Smckusick		break;
141207736Smckusick
1421541Srgrimes	case Q_SETQUOTA:
143166381Smpp		error = setquota(td, mp, id, type, arg);
14422521Sdyson		break;
1451541Srgrimes
1461541Srgrimes	case Q_SETUSE:
147166381Smpp		error = setuse(td, mp, id, type, arg);
14822521Sdyson		break;
1491541Srgrimes
1501541Srgrimes	case Q_GETQUOTA:
151166381Smpp		error = getquota(td, mp, id, type, arg);
15222521Sdyson		break;
1531541Srgrimes
154207736Smckusick	case Q_GETQUOTASIZE:
155207736Smckusick		error = getquotasize(td, mp, id, type, arg);
156207736Smckusick		break;
157207736Smckusick
1581541Srgrimes	case Q_SYNC:
1591541Srgrimes		error = qsync(mp);
16022521Sdyson		break;
1611541Srgrimes
1621541Srgrimes	default:
16322521Sdyson		error = EINVAL;
16422521Sdyson		break;
1651541Srgrimes	}
16622521Sdyson	return (error);
1671541Srgrimes#endif
1681541Srgrimes}
1691541Srgrimes
1701541Srgrimes/*
17122521Sdyson * Initial UFS filesystems, done only once.
17222521Sdyson */
17322521Sdysonint
17422521Sdysonufs_init(vfsp)
17522521Sdyson	struct vfsconf *vfsp;
17622521Sdyson{
17722521Sdyson
17822521Sdyson#ifdef QUOTA
17922521Sdyson	dqinit();
18022521Sdyson#endif
18199101Siedowse#ifdef UFS_DIRHASH
18299101Siedowse	ufsdirhash_init();
18399101Siedowse#endif
18422521Sdyson	return (0);
18522521Sdyson}
18622521Sdyson
18722521Sdyson/*
18899101Siedowse * Uninitialise UFS filesystems, done before module unload.
18999101Siedowse */
19099101Siedowseint
19199101Siedowseufs_uninit(vfsp)
19299101Siedowse	struct vfsconf *vfsp;
19399101Siedowse{
19499101Siedowse
19599101Siedowse#ifdef QUOTA
19699101Siedowse	dquninit();
19799101Siedowse#endif
19899101Siedowse#ifdef UFS_DIRHASH
19999101Siedowse	ufsdirhash_uninit();
20099101Siedowse#endif
20199101Siedowse	return (0);
20299101Siedowse}
20399101Siedowse
20499101Siedowse/*
2051541Srgrimes * This is the generic part of fhtovp called after the underlying
2061541Srgrimes * filesystem has validated the file handle.
2071541Srgrimes *
20851138Salfred * Call the VFS_CHECKEXP beforehand to verify access.
2091541Srgrimes */
2101541Srgrimesint
211222167Srmacklemufs_fhtovp(mp, ufhp, flags, vpp)
21296482Sphk	struct mount *mp;
2131541Srgrimes	struct ufid *ufhp;
214222167Srmacklem	int flags;
2151541Srgrimes	struct vnode **vpp;
2161541Srgrimes{
21796482Sphk	struct inode *ip;
2181541Srgrimes	struct vnode *nvp;
2191541Srgrimes	int error;
2201541Srgrimes
221222196Srmacklem	error = VFS_VGET(mp, ufhp->ufid_ino, flags, &nvp);
2223427Sphk	if (error) {
2231541Srgrimes		*vpp = NULLVP;
2241541Srgrimes		return (error);
2251541Srgrimes	}
2261541Srgrimes	ip = VTOI(nvp);
22796873Siedowse	if (ip->i_mode == 0 || ip->i_gen != ufhp->ufid_gen ||
22896873Siedowse	    ip->i_effnlink <= 0) {
2291541Srgrimes		vput(nvp);
2301541Srgrimes		*vpp = NULLVP;
2311541Srgrimes		return (ESTALE);
2321541Srgrimes	}
2331541Srgrimes	*vpp = nvp;
234140962Speadar	vnode_create_vobject(*vpp, DIP(ip, i_size), curthread);
23551138Salfred	return (0);
23651138Salfred}
237