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