Sun May 3 16:01:44 2009 UTC ()
Add rump_vfs_getmp(), which returns struct mount for a given path.
(yes, it does not take a reference to the mountpoint)


(pooka)
diff -r1.14 -r1.15 src/sys/rump/include/rump/rump.h
diff -r1.18 -r1.19 src/sys/rump/librump/rumpvfs/rump_vfs.c

cvs diff -r1.14 -r1.15 src/sys/rump/include/rump/rump.h (switch to unified diff)

--- src/sys/rump/include/rump/rump.h 2009/05/02 15:20:08 1.14
+++ src/sys/rump/include/rump/rump.h 2009/05/03 16:01:44 1.15
@@ -1,190 +1,191 @@ @@ -1,190 +1,191 @@
1/* $NetBSD: rump.h,v 1.14 2009/05/02 15:20:08 pooka Exp $ */ 1/* $NetBSD: rump.h,v 1.15 2009/05/03 16:01:44 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2007 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by Google Summer of Code. 6 * Development of this software was supported by Google Summer of Code.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution. 15 * documentation and/or other materials provided with the distribution.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE. 27 * SUCH DAMAGE.
28 */ 28 */
29 29
30#ifndef _RUMP_RUMP_H_ 30#ifndef _RUMP_RUMP_H_
31#define _RUMP_RUMP_H_ 31#define _RUMP_RUMP_H_
32 32
33/* 33/*
34 * NOTE: do not #include anything from <sys> here. Otherwise this 34 * NOTE: do not #include anything from <sys> here. Otherwise this
35 * has no chance of working on non-NetBSD platforms. 35 * has no chance of working on non-NetBSD platforms.
36 */ 36 */
37 37
38struct mount; 38struct mount;
39struct vnode; 39struct vnode;
40struct vattr; 40struct vattr;
41struct componentname; 41struct componentname;
42struct vfsops; 42struct vfsops;
43struct fid; 43struct fid;
44struct statvfs; 44struct statvfs;
45 45
46/* yetch */ 46/* yetch */
47#if !defined(_RUMPKERNEL) && !defined(__NetBSD__) 47#if !defined(_RUMPKERNEL) && !defined(__NetBSD__)
48struct kauth_cred; 48struct kauth_cred;
49typedef struct kauth_cred *kauth_cred_t; 49typedef struct kauth_cred *kauth_cred_t;
50#endif 50#endif
51#if defined(__NetBSD__) 51#if defined(__NetBSD__)
52#include <prop/proplib.h> 52#include <prop/proplib.h>
53#else 53#else
54struct prop_dictionary; 54struct prop_dictionary;
55typedef struct prop_dictionary *prop_dictionary_t; 55typedef struct prop_dictionary *prop_dictionary_t;
56#endif /* __NetBSD__ */ 56#endif /* __NetBSD__ */
57 57
58struct lwp; 58struct lwp;
59struct modinfo; 59struct modinfo;
60 60
61#include <rump/rumpvnode_if.h> 61#include <rump/rumpvnode_if.h>
62#include <rump/rumpdefs.h> 62#include <rump/rumpdefs.h>
63 63
64#ifndef curlwp 64#ifndef curlwp
65#define curlwp rump_get_curlwp() 65#define curlwp rump_get_curlwp()
66#endif 66#endif
67 67
68/* 68/*
69 * Something like rump capabilities would be nicer, but let's 69 * Something like rump capabilities would be nicer, but let's
70 * do this for a start. 70 * do this for a start.
71 */ 71 */
72#define RUMP_VERSION 01 72#define RUMP_VERSION 01
73#define rump_init() rump__init(RUMP_VERSION) 73#define rump_init() rump__init(RUMP_VERSION)
74int rump_module_init(struct modinfo *, prop_dictionary_t props); 74int rump_module_init(struct modinfo *, prop_dictionary_t props);
75int rump_module_fini(struct modinfo *); 75int rump_module_fini(struct modinfo *);
76 76
77int rump__init(int); 77int rump__init(int);
78struct mount *rump_mnt_init(struct vfsops *, int); 78struct mount *rump_mnt_init(struct vfsops *, int);
79int rump_mnt_mount(struct mount *, const char *, void *, size_t *); 79int rump_mnt_mount(struct mount *, const char *, void *, size_t *);
80void rump_mnt_destroy(struct mount *); 80void rump_mnt_destroy(struct mount *);
81 81
82struct componentname *rump_makecn(u_long, u_long, const char *, size_t, 82struct componentname *rump_makecn(u_long, u_long, const char *, size_t,
83 kauth_cred_t, struct lwp *); 83 kauth_cred_t, struct lwp *);
84void rump_freecn(struct componentname *, int); 84void rump_freecn(struct componentname *, int);
85#define RUMPCN_ISLOOKUP 0x01 85#define RUMPCN_ISLOOKUP 0x01
86#define RUMPCN_FREECRED 0x02 86#define RUMPCN_FREECRED 0x02
87#define RUMPCN_HASNTBUF 0x04 87#define RUMPCN_HASNTBUF 0x04
88int rump_namei(uint32_t, uint32_t, const char *, 88int rump_namei(uint32_t, uint32_t, const char *,
89 struct vnode **, struct vnode **, 89 struct vnode **, struct vnode **,
90 struct componentname **); 90 struct componentname **);
91 91
92void rump_getvninfo(struct vnode *, enum vtype *, off_t * /*XXX*/, dev_t *); 92void rump_getvninfo(struct vnode *, enum vtype *, off_t * /*XXX*/, dev_t *);
93 93
94int rump_fakeblk_register(const char *); 94int rump_fakeblk_register(const char *);
95int rump_fakeblk_find(const char *); 95int rump_fakeblk_find(const char *);
96void rump_fakeblk_deregister(const char *); 96void rump_fakeblk_deregister(const char *);
97 97
98struct vfsops *rump_vfslist_iterate(struct vfsops *); 98struct vfsops *rump_vfslist_iterate(struct vfsops *);
99struct vfsops *rump_vfs_getopsbyname(const char *); 99struct vfsops *rump_vfs_getopsbyname(const char *);
100 100
101struct vattr *rump_vattr_init(void); 101struct vattr *rump_vattr_init(void);
102void rump_vattr_settype(struct vattr *, enum vtype); 102void rump_vattr_settype(struct vattr *, enum vtype);
103void rump_vattr_setmode(struct vattr *, mode_t); 103void rump_vattr_setmode(struct vattr *, mode_t);
104void rump_vattr_setrdev(struct vattr *, dev_t); 104void rump_vattr_setrdev(struct vattr *, dev_t);
105void rump_vattr_free(struct vattr *); 105void rump_vattr_free(struct vattr *);
106 106
107void rump_vp_incref(struct vnode *); 107void rump_vp_incref(struct vnode *);
108int rump_vp_getref(struct vnode *); 108int rump_vp_getref(struct vnode *);
109void rump_vp_decref(struct vnode *); 109void rump_vp_decref(struct vnode *);
110void rump_vp_recycle_nokidding(struct vnode *); 110void rump_vp_recycle_nokidding(struct vnode *);
111void rump_vp_rele(struct vnode *); 111void rump_vp_rele(struct vnode *);
112 112
113enum rump_uiorw { RUMPUIO_READ, RUMPUIO_WRITE }; 113enum rump_uiorw { RUMPUIO_READ, RUMPUIO_WRITE };
114struct uio *rump_uio_setup(void *, size_t, off_t, enum rump_uiorw); 114struct uio *rump_uio_setup(void *, size_t, off_t, enum rump_uiorw);
115size_t rump_uio_getresid(struct uio *); 115size_t rump_uio_getresid(struct uio *);
116off_t rump_uio_getoff(struct uio *); 116off_t rump_uio_getoff(struct uio *);
117size_t rump_uio_free(struct uio *); 117size_t rump_uio_free(struct uio *);
118 118
119void rump_vp_interlock(struct vnode *); 119void rump_vp_interlock(struct vnode *);
120 120
121kauth_cred_t rump_cred_create(uid_t, gid_t, size_t, gid_t *); 121kauth_cred_t rump_cred_create(uid_t, gid_t, size_t, gid_t *);
122kauth_cred_t rump_cred_suserget(void); 122kauth_cred_t rump_cred_suserget(void);
123void rump_cred_destroy(kauth_cred_t); 123void rump_cred_destroy(kauth_cred_t);
124 124
125#define rump_cred_suserput(c) rump_cred_destroy(c) 125#define rump_cred_suserput(c) rump_cred_destroy(c)
126/* COMPAT_NETHACK */ 126/* COMPAT_NETHACK */
127#define WizardMode() rump_cred_suserget() 127#define WizardMode() rump_cred_suserget()
128#define YASD(cred) rump_cred_suserput(cred) 128#define YASD(cred) rump_cred_suserput(cred)
129 129
130int rump_vfs_unmount(struct mount *, int); 130int rump_vfs_unmount(struct mount *, int);
131int rump_vfs_root(struct mount *, struct vnode **, int); 131int rump_vfs_root(struct mount *, struct vnode **, int);
132int rump_vfs_statvfs(struct mount *, struct statvfs *); 132int rump_vfs_statvfs(struct mount *, struct statvfs *);
133int rump_vfs_sync(struct mount *, int, kauth_cred_t); 133int rump_vfs_sync(struct mount *, int, kauth_cred_t);
134int rump_vfs_fhtovp(struct mount *, struct fid *, struct vnode **); 134int rump_vfs_fhtovp(struct mount *, struct fid *, struct vnode **);
135int rump_vfs_vptofh(struct vnode *, struct fid *, size_t *); 135int rump_vfs_vptofh(struct vnode *, struct fid *, size_t *);
136void rump_vfs_syncwait(struct mount *); 136void rump_vfs_syncwait(struct mount *);
 137int rump_vfs_getmp(const char *, struct mount **);
