1 /* $NetBSD: rump_vfs.c,v 1.41 2009/12/03 15:06:04 pooka Exp $ */
4 * Copyright (c) 2008 Antti Kantee. All Rights Reserved.
6 * Development of this software was supported by the
7 * Finnish Cultural Foundation.
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #include <sys/cdefs.h>
32 __KERNEL_RCSID(0, "$NetBSD: rump_vfs.c,v 1.41 2009/12/03 15:06:04 pooka Exp $");
34 #include <sys/param.h>
37 #include <sys/evcnt.h>
38 #include <sys/filedesc.h>
39 #include <sys/lockf.h>
40 #include <sys/kthread.h>
41 #include <sys/module.h>
42 #include <sys/namei.h>
43 #include <sys/queue.h>
44 #include <sys/vfs_syscalls.h>
45 #include <sys/vnode.h>
46 #include <sys/wapbl.h>
48 #include <miscfs/specfs/specdev.h>
49 #include <miscfs/syncfs/syncfs.h>
51 #include <rump/rump.h>
52 #include <rump/rumpuser.h>
54 #include "rump_private.h"
55 #include "rump_vfs_private.h"
59 static void rump_rcvp_lwpset(struct vnode
*, struct vnode
*, struct lwp
*);
62 pvfs_init(struct proc
*p
)
65 p
->p_cwdi
= cwdinit();
69 pvfs_rele(struct proc
*p
)
78 extern struct vfsops rumpfs_vfsops
;
82 extern int dovfsusermount
; /* XXX */
84 dovfsusermount
= 1; /* XXX */
86 if (rumpuser_getenv("RUMP_NVNODES", buf
, sizeof(buf
), &error
) == 0) {
87 desiredvnodes
= strtoul(buf
, NULL
, 10);
89 desiredvnodes
= 1<<16;
94 for (i
= 0; i
< ncpu
; i
++) {
95 struct cpu_info
*ci
= cpu_lookup(i
);
106 if ((rv
= kthread_create(PRI_BIO
, KTHREAD_MPSAFE
, NULL
,
107 rumpuser_biothread
, rump_biodone
, NULL
, "rmpabio")) != 0)
108 panic("syncer thread create failed: %d", rv
);
111 rootfstype
= ROOT_FSTYPE_ANY
;
112 root_device
= &rump_rootdev
;
114 /* bootstrap cwdi (rest done in vfs_mountroot() */
115 rw_init(&cwdi0
.cwdi_lock
);
116 proc0
.p_cwdi
= &cwdi0
;
117 proc0
.p_cwdi
= cwdinit();
119 vfs_attach(&rumpfs_vfsops
);
122 /* "mtree": create /dev */
123 do_sys_mkdir("/dev", 0777, UIO_SYSSPACE
);
126 rump_proc_vfs_init
= pvfs_init
;
127 rump_proc_vfs_release
= pvfs_rele
;
130 if ((rv
= kthread_create(PRI_IOFLUSH
, KTHREAD_MPSAFE
, NULL
,
131 sched_sync
, NULL
, NULL
, "ioflush")) != 0)
132 panic("syncer thread create failed: %d", rv
);
145 struct componentname
*
146 rump_makecn(u_long nameiop
, u_long flags
, const char *name
, size_t namelen
,
147 kauth_cred_t creds
, struct lwp
*l
)
149 struct componentname
*cnp
;
150 const char *cp
= NULL
;
152 cnp
= kmem_zalloc(sizeof(struct componentname
), KM_SLEEP
);
154 cnp
->cn_nameiop
= nameiop
;
155 cnp
->cn_flags
= flags
;
157 cnp
->cn_pnbuf
= PNBUF_GET();
158 strcpy(cnp
->cn_pnbuf
, name
);
159 cnp
->cn_nameptr
= cnp
->cn_pnbuf
;
160 cnp
->cn_namelen
= namelen
;
161 cnp
->cn_hash
= namei_hash(name
, &cp
);
163 cnp
->cn_cred
= creds
;
169 rump_freecn(struct componentname
*cnp
, int flags
)
172 if (flags
& RUMPCN_FREECRED
)
173 rump_cred_put(cnp
->cn_cred
);
175 if ((cnp
->cn_flags
& SAVENAME
) == 0 || flags
& RUMPCN_FORCEFREE
)
176 PNBUF_PUT(cnp
->cn_pnbuf
);
177 kmem_free(cnp
, sizeof(*cnp
));
181 rump_checksavecn(struct componentname
*cnp
)
184 if ((cnp
->cn_flags
& (SAVENAME
| SAVESTART
)) == 0) {
187 cnp
->cn_flags
|= HASBUF
;
192 /* hey baby, what's your namei? */
194 rump_namei(uint32_t op
, uint32_t flags
, const char *namep
,
195 struct vnode
**dvpp
, struct vnode
**vpp
, struct componentname
**cnpp
)
200 NDINIT(&nd
, op
, flags
, UIO_SYSSPACE
, namep
);
206 KASSERT(flags
& LOCKPARENT
);
209 KASSERT((flags
& LOCKPARENT
) == 0);
216 if (flags
& LOCKLEAF
)
224 struct componentname
*cnp
;
226 cnp
= kmem_alloc(sizeof(*cnp
), KM_SLEEP
);
227 memcpy(cnp
, &nd
.ni_cnd
, sizeof(*cnp
));
229 } else if (nd
.ni_cnd
.cn_flags
& HASBUF
) {
230 panic("%s: pathbuf mismatch", __func__
);
237 rump_getvninfo(struct vnode
*vp
, enum vtype
*vtype
,
238 voff_t
*vsize
, dev_t
*vdev
)
250 rump_vfslist_iterate(struct vfsops
*ops
)
254 return LIST_FIRST(&vfs_list
);
256 return LIST_NEXT(ops
, vfs_list
);
260 rump_vfs_getopsbyname(const char *name
)
263 return vfs_getopsbyname(name
);
267 rump_vfs_getmp(const char *path
, struct mount
**mpp
)
272 if ((rv
= namei_simple_user(path
, NSM_FOLLOW_TRYEMULROOT
, &vp
)) != 0)
281 rump_vattr_init(void)
285 vap
= kmem_alloc(sizeof(struct vattr
), KM_SLEEP
);
292 rump_vattr_settype(struct vattr
*vap
, enum vtype vt
)
299 rump_vattr_setmode(struct vattr
*vap
, mode_t mode
)
306 rump_vattr_setrdev(struct vattr
*vap
, dev_t dev
)
313 rump_vattr_free(struct vattr
*vap
)
316 kmem_free(vap
, sizeof(*vap
));
320 rump_vp_incref(struct vnode
*vp
)
327 rump_vp_getref(struct vnode
*vp
)
330 return vp
->v_usecount
;
334 rump_vp_rele(struct vnode
*vp
)
341 rump_vp_interlock(struct vnode
*vp
)
344 mutex_enter(&vp
->v_interlock
);
348 rump_vfs_unmount(struct mount
*mp
, int mntflags
)
353 printf("event counters:\n");
354 TAILQ_FOREACH(ev
, &allevents
, ev_list
)
355 printf("%s: %llu\n", ev
->ev_name
, ev
->ev_count
);
358 return VFS_UNMOUNT(mp
, mntflags
);
362 rump_vfs_root(struct mount
*mp
, struct vnode
**vpp
, int lock
)
366 rv
= VFS_ROOT(mp
, vpp
);
377 rump_vfs_statvfs(struct mount
*mp
, struct statvfs
*sbp
)
380 return VFS_STATVFS(mp
, sbp
);
384 rump_vfs_sync(struct mount
*mp
, int wait
, kauth_cred_t cred
)
387 return VFS_SYNC(mp
, wait
? MNT_WAIT
: MNT_NOWAIT
, cred
);
391 rump_vfs_fhtovp(struct mount
*mp
, struct fid
*fid
, struct vnode
**vpp
)
394 return VFS_FHTOVP(mp
, fid
, vpp
);
398 rump_vfs_vptofh(struct vnode
*vp
, struct fid
*fid
, size_t *fidsize
)
401 return VFS_VPTOFH(vp
, fid
, fidsize
);
406 rump_vfs_syncwait(struct mount
*mp
)
412 printf("syncwait: unsynced buffers: %d\n", n
);
416 rump_biodone(void *arg
, size_t count
, int error
)
418 struct buf
*bp
= arg
;
420 bp
->b_resid
= bp
->b_bcount
- count
;
421 KASSERT(bp
->b_resid
>= 0);
428 rump_rcvp_lwpset(struct vnode
*rvp
, struct vnode
*cvp
, struct lwp
*l
)
430 struct cwdinfo
*cwdi
= l
->l_proc
->p_cwdi
;
434 rw_enter(&cwdi
->cwdi_lock
, RW_WRITER
);
436 vrele(cwdi
->cwdi_rdir
);
439 cwdi
->cwdi_rdir
= rvp
;
441 vrele(cwdi
->cwdi_cdir
);
443 cwdi
->cwdi_cdir
= cvp
;
444 rw_exit(&cwdi
->cwdi_lock
);
448 rump_rcvp_set(struct vnode
*rvp
, struct vnode
*cvp
)
451 rump_rcvp_lwpset(rvp
, cvp
, curlwp
);
458 struct cwdinfo
*cwdi
= curlwp
->l_proc
->p_cwdi
;
460 rw_enter(&cwdi
->cwdi_lock
, RW_READER
);
461 vp
= cwdi
->cwdi_cdir
;
462 rw_exit(&cwdi
->cwdi_lock
);