dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / kernel / fs / sharefs / sharefs_vfsops.c
blob70c15dd9c1928cbdee5792afd3c903e4e0899875
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/atomic.h>
27 #include <sys/cmn_err.h>
28 #include <sys/errno.h>
29 #include <sys/mount.h>
30 #include <sharefs/sharefs.h>
31 #include <sys/vfs.h>
32 #include <sys/policy.h>
33 #include <sys/sunddi.h>
34 #include <sys/sysmacros.h>
35 #include <sys/systm.h>
37 #include <sys/mntent.h>
38 #include <sys/vfs.h>
41 * Kernel sharetab filesystem.
43 * This is a pseudo filesystem which exports information about shares currently
44 * in kernel memory. The only element of the pseudo filesystem is a file.
46 * This file contains functions that interact with the VFS layer.
48 * sharetab sharefs_datanode_t sharefs.c
52 static const struct vfsops sharefs_vfsops;
54 static int sharefs_init(int, char *);
57 * The sharefs system call.
59 static struct sysent sharefs_sysent = {
61 SE_32RVAL1 | SE_ARGC | SE_NOUNLOAD,
62 sharefs
65 static struct modlsys modlsys = {
66 &mod_syscallops,
67 "sharefs syscall",
68 &sharefs_sysent
71 #ifdef _SYSCALL32_IMPL
72 static struct modlsys modlsys32 = {
73 &mod_syscallops32,
74 "sharefs syscall (32-bit)",
75 &sharefs_sysent
77 #endif /* _SYSCALL32_IMPL */
80 * Module linkage
82 static mntopts_t sharefs_mntopts = {
84 NULL
87 static vfsdef_t vfw = {
88 VFSDEF_VERSION,
89 "sharefs",
90 sharefs_init,
91 VSW_HASPROTO | VSW_ZMOUNT,
92 &sharefs_mntopts,
95 extern struct mod_ops mod_fsops;
97 static struct modlfs modlfs = {
98 &mod_fsops,
99 "sharetab filesystem",
100 &vfw
103 static struct modlinkage modlinkage = {
104 MODREV_1,
105 &modlfs,
106 &modlsys,
107 #ifdef _SYSCALL32_IMPL
108 &modlsys32,
109 #endif
110 NULL
114 _init(void)
116 return (mod_install(&modlinkage));
120 _info(struct modinfo *modinfop)
122 return (mod_info(&modlinkage, modinfop));
126 _fini(void)
129 * The sharetab filesystem cannot be unloaded.
131 return (EBUSY);
135 * Filesystem initialization.
138 static int sharefs_fstype;
139 static major_t sharefs_major;
140 static minor_t sharefs_minor;
142 /* ARGSUSED */
143 static int
144 sharefs_init(int fstype, char *name)
146 int error;
148 sharefs_fstype = fstype;
149 if (error = vfs_setfsops(fstype, &sharefs_vfsops)) {
150 cmn_err(CE_WARN, "sharefs_init: bad vfs ops template");
151 return (error);
154 if ((sharefs_major = getudev()) == (major_t)-1) {
155 cmn_err(CE_WARN,
156 "sharefs_init: can't get unique device number");
157 sharefs_major = 0;
160 sharefs_sharetab_init();
162 return (0);
166 * VFS entry points
168 static int
169 sharefs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
171 sharefs_vfs_t *data;
172 dev_t dev;
174 if (secpolicy_fs_mount(cr, mvp, vfsp) != 0)
175 return (EPERM);
177 if ((uap->flags & MS_OVERLAY) == 0 &&
178 (mvp->v_count > 1 || (mvp->v_flag & VROOT)))
179 return (EBUSY);
181 data = kmem_alloc(sizeof (sharefs_vfs_t), KM_SLEEP);
184 * Initialize vfs fields
186 vfsp->vfs_bsize = DEV_BSIZE;
187 vfsp->vfs_fstype = sharefs_fstype;
188 do {
189 dev = makedevice(sharefs_major,
190 atomic_inc_32_nv(&sharefs_minor) & L_MAXMIN32);
191 } while (vfs_devismounted(dev));
192 vfs_make_fsid(&vfsp->vfs_fsid, dev, sharefs_fstype);
193 vfsp->vfs_data = data;
194 vfsp->vfs_dev = dev;
197 * Create root
199 data->sharefs_vfs_root = sharefs_create_root_file(vfsp);
201 return (0);
204 static int
205 sharefs_unmount(vfs_t *vfsp, int flag, struct cred *cr)
207 sharefs_vfs_t *data;
209 if (secpolicy_fs_unmount(cr, vfsp) != 0)
210 return (EPERM);
213 * We do not currently support forced unmounts
215 if (flag & MS_FORCE)
216 return (ENOTSUP);
219 * We should never have a reference count of less than 2: one for the
220 * caller, one for the root vnode.
222 ASSERT(vfsp->vfs_count >= 2);
225 * Any active vnodes will result in a hold on the root vnode
227 data = vfsp->vfs_data;
228 if (data->sharefs_vfs_root->v_count > 1)
229 return (EBUSY);
232 * Only allow an unmount iff there are no entries in memory.
234 rw_enter(&sharetab_lock, RW_READER);
235 if (sharetab_size != 0) {
236 rw_exit(&sharetab_lock);
237 return (EBUSY);
239 rw_exit(&sharetab_lock);
242 * Release the last hold on the root vnode
244 VN_RELE(data->sharefs_vfs_root);
246 kmem_free(data, sizeof (sharefs_vfs_t));
248 return (0);
251 static int
252 sharefs_root(vfs_t *vfsp, vnode_t **vpp)
254 sharefs_vfs_t *data = vfsp->vfs_data;
256 *vpp = data->sharefs_vfs_root;
257 VN_HOLD(*vpp);
259 return (0);
262 static int
263 sharefs_statvfs(vfs_t *vfsp, statvfs64_t *sp)
265 dev32_t d32;
266 int total = 1;
268 bzero(sp, sizeof (*sp));
269 sp->f_bsize = DEV_BSIZE;
270 sp->f_frsize = DEV_BSIZE;
271 sp->f_files = total;
272 sp->f_ffree = sp->f_favail = INT_MAX - total;
273 (void) cmpldev(&d32, vfsp->vfs_dev);
274 sp->f_fsid = d32;
275 (void) strlcpy(sp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name,
276 sizeof (sp->f_basetype));
277 sp->f_flag = vf_to_stf(vfsp->vfs_flag);
278 sp->f_namemax = SHAREFS_NAME_MAX;
279 (void) strlcpy(sp->f_fstr, "sharefs", sizeof (sp->f_fstr));
281 return (0);
284 static const struct vfsops sharefs_vfsops = {
285 .vfs_mount = sharefs_mount,
286 .vfs_unmount = sharefs_unmount,
287 .vfs_root = sharefs_root,
288 .vfs_statvfs = sharefs_statvfs,