137 138
138struct lwp *rump_newproc_switch(void); 139struct lwp *rump_newproc_switch(void);
139struct lwp *rump_setup_curlwp(pid_t, lwpid_t, int); 140struct lwp *rump_setup_curlwp(pid_t, lwpid_t, int);
140struct lwp *rump_get_curlwp(void); 141struct lwp *rump_get_curlwp(void);
141void rump_clear_curlwp(void); 142void rump_clear_curlwp(void);
142 143
143void rump_rcvp_set(struct vnode *, struct vnode *); 144void rump_rcvp_set(struct vnode *, struct vnode *);
144struct vnode *rump_cdir_get(void); 145struct vnode *rump_cdir_get(void);
145 146
146/* I picked the wrong header to stop sniffin' glue */ 147/* I picked the wrong header to stop sniffin' glue */
147int rump_syspuffs_glueinit(int, int *); 148int rump_syspuffs_glueinit(int, int *);
148 149
149int rump_virtif_create(int); 150int rump_virtif_create(int);
150 151
151typedef int (*rump_sysproxy_t)(int, void *, uint8_t *, size_t, register_t *); 152typedef int (*rump_sysproxy_t)(int, void *, uint8_t *, size_t, register_t *);
152int rump_sysproxy_set(rump_sysproxy_t, void *); 153int rump_sysproxy_set(rump_sysproxy_t, void *);
153int rump_sysproxy_socket_setup_client(int); 154int rump_sysproxy_socket_setup_client(int);
154int rump_sysproxy_socket_setup_server(int); 155int rump_sysproxy_socket_setup_server(int);
155 156
156/* 157/*
157 * Begin rump syscall conditionals. Yes, something a little better 158 * Begin rump syscall conditionals. Yes, something a little better
158 * is required here. 159 * is required here.
159 */ 160 */
160#ifdef RUMP_SYS_NETWORKING 161#ifdef RUMP_SYS_NETWORKING
161#define socket(a,b,c) rump_sys_socket(a,b,c) 162#define socket(a,b,c) rump_sys_socket(a,b,c)
162#define accept(a,b,c) rump_sys_accept(a,b,c) 163#define accept(a,b,c) rump_sys_accept(a,b,c)
163#define bind(a,b,c) rump_sys_bind(a,b,c) 164#define bind(a,b,c) rump_sys_bind(a,b,c)
164#define connect(a,b,c) rump_sys_connect(a,b,c) 165#define connect(a,b,c) rump_sys_connect(a,b,c)
165#define getpeername(a,b,c) rump_sys_getpeername(a,b,c) 166#define getpeername(a,b,c) rump_sys_getpeername(a,b,c)
166#define getsockname(a,b,c) rump_sys_getsockname(a,b,c) 167#define getsockname(a,b,c) rump_sys_getsockname(a,b,c)
167#define listen(a,b) rump_sys_listen(a,b) 168#define listen(a,b) rump_sys_listen(a,b)
168#define recvfrom(a,b,c,d,e,f) rump_sys_recvfrom(a,b,c,d,e,f) 169#define recvfrom(a,b,c,d,e,f) rump_sys_recvfrom(a,b,c,d,e,f)
169#define sendto(a,b,c,d,e,f) rump_sys_sendto(a,b,c,d,e,f) 170#define sendto(a,b,c,d,e,f) rump_sys_sendto(a,b,c,d,e,f)
170#define getsockopt(a,b,c,d,e) rump_sys_getsockopt(a,b,c,d,e) 171#define getsockopt(a,b,c,d,e) rump_sys_getsockopt(a,b,c,d,e)
171#define setsockopt(a,b,c,d,e) rump_sys_setsockopt(a,b,c,d,e) 172#define setsockopt(a,b,c,d,e) rump_sys_setsockopt(a,b,c,d,e)
172#define shutdown(a,b) rump_sys_shutdown(a,b) 173#define shutdown(a,b) rump_sys_shutdown(a,b)
173#endif /* RUMP_SYS_NETWORKING */ 174#endif /* RUMP_SYS_NETWORKING */
174 175
175#ifdef RUMP_SYS_CLOSE 176#ifdef RUMP_SYS_CLOSE
176#define close(a) rump_sys_close(a) 177#define close(a) rump_sys_close(a)
177#endif /* RUMP_SYS_CLOSE */ 178#endif /* RUMP_SYS_CLOSE */
178 179
179#ifdef RUMP_SYS_READWRITE 180#ifdef RUMP_SYS_READWRITE
180#define read(a,b,c) rump_sys_read(a,b,c) 181#define read(a,b,c) rump_sys_read(a,b,c)
181#define readv(a,b,c) rump_sys_readv(a,b,c) 182#define readv(a,b,c) rump_sys_readv(a,b,c)
182#define pread(a,b,c,d) rump_sys_pread(a,b,c,d) 183#define pread(a,b,c,d) rump_sys_pread(a,b,c,d)
183#define preadv(a,b,c,d) rump_sys_preadv(a,b,c,d) 184#define preadv(a,b,c,d) rump_sys_preadv(a,b,c,d)
184#define write(a,b,c) rump_sys_write(a,b,c) 185#define write(a,b,c) rump_sys_write(a,b,c)
185#define writev(a,b,c) rump_sys_writev(a,b,c) 186#define writev(a,b,c) rump_sys_writev(a,b,c)
186#define pwrite(a,b,c,d) rump_sys_pwrite(a,b,c,d) 187#define pwrite(a,b,c,d) rump_sys_pwrite(a,b,c,d)
187#define pwritev(a,b,c,d) rump_sys_pwritev(a,b,c,d) 188#define pwritev(a,b,c,d) rump_sys_pwritev(a,b,c,d)
188#endif /* RUMP_SYS_READWRITE */ 189#endif /* RUMP_SYS_READWRITE */
189 190
190#endif /* _RUMP_RUMP_H_ */ 191#endif /* _RUMP_RUMP_H_ */

