xref: /original-bsd/sys/ufs/mfs/mfs_vfsops.c (revision 10020db5)
1 /*
2  * Copyright (c) 1989, 1990 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  *
17  *	@(#)mfs_vfsops.c	7.14 (Berkeley) 05/04/90
18  */
19 
20 #include "param.h"
21 #include "time.h"
22 #include "user.h"
23 #include "proc.h"
24 #include "buf.h"
25 #include "mount.h"
26 #include "vnode.h"
27 #include "../ufs/quota.h"
28 #include "../ufs/inode.h"
29 #include "../ufs/ufsmount.h"
30 #include "../ufs/mfsnode.h"
31 #include "../ufs/fs.h"
32 
33 extern struct vnodeops mfs_vnodeops;
34 
35 /*
36  * mfs vfs operations.
37  */
38 int mfs_mount();
39 int mfs_start();
40 int ufs_unmount();
41 int ufs_root();
42 int ufs_quotactl();
43 int mfs_statfs();
44 int ufs_sync();
45 int ufs_fhtovp();
46 int ufs_vptofh();
47 int mfs_init();
48 
49 struct vfsops mfs_vfsops = {
50 	mfs_mount,
51 	mfs_start,
52 	ufs_unmount,
53 	ufs_root,
54 	ufs_quotactl,
55 	mfs_statfs,
56 	ufs_sync,
57 	ufs_fhtovp,
58 	ufs_vptofh,
59 	mfs_init,
60 };
61 
62 /*
63  * VFS Operations.
64  *
65  * mount system call
66  */
67 /* ARGSUSED */
68 mfs_mount(mp, path, data, ndp)
69 	register struct mount *mp;
70 	char *path;
71 	caddr_t data;
72 	struct nameidata *ndp;
73 {
74 	struct vnode *devvp;
75 	struct mfs_args args;
76 	struct ufsmount *ump;
77 	register struct fs *fs;
78 	register struct mfsnode *mfsp;
79 	static int mfs_minor;
80 	u_int size;
81 	int error;
82 
83 	if (mp->mnt_flag & MNT_UPDATE) {
84 		ump = VFSTOUFS(mp);
85 		fs = ump->um_fs;
86 		if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0)
87 			fs->fs_ronly = 0;
88 		return (0);
89 	}
90 	if (error = copyin(data, (caddr_t)&args, sizeof (struct mfs_args)))
91 		return (error);
92 	error = getnewvnode(VT_MFS, (struct mount *)0, &mfs_vnodeops, &devvp);
93 	if (error)
94 		return (error);
95 	devvp->v_type = VBLK;
96 	if (checkalias(devvp, makedev(255, mfs_minor++), (struct mount *)0))
97 		panic("mfs_mount: dup dev");
98 	mfsp = VTOMFS(devvp);
99 	mfsp->mfs_baseoff = args.base;
100 	mfsp->mfs_size = args.size;
101 	mfsp->mfs_vnode = devvp;
102 	mfsp->mfs_pid = u.u_procp->p_pid;
103 	mfsp->mfs_buflist = (struct buf *)0;
104 	if (error = mountfs(devvp, mp)) {
105 		mfsp->mfs_buflist = (struct buf *)-1;
106 		vrele(devvp);
107 		return (error);
108 	}
109 	ump = VFSTOUFS(mp);
110 	fs = ump->um_fs;
111 	(void) copyinstr(path, fs->fs_fsmnt, sizeof(fs->fs_fsmnt) - 1, &size);
112 	bzero(fs->fs_fsmnt + size, sizeof(fs->fs_fsmnt) - size);
113 	bcopy((caddr_t)fs->fs_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
114 		MNAMELEN);
115 	(void) copyinstr(args.name, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
116 		&size);
117 	bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
118 	(void) mfs_statfs(mp, &mp->mnt_stat);
119 	return (0);
120 }
121 
122 int	mfs_pri = PWAIT | PCATCH;		/* XXX prob. temp */
123 
124 /*
125  * Used to grab the process and keep it in the kernel to service
126  * memory filesystem I/O requests.
127  *
128  * Loop servicing I/O requests.
129  * Copy the requested data into or out of the memory filesystem
130  * address space.
131  */
132 /* ARGSUSED */
133 mfs_start(mp, flags)
134 	struct mount *mp;
135 	int flags;
136 {
137 	register struct vnode *vp = VFSTOUFS(mp)->um_devvp;
138 	register struct mfsnode *mfsp = VTOMFS(vp);
139 	register struct buf *bp;
140 	register caddr_t base;
141 	int error = 0;
142 
143 	base = mfsp->mfs_baseoff;
144 	while (mfsp->mfs_buflist != (struct buf *)(-1)) {
145 		while (bp = mfsp->mfs_buflist) {
146 			mfsp->mfs_buflist = bp->av_forw;
147 			mfs_doio(bp, base);
148 			wakeup((caddr_t)bp);
149 		}
150 		if (error = tsleep((caddr_t)vp, mfs_pri, "mfsidl", 0)) {
151 			/*
152 			 * We have received a signal, so try to unmount.
153 			 */
154 			(void) dounmount(mp, MNT_NOFORCE);
155 		}
156 	}
157 	return (error);
158 }
159 
160 /*
161  * Get file system statistics.
162  */
163 mfs_statfs(mp, sbp)
164 	struct mount *mp;
165 	struct statfs *sbp;
166 {
167 	int error;
168 
169 	error = ufs_statfs(mp, sbp);
170 	sbp->f_type = MOUNT_MFS;
171 	return (error);
172 }
173