kernel - Tear out vfs polling
[dragonfly.git] / sys / kern / vfs_default.c
CommitLineData
984263bc
MD
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed
6 * to Berkeley by John Heidemann of the UCLA Ficus project.
7 *
d9fad06e
MD
8 * The statvfs->statfs conversion code was contributed to the DragonFly
9 * Project by Joerg Sonnenberger <joerg@bec.de>.
984263bc
MD
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by the University of
22 * California, Berkeley and its contributors.
23 * 4. Neither the name of the University nor the names of its contributors
24 * may be used to endorse or promote products derived from this software
25 * without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 * SUCH DAMAGE.
38 *
d9fad06e 39 * Source: * @(#)i405_init.c 2.10 92/04/27 UCLA Ficus project
984263bc 40 * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $
27469235 41 * $DragonFly: src/sys/kern/vfs_default.c,v 1.55 2008/09/28 04:31:50 dillon Exp $
984263bc
MD
42 */
43
44#include <sys/param.h>
45#include <sys/systm.h>
46#include <sys/buf.h>
47#include <sys/conf.h>
8ddc6004
MD
48#include <sys/fcntl.h>
49#include <sys/file.h>
984263bc
MD
50#include <sys/kernel.h>
51#include <sys/lock.h>
52#include <sys/malloc.h>
53#include <sys/mount.h>
54#include <sys/unistd.h>
55#include <sys/vnode.h>
690a3127 56#include <sys/namei.h>
fad57d0e 57#include <sys/nlookup.h>
949ecb9b 58#include <sys/mountctl.h>
984263bc
MD
59
60#include <machine/limits.h>
61
62#include <vm/vm.h>
63#include <vm/vm_object.h>
64#include <vm/vm_page.h>
65#include <vm/vm_pager.h>
66#include <vm/vnode_pager.h>
67
e62afb5f 68static int vop_nolookup (struct vop_old_lookup_args *);
402ed7e1 69static int vop_nostrategy (struct vop_strategy_args *);
984263bc
MD
70
71/*
72 * This vnode table stores what we want to do if the filesystem doesn't
73 * implement a particular VOP.
74 *
75 * If there is no specific entry here, we will return EOPNOTSUPP.
984263bc 76 */
66a1ddf5
MD
77struct vop_ops default_vnode_vops = {
78 .vop_default = vop_eopnotsupp,
79 .vop_advlock = (void *)vop_einval,
80 .vop_fsync = (void *)vop_null,
81 .vop_ioctl = (void *)vop_enotty,
66a1ddf5
MD
82 .vop_mmap = (void *)vop_einval,
83 .vop_old_lookup = vop_nolookup,
84 .vop_open = vop_stdopen,
85 .vop_close = vop_stdclose,
27469235 86 .vop_pathconf = vop_stdpathconf,
66a1ddf5
MD
87 .vop_readlink = (void *)vop_einval,
88 .vop_reallocblks = (void *)vop_eopnotsupp,
66a1ddf5 89 .vop_strategy = vop_nostrategy,
66a1ddf5
MD
90 .vop_getacl = (void *)vop_eopnotsupp,
91 .vop_setacl = (void *)vop_eopnotsupp,
92 .vop_aclcheck = (void *)vop_eopnotsupp,
93 .vop_getextattr = (void *)vop_eopnotsupp,
94 .vop_setextattr = (void *)vop_eopnotsupp,
349433c9 95 .vop_markatime = vop_stdmarkatime,
66a1ddf5
MD
96 .vop_nresolve = vop_compat_nresolve,
97 .vop_nlookupdotdot = vop_compat_nlookupdotdot,
98 .vop_ncreate = vop_compat_ncreate,
99 .vop_nmkdir = vop_compat_nmkdir,
100 .vop_nmknod = vop_compat_nmknod,
101 .vop_nlink = vop_compat_nlink,
102 .vop_nsymlink = vop_compat_nsymlink,
103 .vop_nwhiteout = vop_compat_nwhiteout,
104 .vop_nremove = vop_compat_nremove,
105 .vop_nrmdir = vop_compat_nrmdir,
106 .vop_nrename = vop_compat_nrename,
177403a9 107 .vop_mountctl = vop_stdmountctl
984263bc
MD
108};
109
66a1ddf5 110VNODEOP_SET(default_vnode_vops);
984263bc
MD
111
112int
113vop_eopnotsupp(struct vop_generic_args *ap)
114{
984263bc
MD
115 return (EOPNOTSUPP);
116}
117
118int
119vop_ebadf(struct vop_generic_args *ap)
120{
984263bc
MD
121 return (EBADF);
122}
123
124int
125vop_enotty(struct vop_generic_args *ap)
126{
984263bc
MD
127 return (ENOTTY);
128}
129
130int
131vop_einval(struct vop_generic_args *ap)
132{
984263bc
MD
133 return (EINVAL);
134}
135
349433c9
MD
136int
137vop_stdmarkatime(struct vop_markatime_args *ap)
138{
139 return (EOPNOTSUPP);
140}
141
984263bc
MD
142int
143vop_null(struct vop_generic_args *ap)
144{
984263bc
MD
145 return (0);
146}
147
148int
149vop_defaultop(struct vop_generic_args *ap)
150{
66a1ddf5 151 return (VOCALL(&default_vnode_vops, ap));
984263bc
MD
152}
153
154int
155vop_panic(struct vop_generic_args *ap)
156{
31bd717a 157 panic("filesystem goof: vop_panic[%s]", ap->a_desc->sd_name);
984263bc
MD
158}
159
690a3127 160/*
dff430ab
MD
161 * vop_compat_resolve { struct nchandle *a_nch, struct vnode *dvp }
162 * XXX STOPGAP FUNCTION
690a3127 163 *
21739618
MD
164 * XXX OLD API ROUTINE! WHEN ALL VFSs HAVE BEEN CLEANED UP THIS PROCEDURE
165 * WILL BE REMOVED. This procedure exists for all VFSs which have not
fad57d0e 166 * yet implemented VOP_NRESOLVE(). It converts VOP_NRESOLVE() into a
e62afb5f 167 * vop_old_lookup() and does appropriate translations.
21739618 168 *
690a3127
MD
169 * Resolve a ncp for VFSs which do not support the VOP. Eventually all
170 * VFSs will support this VOP and this routine can be removed, since
fad57d0e 171 * VOP_NRESOLVE() is far less complex then the older LOOKUP/CACHEDLOOKUP
690a3127
MD
172 * API.
173 *
21739618
MD
174 * A locked ncp is passed in to be resolved. The NCP is resolved by
175 * figuring out the vnode (if any) and calling cache_setvp() to attach the
176 * vnode to the entry. If the entry represents a non-existant node then
177 * cache_setvp() is called with a NULL vnode to resolve the entry into a
178 * negative cache entry. No vnode locks are retained and the
690a3127 179 * ncp is left locked on return.
8e005a45 180 *
fad57d0e
MD
181 * The ncp will NEVER represent "", "." or "..", or contain any slashes.
182 *
8e005a45
MD
183 * There is a potential directory and vnode interlock. The lock order
184 * requirement is: namecache, governing directory, resolved vnode.
690a3127 185 */
417215fe 186int
fad57d0e 187vop_compat_nresolve(struct vop_nresolve_args *ap)
690a3127
MD
188{
189 int error;
190 struct vnode *dvp;
191 struct vnode *vp;
28623bf9 192 struct nchandle *nch;
690a3127
MD
193 struct namecache *ncp;
194 struct componentname cnp;
195
28623bf9
MD
196 nch = ap->a_nch; /* locked namecache node */
197 ncp = nch->ncp;
dff430ab 198 dvp = ap->a_dvp;
8c361dda 199
fad57d0e
MD
200 /*
201 * UFS currently stores all sorts of side effects, including a loop
202 * variable, in the directory inode. That needs to be fixed and the
203 * other VFS's audited before we can switch to LK_SHARED.
204 */
87de5057 205 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 206 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e 207 ncp, ncp->nc_name);
67773eb3
MD
208 return(EAGAIN);
209 }
690a3127
MD
210
211 bzero(&cnp, sizeof(cnp));
212 cnp.cn_nameiop = NAMEI_LOOKUP;
fad57d0e 213 cnp.cn_flags = 0;
690a3127
MD
214 cnp.cn_nameptr = ncp->nc_name;
215 cnp.cn_namelen = ncp->nc_nlen;
21739618
MD
216 cnp.cn_cred = ap->a_cred;
217 cnp.cn_td = curthread; /* XXX */
218
219 /*
e62afb5f 220 * vop_old_lookup() always returns vp locked. dvp may or may not be
21739618
MD
221 * left locked depending on CNP_PDIRUNLOCK.
222 */
e62afb5f 223 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
8c361dda 224 if (error == 0)
a11aaa81 225 vn_unlock(vp);
8c361dda 226 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 227 vn_unlock(dvp);
8c361dda
MD
228 if ((ncp->nc_flag & NCF_UNRESOLVED) == 0) {
229 /* was resolved by another process while we were unlocked */
230 if (error == 0)
231 vrele(vp);
232 } else if (error == 0) {
690a3127 233 KKASSERT(vp != NULL);
28623bf9 234 cache_setvp(nch, vp);
8c361dda 235 vrele(vp);
690a3127
MD
236 } else if (error == ENOENT) {
237 KKASSERT(vp == NULL);
238 if (cnp.cn_flags & CNP_ISWHITEOUT)
239 ncp->nc_flag |= NCF_WHITEOUT;
28623bf9 240 cache_setvp(nch, NULL);
690a3127 241 }
8c361dda 242 vrele(dvp);
21739618 243 return (error);
690a3127
MD
244}
245
fad57d0e
MD
246/*
247 * vop_compat_nlookupdotdot { struct vnode *a_dvp,
248 * struct vnode **a_vpp,
249 * struct ucred *a_cred }
250 *
251 * Lookup the vnode representing the parent directory of the specified
252 * directory vnode. a_dvp should not be locked. If no error occurs *a_vpp
253 * will contained the parent vnode, locked and refd, else *a_vpp will be NULL.
254 *
255 * This function is designed to aid NFS server-side operations and is
256 * used by cache_fromdvp() to create a consistent, connected namecache
257 * topology.
258 *
259 * As part of the NEW API work, VFSs will first split their CNP_ISDOTDOT
260 * code out from their *_lookup() and create *_nlookupdotdot(). Then as time
261 * permits VFSs will implement the remaining *_n*() calls and finally get
262 * rid of their *_lookup() call.
263 */
264int
265vop_compat_nlookupdotdot(struct vop_nlookupdotdot_args *ap)
266{
267 struct componentname cnp;
268 int error;
269
270 /*
271 * UFS currently stores all sorts of side effects, including a loop
272 * variable, in the directory inode. That needs to be fixed and the
273 * other VFS's audited before we can switch to LK_SHARED.
274 */
275 *ap->a_vpp = NULL;
87de5057 276 if ((error = vget(ap->a_dvp, LK_EXCLUSIVE)) != 0)
fad57d0e
MD
277 return (error);
278 if (ap->a_dvp->v_type != VDIR) {
279 vput(ap->a_dvp);
280 return (ENOTDIR);
281 }
282
283 bzero(&cnp, sizeof(cnp));
284 cnp.cn_nameiop = NAMEI_LOOKUP;
285 cnp.cn_flags = CNP_ISDOTDOT;
286 cnp.cn_nameptr = "..";
287 cnp.cn_namelen = 2;
288 cnp.cn_cred = ap->a_cred;
289 cnp.cn_td = curthread; /* XXX */
290
291 /*
e62afb5f 292 * vop_old_lookup() always returns vp locked. dvp may or may not be
fad57d0e
MD
293 * left locked depending on CNP_PDIRUNLOCK.
294 */
e62afb5f 295 error = vop_old_lookup(ap->a_head.a_ops, ap->a_dvp, ap->a_vpp, &cnp);
fad57d0e 296 if (error == 0)
a11aaa81 297 vn_unlock(*ap->a_vpp);
fad57d0e
MD
298 if (cnp.cn_flags & CNP_PDIRUNLOCK)
299 vrele(ap->a_dvp);
300 else
301 vput(ap->a_dvp);
302 return (error);
303}
21739618
MD
304
305/*
28623bf9 306 * vop_compat_ncreate { struct nchandle *a_nch, XXX STOPGAP FUNCTION
dff430ab
MD
307 * struct vnode *a_dvp,
308 * struct vnode **a_vpp,
fad57d0e
MD
309 * struct ucred *a_cred,
310 * struct vattr *a_vap }
21739618 311 *
fad57d0e
MD
312 * Create a file as specified by a_vap. Compatibility requires us to issue
313 * the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_CREATE in order
314 * to setup the directory inode's i_offset and i_count (e.g. in UFS).
315 */
316int
317vop_compat_ncreate(struct vop_ncreate_args *ap)
318{
319 struct thread *td = curthread;
320 struct componentname cnp;
28623bf9 321 struct nchandle *nch;
fad57d0e
MD
322 struct namecache *ncp;
323 struct vnode *dvp;
324 int error;
325
326 /*
327 * Sanity checks, get a locked directory vnode.
328 */
28623bf9 329 nch = ap->a_nch; /* locked namecache node */
dff430ab 330 dvp = ap->a_dvp;
28623bf9 331 ncp = nch->ncp;
fad57d0e 332
87de5057 333 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 334 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
335 ncp, ncp->nc_name);
336 return(EAGAIN);
337 }
338
339 /*
e62afb5f 340 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
341 * caches all information required to create the entry in the
342 * directory inode. We expect a return code of EJUSTRETURN for
343 * the CREATE case. The cnp must simulated a saved-name situation.
344 */
345 bzero(&cnp, sizeof(cnp));
346 cnp.cn_nameiop = NAMEI_CREATE;
347 cnp.cn_flags = CNP_LOCKPARENT;
348 cnp.cn_nameptr = ncp->nc_name;
349 cnp.cn_namelen = ncp->nc_nlen;
350 cnp.cn_cred = ap->a_cred;
351 cnp.cn_td = td;
352 *ap->a_vpp = NULL;
353
e62afb5f 354 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
fad57d0e
MD
355
356 /*
357 * EJUSTRETURN should be returned for this case, which means that
358 * the VFS has setup the directory inode for the create. The dvp we
359 * passed in is expected to remain in a locked state.
360 *
361 * If the VOP_OLD_CREATE is successful we are responsible for updating
362 * the cache state of the locked ncp that was passed to us.
363 */
364 if (error == EJUSTRETURN) {
365 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
366 error = VOP_OLD_CREATE(dvp, ap->a_vpp, &cnp, ap->a_vap);
367 if (error == 0) {
28623bf9
MD
368 cache_setunresolved(nch);
369 cache_setvp(nch, *ap->a_vpp);
fad57d0e
MD
370 }
371 } else {
372 if (error == 0) {
373 vput(*ap->a_vpp);
374 *ap->a_vpp = NULL;
375 error = EEXIST;
376 }
377 KKASSERT(*ap->a_vpp == NULL);
378 }
379 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 380 vn_unlock(dvp);
fad57d0e
MD
381 vrele(dvp);
382 return (error);
383}
384
385/*
28623bf9 386 * vop_compat_nmkdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
dff430ab
MD
387 * struct vnode *a_dvp,
388 * struct vnode **a_vpp,
fad57d0e
MD
389 * struct ucred *a_cred,
390 * struct vattr *a_vap }
21739618 391 *
fad57d0e
MD
392 * Create a directory as specified by a_vap. Compatibility requires us to
393 * issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKDIR in
394 * order to setup the directory inode's i_offset and i_count (e.g. in UFS).
21739618 395 */
fad57d0e
MD
396int
397vop_compat_nmkdir(struct vop_nmkdir_args *ap)
398{
399 struct thread *td = curthread;
400 struct componentname cnp;
28623bf9 401 struct nchandle *nch;
fad57d0e
MD
402 struct namecache *ncp;
403 struct vnode *dvp;
404 int error;
405
406 /*
407 * Sanity checks, get a locked directory vnode.
408 */
28623bf9
MD
409 nch = ap->a_nch; /* locked namecache node */
410 ncp = nch->ncp;
dff430ab 411 dvp = ap->a_dvp;
87de5057 412 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 413 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
414 ncp, ncp->nc_name);
415 return(EAGAIN);
416 }
417
418 /*
e62afb5f 419 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
420 * caches all information required to create the entry in the
421 * directory inode. We expect a return code of EJUSTRETURN for
422 * the CREATE case. The cnp must simulated a saved-name situation.
423 */
424 bzero(&cnp, sizeof(cnp));
425 cnp.cn_nameiop = NAMEI_CREATE;
426 cnp.cn_flags = CNP_LOCKPARENT;
427 cnp.cn_nameptr = ncp->nc_name;
428 cnp.cn_namelen = ncp->nc_nlen;
429 cnp.cn_cred = ap->a_cred;
430 cnp.cn_td = td;
431 *ap->a_vpp = NULL;
432
e62afb5f 433 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
fad57d0e
MD
434
435 /*
436 * EJUSTRETURN should be returned for this case, which means that
437 * the VFS has setup the directory inode for the create. The dvp we
438 * passed in is expected to remain in a locked state.
439 *
440 * If the VOP_OLD_MKDIR is successful we are responsible for updating
441 * the cache state of the locked ncp that was passed to us.
442 */
443 if (error == EJUSTRETURN) {
444 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
445 error = VOP_OLD_MKDIR(dvp, ap->a_vpp, &cnp, ap->a_vap);
446 if (error == 0) {
28623bf9
MD
447 cache_setunresolved(nch);
448 cache_setvp(nch, *ap->a_vpp);
fad57d0e
MD
449 }
450 } else {
451 if (error == 0) {
452 vput(*ap->a_vpp);
453 *ap->a_vpp = NULL;
454 error = EEXIST;
455 }
456 KKASSERT(*ap->a_vpp == NULL);
457 }
458 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 459 vn_unlock(dvp);
fad57d0e
MD
460 vrele(dvp);
461 return (error);
462}
463
464/*
28623bf9 465 * vop_compat_nmknod { struct nchandle *a_nch, XXX STOPGAP FUNCTION
dff430ab
MD
466 * struct vnode *a_dvp,
467 * struct vnode **a_vpp,
fad57d0e
MD
468 * struct ucred *a_cred,
469 * struct vattr *a_vap }
470 *
471 * Create a device or fifo node as specified by a_vap. Compatibility requires
472 * us to issue the appropriate VOP_OLD_LOOKUP before we issue VOP_OLD_MKNOD
473 * in order to setup the directory inode's i_offset and i_count (e.g. in UFS).
474 */
475int
476vop_compat_nmknod(struct vop_nmknod_args *ap)
477{
478 struct thread *td = curthread;
479 struct componentname cnp;
28623bf9 480 struct nchandle *nch;
fad57d0e
MD
481 struct namecache *ncp;
482 struct vnode *dvp;
483 int error;
484
485 /*
486 * Sanity checks, get a locked directory vnode.
487 */
28623bf9
MD
488 nch = ap->a_nch; /* locked namecache node */
489 ncp = nch->ncp;
dff430ab 490 dvp = ap->a_dvp;
fad57d0e 491
87de5057 492 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 493 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
494 ncp, ncp->nc_name);
495 return(EAGAIN);
496 }
497
498 /*
e62afb5f 499 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
500 * caches all information required to create the entry in the
501 * directory inode. We expect a return code of EJUSTRETURN for
502 * the CREATE case. The cnp must simulated a saved-name situation.
503 */
504 bzero(&cnp, sizeof(cnp));
505 cnp.cn_nameiop = NAMEI_CREATE;
506 cnp.cn_flags = CNP_LOCKPARENT;
507 cnp.cn_nameptr = ncp->nc_name;
508 cnp.cn_namelen = ncp->nc_nlen;
509 cnp.cn_cred = ap->a_cred;
510 cnp.cn_td = td;
511 *ap->a_vpp = NULL;
512
e62afb5f 513 error = vop_old_lookup(ap->a_head.a_ops, dvp, ap->a_vpp, &cnp);
fad57d0e
MD
514
515 /*
516 * EJUSTRETURN should be returned for this case, which means that
517 * the VFS has setup the directory inode for the create. The dvp we
518 * passed in is expected to remain in a locked state.
519 *
520 * If the VOP_OLD_MKNOD is successful we are responsible for updating
521 * the cache state of the locked ncp that was passed to us.
522 */
523 if (error == EJUSTRETURN) {
524 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
525 error = VOP_OLD_MKNOD(dvp, ap->a_vpp, &cnp, ap->a_vap);
526 if (error == 0) {
28623bf9
MD
527 cache_setunresolved(nch);
528 cache_setvp(nch, *ap->a_vpp);
fad57d0e
MD
529 }
530 } else {
531 if (error == 0) {
532 vput(*ap->a_vpp);
533 *ap->a_vpp = NULL;
534 error = EEXIST;
535 }
536 KKASSERT(*ap->a_vpp == NULL);
537 }
538 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 539 vn_unlock(dvp);
fad57d0e
MD
540 vrele(dvp);
541 return (error);
542}
543
544/*
28623bf9 545 * vop_compat_nlink { struct nchandle *a_nch, XXX STOPGAP FUNCTION
dff430ab 546 * struct vnode *a_dvp,
fad57d0e
MD
547 * struct vnode *a_vp,
548 * struct ucred *a_cred }
549 *
550 * The passed vp is locked and represents the source. The passed ncp is
551 * locked and represents the target to create.
552 */
553int
554vop_compat_nlink(struct vop_nlink_args *ap)
555{
556 struct thread *td = curthread;
557 struct componentname cnp;
28623bf9 558 struct nchandle *nch;
fad57d0e
MD
559 struct namecache *ncp;
560 struct vnode *dvp;
561 struct vnode *tvp;
562 int error;
563
564 /*
565 * Sanity checks, get a locked directory vnode.
566 */
28623bf9
MD
567 nch = ap->a_nch; /* locked namecache node */
568 ncp = nch->ncp;
dff430ab 569 dvp = ap->a_dvp;
fad57d0e 570
87de5057 571 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 572 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
573 ncp, ncp->nc_name);
574 return(EAGAIN);
575 }
576
577 /*
e62afb5f 578 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
579 * caches all information required to create the entry in the
580 * directory inode. We expect a return code of EJUSTRETURN for
581 * the CREATE case. The cnp must simulated a saved-name situation.
582 */
583 bzero(&cnp, sizeof(cnp));
584 cnp.cn_nameiop = NAMEI_CREATE;
585 cnp.cn_flags = CNP_LOCKPARENT;
586 cnp.cn_nameptr = ncp->nc_name;
587 cnp.cn_namelen = ncp->nc_nlen;
588 cnp.cn_cred = ap->a_cred;
589 cnp.cn_td = td;
590
591 tvp = NULL;
e62afb5f 592 error = vop_old_lookup(ap->a_head.a_ops, dvp, &tvp, &cnp);
fad57d0e
MD
593
594 /*
595 * EJUSTRETURN should be returned for this case, which means that
596 * the VFS has setup the directory inode for the create. The dvp we
597 * passed in is expected to remain in a locked state.
598 *
599 * If the VOP_OLD_LINK is successful we are responsible for updating
600 * the cache state of the locked ncp that was passed to us.
601 */
602 if (error == EJUSTRETURN) {
603 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
604 error = VOP_OLD_LINK(dvp, ap->a_vp, &cnp);
605 if (error == 0) {
28623bf9
MD
606 cache_setunresolved(nch);
607 cache_setvp(nch, ap->a_vp);
fad57d0e
MD
608 }
609 } else {
610 if (error == 0) {
611 vput(tvp);
612 error = EEXIST;
613 }
614 }
615 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 616 vn_unlock(dvp);
fad57d0e
MD
617 vrele(dvp);
618 return (error);
619}
620
621int
622vop_compat_nsymlink(struct vop_nsymlink_args *ap)
623{
624 struct thread *td = curthread;
625 struct componentname cnp;
28623bf9 626 struct nchandle *nch;
fad57d0e
MD
627 struct namecache *ncp;
628 struct vnode *dvp;
629 struct vnode *vp;
630 int error;
631
632 /*
633 * Sanity checks, get a locked directory vnode.
634 */
635 *ap->a_vpp = NULL;
28623bf9
MD
636 nch = ap->a_nch; /* locked namecache node */
637 ncp = nch->ncp;
dff430ab 638 dvp = ap->a_dvp;
fad57d0e 639
87de5057 640 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 641 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
642 ncp, ncp->nc_name);
643 return(EAGAIN);
644 }
645
646 /*
e62afb5f 647 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
648 * caches all information required to create the entry in the
649 * directory inode. We expect a return code of EJUSTRETURN for
650 * the CREATE case. The cnp must simulated a saved-name situation.
651 */
652 bzero(&cnp, sizeof(cnp));
653 cnp.cn_nameiop = NAMEI_CREATE;
654 cnp.cn_flags = CNP_LOCKPARENT;
655 cnp.cn_nameptr = ncp->nc_name;
656 cnp.cn_namelen = ncp->nc_nlen;
657 cnp.cn_cred = ap->a_cred;
658 cnp.cn_td = td;
659
660 vp = NULL;
e62afb5f 661 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
fad57d0e
MD
662
663 /*
664 * EJUSTRETURN should be returned for this case, which means that
665 * the VFS has setup the directory inode for the create. The dvp we
666 * passed in is expected to remain in a locked state.
667 *
668 * If the VOP_OLD_SYMLINK is successful we are responsible for updating
669 * the cache state of the locked ncp that was passed to us.
670 */
671 if (error == EJUSTRETURN) {
672 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
673 error = VOP_OLD_SYMLINK(dvp, &vp, &cnp, ap->a_vap, ap->a_target);
674 if (error == 0) {
28623bf9
MD
675 cache_setunresolved(nch);
676 cache_setvp(nch, vp);
fad57d0e
MD
677 *ap->a_vpp = vp;
678 }
679 } else {
680 if (error == 0) {
681 vput(vp);
682 vp = NULL;
683 error = EEXIST;
684 }
685 KKASSERT(vp == NULL);
686 }
687 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 688 vn_unlock(dvp);
fad57d0e
MD
689 vrele(dvp);
690 return (error);
691}
692
693/*
28623bf9 694 * vop_compat_nwhiteout { struct nchandle *a_nch, XXX STOPGAP FUNCTION
dff430ab 695 * struct vnode *a_dvp,
fad57d0e
MD
696 * struct ucred *a_cred,
697 * int a_flags }
698 *
699 * Issie a whiteout operation (create, lookup, or delete). Compatibility
700 * requires us to issue the appropriate VOP_OLD_LOOKUP before we issue
701 * VOP_OLD_WHITEOUT in order to setup the directory inode's i_offset and i_count
702 * (e.g. in UFS) for the NAMEI_CREATE and NAMEI_DELETE ops. For NAMEI_LOOKUP
703 * no lookup is necessary.
704 */
705int
706vop_compat_nwhiteout(struct vop_nwhiteout_args *ap)
21739618 707{
fad57d0e
MD
708 struct thread *td = curthread;
709 struct componentname cnp;
28623bf9 710 struct nchandle *nch;
fad57d0e
MD
711 struct namecache *ncp;
712 struct vnode *dvp;
21739618 713 struct vnode *vp;
21739618
MD
714 int error;
715
fad57d0e
MD
716 /*
717 * Sanity checks, get a locked directory vnode.
718 */
28623bf9
MD
719 nch = ap->a_nch; /* locked namecache node */
720 ncp = nch->ncp;
dff430ab 721 dvp = ap->a_dvp;
21739618 722
87de5057 723 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 724 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
725 ncp, ncp->nc_name);
726 return(EAGAIN);
21739618 727 }
21739618
MD
728
729 /*
e62afb5f 730 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
731 * caches all information required to create the entry in the
732 * directory inode. We expect a return code of EJUSTRETURN for
733 * the CREATE case. The cnp must simulated a saved-name situation.
734 */
735 bzero(&cnp, sizeof(cnp));
736 cnp.cn_nameiop = ap->a_flags;
737 cnp.cn_flags = CNP_LOCKPARENT;
738 cnp.cn_nameptr = ncp->nc_name;
739 cnp.cn_namelen = ncp->nc_nlen;
740 cnp.cn_cred = ap->a_cred;
741 cnp.cn_td = td;
742
743 vp = NULL;
744
745 /*
746 * EJUSTRETURN should be returned for the CREATE or DELETE cases.
747 * The VFS has setup the directory inode for the create. The dvp we
748 * passed in is expected to remain in a locked state.
749 *
750 * If the VOP_OLD_WHITEOUT is successful we are responsible for updating
751 * the cache state of the locked ncp that was passed to us.
752 */
753 switch(ap->a_flags) {
754 case NAMEI_DELETE:
755 cnp.cn_flags |= CNP_DOWHITEOUT;
756 /* fall through */
757 case NAMEI_CREATE:
e62afb5f 758 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
fad57d0e
MD
759 if (error == EJUSTRETURN) {
760 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
761 error = VOP_OLD_WHITEOUT(dvp, &cnp, ap->a_flags);
762 if (error == 0)
28623bf9 763 cache_setunresolved(nch);
fad57d0e
MD
764 } else {
765 if (error == 0) {
766 vput(vp);
767 vp = NULL;
768 error = EEXIST;
769 }
770 KKASSERT(vp == NULL);
771 }
772 break;
773 case NAMEI_LOOKUP:
774 error = VOP_OLD_WHITEOUT(dvp, NULL, ap->a_flags);
775 break;
776 default:
777 error = EINVAL;
778 break;
779 }
780 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 781 vn_unlock(dvp);
fad57d0e
MD
782 vrele(dvp);
783 return (error);
784}
785
786
787/*
28623bf9 788 * vop_compat_nremove { struct nchandle *a_nch, XXX STOPGAP FUNCTION
dff430ab
MD
789 * struct vnode *a_dvp,
790 * struct ucred *a_cred }
fad57d0e
MD
791 */
792int
793vop_compat_nremove(struct vop_nremove_args *ap)
794{
795 struct thread *td = curthread;
796 struct componentname cnp;
28623bf9 797 struct nchandle *nch;
fad57d0e
MD
798 struct namecache *ncp;
799 struct vnode *dvp;
800 struct vnode *vp;
801 int error;
802
803 /*
804 * Sanity checks, get a locked directory vnode.
805 */
28623bf9
MD
806 nch = ap->a_nch; /* locked namecache node */
807 ncp = nch->ncp;
dff430ab 808 dvp = ap->a_dvp;
fad57d0e 809
87de5057 810 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 811 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
812 ncp, ncp->nc_name);
813 return(EAGAIN);
814 }
815
816 /*
e62afb5f 817 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
818 * caches all information required to delete the entry in the
819 * directory inode. We expect a return code of 0 for the DELETE
820 * case (meaning that a vp has been found). The cnp must simulated
821 * a saved-name situation.
822 */
823 bzero(&cnp, sizeof(cnp));
824 cnp.cn_nameiop = NAMEI_DELETE;
825 cnp.cn_flags = CNP_LOCKPARENT;
826 cnp.cn_nameptr = ncp->nc_name;
827 cnp.cn_namelen = ncp->nc_nlen;
828 cnp.cn_cred = ap->a_cred;
829 cnp.cn_td = td;
830
831 /*
832 * The vnode must be a directory and must not represent the
833 * current directory.
21739618 834 */
fad57d0e 835 vp = NULL;
e62afb5f 836 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
fad57d0e
MD
837 if (error == 0 && vp->v_type == VDIR)
838 error = EPERM;
b8997912 839 if (error == 0) {
fad57d0e 840 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
841 error = VOP_OLD_REMOVE(dvp, vp, &cnp);
842 if (error == 0) {
28623bf9
MD
843 cache_setunresolved(nch);
844 cache_setvp(nch, NULL);
bf40a153 845 cache_inval_vp(vp, CINV_DESTROY);
fad57d0e 846 }
b8997912 847 }
fad57d0e
MD
848 if (vp) {
849 if (dvp == vp)
850 vrele(vp);
851 else
852 vput(vp);
853 }
854 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 855 vn_unlock(dvp);
fad57d0e
MD
856 vrele(dvp);
857 return (error);
21739618
MD
858}
859
fad57d0e 860/*
28623bf9 861 * vop_compat_nrmdir { struct nchandle *a_nch, XXX STOPGAP FUNCTION
dff430ab
MD
862 * struct vnode *dvp,
863 * struct ucred *a_cred }
fad57d0e
MD
864 */
865int
866vop_compat_nrmdir(struct vop_nrmdir_args *ap)
867{
868 struct thread *td = curthread;
869 struct componentname cnp;
28623bf9 870 struct nchandle *nch;
fad57d0e
MD
871 struct namecache *ncp;
872 struct vnode *dvp;
873 struct vnode *vp;
874 int error;
21739618 875
fad57d0e
MD
876 /*
877 * Sanity checks, get a locked directory vnode.
878 */
28623bf9
MD
879 nch = ap->a_nch; /* locked namecache node */
880 ncp = nch->ncp;
dff430ab 881 dvp = ap->a_dvp;
fad57d0e 882
87de5057 883 if ((error = vget(dvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 884 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
885 ncp, ncp->nc_name);
886 return(EAGAIN);
887 }
888
889 /*
e62afb5f 890 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
891 * caches all information required to delete the entry in the
892 * directory inode. We expect a return code of 0 for the DELETE
893 * case (meaning that a vp has been found). The cnp must simulated
894 * a saved-name situation.
895 */
896 bzero(&cnp, sizeof(cnp));
897 cnp.cn_nameiop = NAMEI_DELETE;
898 cnp.cn_flags = CNP_LOCKPARENT;
899 cnp.cn_nameptr = ncp->nc_name;
900 cnp.cn_namelen = ncp->nc_nlen;
901 cnp.cn_cred = ap->a_cred;
902 cnp.cn_td = td;
903
904 /*
905 * The vnode must be a directory and must not represent the
906 * current directory.
907 */
908 vp = NULL;
e62afb5f 909 error = vop_old_lookup(ap->a_head.a_ops, dvp, &vp, &cnp);
fad57d0e
MD
910 if (error == 0 && vp->v_type != VDIR)
911 error = ENOTDIR;
912 if (error == 0 && vp == dvp)
913 error = EINVAL;
914 if (error == 0 && (vp->v_flag & VROOT))
915 error = EBUSY;
916 if (error == 0) {
917 KKASSERT((cnp.cn_flags & CNP_PDIRUNLOCK) == 0);
fad57d0e
MD
918 error = VOP_OLD_RMDIR(dvp, vp, &cnp);
919
920 /*
921 * Note that this invalidation will cause any process
922 * currently CD'd into the directory being removed to be
923 * disconnected from the topology and not be able to ".."
924 * back out.
925 */
bf40a153 926 if (error == 0) {
28623bf9 927 cache_inval(nch, CINV_DESTROY);
bf40a153
MD
928 cache_inval_vp(vp, CINV_DESTROY);
929 }
fad57d0e
MD
930 }
931 if (vp) {
932 if (dvp == vp)
933 vrele(vp);
934 else
935 vput(vp);
936 }
937 if ((cnp.cn_flags & CNP_PDIRUNLOCK) == 0)
a11aaa81 938 vn_unlock(dvp);
fad57d0e
MD
939 vrele(dvp);
940 return (error);
941}
942
943/*
28623bf9
MD
944 * vop_compat_nrename { struct nchandle *a_fnch, XXX STOPGAP FUNCTION
945 * struct nchandle *a_tnch,
fad57d0e
MD
946 * struct ucred *a_cred }
947 *
948 * This is a fairly difficult procedure. The old VOP_OLD_RENAME requires that
949 * the source directory and vnode be unlocked and the target directory and
950 * vnode (if it exists) be locked. All arguments will be vrele'd and
951 * the targets will also be unlocked regardless of the return code.
952 */
953int
954vop_compat_nrename(struct vop_nrename_args *ap)
955{
956 struct thread *td = curthread;
957 struct componentname fcnp;
958 struct componentname tcnp;
28623bf9
MD
959 struct nchandle *fnch;
960 struct nchandle *tnch;
fad57d0e
MD
961 struct namecache *fncp;
962 struct namecache *tncp;
963 struct vnode *fdvp, *fvp;
964 struct vnode *tdvp, *tvp;
965 int error;
966
967 /*
968 * Sanity checks, get referenced vnodes representing the source.
969 */
28623bf9
MD
970 fnch = ap->a_fnch; /* locked namecache node */
971 fncp = fnch->ncp;
dff430ab 972 fdvp = ap->a_fdvp;
fad57d0e
MD
973
974 /*
975 * Temporarily lock the source directory and lookup in DELETE mode to
976 * check permissions. XXX delete permissions should have been
977 * checked by nlookup(), we need to add NLC_DELETE for delete
978 * checking. It is unclear whether VFS's require the directory setup
979 * info NAMEI_DELETE causes to be stored in the fdvp's inode, but
980 * since it isn't locked and since UFS always does a relookup of
981 * the source, it is believed that the only side effect that matters
982 * is the permissions check.
983 */
87de5057 984 if ((error = vget(fdvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 985 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
986 fncp, fncp->nc_name);
987 return(EAGAIN);
988 }
989
990 bzero(&fcnp, sizeof(fcnp));
991 fcnp.cn_nameiop = NAMEI_DELETE;
992 fcnp.cn_flags = CNP_LOCKPARENT;
993 fcnp.cn_nameptr = fncp->nc_name;
994 fcnp.cn_namelen = fncp->nc_nlen;
995 fcnp.cn_cred = ap->a_cred;
996 fcnp.cn_td = td;
997
998 /*
e62afb5f 999 * note: vop_old_lookup (i.e. VOP_OLD_LOOKUP) always returns a locked
fad57d0e
MD
1000 * fvp.
1001 */
1002 fvp = NULL;
e62afb5f 1003 error = vop_old_lookup(ap->a_head.a_ops, fdvp, &fvp, &fcnp);
fad57d0e 1004 if (error == 0 && (fvp->v_flag & VROOT)) {
e62afb5f 1005 vput(fvp); /* as if vop_old_lookup had failed */
fad57d0e
MD
1006 error = EBUSY;
1007 }
1008 if ((fcnp.cn_flags & CNP_PDIRUNLOCK) == 0) {
1009 fcnp.cn_flags |= CNP_PDIRUNLOCK;
a11aaa81 1010 vn_unlock(fdvp);
fad57d0e
MD
1011 }
1012 if (error) {
1013 vrele(fdvp);
1014 return (error);
1015 }
a11aaa81 1016 vn_unlock(fvp);
fad57d0e
MD
1017
1018 /*
1019 * fdvp and fvp are now referenced and unlocked.
1020 *
1021 * Get a locked directory vnode for the target and lookup the target
1022 * in CREATE mode so it places the required information in the
1023 * directory inode.
1024 */
28623bf9
MD
1025 tnch = ap->a_tnch; /* locked namecache node */
1026 tncp = tnch->ncp;
dff430ab 1027 tdvp = ap->a_tdvp;
fad57d0e
MD
1028 if (error) {
1029 vrele(fdvp);
1030 vrele(fvp);
1031 return (error);
1032 }
87de5057 1033 if ((error = vget(tdvp, LK_EXCLUSIVE)) != 0) {
6ea70f76 1034 kprintf("[diagnostic] vop_compat_resolve: EAGAIN on ncp %p %s\n",
fad57d0e
MD
1035 tncp, tncp->nc_name);
1036 vrele(fdvp);
1037 vrele(fvp);
1038 return(EAGAIN);
1039 }
1040
1041 /*
e62afb5f 1042 * Setup the cnp for a traditional vop_old_lookup() call. The lookup
fad57d0e
MD
1043 * caches all information required to create the entry in the
1044 * target directory inode.
1045 */
1046 bzero(&tcnp, sizeof(tcnp));
1047 tcnp.cn_nameiop = NAMEI_RENAME;
1048 tcnp.cn_flags = CNP_LOCKPARENT;
1049 tcnp.cn_nameptr = tncp->nc_name;
1050 tcnp.cn_namelen = tncp->nc_nlen;
1051 tcnp.cn_cred = ap->a_cred;
1052 tcnp.cn_td = td;
1053
1054 tvp = NULL;
e62afb5f 1055 error = vop_old_lookup(ap->a_head.a_ops, tdvp, &tvp, &tcnp);
fad57d0e
MD
1056
1057 if (error == EJUSTRETURN) {
1058 /*
1059 * Target does not exist. tvp should be NULL.
1060 */
1061 KKASSERT(tvp == NULL);
1062 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1063 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
227cf16d 1064 if (error == 0)
28623bf9 1065 cache_rename(fnch, tnch);
fad57d0e
MD
1066 } else if (error == 0) {
1067 /*
1068 * Target exists. VOP_OLD_RENAME should correctly delete the
1069 * target.
1070 */
1071 KKASSERT((tcnp.cn_flags & CNP_PDIRUNLOCK) == 0);
1072 error = VOP_OLD_RENAME(fdvp, fvp, &fcnp, tdvp, tvp, &tcnp);
227cf16d 1073 if (error == 0)
28623bf9 1074 cache_rename(fnch, tnch);
fad57d0e
MD
1075 } else {
1076 vrele(fdvp);
1077 vrele(fvp);
1078 if (tcnp.cn_flags & CNP_PDIRUNLOCK)
1079 vrele(tdvp);
1080 else
1081 vput(tdvp);
1082 }
1083 return (error);
1084}
21739618 1085
984263bc 1086static int
c972a82f 1087vop_nolookup(struct vop_old_lookup_args *ap)
984263bc
MD
1088{
1089
1090 *ap->a_vpp = NULL;
1091 return (ENOTDIR);
1092}
1093
1094/*
1095 * vop_nostrategy:
1096 *
1097 * Strategy routine for VFS devices that have none.
1098 *
1099 * B_ERROR and B_INVAL must be cleared prior to calling any strategy
10f3fee5
MD
1100 * routine. Typically this is done for a BUF_CMD_READ strategy call.
1101 * Typically B_INVAL is assumed to already be clear prior to a write
1102 * and should not be cleared manually unless you just made the buffer
1103 * invalid. B_ERROR should be cleared either way.
984263bc
MD
1104 */
1105
1106static int
1107vop_nostrategy (struct vop_strategy_args *ap)
1108{
6ea70f76 1109 kprintf("No strategy for buffer at %p\n", ap->a_bio->bio_buf);
984263bc 1110 vprint("", ap->a_vp);
81b5c339
MD
1111 ap->a_bio->bio_buf->b_flags |= B_ERROR;
1112 ap->a_bio->bio_buf->b_error = EOPNOTSUPP;
1113 biodone(ap->a_bio);
984263bc
MD
1114 return (EOPNOTSUPP);
1115}
1116
1117int
c972a82f 1118vop_stdpathconf(struct vop_pathconf_args *ap)
984263bc 1119{
27469235 1120 int error = 0;
984263bc
MD
1121
1122 switch (ap->a_name) {
27469235
MD
1123 case _PC_LINK_MAX:
1124 *ap->a_retval = LINK_MAX;
1125 break;
1126 case _PC_NAME_MAX:
1127 *ap->a_retval = NAME_MAX;
1128 break;
1129 case _PC_PATH_MAX:
1130 *ap->a_retval = PATH_MAX;
1131 break;
1132 case _PC_MAX_CANON:
1133 *ap->a_retval = MAX_CANON;
1134 break;
1135 case _PC_MAX_INPUT:
1136 *ap->a_retval = MAX_INPUT;
1137 break;
1138 case _PC_PIPE_BUF:
1139 *ap->a_retval = PIPE_BUF;
1140 break;
1141 case _PC_CHOWN_RESTRICTED:
1142 *ap->a_retval = 1;
1143 break;
1144 case _PC_NO_TRUNC:
1145 *ap->a_retval = 1;
1146 break;
1147 case _PC_VDISABLE:
1148 *ap->a_retval = _POSIX_VDISABLE;
1149 break;
1150 default:
1151 error = EINVAL;
1152 break;
984263bc 1153 }
27469235 1154 return (error);
984263bc
MD
1155}
1156
8ddc6004
MD
1157/*
1158 * Standard open.
1159 *
b478fdce 1160 * (struct vnode *a_vp, int a_mode, struct ucred *a_ucred, struct file *a_fp)
8ddc6004
MD
1161 *
1162 * a_mode: note, 'F' modes, e.g. FREAD, FWRITE
1163 */
1164int
1165vop_stdopen(struct vop_open_args *ap)
1166{
1167 struct vnode *vp = ap->a_vp;
1168 struct file *fp;
1169
1170 if ((fp = ap->a_fp) != NULL) {
1171 switch(vp->v_type) {
1172 case VFIFO:
1173 fp->f_type = DTYPE_FIFO;
1174 break;
1175 default:
1176 fp->f_type = DTYPE_VNODE;
1177 break;
1178 }
1179 fp->f_flag = ap->a_mode & FMASK;
1180 fp->f_ops = &vnode_fileops;
1181 fp->f_data = vp;
1182 vref(vp);
1183 }
1184 if (ap->a_mode & FWRITE)
1185 ++vp->v_writecount;
1186 KKASSERT(vp->v_opencount >= 0 && vp->v_opencount != INT_MAX);
1187 ++vp->v_opencount;
1188 return (0);
1189}
1190
1191/*
1192 * Standard close.
1193 *
b478fdce 1194 * (struct vnode *a_vp, int a_fflag)
8ddc6004
MD
1195 *
1196 * a_fflag: note, 'F' modes, e.g. FREAD, FWRITE. same as a_mode in stdopen?
1197 */
1198int
1199vop_stdclose(struct vop_close_args *ap)
1200{
1201 struct vnode *vp = ap->a_vp;
1202
1203 KASSERT(vp->v_opencount > 0,
a2a3460a
MD
1204 ("VOP_STDCLOSE: BAD OPENCOUNT %p %d type=%d ops=%p flgs=%08x\n",
1205 vp, vp->v_opencount, vp->v_type, *vp->v_ops, vp->v_flag));
8ddc6004
MD
1206 if (ap->a_fflag & FWRITE) {
1207 KASSERT(vp->v_writecount > 0,
1208 ("VOP_STDCLOSE: BAD WRITECOUNT %p %d\n",
1209 vp, vp->v_writecount));
1210 --vp->v_writecount;
1211 }
1212 --vp->v_opencount;
1213 return (0);
1214}
1215
1787385d
MD
1216/*
1217 * Implement standard getpages and putpages. All filesystems must use
1218 * the buffer cache to back regular files.
1219 */
1220int
1221vop_stdgetpages(struct vop_getpages_args *ap)
1222{
1223 struct mount *mp;
1224 int error;
1225
1226 if ((mp = ap->a_vp->v_mount) != NULL) {
1227 error = vnode_pager_generic_getpages(
1228 ap->a_vp, ap->a_m, ap->a_count,
1c48c952 1229 ap->a_reqpage, ap->a_seqaccess);
1787385d
MD
1230 } else {
1231 error = VM_PAGER_BAD;
1232 }
1233 return (error);
1234}
1235
1236int
1237vop_stdputpages(struct vop_putpages_args *ap)
1238{
1239 struct mount *mp;
1240 int error;
1241
1242 if ((mp = ap->a_vp->v_mount) != NULL) {
1243 error = vnode_pager_generic_putpages(
1244 ap->a_vp, ap->a_m, ap->a_count,
1245 ap->a_sync, ap->a_rtvals);
1246 } else {
1247 error = VM_PAGER_BAD;
1248 }
1249 return (error);
1250}
1251
aec8eea4
MD
1252int
1253vop_stdnoread(struct vop_read_args *ap)
1254{
1255 return (EINVAL);
1256}
1257
1258int
1259vop_stdnowrite(struct vop_write_args *ap)
1260{
1261 return (EINVAL);
1262}
1263
984263bc
MD
1264/*
1265 * vfs default ops
1266 * used to fill the vfs fucntion table to get reasonable default return values.
1267 */
1268int
acde96db 1269vfs_stdmount(struct mount *mp, char *path, caddr_t data, struct ucred *cred)
984263bc
MD
1270{
1271 return (0);
1272}
1273
1274int
acde96db 1275vfs_stdunmount(struct mount *mp, int mntflags)
984263bc
MD
1276{
1277 return (0);
1278}
1279
177403a9
MD
1280int
1281vop_stdmountctl(struct vop_mountctl_args *ap)
1282{
1283
1284 struct mount *mp;
1285 int error = 0;
1286
1287 mp = ap->a_head.a_ops->head.vv_mount;
1288
1289 switch(ap->a_op) {
1290 case MOUNTCTL_MOUNTFLAGS:
1291 /*
1292 * Get a string buffer with all the mount flags
1293 * names comman separated.
1294 * mount(2) will use this information.
1295 */
dad088a5
MD
1296 *ap->a_res = vfs_flagstostr(mp->mnt_flag & MNT_VISFLAGMASK, NULL,
1297 ap->a_buf, ap->a_buflen, &error);
177403a9
MD
1298 break;
1299 case MOUNTCTL_INSTALL_VFS_JOURNAL:
1300 case MOUNTCTL_RESTART_VFS_JOURNAL:
1301 case MOUNTCTL_REMOVE_VFS_JOURNAL:
1302 case MOUNTCTL_RESYNC_VFS_JOURNAL:
1303 case MOUNTCTL_STATUS_VFS_JOURNAL:
1304 error = journal_mountctl(ap);
1305 break;
1306 default:
1307 error = EOPNOTSUPP;
1308 break;
1309 }
1310 return (error);
1311}
1312
984263bc 1313int
dadab5e9 1314vfs_stdroot(struct mount *mp, struct vnode **vpp)
984263bc
MD
1315{
1316 return (EOPNOTSUPP);
1317}
1318
1319int
acde96db 1320vfs_stdstatfs(struct mount *mp, struct statfs *sbp, struct ucred *cred)
984263bc
MD
1321{
1322 return (EOPNOTSUPP);
1323}
1324
d9fad06e
MD
1325/*
1326 * If the VFS does not implement statvfs, then call statfs and convert
1327 * the values. This code was taken from libc's __cvtstatvfs() function,
1328 * contributed by Joerg Sonnenberger.
1329 */
1330int
1331vfs_stdstatvfs(struct mount *mp, struct statvfs *sbp, struct ucred *cred)
1332{
1333 struct statfs *in;
1334 int error;
1335
1336 in = &mp->mnt_stat;
1337 error = VFS_STATFS(mp, in, cred);
1338 if (error == 0) {
1339 bzero(sbp, sizeof(*sbp));
1340
1341 sbp->f_bsize = in->f_bsize;
1342 sbp->f_frsize = in->f_bsize;
1343 sbp->f_blocks = in->f_blocks;
1344 sbp->f_bfree = in->f_bfree;
1345 sbp->f_bavail = in->f_bavail;
1346 sbp->f_files = in->f_files;
1347 sbp->f_ffree = in->f_ffree;
1348
1349 /*
1350 * XXX
1351 * This field counts the number of available inodes to non-root
1352 * users, but this information is not available via statfs.
1353 * Just ignore this issue by returning the total number
1354 * instead.
1355 */
1356 sbp->f_favail = in->f_ffree;
1357
1358 /*
1359 * XXX
1360 * This field has a different meaning for statfs and statvfs.
1361 * For the former it is the cookie exported for NFS and not
1362 * intended for normal userland use.
1363 */
1364 sbp->f_fsid = 0;
1365
1366 sbp->f_flag = 0;
1367 if (in->f_flags & MNT_RDONLY)
1368 sbp->f_flag |= ST_RDONLY;
1369 if (in->f_flags & MNT_NOSUID)
1370 sbp->f_flag |= ST_NOSUID;
1371 sbp->f_namemax = 0;
1372 sbp->f_owner = in->f_owner;
1373 /*
1374 * XXX
1375 * statfs contains the type as string, statvfs expects it as
1376 * enumeration.
1377 */
1378 sbp->f_type = 0;
1379
1380 sbp->f_syncreads = in->f_syncreads;
1381 sbp->f_syncwrites = in->f_syncwrites;
1382 sbp->f_asyncreads = in->f_asyncreads;
1383 sbp->f_asyncwrites = in->f_asyncwrites;
1384 }
1385 return (error);
1386}
1387
984263bc 1388int
dadab5e9 1389vfs_stdvptofh(struct vnode *vp, struct fid *fhp)
984263bc
MD
1390{
1391 return (EOPNOTSUPP);
1392}
1393
1394int
acde96db 1395vfs_stdstart(struct mount *mp, int flags)
984263bc
MD
1396{
1397 return (0);
1398}
1399
1400int
dadab5e9 1401vfs_stdquotactl(struct mount *mp, int cmds, uid_t uid,
acde96db 1402 caddr_t arg, struct ucred *cred)
984263bc
MD
1403{
1404 return (EOPNOTSUPP);
1405}
1406
1407int
87de5057 1408vfs_stdsync(struct mount *mp, int waitfor)
984263bc
MD
1409{
1410 return (0);
1411}
1412
43c45e8f 1413int
87de5057 1414vfs_stdnosync(struct mount *mp, int waitfor)
43c45e8f
HP
1415{
1416 return (EOPNOTSUPP);
1417}
1418
984263bc 1419int
b9b0a6d0 1420vfs_stdvget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp)
984263bc
MD
1421{
1422 return (EOPNOTSUPP);
1423}
1424
1425int
67863d04
MD
1426vfs_stdfhtovp(struct mount *mp, struct vnode *rootvp,
1427 struct fid *fhp, struct vnode **vpp)
984263bc
MD
1428{
1429 return (EOPNOTSUPP);
1430}
1431
1432int
dadab5e9
MD
1433vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp,
1434 struct ucred **credanonp)
984263bc
MD
1435{
1436 return (EOPNOTSUPP);
1437}
1438
1439int
dadab5e9 1440vfs_stdinit(struct vfsconf *vfsp)
984263bc
MD
1441{
1442 return (0);
1443}
1444
1445int
dadab5e9 1446vfs_stduninit(struct vfsconf *vfsp)
984263bc
MD
1447{
1448 return(0);
1449}
1450
1451int
0f6997f9
MD
1452vfs_stdextattrctl(struct mount *mp, int cmd, struct vnode *vp,
1453 int attrnamespace, const char *attrname,
1454 struct ucred *cred)
984263bc
MD
1455{
1456 return(EOPNOTSUPP);
1457}
1458
1459/* end of vfs default ops */