cvs diff -r1.18 -r1.19 src/sys/rump/librump/rumpvfs/rump_vfs.c (switch to unified diff)

--- src/sys/rump/librump/rumpvfs/rump_vfs.c 2009/05/01 11:01:34 1.18
+++ src/sys/rump/librump/rumpvfs/rump_vfs.c 2009/05/03 16:01:44 1.19
@@ -1,587 +1,604 @@ @@ -1,587 +1,604 @@
1/* $NetBSD: rump_vfs.c,v 1.18 2009/05/01 11:01:34 pooka Exp $ */ 1/* $NetBSD: rump_vfs.c,v 1.19 2009/05/03 16:01:44 pooka Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2008 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by the 6 * Development of this software was supported by the
7 * Finnish Cultural Foundation. 7 * Finnish Cultural Foundation.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 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 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 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30 30
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32__KERNEL_RCSID(0, "$NetBSD"); 32__KERNEL_RCSID(0, "$NetBSD");
33 33
34#include <sys/param.h> 34#include <sys/param.h>
35#include <sys/buf.h> 35#include <sys/buf.h>
36#include <sys/conf.h> 36#include <sys/conf.h>
37#include <sys/evcnt.h> 37#include <sys/evcnt.h>
38#include <sys/filedesc.h> 38#include <sys/filedesc.h>
39#include <sys/lockf.h> 39#include <sys/lockf.h>
40#include <sys/kthread.h> 40#include <sys/kthread.h>
41#include <sys/module.h> 41#include <sys/module.h>
42#include <sys/namei.h> 42#include <sys/namei.h>
43#include <sys/queue.h> 43#include <sys/queue.h>
44#include <sys/vfs_syscalls.h> 44#include <sys/vfs_syscalls.h>
45#include <sys/vnode.h> 45#include <sys/vnode.h>
46#include <sys/wapbl.h> 46#include <sys/wapbl.h>
47 47
48#include <miscfs/specfs/specdev.h> 48#include <miscfs/specfs/specdev.h>
49#include <miscfs/syncfs/syncfs.h> 49#include <miscfs/syncfs/syncfs.h>
50 50
51#include <rump/rump.h> 51#include <rump/rump.h>
52#include <rump/rumpuser.h> 52#include <rump/rumpuser.h>
53 53
54#include "rump_private.h" 54#include "rump_private.h"
55#include "rump_vfs_private.h" 55#include "rump_vfs_private.h"
56 56
57struct fakeblk { 57struct fakeblk {
58 char path[MAXPATHLEN]; 58 char path[MAXPATHLEN];
59 LIST_ENTRY(fakeblk) entries; 59 LIST_ENTRY(fakeblk) entries;
60}; 60};
61static LIST_HEAD(, fakeblk) fakeblks = LIST_HEAD_INITIALIZER(fakeblks); 61static LIST_HEAD(, fakeblk) fakeblks = LIST_HEAD_INITIALIZER(fakeblks);
62 62
63static struct cwdinfo rump_cwdi; 63static struct cwdinfo rump_cwdi;
64 64
65static void rump_rcvp_lwpset(struct vnode *, struct vnode *, struct lwp *); 65static void rump_rcvp_lwpset(struct vnode *, struct vnode *, struct lwp *);
66 66
67static void 67static void
68pvfs_init(struct proc *p) 68pvfs_init(struct proc *p)
69{ 69{
70 70
71 p->p_cwdi = cwdinit(); 71 p->p_cwdi = cwdinit();
72} 72}
73 73
74static void 74static void
75pvfs_rele(struct proc *p) 75pvfs_rele(struct proc *p)
76{ 76{
77 77
78 cwdfree(p->p_cwdi); 78 cwdfree(p->p_cwdi);
79} 79}
80 80
81void 81void
82rump_vfs_init(void) 82rump_vfs_init(void)
83{ 83{
84 char buf[64]; 84 char buf[64];
85 int error; 85 int error;
86 86
87 dovfsusermount = 1; 87 dovfsusermount = 1;
88 88
89 if (rumpuser_getenv("RUMP_NVNODES", buf, sizeof(buf), &error) == 0) { 89 if (rumpuser_getenv("RUMP_NVNODES", buf, sizeof(buf), &error) == 0) {
90 desiredvnodes = strtoul(buf, NULL, 10); 90 desiredvnodes = strtoul(buf, NULL, 10);
91 } else { 91 } else {
92 desiredvnodes = 1<<16; 92 desiredvnodes = 1<<16;
93 } 93 }
94 94
95 rumpblk_init(); 95 rumpblk_init();
96 96
97 cache_cpu_init(&rump_cpu); 97 cache_cpu_init(&rump_cpu);
98 vfsinit(); 98 vfsinit();
99 bufinit(); 99 bufinit();
100 wapbl_init(); 100 wapbl_init();
101 cwd_sys_init(); 101 cwd_sys_init();
102 lf_init(); 102 lf_init();
103 103
104 rumpuser_bioinit(rump_biodone); 104 rumpuser_bioinit(rump_biodone);
105 rumpfs_init(); 105 rumpfs_init();
106 106
107 rump_proc_vfs_init = pvfs_init; 107 rump_proc_vfs_init = pvfs_init;
108 rump_proc_vfs_release = pvfs_rele; 108 rump_proc_vfs_release = pvfs_rele;
109 109
110 /* bootstrap cwdi */ 110 /* bootstrap cwdi */
111 rw_init(&rump_cwdi.cwdi_lock); 111 rw_init(&rump_cwdi.cwdi_lock);
112 rump_cwdi.cwdi_cdir = rootvnode; 112 rump_cwdi.cwdi_cdir = rootvnode;
113 vref(rump_cwdi.cwdi_cdir); 113 vref(rump_cwdi.cwdi_cdir);
114 proc0.p_cwdi = &rump_cwdi; 114 proc0.p_cwdi = &rump_cwdi;
115 proc0.p_cwdi = cwdinit(); 115 proc0.p_cwdi = cwdinit();
116 116
117 if (rump_threads) { 117 if (rump_threads) {
118 int rv; 118 int rv;
119 119
120 if ((rv = kthread_create(PRI_IOFLUSH, KTHREAD_MPSAFE, NULL, 120 if ((rv = kthread_create(PRI_IOFLUSH, KTHREAD_MPSAFE, NULL,
121 sched_sync, NULL, NULL, "ioflush")) != 0) 121 sched_sync, NULL, NULL, "ioflush")) != 0)
122 panic("syncer thread create failed: %d", rv); 122 panic("syncer thread create failed: %d", rv);
123 } else { 123 } else {
124 syncdelay = 0; 124 syncdelay = 0;
125 } 125 }
126} 126}
127 127
128struct mount * 128struct mount *
129rump_mnt_init(struct vfsops *vfsops, int mntflags) 129rump_mnt_init(struct vfsops *vfsops, int mntflags)
130{ 130{
131 struct mount *mp; 131 struct mount *mp;
132 132
133 mp = kmem_zalloc(sizeof(struct mount), KM_SLEEP); 133 mp = kmem_zalloc(sizeof(struct mount), KM_SLEEP);
134 134
135 mp->mnt_op = vfsops; 135 mp->mnt_op = vfsops;
136 mp->mnt_flag = mntflags; 136 mp->mnt_flag = mntflags;
137 TAILQ_INIT(&mp->mnt_vnodelist); 137 TAILQ_INIT(&mp->mnt_vnodelist);
138 rw_init(&mp->mnt_unmounting); 138 rw_init(&mp->mnt_unmounting);
139 mutex_init(&mp->mnt_updating, MUTEX_DEFAULT, IPL_NONE); 139 mutex_init(&mp->mnt_updating, MUTEX_DEFAULT, IPL_NONE);
140 mutex_init(&mp->mnt_renamelock, MUTEX_DEFAULT, IPL_NONE); 140 mutex_init(&mp->mnt_renamelock, MUTEX_DEFAULT, IPL_NONE);
141 mp->mnt_refcnt = 1; 141 mp->mnt_refcnt = 1;
142 mp->mnt_vnodecovered = rootvnode; 142 mp->mnt_vnodecovered = rootvnode;
143 143
144 mount_initspecific(mp); 144 mount_initspecific(mp);
145 145
146 return mp; 146 return mp;
147} 147}
148 148
149int 149int
150rump_mnt_mount(struct mount *mp, const char *path, void *data, size_t *dlen) 150rump_mnt_mount(struct mount *mp, const char *path, void *data, size_t *dlen)
151{ 151{
152 struct vnode *rvp; 152 struct vnode *rvp;
153 int rv; 153 int rv;
154 154
155 rv = VFS_MOUNT(mp, path, data, dlen); 155 rv = VFS_MOUNT(mp, path, data, dlen);
156 if (rv) 156 if (rv)
157 return rv; 157 return rv;
158 158
159 (void) VFS_STATVFS(mp, &mp->mnt_stat); 159 (void) VFS_STATVFS(mp, &mp->mnt_stat);
160 rv = VFS_START(mp, 0); 160 rv = VFS_START(mp, 0);
161 if (rv) { 161 if (rv) {
162 VFS_UNMOUNT(mp, MNT_FORCE); 162 VFS_UNMOUNT(mp, MNT_FORCE);
163 return rv; 163 return rv;
164 } 164 }
165 165
166 /* 166 /*
167 * XXX: set a root for lwp0. This is strictly not correct, 167 * XXX: set a root for lwp0. This is strictly not correct,
168 * but makes things work for single fs case without having 168 * but makes things work for single fs case without having
169 * to manually call rump_rcvp_set(). 169 * to manually call rump_rcvp_set().
170 */ 170 */
171 VFS_ROOT(mp, &rvp); 171 VFS_ROOT(mp, &rvp);
172 rump_rcvp_lwpset(rvp, rvp, &lwp0); 172 rump_rcvp_lwpset(rvp, rvp, &lwp0);
173 vput(rvp); 173 vput(rvp);
174 174
175 return rv; 175 return rv;
176} 176}
177 177
178void 178void
179rump_mnt_destroy(struct mount *mp) 179rump_mnt_destroy(struct mount *mp)
180{ 180{
181 181
182 /* See rcvp XXX above */ 182 /* See rcvp XXX above */
183 rump_cwdi.cwdi_rdir = NULL; 183 rump_cwdi.cwdi_rdir = NULL;
184 vref(rootvnode); 184 vref(rootvnode);
185 rump_cwdi.cwdi_cdir = rootvnode; 185 rump_cwdi.cwdi_cdir = rootvnode;
186 186
187 mount_finispecific(mp); 187 mount_finispecific(mp);
188 kmem_free(mp, sizeof(*mp)); 188 kmem_free(mp, sizeof(*mp));
189} 189}
190 190
191struct componentname * 191struct componentname *
192rump_makecn(u_long nameiop, u_long flags, const char *name, size_t namelen, 192rump_makecn(u_long nameiop, u_long flags, const char *name, size_t namelen,
193 kauth_cred_t creds, struct lwp *l) 193 kauth_cred_t creds, struct lwp *l)
194{ 194{
195 struct componentname *cnp; 195 struct componentname *cnp;
196 const char *cp = NULL; 196 const char *cp = NULL;
197 197
198 cnp = kmem_zalloc(sizeof(struct componentname), KM_SLEEP); 198 cnp = kmem_zalloc(sizeof(struct componentname), KM_SLEEP);
199 199
200 cnp->cn_nameiop = nameiop; 200 cnp->cn_nameiop = nameiop;
201 cnp->cn_flags = flags | HASBUF; 201 cnp->cn_flags = flags | HASBUF;
202 202
203 cnp->cn_pnbuf = PNBUF_GET(); 203 cnp->cn_pnbuf = PNBUF_GET();
204 strcpy(cnp->cn_pnbuf, name); 204 strcpy(cnp->cn_pnbuf, name);
205 cnp->cn_nameptr = cnp->cn_pnbuf; 205 cnp->cn_nameptr = cnp->cn_pnbuf;
206 cnp->cn_namelen = namelen; 206 cnp->cn_namelen = namelen;
207 cnp->cn_hash = namei_hash(name, &cp); 207 cnp->cn_hash = namei_hash(name, &cp);
208 208
209 cnp->cn_cred = creds; 209 cnp->cn_cred = creds;
210 210
211 return cnp; 211 return cnp;
212} 212}
213 213
214void 214void
215rump_freecn(struct componentname *cnp, int flags) 215rump_freecn(struct componentname *cnp, int flags)
216{ 216{
217 217
218 if (flags & RUMPCN_FREECRED) 218 if (flags & RUMPCN_FREECRED)
219 rump_cred_destroy(cnp->cn_cred); 219 rump_cred_destroy(cnp->cn_cred);
220 220
221 if ((flags & RUMPCN_HASNTBUF) == 0) { 221 if ((flags & RUMPCN_HASNTBUF) == 0) {
222 if (cnp->cn_flags & SAVENAME) { 222 if (cnp->cn_flags & SAVENAME) {
223 if (flags & RUMPCN_ISLOOKUP ||cnp->cn_flags & SAVESTART) 223 if (flags & RUMPCN_ISLOOKUP ||cnp->cn_flags & SAVESTART)
224 PNBUF_PUT(cnp->cn_pnbuf); 224 PNBUF_PUT(cnp->cn_pnbuf);
225 } else { 225 } else {
226 PNBUF_PUT(cnp->cn_pnbuf); 226 PNBUF_PUT(cnp->cn_pnbuf);
227 } 227 }
228 } 228 }
229 kmem_free(cnp, sizeof(*cnp)); 229 kmem_free(cnp, sizeof(*cnp));
230} 230}
231 231
232/* hey baby, what's your namei? */ 232/* hey baby, what's your namei? */
233int 233int
234rump_namei(uint32_t op, uint32_t flags, const char *namep, 234rump_namei(uint32_t op, uint32_t flags, const char *namep,
235 struct vnode **dvpp, struct vnode **vpp, struct componentname **cnpp) 235 struct vnode **dvpp, struct vnode **vpp, struct componentname **cnpp)
236{ 236{
237 struct nameidata nd; 237 struct nameidata nd;
238 int rv; 238 int rv;
239 239
240 NDINIT(&nd, op, flags, UIO_SYSSPACE, namep); 240 NDINIT(&nd, op, flags, UIO_SYSSPACE, namep);
241 rv = namei(&nd); 241 rv = namei(&nd);
242 if (rv) 242 if (rv)
243 return rv; 243 return rv;
244 244
245 if (dvpp) { 245 if (dvpp) {
246 KASSERT(flags & LOCKPARENT); 246 KASSERT(flags & LOCKPARENT);
247 *dvpp = nd.ni_dvp; 247 *dvpp = nd.ni_dvp;
248 } else { 248 } else {
249 KASSERT((flags & LOCKPARENT) == 0); 249 KASSERT((flags & LOCKPARENT) == 0);
250 } 250 }
251 251
252 if (vpp) { 252 if (vpp) {
253 *vpp = nd.ni_vp; 253 *vpp = nd.ni_vp;
254 } else { 254 } else {
255 if (nd.ni_vp) { 255 if (nd.ni_vp) {
256 if (flags & LOCKLEAF) 256 if (flags & LOCKLEAF)
257 vput(nd.ni_vp); 257 vput(nd.ni_vp);
258 else 258 else
259 vrele(nd.ni_vp); 259 vrele(nd.ni_vp);
260 } 260 }
261 } 261 }
262 262
263 if (cnpp) { 263 if (cnpp) {
264 struct componentname *cnp; 264 struct componentname *cnp;
265 265
266 cnp = kmem_alloc(sizeof(*cnp), KM_SLEEP); 266 cnp = kmem_alloc(sizeof(*cnp), KM_SLEEP);
267 memcpy(cnp, &nd.ni_cnd, sizeof(*cnp)); 267 memcpy(cnp, &nd.ni_cnd, sizeof(*cnp));
268 *cnpp = cnp; 268 *cnpp = cnp;
269 } else if (nd.ni_cnd.cn_flags & HASBUF) { 269 } else if (nd.ni_cnd.cn_flags & HASBUF) {
270 panic("%s: pathbuf mismatch", __func__); 270 panic("%s: pathbuf mismatch", __func__);
271 } 271 }
272 272
273 return rv; 273 return rv;
274} 274}
275 275
276static struct fakeblk * 276static struct fakeblk *
277_rump_fakeblk_find(const char *path) 277_rump_fakeblk_find(const char *path)
278{ 278{
279 char buf[MAXPATHLEN]; 279 char buf[MAXPATHLEN];
280 struct fakeblk *fblk; 280 struct fakeblk *fblk;
281 int error; 281 int error;
282 282
283 if (rumpuser_realpath(path, buf, &error) == NULL) 283 if (rumpuser_realpath(path, buf, &error) == NULL)
284 return NULL; 284 return NULL;
285 285
286 LIST_FOREACH(fblk, &fakeblks, entries) 286 LIST_FOREACH(fblk, &fakeblks, entries)
287 if (strcmp(fblk->path, buf) == 0) 287 if (strcmp(fblk->path, buf) == 0)
288 return fblk; 288 return fblk;
289 289
290 return NULL; 290 return NULL;
291} 291}
292 292
293int 293int
294rump_fakeblk_register(const char *path) 294rump_fakeblk_register(const char *path)
295{ 295{
296 char buf[MAXPATHLEN]; 296 char buf[MAXPATHLEN];
297 struct fakeblk *fblk; 297 struct fakeblk *fblk;
298 int error; 298 int error;
299 299
300 if (_rump_fakeblk_find(path)) 300 if (_rump_fakeblk_find(path))
301 return EEXIST; 301 return EEXIST;
302 302
303 if (rumpuser_realpath(path, buf, &error) == NULL) 303 if (rumpuser_realpath(path, buf, &error) == NULL)
304 return error; 304 return error;
305 305
306 fblk = kmem_alloc(sizeof(struct fakeblk), KM_NOSLEEP); 306 fblk = kmem_alloc(sizeof(struct fakeblk), KM_NOSLEEP);
307 if (fblk == NULL) 307 if (fblk == NULL)
308 return ENOMEM; 308 return ENOMEM;
309 309
310 strlcpy(fblk->path, buf, MAXPATHLEN); 310 strlcpy(fblk->path, buf, MAXPATHLEN);
311 LIST_INSERT_HEAD(&fakeblks, fblk, entries); 311 LIST_INSERT_HEAD(&fakeblks, fblk, entries);
312 312
313 return 0; 313 return 0;
314} 314}
315 315
316int 316int
317rump_fakeblk_find(const char *path) 317rump_fakeblk_find(const char *path)
318{ 318{
319 319
320 return _rump_fakeblk_find(path) != NULL; 320 return _rump_fakeblk_find(path) != NULL;
321} 321}
322 322
323void 323void
324rump_fakeblk_deregister(const char *path) 324rump_fakeblk_deregister(const char *path)
325{ 325{
326 struct fakeblk *fblk; 326 struct fakeblk *fblk;
327 327
328 fblk = _rump_fakeblk_find(path); 328 fblk = _rump_fakeblk_find(path);
329 if (fblk == NULL) 329 if (fblk == NULL)
330 return; 330 return;
331 331
332 LIST_REMOVE(fblk, entries); 332 LIST_REMOVE(fblk, entries);
333 kmem_free(fblk, sizeof(*fblk)); 333 kmem_free(fblk, sizeof(*fblk));
334} 334}
335 335
336void 336void
337rump_getvninfo(struct vnode *vp, enum vtype *vtype, voff_t *vsize, dev_t *vdev) 337rump_getvninfo(struct vnode *vp, enum vtype *vtype, voff_t *vsize, dev_t *vdev)
338{ 338{
339 339
340 *vtype = vp->v_type; 340 *vtype = vp->v_type;
341 *vsize = vp->v_size; 341 *vsize = vp->v_size;
342 if (vp->v_specnode) 342 if (vp->v_specnode)
343 *vdev = vp->v_rdev; 343 *vdev = vp->v_rdev;
344 else 344 else
345 *vdev = 0; 345 *vdev = 0;
346} 346}
347 347
348struct vfsops * 348struct vfsops *
349rump_vfslist_iterate(struct vfsops *ops) 349rump_vfslist_iterate(struct vfsops *ops)
350{ 350{
351 351
352 if (ops == NULL) 352 if (ops == NULL)
353 return LIST_FIRST(&vfs_list); 353 return LIST_FIRST(&vfs_list);
354 else 354 else
355 return LIST_NEXT(ops, vfs_list); 355 return LIST_NEXT(ops, vfs_list);
356} 356}
357 357
358struct vfsops * 358struct vfsops *
359rump_vfs_getopsbyname(const char *name) 359rump_vfs_getopsbyname(const char *name)
360{ 360{
361 361
362 return vfs_getopsbyname(name); 362 return vfs_getopsbyname(name);
363} 363}
364 364
 365int
 366rump_vfs_getmp(const char *path, struct mount **mpp)
 367{
 368 struct nameidata nd;
 369 struct vnode *vp;
 370 int rv;
 371
 372 NDINIT(&nd, LOOKUP, FOLLOW | TRYEMULROOT, UIO_USERSPACE, path);
 373 if ((rv = namei(&nd)) != 0)
 374 return rv;
 375 vp = nd.ni_vp;
 376
 377 *mpp = vp->v_mount;
 378 vrele(vp);
 379 return 0;
 380}
 381
