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]
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>
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>
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
,
65 static struct modlsys modlsys
= {
71 #ifdef _SYSCALL32_IMPL
72 static struct modlsys modlsys32
= {
74 "sharefs syscall (32-bit)",
77 #endif /* _SYSCALL32_IMPL */
82 static mntopts_t sharefs_mntopts
= {
87 static vfsdef_t vfw
= {
91 VSW_HASPROTO
| VSW_ZMOUNT
,
95 extern struct mod_ops mod_fsops
;
97 static struct modlfs modlfs
= {
99 "sharetab filesystem",
103 static struct modlinkage modlinkage
= {
107 #ifdef _SYSCALL32_IMPL
116 return (mod_install(&modlinkage
));
120 _info(struct modinfo
*modinfop
)
122 return (mod_info(&modlinkage
, modinfop
));
129 * The sharetab filesystem cannot be unloaded.
135 * Filesystem initialization.
138 static int sharefs_fstype
;
139 static major_t sharefs_major
;
140 static minor_t sharefs_minor
;
144 sharefs_init(int fstype
, char *name
)
148 sharefs_fstype
= fstype
;
149 if (error
= vfs_setfsops(fstype
, &sharefs_vfsops
)) {
150 cmn_err(CE_WARN
, "sharefs_init: bad vfs ops template");
154 if ((sharefs_major
= getudev()) == (major_t
)-1) {
156 "sharefs_init: can't get unique device number");
160 sharefs_sharetab_init();
169 sharefs_mount(vfs_t
*vfsp
, vnode_t
*mvp
, struct mounta
*uap
, cred_t
*cr
)
174 if (secpolicy_fs_mount(cr
, mvp
, vfsp
) != 0)
177 if ((uap
->flags
& MS_OVERLAY
) == 0 &&
178 (mvp
->v_count
> 1 || (mvp
->v_flag
& VROOT
)))
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
;
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
;
199 data
->sharefs_vfs_root
= sharefs_create_root_file(vfsp
);
205 sharefs_unmount(vfs_t
*vfsp
, int flag
, struct cred
*cr
)
209 if (secpolicy_fs_unmount(cr
, vfsp
) != 0)
213 * We do not currently support forced unmounts
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)
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
);
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
));
252 sharefs_root(vfs_t
*vfsp
, vnode_t
**vpp
)
254 sharefs_vfs_t
*data
= vfsp
->vfs_data
;
256 *vpp
= data
->sharefs_vfs_root
;
263 sharefs_statvfs(vfs_t
*vfsp
, statvfs64_t
*sp
)
268 bzero(sp
, sizeof (*sp
));
269 sp
->f_bsize
= DEV_BSIZE
;
270 sp
->f_frsize
= DEV_BSIZE
;
272 sp
->f_ffree
= sp
->f_favail
= INT_MAX
- total
;
273 (void) cmpldev(&d32
, vfsp
->vfs_dev
);
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
));
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
,