xref: /openbsd-src/sys/ufs/mfs/mfs_vfsops.c (revision 3b30ff2ab7969af0fd9a5f043abb71c2592340bb)
1*3b30ff2aSclaudio /*	$OpenBSD: mfs_vfsops.c,v 1.63 2024/10/17 09:11:35 claudio Exp $	*/
21faf140aSniklas /*	$NetBSD: mfs_vfsops.c,v 1.10 1996/02/09 22:31:28 christos Exp $	*/
3df930be7Sderaadt 
4df930be7Sderaadt /*
5df930be7Sderaadt  * Copyright (c) 1989, 1990, 1993, 1994
6df930be7Sderaadt  *	The Regents of the University of California.  All rights reserved.
7df930be7Sderaadt  *
8df930be7Sderaadt  * Redistribution and use in source and binary forms, with or without
9df930be7Sderaadt  * modification, are permitted provided that the following conditions
10df930be7Sderaadt  * are met:
11df930be7Sderaadt  * 1. Redistributions of source code must retain the above copyright
12df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer.
13df930be7Sderaadt  * 2. Redistributions in binary form must reproduce the above copyright
14df930be7Sderaadt  *    notice, this list of conditions and the following disclaimer in the
15df930be7Sderaadt  *    documentation and/or other materials provided with the distribution.
1629295d1cSmillert  * 3. Neither the name of the University nor the names of its contributors
17df930be7Sderaadt  *    may be used to endorse or promote products derived from this software
18df930be7Sderaadt  *    without specific prior written permission.
19df930be7Sderaadt  *
20df930be7Sderaadt  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21df930be7Sderaadt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22df930be7Sderaadt  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23df930be7Sderaadt  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24df930be7Sderaadt  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25df930be7Sderaadt  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26df930be7Sderaadt  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27df930be7Sderaadt  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28df930be7Sderaadt  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29df930be7Sderaadt  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30df930be7Sderaadt  * SUCH DAMAGE.
31df930be7Sderaadt  *
32df930be7Sderaadt  *	@(#)mfs_vfsops.c	8.4 (Berkeley) 4/16/94
33df930be7Sderaadt  */
34df930be7Sderaadt 
35df930be7Sderaadt #include <sys/param.h>
36df930be7Sderaadt #include <sys/systm.h>
37df930be7Sderaadt #include <sys/time.h>
38df930be7Sderaadt #include <sys/proc.h>
39df930be7Sderaadt #include <sys/buf.h>
40df930be7Sderaadt #include <sys/mount.h>
41df930be7Sderaadt #include <sys/signalvar.h>
42df930be7Sderaadt #include <sys/vnode.h>
43df930be7Sderaadt #include <sys/malloc.h>
44df930be7Sderaadt 
45df930be7Sderaadt #include <ufs/ufs/quota.h>
46df930be7Sderaadt #include <ufs/ufs/inode.h>
47df930be7Sderaadt #include <ufs/ufs/ufsmount.h>
48df930be7Sderaadt #include <ufs/ufs/ufs_extern.h>
49df930be7Sderaadt 
50df930be7Sderaadt #include <ufs/ffs/fs.h>
51df930be7Sderaadt #include <ufs/ffs/ffs_extern.h>
52df930be7Sderaadt 
53df930be7Sderaadt #include <ufs/mfs/mfsnode.h>
54df930be7Sderaadt #include <ufs/mfs/mfs_extern.h>
55df930be7Sderaadt 
56df930be7Sderaadt static	int mfs_minor;	/* used for building internal dev_t */
57df930be7Sderaadt 
58df930be7Sderaadt /*
59df930be7Sderaadt  * mfs vfs operations.
60df930be7Sderaadt  */
61e4b1e213Smickey const struct vfsops mfs_vfsops = {
6241f642fcSbluhm 	.vfs_mount	= mfs_mount,
6341f642fcSbluhm 	.vfs_start	= mfs_start,
6441f642fcSbluhm 	.vfs_unmount	= ffs_unmount,
6541f642fcSbluhm 	.vfs_root	= ufs_root,
6641f642fcSbluhm 	.vfs_quotactl	= ufs_quotactl,
6741f642fcSbluhm 	.vfs_statfs	= ffs_statfs,
6841f642fcSbluhm 	.vfs_sync	= ffs_sync,
6941f642fcSbluhm 	.vfs_vget	= ffs_vget,
7041f642fcSbluhm 	.vfs_fhtovp	= ffs_fhtovp,
7141f642fcSbluhm 	.vfs_vptofh	= ffs_vptofh,
7241f642fcSbluhm 	.vfs_init	= mfs_init,
7341f642fcSbluhm 	.vfs_sysctl	= ffs_sysctl,
7441f642fcSbluhm 	.vfs_checkexp	= mfs_checkexp,
75df930be7Sderaadt };
76df930be7Sderaadt 
77df930be7Sderaadt /*
78df930be7Sderaadt  * VFS Operations.
79df930be7Sderaadt  *
80df930be7Sderaadt  * mount system call
81df930be7Sderaadt  */
82df930be7Sderaadt int
83fd531022Spedro mfs_mount(struct mount *mp, const char *path, void *data,
84fd531022Spedro     struct nameidata *ndp, struct proc *p)
85df930be7Sderaadt {
86df930be7Sderaadt 	struct vnode *devvp;
877efda1a1Sderaadt 	struct mfs_args *args = data;
88df930be7Sderaadt 	struct ufsmount *ump;
89fd531022Spedro 	struct fs *fs;
90fd531022Spedro 	struct mfsnode *mfsp;
91a93bb724Sjsing 	char fspec[MNAMELEN];
92df930be7Sderaadt 	int flags, error;
93df930be7Sderaadt 
94df930be7Sderaadt 	/*
95df930be7Sderaadt 	 * If updating, check whether changing from read-only to
96df930be7Sderaadt 	 * read/write; if there is no device name, that's all we do.
97df930be7Sderaadt 	 */
98df930be7Sderaadt 	if (mp->mnt_flag & MNT_UPDATE) {
99df930be7Sderaadt 		ump = VFSTOUFS(mp);
100df930be7Sderaadt 		fs = ump->um_fs;
101df930be7Sderaadt 		if (fs->fs_ronly == 0 && (mp->mnt_flag & MNT_RDONLY)) {
102df930be7Sderaadt 			flags = WRITECLOSE;
103df930be7Sderaadt 			if (mp->mnt_flag & MNT_FORCE)
104df930be7Sderaadt 				flags |= FORCECLOSE;
105df930be7Sderaadt 			error = ffs_flushfiles(mp, flags, p);
106df930be7Sderaadt 			if (error)
107df930be7Sderaadt 				return (error);
108df930be7Sderaadt 		}
109df930be7Sderaadt 		if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
110df930be7Sderaadt 			fs->fs_ronly = 0;
111df930be7Sderaadt #ifdef EXPORTMFS
1127efda1a1Sderaadt 		if (args && args->fspec == NULL)
113ef9317a4Sespie 			return (vfs_export(mp, &ump->um_export,
1147efda1a1Sderaadt 			    &args->export_info));
115df930be7Sderaadt #endif
116df930be7Sderaadt 		return (0);
117df930be7Sderaadt 	}
1187efda1a1Sderaadt 	error = copyinstr(args->fspec, fspec, sizeof(fspec), NULL);
119a93bb724Sjsing 	if (error)
120a93bb724Sjsing 		return (error);
121dc81e71aSthib 	error = getnewvnode(VT_MFS, NULL, &mfs_vops, &devvp);
122df930be7Sderaadt 	if (error)
123df930be7Sderaadt 		return (error);
124df930be7Sderaadt 	devvp->v_type = VBLK;
12514bf419fSkrw 	if (checkalias(devvp, makedev(255, mfs_minor), NULL))
126df930be7Sderaadt 		panic("mfs_mount: dup dev");
1271456bc8bSespie 	mfs_minor++;
1282c7a7344Sjsing 	mfsp = malloc(sizeof *mfsp, M_MFSNODE, M_WAITOK | M_ZERO);
129df930be7Sderaadt 	devvp->v_data = mfsp;
1307efda1a1Sderaadt 	mfsp->mfs_baseoff = args->base;
1317efda1a1Sderaadt 	mfsp->mfs_size = args->size;
132df930be7Sderaadt 	mfsp->mfs_vnode = devvp;
1333b7181b7Sguenther 	mfsp->mfs_tid = p->p_tid;
1342c7a7344Sjsing 	bufq_init(&mfsp->mfs_bufq, BUFQ_FIFO);
1351faf140aSniklas 	if ((error = ffs_mountfs(devvp, mp, p)) != 0) {
1362c7a7344Sjsing 		mfsp->mfs_shutdown = 1;
137df930be7Sderaadt 		vrele(devvp);
138df930be7Sderaadt 		return (error);
139df930be7Sderaadt 	}
140df930be7Sderaadt 	ump = VFSTOUFS(mp);
141df930be7Sderaadt 	fs = ump->um_fs;
142a93bb724Sjsing 
1430f5c6c8bStedu 	memset(fs->fs_fsmnt, 0, sizeof(fs->fs_fsmnt));
144a93bb724Sjsing 	strlcpy(fs->fs_fsmnt, path, sizeof(fs->fs_fsmnt));
1450f5c6c8bStedu 	memcpy(mp->mnt_stat.f_mntonname, fs->fs_fsmnt, MNAMELEN);
1460f5c6c8bStedu 	memset(mp->mnt_stat.f_mntfromname, 0, MNAMELEN);
147a93bb724Sjsing 	strlcpy(mp->mnt_stat.f_mntfromname, fspec, MNAMELEN);
1480f5c6c8bStedu 	memset(mp->mnt_stat.f_mntfromspec, 0, MNAMELEN);
149aec3986eSjsing 	strlcpy(mp->mnt_stat.f_mntfromspec, fspec, MNAMELEN);
1507efda1a1Sderaadt 	memcpy(&mp->mnt_stat.mount_info.mfs_args, args, sizeof(*args));
151a93bb724Sjsing 
152df930be7Sderaadt 	return (0);
153df930be7Sderaadt }
154df930be7Sderaadt 
155df930be7Sderaadt /*
156df930be7Sderaadt  * Used to grab the process and keep it in the kernel to service
157df930be7Sderaadt  * memory filesystem I/O requests.
158df930be7Sderaadt  *
159df930be7Sderaadt  * Loop servicing I/O requests.
160df930be7Sderaadt  * Copy the requested data into or out of the memory filesystem
161df930be7Sderaadt  * address space.
162df930be7Sderaadt  */
163df930be7Sderaadt int
164fd531022Spedro mfs_start(struct mount *mp, int flags, struct proc *p)
165df930be7Sderaadt {
166ff7a2582Sart 	struct vnode *vp = VFSTOUFS(mp)->um_devvp;
167ff7a2582Sart 	struct mfsnode *mfsp = VTOMFS(vp);
168ff7a2582Sart 	struct buf *bp;
169725684caSclaudio 	int sleepreturn = 0, sig;
17049e9d6d1Sclaudio 	struct sigctx ctx;
171df930be7Sderaadt 
1725b902598Sotto 	while (1) {
173e43229a5Sotto 		while (1) {
1742c7a7344Sjsing 			if (mfsp->mfs_shutdown == 1)
175e43229a5Sotto 				break;
1762c7a7344Sjsing 			bp = bufq_dequeue(&mfsp->mfs_bufq);
1772c7a7344Sjsing 			if (bp == NULL)
1782c7a7344Sjsing 				break;
17931991969Sotto 			mfs_doio(mfsp, bp);
1802c7a7344Sjsing 			wakeup(bp);
181df930be7Sderaadt 		}
1822c7a7344Sjsing 		if (mfsp->mfs_shutdown == 1)
1835b902598Sotto 			break;
1842c7a7344Sjsing 
185df930be7Sderaadt 		/*
186df930be7Sderaadt 		 * If a non-ignored signal is received, try to unmount.
187df930be7Sderaadt 		 * If that fails, clear the signal (it has been "processed"),
188df930be7Sderaadt 		 * otherwise we will loop here, as tsleep will always return
189df930be7Sderaadt 		 * EINTR/ERESTART.
190df930be7Sderaadt 		 */
19126278cadSericj 		if (sleepreturn != 0) {
192*3b30ff2aSclaudio 			sig = cursig(p, &ctx, 0);
19328d58497Ssturm 			if (vfs_busy(mp, VB_WRITE|VB_NOWAIT) ||
194725684caSclaudio 			    dounmount(mp, (sig == SIGKILL) ? MNT_FORCE : 0, p))
195c10ca2e1Sclaudio 				atomic_clearbits_int(&p->p_siglist,
196c10ca2e1Sclaudio 				    sigmask(sig));
19726278cadSericj 			sleepreturn = 0;
19826278cadSericj 			continue;
199df930be7Sderaadt 		}
200517561b5Smpi 		sleepreturn = tsleep_nsec(vp, PWAIT | PCATCH, "mfsidl", INFSLP);
20115ec14ceSart 	}
20207feb63cScsapuntz 	return (0);
203df930be7Sderaadt }
204df930be7Sderaadt 
205df930be7Sderaadt /*
206b99d154aSassar  * check export permission, not supported
207b99d154aSassar  */
208b99d154aSassar int
209fd531022Spedro mfs_checkexp(struct mount *mp, struct mbuf *nam, int *exflagsp,
210fd531022Spedro     struct ucred **credanonp)
211b99d154aSassar {
212b99d154aSassar 	return (EOPNOTSUPP);
213b99d154aSassar }
21423fb1970Scsapuntz 
21523fb1970Scsapuntz /*
21623fb1970Scsapuntz  * Memory based filesystem initialization.
21723fb1970Scsapuntz  */
21823fb1970Scsapuntz int
219fd531022Spedro mfs_init(struct vfsconf *vfsp)
22023fb1970Scsapuntz {
22123fb1970Scsapuntz 	return (ffs_init(vfsp));
22223fb1970Scsapuntz }
223