365struct vattr* 382struct vattr*
366rump_vattr_init(void) 383rump_vattr_init(void)
367{ 384{
368 struct vattr *vap; 385 struct vattr *vap;
369 386
370 vap = kmem_alloc(sizeof(struct vattr), KM_SLEEP); 387 vap = kmem_alloc(sizeof(struct vattr), KM_SLEEP);
371 vattr_null(vap); 388 vattr_null(vap);
372 389
373 return vap; 390 return vap;
374} 391}
375 392
376void 393void
377rump_vattr_settype(struct vattr *vap, enum vtype vt) 394rump_vattr_settype(struct vattr *vap, enum vtype vt)
378{ 395{
379 396
380 vap->va_type = vt; 397 vap->va_type = vt;
381} 398}
382 399
383void 400void
384rump_vattr_setmode(struct vattr *vap, mode_t mode) 401rump_vattr_setmode(struct vattr *vap, mode_t mode)
385{ 402{
386 403
387 vap->va_mode = mode; 404 vap->va_mode = mode;
388} 405}
389 406
390void 407void
391rump_vattr_setrdev(struct vattr *vap, dev_t dev) 408rump_vattr_setrdev(struct vattr *vap, dev_t dev)
392{ 409{
393 410
394 vap->va_rdev = dev; 411 vap->va_rdev = dev;
395} 412}
396 413
397void 414void
398rump_vattr_free(struct vattr *vap) 415rump_vattr_free(struct vattr *vap)
399{ 416{
400 417
401 kmem_free(vap, sizeof(*vap)); 418 kmem_free(vap, sizeof(*vap));
402} 419}
403 420
404void 421void
405rump_vp_incref(struct vnode *vp) 422rump_vp_incref(struct vnode *vp)
406{ 423{
407 424
408 mutex_enter(&vp->v_interlock); 425 mutex_enter(&vp->v_interlock);
409 ++vp->v_usecount; 426 ++vp->v_usecount;
410 mutex_exit(&vp->v_interlock); 427 mutex_exit(&vp->v_interlock);
411} 428}
412 429
413int 430int
414rump_vp_getref(struct vnode *vp) 431rump_vp_getref(struct vnode *vp)
415{ 432{
416 433
417 return vp->v_usecount; 434 return vp->v_usecount;
418} 435}
419 436
420void 437void
421rump_vp_decref(struct vnode *vp) 438rump_vp_decref(struct vnode *vp)
422{ 439{
423 440
424 mutex_enter(&vp->v_interlock); 441 mutex_enter(&vp->v_interlock);
425 --vp->v_usecount; 442 --vp->v_usecount;
426 mutex_exit(&vp->v_interlock); 443 mutex_exit(&vp->v_interlock);
427} 444}
428 445
429/* 446/*
430 * Really really recycle with a cherry on top. We should be 447 * Really really recycle with a cherry on top. We should be
431 * extra-sure we can do this. For example with p2k there is 448 * extra-sure we can do this. For example with p2k there is
432 * no problem, since puffs in the kernel takes care of refcounting 449 * no problem, since puffs in the kernel takes care of refcounting
433 * for us. 450 * for us.
434 */ 451 */
435void 452void
436rump_vp_recycle_nokidding(struct vnode *vp) 453rump_vp_recycle_nokidding(struct vnode *vp)
437{ 454{
438 455
439 mutex_enter(&vp->v_interlock); 456 mutex_enter(&vp->v_interlock);
440 vp->v_usecount = 1; 457 vp->v_usecount = 1;
441 /* 458 /*
442 * XXX: NFS holds a reference to the root vnode, so don't clean 459 * XXX: NFS holds a reference to the root vnode, so don't clean
443 * it out. This is very wrong, but fixing it properly would 460 * it out. This is very wrong, but fixing it properly would
444 * take too much effort for now 461 * take too much effort for now
445 */ 462 */
446 if (vp->v_tag == VT_NFS && vp->v_vflag & VV_ROOT) { 463 if (vp->v_tag == VT_NFS && vp->v_vflag & VV_ROOT) {
447 mutex_exit(&vp->v_interlock); 464 mutex_exit(&vp->v_interlock);
448 return; 465 return;
449 } 466 }
450 vclean(vp, DOCLOSE); 467 vclean(vp, DOCLOSE);
451 vrelel(vp, 0); 468 vrelel(vp, 0);
452} 469}
453 470
454void 471void
455rump_vp_rele(struct vnode *vp) 472rump_vp_rele(struct vnode *vp)
456{ 473{
457 474
458 vrele(vp); 475 vrele(vp);
459} 476}
460 477
461void 478void
462rump_vp_interlock(struct vnode *vp) 479rump_vp_interlock(struct vnode *vp)
463{ 480{
464 481
465 mutex_enter(&vp->v_interlock); 482 mutex_enter(&vp->v_interlock);
466} 483}
467 484
468int 485int
469rump_vfs_unmount(struct mount *mp, int mntflags) 486rump_vfs_unmount(struct mount *mp, int mntflags)
470{ 487{
471#if 0 488#if 0
472 struct evcnt *ev; 489 struct evcnt *ev;
473 490
474 printf("event counters:\n"); 491 printf("event counters:\n");
475 TAILQ_FOREACH(ev, &allevents, ev_list) 492 TAILQ_FOREACH(ev, &allevents, ev_list)
476 printf("%s: %llu\n", ev->ev_name, ev->ev_count); 493 printf("%s: %llu\n", ev->ev_name, ev->ev_count);
477#endif 494#endif
478 495
479 return VFS_UNMOUNT(mp, mntflags); 496 return VFS_UNMOUNT(mp, mntflags);
480} 497}
481 498
482int 499int
483rump_vfs_root(struct mount *mp, struct vnode **vpp, int lock) 500rump_vfs_root(struct mount *mp, struct vnode **vpp, int lock)
484{ 501{
485 int rv; 502 int rv;
486 503
487 rv = VFS_ROOT(mp, vpp); 504 rv = VFS_ROOT(mp, vpp);
488 if (rv) 505 if (rv)
489 return rv; 506 return rv;
490 507
491 if (!lock) 508 if (!lock)
492 VOP_UNLOCK(*vpp, 0); 509 VOP_UNLOCK(*vpp, 0);
493 510
494 return 0; 511 return 0;
495} 512}
496 513
497int 514int
498rump_vfs_statvfs(struct mount *mp, struct statvfs *sbp) 515rump_vfs_statvfs(struct mount *mp, struct statvfs *sbp)
499{ 516{
500 517
501 return VFS_STATVFS(mp, sbp); 518 return VFS_STATVFS(mp, sbp);
502} 519}
503 520
504int 521int
505rump_vfs_sync(struct mount *mp, int wait, kauth_cred_t cred) 522rump_vfs_sync(struct mount *mp, int wait, kauth_cred_t cred)
506{ 523{
507 524
508 return VFS_SYNC(mp, wait ? MNT_WAIT : MNT_NOWAIT, cred); 525 return VFS_SYNC(mp, wait ? MNT_WAIT : MNT_NOWAIT, cred);
509} 526}
510 527
511int 528int
512rump_vfs_fhtovp(struct mount *mp, struct fid *fid, struct vnode **vpp) 529rump_vfs_fhtovp(struct mount *mp, struct fid *fid, struct vnode **vpp)
513{ 530{
514 531
515 return VFS_FHTOVP(mp, fid, vpp); 532 return VFS_FHTOVP(mp, fid, vpp);
516} 533}
517 534
518int 535int
519rump_vfs_vptofh(struct vnode *vp, struct fid *fid, size_t *fidsize) 536rump_vfs_vptofh(struct vnode *vp, struct fid *fid, size_t *fidsize)
520{ 537{
521 538
522 return VFS_VPTOFH(vp, fid, fidsize); 539 return VFS_VPTOFH(vp, fid, fidsize);
523} 540}
524 541
525/*ARGSUSED*/ 542/*ARGSUSED*/
526void 543void
527rump_vfs_syncwait(struct mount *mp) 544rump_vfs_syncwait(struct mount *mp)
528{ 545{
529 int n; 546 int n;
530 547
531 n = buf_syncwait(); 548 n = buf_syncwait();
532 if (n) 549 if (n)
533 printf("syncwait: unsynced buffers: %d\n", n); 550 printf("syncwait: unsynced buffers: %d\n", n);
534} 551}
535 552
536void 553void
537rump_biodone(void *arg, size_t count, int error) 554rump_biodone(void *arg, size_t count, int error)
538{ 555{
539 struct buf *bp = arg; 556 struct buf *bp = arg;
540 557
541 bp->b_resid = bp->b_bcount - count; 558 bp->b_resid = bp->b_bcount - count;
542 KASSERT(bp->b_resid >= 0); 559 KASSERT(bp->b_resid >= 0);
543 bp->b_error = error; 560 bp->b_error = error;
544 561
545 biodone(bp); 562 biodone(bp);
546} 563}
547 564
548static void 565static void
549rump_rcvp_lwpset(struct vnode *rvp, struct vnode *cvp, struct lwp *l) 566rump_rcvp_lwpset(struct vnode *rvp, struct vnode *cvp, struct lwp *l)
550{ 567{
551 struct cwdinfo *cwdi = l->l_proc->p_cwdi; 568 struct cwdinfo *cwdi = l->l_proc->p_cwdi;
552 569
553 KASSERT(cvp); 570 KASSERT(cvp);
554 571
555 rw_enter(&cwdi->cwdi_lock, RW_WRITER); 572 rw_enter(&cwdi->cwdi_lock, RW_WRITER);
556 if (cwdi->cwdi_rdir) 573 if (cwdi->cwdi_rdir)
557 vrele(cwdi->cwdi_rdir); 574 vrele(cwdi->cwdi_rdir);
558 if (rvp) 575 if (rvp)
559 vref(rvp); 576 vref(rvp);
560 cwdi->cwdi_rdir = rvp; 577 cwdi->cwdi_rdir = rvp;
561 578
562 vrele(cwdi->cwdi_cdir); 579 vrele(cwdi->cwdi_cdir);
563 vref(cvp); 580 vref(cvp);
564 cwdi->cwdi_cdir = cvp; 581 cwdi->cwdi_cdir = cvp;
565 rw_exit(&cwdi->cwdi_lock); 582 rw_exit(&cwdi->cwdi_lock);
566} 583}
567 584
568void 585void
569rump_rcvp_set(struct vnode *rvp, struct vnode *cvp) 586rump_rcvp_set(struct vnode *rvp, struct vnode *cvp)
570{ 587{
571 588
572 rump_rcvp_lwpset(rvp, cvp, curlwp); 589 rump_rcvp_lwpset(rvp, cvp, curlwp);
573} 590}
574 591
575struct vnode * 592struct vnode *
576rump_cdir_get(void) 593rump_cdir_get(void)
577{ 594{
578 struct vnode *vp; 595 struct vnode *vp;
579 struct cwdinfo *cwdi = curlwp->l_proc->p_cwdi; 596 struct cwdinfo *cwdi = curlwp->l_proc->p_cwdi;
580 597
581 rw_enter(&cwdi->cwdi_lock, RW_READER); 598 rw_enter(&cwdi->cwdi_lock, RW_READER);
582 vp = cwdi->cwdi_cdir; 599 vp = cwdi->cwdi_cdir;
583 rw_exit(&cwdi->cwdi_lock); 600 rw_exit(&cwdi->cwdi_lock);
584 vref(vp); 601 vref(vp);
585 602
586 return vp; 603 return vp;
587} 604}