xref: /freebsd/sys/fs/pseudofs/pseudofs.c (revision 9733a808399b6599b24768c5f8f225be95f1cae1)
19733a808SDag-Erling Smørgrav /*-
29733a808SDag-Erling Smørgrav  * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav
39733a808SDag-Erling Smørgrav  * All rights reserved.
49733a808SDag-Erling Smørgrav  *
59733a808SDag-Erling Smørgrav  * Redistribution and use in source and binary forms, with or without
69733a808SDag-Erling Smørgrav  * modification, are permitted provided that the following conditions
79733a808SDag-Erling Smørgrav  * are met:
89733a808SDag-Erling Smørgrav  * 1. Redistributions of source code must retain the above copyright
99733a808SDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer
109733a808SDag-Erling Smørgrav  *    in this position and unchanged.
119733a808SDag-Erling Smørgrav  * 2. Redistributions in binary form must reproduce the above copyright
129733a808SDag-Erling Smørgrav  *    notice, this list of conditions and the following disclaimer in the
139733a808SDag-Erling Smørgrav  *    documentation and/or other materials provided with the distribution.
149733a808SDag-Erling Smørgrav  * 3. The name of the author may not be used to endorse or promote products
159733a808SDag-Erling Smørgrav  *    derived from this software without specific prior written permission.
169733a808SDag-Erling Smørgrav  *
179733a808SDag-Erling Smørgrav  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
189733a808SDag-Erling Smørgrav  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
199733a808SDag-Erling Smørgrav  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
209733a808SDag-Erling Smørgrav  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
219733a808SDag-Erling Smørgrav  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
229733a808SDag-Erling Smørgrav  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
239733a808SDag-Erling Smørgrav  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
249733a808SDag-Erling Smørgrav  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
259733a808SDag-Erling Smørgrav  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
269733a808SDag-Erling Smørgrav  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
279733a808SDag-Erling Smørgrav  *
289733a808SDag-Erling Smørgrav  *	$FreeBSD$
299733a808SDag-Erling Smørgrav  */
309733a808SDag-Erling Smørgrav 
319733a808SDag-Erling Smørgrav #include <sys/param.h>
329733a808SDag-Erling Smørgrav #include <sys/kernel.h>
339733a808SDag-Erling Smørgrav #include <sys/systm.h>
349733a808SDag-Erling Smørgrav #include <sys/malloc.h>
359733a808SDag-Erling Smørgrav #include <sys/module.h>
369733a808SDag-Erling Smørgrav #include <sys/mount.h>
379733a808SDag-Erling Smørgrav #include <sys/proc.h>
389733a808SDag-Erling Smørgrav #include <sys/sbuf.h>
399733a808SDag-Erling Smørgrav #include <sys/sysctl.h>
409733a808SDag-Erling Smørgrav #include <sys/vnode.h>
419733a808SDag-Erling Smørgrav 
429733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs.h>
439733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs_internal.h>
449733a808SDag-Erling Smørgrav 
459733a808SDag-Erling Smørgrav SYSCTL_NODE(_vfs, OID_AUTO, pfs, CTLFLAG_RW, 0,
469733a808SDag-Erling Smørgrav     "pseudofs");
479733a808SDag-Erling Smørgrav 
489733a808SDag-Erling Smørgrav /*
499733a808SDag-Erling Smørgrav  * Mount a pseudofs instance
509733a808SDag-Erling Smørgrav  */
519733a808SDag-Erling Smørgrav int
529733a808SDag-Erling Smørgrav pfs_mount(struct pfs_info *pi, struct mount *mp, char *path, caddr_t data,
539733a808SDag-Erling Smørgrav 	  struct nameidata *ndp, struct proc *p)
549733a808SDag-Erling Smørgrav {
559733a808SDag-Erling Smørgrav 	struct statfs *sbp;
569733a808SDag-Erling Smørgrav 
579733a808SDag-Erling Smørgrav 	if (mp->mnt_flag & MNT_UPDATE)
589733a808SDag-Erling Smørgrav 		return (EOPNOTSUPP);
599733a808SDag-Erling Smørgrav 
609733a808SDag-Erling Smørgrav 	mp->mnt_flag |= MNT_LOCAL;
619733a808SDag-Erling Smørgrav 	mp->mnt_data = (qaddr_t)pi;
629733a808SDag-Erling Smørgrav 	vfs_getnewfsid(mp);
639733a808SDag-Erling Smørgrav 
649733a808SDag-Erling Smørgrav 	sbp = &mp->mnt_stat;
659733a808SDag-Erling Smørgrav 	bcopy(pi->pi_name, sbp->f_mntfromname, sizeof pi->pi_name);
669733a808SDag-Erling Smørgrav 	sbp->f_bsize = PAGE_SIZE;
679733a808SDag-Erling Smørgrav 	sbp->f_iosize = PAGE_SIZE;
689733a808SDag-Erling Smørgrav 	sbp->f_blocks = 1;
699733a808SDag-Erling Smørgrav 	sbp->f_bfree = 0;
709733a808SDag-Erling Smørgrav 	sbp->f_bavail = 0;
719733a808SDag-Erling Smørgrav 	sbp->f_files = 1;
729733a808SDag-Erling Smørgrav 	sbp->f_ffree = 0;
739733a808SDag-Erling Smørgrav 
749733a808SDag-Erling Smørgrav 	return (0);
759733a808SDag-Erling Smørgrav }
769733a808SDag-Erling Smørgrav 
779733a808SDag-Erling Smørgrav /*
789733a808SDag-Erling Smørgrav  * Unmount a pseudofs instance
799733a808SDag-Erling Smørgrav  */
809733a808SDag-Erling Smørgrav int
819733a808SDag-Erling Smørgrav pfs_unmount(struct mount *mp, int mntflags, struct proc *p)
829733a808SDag-Erling Smørgrav {
839733a808SDag-Erling Smørgrav 	struct pfs_info *pi;
849733a808SDag-Erling Smørgrav 	int error;
859733a808SDag-Erling Smørgrav 
869733a808SDag-Erling Smørgrav 	pi = (struct pfs_info *)mp->mnt_data;
879733a808SDag-Erling Smørgrav 
889733a808SDag-Erling Smørgrav 	/* XXX do stuff with pi... */
899733a808SDag-Erling Smørgrav 
909733a808SDag-Erling Smørgrav 	error = vflush(mp, 0, (mntflags & MNT_FORCE) ?  FORCECLOSE : 0);
919733a808SDag-Erling Smørgrav 	return (error);
929733a808SDag-Erling Smørgrav }
939733a808SDag-Erling Smørgrav 
949733a808SDag-Erling Smørgrav /*
959733a808SDag-Erling Smørgrav  * Return a root vnode
969733a808SDag-Erling Smørgrav  */
979733a808SDag-Erling Smørgrav int
989733a808SDag-Erling Smørgrav pfs_root(struct mount *mp, struct vnode **vpp)
999733a808SDag-Erling Smørgrav {
1009733a808SDag-Erling Smørgrav 	struct pfs_info *pi;
1019733a808SDag-Erling Smørgrav 
1029733a808SDag-Erling Smørgrav 	pi = (struct pfs_info *)mp->mnt_data;
1039733a808SDag-Erling Smørgrav 	return pfs_vncache_alloc(mp, vpp, pi->pi_root);
1049733a808SDag-Erling Smørgrav }
1059733a808SDag-Erling Smørgrav 
1069733a808SDag-Erling Smørgrav /*
1079733a808SDag-Erling Smørgrav  * Return filesystem stats
1089733a808SDag-Erling Smørgrav  */
1099733a808SDag-Erling Smørgrav int
1109733a808SDag-Erling Smørgrav pfs_statfs(struct mount *mp, struct statfs *sbp, struct proc *p)
1119733a808SDag-Erling Smørgrav {
1129733a808SDag-Erling Smørgrav 	bcopy(&mp->mnt_stat, sbp, sizeof *sbp);
1139733a808SDag-Erling Smørgrav 	return (0);
1149733a808SDag-Erling Smørgrav }
1159733a808SDag-Erling Smørgrav 
1169733a808SDag-Erling Smørgrav /*
1179733a808SDag-Erling Smørgrav  * Initialize a pseudofs instance
1189733a808SDag-Erling Smørgrav  */
1199733a808SDag-Erling Smørgrav int
1209733a808SDag-Erling Smørgrav pfs_init(struct pfs_info *pi, struct vfsconf *vfc)
1219733a808SDag-Erling Smørgrav {
1229733a808SDag-Erling Smørgrav 	mtx_init(&pi->pi_mutex, "pseudofs", MTX_DEF);
1239733a808SDag-Erling Smørgrav 	pfs_fileno_init(pi);
1249733a808SDag-Erling Smørgrav 	printf("%s registered\n", pi->pi_name);
1259733a808SDag-Erling Smørgrav 	return (0);
1269733a808SDag-Erling Smørgrav }
1279733a808SDag-Erling Smørgrav 
1289733a808SDag-Erling Smørgrav /*
1299733a808SDag-Erling Smørgrav  * Destroy a pseudofs instance
1309733a808SDag-Erling Smørgrav  */
1319733a808SDag-Erling Smørgrav int
1329733a808SDag-Erling Smørgrav pfs_uninit(struct pfs_info *pi, struct vfsconf *vfc)
1339733a808SDag-Erling Smørgrav {
1349733a808SDag-Erling Smørgrav 	pfs_fileno_uninit(pi);
1359733a808SDag-Erling Smørgrav 	mtx_destroy(&pi->pi_mutex);
1369733a808SDag-Erling Smørgrav 	printf("%s unregistered\n", pi->pi_name);
1379733a808SDag-Erling Smørgrav 	return (0);
1389733a808SDag-Erling Smørgrav }
1399733a808SDag-Erling Smørgrav 
1409733a808SDag-Erling Smørgrav /*
1419733a808SDag-Erling Smørgrav  * Handle load / unload events
1429733a808SDag-Erling Smørgrav  */
1439733a808SDag-Erling Smørgrav static int
1449733a808SDag-Erling Smørgrav pfs_modevent(module_t mod, int evt, void *arg)
1459733a808SDag-Erling Smørgrav {
1469733a808SDag-Erling Smørgrav 	switch (evt) {
1479733a808SDag-Erling Smørgrav 	case MOD_LOAD:
1489733a808SDag-Erling Smørgrav 		pfs_fileno_load();
1499733a808SDag-Erling Smørgrav 		pfs_vncache_load();
1509733a808SDag-Erling Smørgrav 		break;
1519733a808SDag-Erling Smørgrav 	case MOD_UNLOAD:
1529733a808SDag-Erling Smørgrav 	case MOD_SHUTDOWN:
1539733a808SDag-Erling Smørgrav 		pfs_vncache_unload();
1549733a808SDag-Erling Smørgrav 		pfs_fileno_unload();
1559733a808SDag-Erling Smørgrav 		break;
1569733a808SDag-Erling Smørgrav 	default:
1579733a808SDag-Erling Smørgrav 		printf("pseudofs: unexpected event type %d\n", evt);
1589733a808SDag-Erling Smørgrav 		break;
1599733a808SDag-Erling Smørgrav 	}
1609733a808SDag-Erling Smørgrav 	return 0;
1619733a808SDag-Erling Smørgrav }
1629733a808SDag-Erling Smørgrav 
1639733a808SDag-Erling Smørgrav /*
1649733a808SDag-Erling Smørgrav  * Module declaration
1659733a808SDag-Erling Smørgrav  */
1669733a808SDag-Erling Smørgrav static moduledata_t pseudofs_data = {
1679733a808SDag-Erling Smørgrav 	"pseudofs",
1689733a808SDag-Erling Smørgrav 	pfs_modevent,
1699733a808SDag-Erling Smørgrav 	NULL
1709733a808SDag-Erling Smørgrav };
1719733a808SDag-Erling Smørgrav DECLARE_MODULE(pseudofs, pseudofs_data, SI_SUB_EXEC, SI_ORDER_FIRST);
1729733a808SDag-Erling Smørgrav MODULE_VERSION(pseudofs, 1);
173