2 * Written by Julian Elischer (julian@DIALix.oz.au)
4 * $Header: /home/ncvs/src/sys/miscfs/devfs/devfs_vfsops.c,v 1.20 1997/08/16 19:15:10 wollman Exp $
10 #include <sys/systm.h>
11 #include <sys/kernel.h>
12 #include <sys/vnode.h>
13 #include <sys/mount.h>
14 #include <sys/malloc.h>
16 #include <miscfs/devfs/devfsdefs.h>
18 MALLOC_DEFINE(M_DEVFSMNT, "DEVFS mount", "DEVFS mount structure");
20 static int devfs_statfs( struct mount *mp, struct statfs *sbp, struct proc *p);
21 static int mountdevfs( struct mount *mp, struct proc *p);
24 devfs_init(struct vfsconf *vfsp)
27 * fill in the missing members on the "hidden" mount
29 dev_root->dnp->dvm->mount->mnt_op = vfsp->vfc_vfsops;
30 dev_root->dnp->dvm->mount->mnt_vfc = vfsp;
32 /* Mark a reference for the "invisible" blueprint mount */
33 dev_root->dnp->dvm->mount->mnt_vfc->vfc_refcount++;
35 printf("DEVFS: ready to run\n");
40 * mp - pointer to 'mount' structure
41 * path - addr in user space of mount point (ie /usr or whatever)
42 * data - addr in user space of mount params including the
43 * name of the block special file to treat as a filesystem.
44 * ndp - namei data pointer
46 * devfs is special in that it doesn't require any device to be mounted..
47 * It makes up it's data as it goes along.
48 * it must be mounted during single user.. until it is, only std{in/out/err}
49 * and the root filesystem are available.
53 devfs_mount(struct mount *mp, char *path, caddr_t data,
54 struct nameidata *ndp, struct proc *p)
56 struct devfsmount *devfs_mp_p; /* devfs specific mount control block */
62 * If they just want to update, we don't need to do anything.
64 if (mp->mnt_flag & MNT_UPDATE)
70 * Well, it's not an update, it's a real mount request.
72 * HERE we should check to see if we are already mounted here.
74 if(error = mountdevfs( mp, p))
78 * Copy in the name of the directory the filesystem
79 * is to be mounted on.
80 * And we clear the remainder of the character strings
82 * Then, we try to fill in the filesystem stats structure
83 * as best we can with whatever we can think of at the time
85 devfs_mp_p = (struct devfsmount *)mp->mnt_data;
86 if(devfs_up_and_going) {
87 copyinstr(path, (caddr_t)mp->mnt_stat.f_mntonname,
88 sizeof(mp->mnt_stat.f_mntonname)-1, &size);
89 bzero(mp->mnt_stat.f_mntonname + size,
90 sizeof(mp->mnt_stat.f_mntonname) - size);
92 bcopy("dummy_mount", (caddr_t)mp->mnt_stat.f_mntonname,12);
94 bzero(mp->mnt_stat.f_mntfromname , MNAMELEN );
95 bcopy("devfs",mp->mnt_stat.f_mntfromname, 5);
96 (void)devfs_statfs(mp, &mp->mnt_stat, p);
101 mountdevfs( struct mount *mp, struct proc *p)
104 struct devfsmount *devfs_mp_p;
107 devfs_mp_p = (struct devfsmount *)malloc(sizeof *devfs_mp_p,
108 M_DEVFSMNT, M_WAITOK);
109 bzero(devfs_mp_p,sizeof(*devfs_mp_p));
110 devfs_mp_p->mount = mp;
113 * Fill out some fields
115 mp->mnt_data = (qaddr_t)devfs_mp_p;
116 mp->mnt_stat.f_type = MOUNT_DEVFS;
117 mp->mnt_stat.f_fsid.val[0] = (long)devfs_mp_p;
118 mp->mnt_stat.f_fsid.val[1] = MOUNT_DEVFS;
119 mp->mnt_flag |= MNT_LOCAL;
121 if(error = dev_dup_plane(devfs_mp_p))
123 mp->mnt_data = (qaddr_t)0;
124 free((caddr_t)devfs_mp_p, M_DEVFSMNT);
130 devfs_start(struct mount *mp, int flags, struct proc *p)
137 * Unmount the filesystem described by mp.
140 devfs_unmount( struct mount *mp, int mntflags, struct proc *p)
142 struct devfsmount *devfs_mp_p = (struct devfsmount *)mp->mnt_data;
146 if (mntflags & MNT_FORCE) {
149 error = vflush(mp, NULLVP, flags);
153 DBPRINT(("unmount "));
154 devfs_free_plane(devfs_mp_p);
155 free((caddr_t)devfs_mp_p, M_DEVFSMNT);
156 mp->mnt_data = (qaddr_t)0;
157 mp->mnt_flag &= ~MNT_LOCAL;
162 /* return the address of the root vnode in *vpp */
164 devfs_root(struct mount *mp, struct vnode **vpp)
166 struct devfsmount *devfs_mp_p = (struct devfsmount *)(mp->mnt_data);
169 devfs_dntovn(devfs_mp_p->plane_root->dnp,vpp);
174 devfs_quotactl(struct mount *mp, int cmds, uid_t uid, caddr_t arg,
177 DBPRINT(("quotactl "));
182 devfs_statfs( struct mount *mp, struct statfs *sbp, struct proc *p)
184 struct devfsmount *devfs_mp_p = (struct devfsmount *)mp->mnt_data;
187 * Fill in the stat block.
189 DBPRINT(("statfs "));
190 sbp->f_type = MOUNT_DEVFS;
191 sbp->f_flags = 0; /* XXX */
193 sbp->f_iosize = 1024; /* XXX*/
198 sbp->f_ffree = 0; /* what to put in here? */
199 sbp->f_fsid.val[0] = (long)devfs_mp_p;
200 sbp->f_fsid.val[1] = MOUNT_DEVFS;
203 * Copy the mounted on and mounted from names into
204 * the passed in stat block, if it is not the one
205 * in the mount structure.
207 if (sbp != &mp->mnt_stat) {
208 bcopy((caddr_t)mp->mnt_stat.f_mntonname,
209 (caddr_t)&sbp->f_mntonname[0], MNAMELEN);
210 bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
211 (caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
217 * Go through the disk queues to initiate sandbagged IO;
218 * go through the inodes to write those that have been modified;
219 * initiate the writing of the super block if it has been modified.
221 * Note: we are always called with the filesystem marked `MPBUSY'.
224 devfs_sync(struct mount *mp, int waitfor,struct ucred *cred,struct proc *p)
226 register struct vnode *vp, *nvp;
228 int error, allerror = 0;
233 * Write back modified superblock.
234 * Consistency check that the superblock
235 * is still in the buffer cache.
238 * Write back each (modified) inode.
241 for (vp = mp->mnt_vnodelist.lh_first; vp != NULL; vp = nvp) {
243 * If the vnode that we are about to sync is no longer
244 * associated with this mount point, start over.
246 if (vp->v_mount != mp)
248 nvp = vp->v_mntvnodes.le_next;
249 if (VOP_ISLOCKED(vp))
251 if ( vp->v_dirtyblkhd.lh_first == NULL)
253 if (vp->v_type == VBLK) {
254 if (vget(vp, LK_EXCLUSIVE, p))
256 error = VOP_FSYNC(vp, cred, waitfor, p);
264 /* VOP_UPDATE(vp, &tv, &tv, waitfor == MNT_WAIT); */
265 VOP_UPDATE(vp, &tv, &tv, 0);
270 * Force stale file system control information to be flushed.
271 *( except that htat makes no sense with devfs
277 devfs_vget(struct mount *mp, ino_t ino,struct vnode **vpp)
283 /*************************************************************
284 * The concept of exporting a kernel generated devfs is stupid
285 * So don't handle filehandles
289 devfs_fhtovp (struct mount *mp, struct fid *fhp, struct sockaddr *nam,
290 struct vnode **vpp, int *exflagsp, struct ucred **credanonp)
292 DBPRINT(("fhtovp "));
298 devfs_vptofh (struct vnode *vp, struct fid *fhp)
300 DBPRINT(("vptofh "));
304 static struct vfsops devfs_vfsops = {
318 VFS_SET(devfs_vfsops, devfs, MOUNT_DEVFS, 0);