xref: /freebsd/sys/fs/pseudofs/pseudofs_fileno.c (revision 15bad11fdb1eb2e58d4c17e0f931eebe9b50d0de)
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 
29de52d21aSDag-Erling Smørgrav #include <sys/cdefs.h>
30de52d21aSDag-Erling Smørgrav __FBSDID("$FreeBSD$");
31de52d21aSDag-Erling Smørgrav 
32de52d21aSDag-Erling Smørgrav #include "opt_pseudofs.h"
33de52d21aSDag-Erling Smørgrav 
349733a808SDag-Erling Smørgrav #include <sys/param.h>
359733a808SDag-Erling Smørgrav #include <sys/kernel.h>
369733a808SDag-Erling Smørgrav #include <sys/systm.h>
37104a9b7eSAlexander Kabaev #include <sys/limits.h>
3821ceb6efSDag-Erling Smørgrav #include <sys/lock.h>
399733a808SDag-Erling Smørgrav #include <sys/malloc.h>
4049fa664fSDag-Erling Smørgrav #include <sys/mutex.h>
419733a808SDag-Erling Smørgrav #include <sys/sysctl.h>
4215bad11fSDag-Erling Smørgrav #include <sys/systm.h>
439733a808SDag-Erling Smørgrav 
449733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs.h>
459733a808SDag-Erling Smørgrav #include <fs/pseudofs/pseudofs_internal.h>
469733a808SDag-Erling Smørgrav 
479733a808SDag-Erling Smørgrav /*
489733a808SDag-Erling Smørgrav  * Initialize fileno bitmap
499733a808SDag-Erling Smørgrav  */
509733a808SDag-Erling Smørgrav void
519733a808SDag-Erling Smørgrav pfs_fileno_init(struct pfs_info *pi)
529733a808SDag-Erling Smørgrav {
537f661c6bSPoul-Henning Kamp 	struct unrhdr *up;
549733a808SDag-Erling Smørgrav 
557f661c6bSPoul-Henning Kamp 	up = new_unrhdr(3, INT_MAX, &pi->pi_mutex);
569733a808SDag-Erling Smørgrav 	mtx_lock(&pi->pi_mutex);
577f661c6bSPoul-Henning Kamp 	pi->pi_unrhdr = up;
589733a808SDag-Erling Smørgrav 	mtx_unlock(&pi->pi_mutex);
599733a808SDag-Erling Smørgrav }
609733a808SDag-Erling Smørgrav 
619733a808SDag-Erling Smørgrav /*
629733a808SDag-Erling Smørgrav  * Tear down fileno bitmap
639733a808SDag-Erling Smørgrav  */
649733a808SDag-Erling Smørgrav void
659733a808SDag-Erling Smørgrav pfs_fileno_uninit(struct pfs_info *pi)
669733a808SDag-Erling Smørgrav {
677f661c6bSPoul-Henning Kamp 	struct unrhdr *up;
689733a808SDag-Erling Smørgrav 
699733a808SDag-Erling Smørgrav 	mtx_lock(&pi->pi_mutex);
709733a808SDag-Erling Smørgrav 
717f661c6bSPoul-Henning Kamp 	up = pi->pi_unrhdr;
727f661c6bSPoul-Henning Kamp 	pi->pi_unrhdr = NULL;
739733a808SDag-Erling Smørgrav 
749733a808SDag-Erling Smørgrav 	mtx_unlock(&pi->pi_mutex);
759733a808SDag-Erling Smørgrav 
767f661c6bSPoul-Henning Kamp 	delete_unrhdr(up);
779733a808SDag-Erling Smørgrav }
789733a808SDag-Erling Smørgrav 
799733a808SDag-Erling Smørgrav /*
809733a808SDag-Erling Smørgrav  * Allocate a file number
819733a808SDag-Erling Smørgrav  */
829733a808SDag-Erling Smørgrav void
839733a808SDag-Erling Smørgrav pfs_fileno_alloc(struct pfs_info *pi, struct pfs_node *pn)
849733a808SDag-Erling Smørgrav {
8515bad11fSDag-Erling Smørgrav 	/* pi is not really necessary as it can be derived */
8615bad11fSDag-Erling Smørgrav 	KASSERT(pi == pn->pn_info, ("pn / pi mismatch"));
8715bad11fSDag-Erling Smørgrav 
889733a808SDag-Erling Smørgrav 	/* make sure our parent has a file number */
899733a808SDag-Erling Smørgrav 	if (pn->pn_parent && !pn->pn_parent->pn_fileno)
909733a808SDag-Erling Smørgrav 		pfs_fileno_alloc(pi, pn->pn_parent);
919733a808SDag-Erling Smørgrav 
929733a808SDag-Erling Smørgrav 	switch (pn->pn_type) {
939733a808SDag-Erling Smørgrav 	case pfstype_root:
9415bad11fSDag-Erling Smørgrav 		/* root must always be 2 */
9515bad11fSDag-Erling Smørgrav 		pn->pn_fileno = 2;
9615bad11fSDag-Erling Smørgrav 		break;
979733a808SDag-Erling Smørgrav 	case pfstype_dir:
989733a808SDag-Erling Smørgrav 	case pfstype_file:
999733a808SDag-Erling Smørgrav 	case pfstype_symlink:
100649ad985SDag-Erling Smørgrav 	case pfstype_procdir:
1017f661c6bSPoul-Henning Kamp 		pn->pn_fileno = alloc_unr(pi->pi_unrhdr);
1029733a808SDag-Erling Smørgrav 		break;
1039733a808SDag-Erling Smørgrav 	case pfstype_this:
1049733a808SDag-Erling Smørgrav 		KASSERT(pn->pn_parent != NULL,
1059733a808SDag-Erling Smørgrav 		    ("pfstype_this node has no parent"));
1069733a808SDag-Erling Smørgrav 		pn->pn_fileno = pn->pn_parent->pn_fileno;
1079733a808SDag-Erling Smørgrav 		break;
1089733a808SDag-Erling Smørgrav 	case pfstype_parent:
1099733a808SDag-Erling Smørgrav 		KASSERT(pn->pn_parent != NULL,
1109733a808SDag-Erling Smørgrav 		    ("pfstype_parent node has no parent"));
1119733a808SDag-Erling Smørgrav 		if (pn->pn_parent == pi->pi_root) {
1129733a808SDag-Erling Smørgrav 			pn->pn_fileno = pn->pn_parent->pn_fileno;
1139733a808SDag-Erling Smørgrav 			break;
1149733a808SDag-Erling Smørgrav 		}
1159733a808SDag-Erling Smørgrav 		KASSERT(pn->pn_parent->pn_parent != NULL,
1169733a808SDag-Erling Smørgrav 		    ("pfstype_parent node has no grandparent"));
1179733a808SDag-Erling Smørgrav 		pn->pn_fileno = pn->pn_parent->pn_parent->pn_fileno;
1189733a808SDag-Erling Smørgrav 		break;
1199733a808SDag-Erling Smørgrav 	case pfstype_none:
120649ad985SDag-Erling Smørgrav 		KASSERT(0,
1219733a808SDag-Erling Smørgrav 		    ("pfs_fileno_alloc() called for pfstype_none node"));
1229733a808SDag-Erling Smørgrav 		break;
1239733a808SDag-Erling Smørgrav 	}
1249733a808SDag-Erling Smørgrav 
125649ad985SDag-Erling Smørgrav #if 0
1269733a808SDag-Erling Smørgrav 	printf("pfs_fileno_alloc(): %s: ", pi->pi_name);
1279733a808SDag-Erling Smørgrav 	if (pn->pn_parent) {
1289733a808SDag-Erling Smørgrav 		if (pn->pn_parent->pn_parent) {
1299733a808SDag-Erling Smørgrav 			printf("%s/", pn->pn_parent->pn_parent->pn_name);
1309733a808SDag-Erling Smørgrav 		}
1319733a808SDag-Erling Smørgrav 		printf("%s/", pn->pn_parent->pn_name);
1329733a808SDag-Erling Smørgrav 	}
1339733a808SDag-Erling Smørgrav 	printf("%s -> %d\n", pn->pn_name, pn->pn_fileno);
134649ad985SDag-Erling Smørgrav #endif
1359733a808SDag-Erling Smørgrav }
1369733a808SDag-Erling Smørgrav 
1379733a808SDag-Erling Smørgrav /*
1389733a808SDag-Erling Smørgrav  * Release a file number
1399733a808SDag-Erling Smørgrav  */
1409733a808SDag-Erling Smørgrav void
1419733a808SDag-Erling Smørgrav pfs_fileno_free(struct pfs_info *pi, struct pfs_node *pn)
1429733a808SDag-Erling Smørgrav {
14315bad11fSDag-Erling Smørgrav 	/* pi is not really necessary as it can be derived */
14415bad11fSDag-Erling Smørgrav 	KASSERT(pi == pn->pn_info, ("pn / pi mismatch"));
14515bad11fSDag-Erling Smørgrav 
1469733a808SDag-Erling Smørgrav 	switch (pn->pn_type) {
1479733a808SDag-Erling Smørgrav 	case pfstype_root:
14815bad11fSDag-Erling Smørgrav 		/* not allocated from unrhdr */
14915bad11fSDag-Erling Smørgrav 		return;
1509733a808SDag-Erling Smørgrav 	case pfstype_dir:
1519733a808SDag-Erling Smørgrav 	case pfstype_file:
1529733a808SDag-Erling Smørgrav 	case pfstype_symlink:
153649ad985SDag-Erling Smørgrav 	case pfstype_procdir:
1547f661c6bSPoul-Henning Kamp 		free_unr(pi->pi_unrhdr, pn->pn_fileno);
1559733a808SDag-Erling Smørgrav 		break;
1569733a808SDag-Erling Smørgrav 	case pfstype_this:
1579733a808SDag-Erling Smørgrav 	case pfstype_parent:
1589733a808SDag-Erling Smørgrav 		/* ignore these, as they don't "own" their file number */
1599733a808SDag-Erling Smørgrav 		break;
1609733a808SDag-Erling Smørgrav 	case pfstype_none:
161649ad985SDag-Erling Smørgrav 		KASSERT(0,
1629733a808SDag-Erling Smørgrav 		    ("pfs_fileno_free() called for pfstype_none node"));
1639733a808SDag-Erling Smørgrav 		break;
1649733a808SDag-Erling Smørgrav 	}
1659733a808SDag-Erling Smørgrav }
166