2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sys/vfs/userfs/userfs_vnops.c,v 1.4 2007/11/20 21:03:51 dillon Exp $
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
40 #include <sys/fcntl.h>
41 #include <sys/namecache.h>
42 #include <sys/vnode.h>
43 #include <sys/lockf.h>
44 #include <sys/event.h>
46 #include <sys/syslink.h>
47 #include <sys/syslink_vfs.h>
48 #include <sys/unistd.h>
49 #include <vm/vnode_pager.h>
55 /*static int user_vop_vnoperate(struct vop_generic_args *);*/
56 static int user_vop_fsync (struct vop_fsync_args
*);
57 static int user_vop_read (struct vop_read_args
*);
58 static int user_vop_write (struct vop_write_args
*);
59 static int user_vop_access (struct vop_access_args
*);
60 static int user_vop_advlock (struct vop_advlock_args
*);
61 static int user_vop_close (struct vop_close_args
*);
62 static int user_vop_ncreate (struct vop_ncreate_args
*);
63 static int user_vop_getattr (struct vop_getattr_args
*);
64 static int user_vop_nresolve (struct vop_nresolve_args
*);
65 static int user_vop_nlookupdotdot (struct vop_nlookupdotdot_args
*);
66 static int user_vop_nlink (struct vop_nlink_args
*);
67 static int user_vop_nmkdir (struct vop_nmkdir_args
*);
68 static int user_vop_nmknod (struct vop_nmknod_args
*);
69 static int user_vop_open (struct vop_open_args
*);
70 static int user_vop_pathconf (struct vop_pathconf_args
*);
71 static int user_vop_print (struct vop_print_args
*);
72 static int user_vop_readdir (struct vop_readdir_args
*);
73 static int user_vop_readlink (struct vop_readlink_args
*);
74 static int user_vop_nremove (struct vop_nremove_args
*);
75 static int user_vop_nrename (struct vop_nrename_args
*);
76 static int user_vop_nrmdir (struct vop_nrmdir_args
*);
77 static int user_vop_setattr (struct vop_setattr_args
*);
78 static int user_vop_strategy (struct vop_strategy_args
*);
79 static int user_vop_nsymlink (struct vop_nsymlink_args
*);
80 static int user_vop_nwhiteout (struct vop_nwhiteout_args
*);
81 static int user_vop_bmap (struct vop_bmap_args
*);
83 struct vop_ops userfs_vnode_vops
= {
84 .vop_default
= vop_defaultop
,
85 .vop_fsync
= user_vop_fsync
,
86 .vop_getpages
= vop_stdgetpages
,
87 .vop_putpages
= vop_stdputpages
,
88 .vop_read
= user_vop_read
,
89 .vop_write
= user_vop_write
,
90 .vop_access
= user_vop_access
,
91 .vop_advlock
= user_vop_advlock
,
92 .vop_close
= user_vop_close
,
93 .vop_ncreate
= user_vop_ncreate
,
94 .vop_getattr
= user_vop_getattr
,
95 .vop_inactive
= user_vop_inactive
,
96 .vop_reclaim
= user_vop_reclaim
,
97 .vop_nresolve
= user_vop_nresolve
,
98 .vop_nlookupdotdot
= user_vop_nlookupdotdot
,
99 .vop_nlink
= user_vop_nlink
,
100 .vop_nmkdir
= user_vop_nmkdir
,
101 .vop_nmknod
= user_vop_nmknod
,
102 .vop_open
= user_vop_open
,
103 .vop_pathconf
= user_vop_pathconf
,
104 .vop_print
= user_vop_print
,
105 .vop_readdir
= user_vop_readdir
,
106 .vop_readlink
= user_vop_readlink
,
107 .vop_nremove
= user_vop_nremove
,
108 .vop_nrename
= user_vop_nrename
,
109 .vop_nrmdir
= user_vop_nrmdir
,
110 .vop_setattr
= user_vop_setattr
,
111 .vop_strategy
= user_vop_strategy
,
112 .vop_nsymlink
= user_vop_nsymlink
,
113 .vop_nwhiteout
= user_vop_nwhiteout
,
114 .vop_bmap
= user_vop_bmap
120 user_vop_vnoperate(struct vop_generic_args
*)
122 return (VOCALL(&userfs_vnode_vops
, ap
));
127 * vop_fsync(struct vnode *vp, int waitfor)
131 user_vop_fsync (struct vop_fsync_args
*ap
)
133 struct user_mount
*ump
;
134 struct user_inode
*ip
;
144 slmsg
= syslink_kallocmsg();
145 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
146 SLVFS_CMD_VOP_FSYNC
);
147 user_elm_push_vnode(par
, ap
->a_vp
);
148 sl_msg_fini(slmsg
->msg
);
150 kprintf("userfs_fsync\n");
151 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
152 par
= &slmsg
->rep
->msg
->sm_head
;
154 if (par
->se_cmd
== (SLVFS_CMD_VOP_FSYNC
|SE_CMDF_REPLY
)) {
160 syslink_kfreemsg(ump
->sldesc
, slmsg
);
161 kprintf("error %d\n", error
);
166 * vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
170 user_vop_read (struct vop_read_args
*ap
)
172 struct user_mount
*ump
;
173 struct user_inode
*ip
;
186 if (uio
->uio_offset
< 0)
188 if (vp
->v_type
!= VREG
)
191 kprintf("userfs_read\n");
193 while (uio
->uio_resid
> 0 && uio
->uio_offset
< ip
->filesize
) {
195 * Use buffer cache I/O (via user_vop_strategy), aligned
196 * on USERFS_BSIZE boundaries.
198 offset
= (int)uio
->uio_offset
& USERFS_BMASK
;
199 error
= bread(vp
, uio
->uio_offset
- offset
, USERFS_BSIZE
, &bp
);
206 * Figure out how many bytes we can actually copy this loop.
208 n
= USERFS_BSIZE
- offset
;
209 if (n
> uio
->uio_resid
)
211 if (n
> ip
->filesize
- uio
->uio_offset
)
212 n
= (int)(ip
->filesize
- uio
->uio_offset
);
214 error
= uiomove((char *)bp
->b_data
+ offset
, n
, uio
);
219 kprintf("userfs_read error %d\n", error
);
224 * vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
228 user_vop_write (struct vop_write_args
*ap
)
230 struct user_mount
*ump
;
231 struct user_inode
*ip
;
244 if (vp
->v_type
!= VREG
)
246 if (ap
->a_ioflag
& IO_APPEND
)
247 uio
->uio_offset
= ip
->filesize
;
250 * Check for illegal write offsets. Valid range is 0...2^63-1
252 if (uio
->uio_offset
< 0 || uio
->uio_offset
+ uio
->uio_resid
<= 0)
255 kprintf("userfs_write\n");
257 while (uio
->uio_resid
> 0) {
259 * Use buffer cache I/O (via user_vop_strategy), aligned
260 * on USERFS_BSIZE boundaries.
262 * XXX not optimized for complete write-overs or file
263 * extensions. Note: must bread on UIO_NOCOPY writes.
265 * XXX No need to read if strictly appending.
267 offset
= (int)uio
->uio_offset
& USERFS_BMASK
;
268 /* if offset == ip->filesize use getblk instead */
269 error
= bread(vp
, uio
->uio_offset
- offset
, USERFS_BSIZE
, &bp
);
276 * Figure out how many bytes we can actually copy this loop.
278 n
= USERFS_BSIZE
- offset
;
279 if (n
> uio
->uio_resid
)
281 if (n
> ip
->filesize
- uio
->uio_offset
)
282 n
= (int)(ip
->filesize
- uio
->uio_offset
);
284 error
= uiomove((char *)bp
->b_data
+ offset
, n
, uio
);
291 * Extend the file's size if necessary
293 if (ip
->filesize
< uio
->uio_offset
)
294 ip
->filesize
= uio
->uio_offset
;
297 * The data has been loaded into the buffer, write it out.
299 if (ap
->a_ioflag
& IO_SYNC
) {
301 } else if (ap
->a_ioflag
& IO_DIRECT
) {
302 bp
->b_flags
|= B_CLUSTEROK
;
305 bp
->b_flags
|= B_CLUSTEROK
;
309 kprintf("userfs_write error %d\n", error
);
314 * vop_access(struct vnode *vp, int mode, struct ucred *cred)
318 user_vop_access (struct vop_access_args
*ap
)
320 struct user_mount
*ump
;
321 struct user_inode
*ip
;
331 slmsg
= syslink_kallocmsg();
332 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
333 SLVFS_CMD_VOP_ACCESS
);
334 user_elm_push_vnode(par
, vp
);
335 user_elm_push_mode(par
, ap
->a_mode
);
336 user_elm_push_cred(par
, ap
->a_cred
);
337 sl_msg_fini(slmsg
->msg
);
340 * Issue the request and do basic validation of the response
342 kprintf("userfs_access\n");
343 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
345 par
= &slmsg
->rep
->msg
->sm_head
;
346 if (par
->se_cmd
!= (SLVFS_CMD_VOP_ACCESS
|SE_CMDF_REPLY
)) {
352 syslink_kfreemsg(ump
->sldesc
, slmsg
);
353 kprintf("error %d\n", error
);
358 * vop_advlock(struct vnode *vp, caddr_t id, int op, struct flock *fl,
361 * This vop is handled directly by the kernel.
365 user_vop_advlock (struct vop_advlock_args
*ap
)
367 struct user_inode
*ip
;
373 return (lf_advlock(ap
, &ip
->lockf
, ip
->filesize
));
377 * vop_open(struct vnode *vp, int mode, struct ucred *cred, struct file *file)
379 * This vop is handled directly by the kernel.
383 user_vop_open (struct vop_open_args
*ap
)
385 return (vop_stdopen(ap
));
389 * vop_close(struct vnode *vp, int fflag)
391 * This vop is handled directly by the kernel.
395 user_vop_close (struct vop_close_args
*ap
)
397 return (vop_stdclose(ap
));
401 * vop_getattr(struct vnode *vp, struct vattr *vap)
405 user_vop_getattr (struct vop_getattr_args
*ap
)
407 struct user_mount
*ump
;
408 struct user_inode
*ip
;
419 slmsg
= syslink_kallocmsg();
420 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
421 SLVFS_CMD_VOP_GETATTR
);
422 sl_msg_fini(slmsg
->msg
);
424 kprintf("userfs_getattr\n");
425 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
427 par
= &slmsg
->rep
->msg
->sm_head
;
428 if (par
->se_cmd
!= (SLVFS_CMD_VOP_GETATTR
|SE_CMDF_REPLY
)) {
434 * Parse reply content
436 SL_FOREACH_ELEMENT(par
, elm
) {
437 switch(elm
->se_cmd
) {
438 case SLVFS_ELM_VATTR
:
439 error
= user_elm_parse_vattr(elm
, ap
->a_vap
);
448 syslink_kfreemsg(ump
->sldesc
, slmsg
);
449 kprintf("error %d\n", error
);
454 * vop_pathconf(int name, int *retval)
456 * This vop is handled directly by the kernel.
460 user_vop_pathconf (struct vop_pathconf_args
*ap
)
466 *ap
->a_retval
= LINK_MAX
;
469 *ap
->a_retval
= MAX_CANON
;
472 *ap
->a_retval
= MAX_INPUT
;
475 *ap
->a_retval
= PIPE_BUF
;
477 case _PC_CHOWN_RESTRICTED
:
481 *ap
->a_retval
= _POSIX_VDISABLE
;
491 * vop_print(int name, int *retval)
493 * This vop is handled directly by the kernel.
497 user_vop_print (struct vop_print_args
*ap
)
503 * vop_readdir(struct vnode *vp, struct uio *uio, struct ucred *cred,
504 * int *eofflag, int *ncookies, off_t **a_cookies)
508 user_vop_readdir (struct vop_readdir_args
*ap
)
510 struct user_mount
*ump
;
511 struct user_inode
*ip
;
521 slmsg
= syslink_kallocmsg();
522 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
523 SLVFS_CMD_VOP_READDIR
);
524 sl_msg_fini(slmsg
->msg
);
526 kprintf("userfs_readdir\n");
527 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
528 par
= &slmsg
->rep
->msg
->sm_head
;
530 if (par
->se_cmd
== (SLVFS_CMD_VOP_READDIR
|SE_CMDF_REPLY
)) {
536 syslink_kfreemsg(ump
->sldesc
, slmsg
);
537 kprintf("error %d\n", error
);
542 * vop_readlink(struct vnode *vp, struct uio *uio, struct ucred *cred)
546 user_vop_readlink (struct vop_readlink_args
*ap
)
548 struct user_mount
*ump
;
549 struct user_inode
*ip
;
559 slmsg
= syslink_kallocmsg();
560 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
561 SLVFS_CMD_VOP_READLINK
);
562 sl_msg_fini(slmsg
->msg
);
564 kprintf("userfs_readlink\n");
565 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
566 par
= &slmsg
->rep
->msg
->sm_head
;
568 if (par
->se_cmd
== (SLVFS_CMD_VOP_READLINK
|SE_CMDF_REPLY
)) {
574 syslink_kfreemsg(ump
->sldesc
, slmsg
);
575 kprintf("error %d\n", error
);
580 * vop_setattr(struct vnode *vp, struct vattr *vap, struct ucred *cred)
584 user_vop_setattr (struct vop_setattr_args
*ap
)
586 struct user_mount
*ump
;
587 struct user_inode
*ip
;
597 slmsg
= syslink_kallocmsg();
598 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
599 SLVFS_CMD_VOP_SETATTR
);
600 sl_msg_fini(slmsg
->msg
);
602 kprintf("userfs_setattr\n");
603 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
604 par
= &slmsg
->rep
->msg
->sm_head
;
606 if (par
->se_cmd
== (SLVFS_CMD_VOP_SETATTR
|SE_CMDF_REPLY
)) {
612 syslink_kfreemsg(ump
->sldesc
, slmsg
);
613 kprintf("error %d\n", error
);
618 * user_vop_strategy() - I/O strategy routine.
620 * Note that userfs interfaces fake-up BMAP so the strategy call just
621 * uses the passed bio instead of pushing a bio to get to the (faked)
622 * device block cache.
624 static void user_strategy_callback(struct slmsg
*msg
, void *arg
, int error
);
628 user_vop_strategy (struct vop_strategy_args
*ap
)
630 struct user_mount
*ump
;
631 struct user_inode
*ip
;
645 bio
->bio_driver_info
= ump
;
647 slmsg
= syslink_kallocmsg();
650 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
651 SLVFS_CMD_VOP_STRATEGY_READ
);
654 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
655 SLVFS_CMD_VOP_STRATEGY_WRITE
);
658 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
659 SLVFS_CMD_VOP_STRATEGY_MISC
);
662 user_elm_push_vnode(par
, vp
);
663 user_elm_push_offset(par
, bio
->bio_offset
);
664 user_elm_push_bio(par
, bp
->b_cmd
, bp
->b_bcount
);
665 syslink_kdmabuf_data(slmsg
, bp
->b_data
, bp
->b_bcount
);
666 sl_msg_fini(slmsg
->msg
);
668 kprintf("userfs_strategy\n");
669 error
= syslink_ksendmsg(ump
->sldesc
, slmsg
,
670 user_strategy_callback
, bio
);
672 syslink_kfreemsg(ump
->sldesc
, slmsg
);
673 kprintf("error %d\n", error
);
678 * This callback is made in the context of the responding process which
679 * may or may not be the process the message was sent to.
682 user_strategy_callback(struct slmsg
*slmsg
, void *arg
, int error
)
684 struct bio
*bio
= arg
;
685 struct buf
*bp
= bio
->bio_buf
;
686 struct user_mount
*ump
;
689 kprintf("user_strategy_callback\n");
691 par
= &slmsg
->rep
->msg
->sm_head
;
692 if (par
->se_cmd
!= (slmsg
->msg
->sm_head
.se_cmd
| SE_CMDF_REPLY
)) {
698 bp
->b_flags
|= B_ERROR
;
700 ump
= bio
->bio_driver_info
;
701 syslink_kfreemsg(ump
->sldesc
, slmsg
);
706 * vop_bmap(struct vnode *vp, off_t loffset, off_t *doffsetp,
707 * int *runp, int *runb)
709 * Dummy up the bmap op so the kernel will cluster I/Os. The strategy
710 * code will ignore the dummied up device block translation.
714 user_vop_bmap(struct vop_bmap_args
*ap
)
718 *ap
->a_doffsetp
= ap
->a_loffset
;
719 cluster_off
= (int)(*ap
->a_doffsetp
& (MAXPHYS
- 1));
722 *ap
->a_runp
= MAXPHYS
- cluster_off
;
724 *ap
->a_runb
= cluster_off
;
730 * vop_ncreate(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
731 * struct ucred *cred, struct vattr *vap)
735 user_vop_ncreate (struct vop_ncreate_args
*ap
)
737 struct user_mount
*ump
;
738 struct user_inode
*ip
;
739 struct namecache
*ncp
;
748 ncp
= ap
->a_nch
->ncp
;
751 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
757 slmsg
= syslink_kallocmsg();
758 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
759 SLVFS_CMD_VOP_NCREATE
);
760 user_elm_push_nch(par
, ap
->a_nch
);
761 user_elm_push_vnode(par
, dvp
);
762 user_elm_push_cred(par
, ap
->a_cred
);
763 user_elm_push_vattr(par
, ap
->a_vap
);
764 sl_msg_fini(slmsg
->msg
);
766 kprintf("userfs_ncreate\n");
767 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
769 par
= &slmsg
->rep
->msg
->sm_head
;
770 if (par
->se_cmd
!= (SLVFS_CMD_VOP_NCREATE
|SE_CMDF_REPLY
)) {
776 * Parse reply - extract the inode number of the newly created
777 * object and construct a vnode using it.
779 SL_FOREACH_ELEMENT(par
, elm
) {
780 switch(elm
->se_cmd
) {
790 /* XXX construct vnode using fileid */
794 syslink_kfreemsg(ump
->sldesc
, slmsg
);
795 kprintf("error %d\n", error
);
801 * vop_nresolve(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
805 user_vop_nresolve (struct vop_nresolve_args
*ap
)
807 struct user_mount
*ump
;
808 struct user_inode
*ip
;
809 struct namecache
*ncp
;
820 ncp
= ap
->a_nch
->ncp
;
822 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
829 slmsg
= syslink_kallocmsg();
830 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
831 SLVFS_CMD_VOP_NRESOLVE
);
832 user_elm_push_nch(par
, ap
->a_nch
);
833 user_elm_push_vnode(par
, dvp
);
834 user_elm_push_cred(par
, ap
->a_cred
);
835 sl_msg_fini(slmsg
->msg
);
838 * Run the RPC. The response must still be parsed for a ENOENT
839 * error to extract the whiteout flag.
841 kprintf("userfs_nresolve\n");
842 error
= syslink_kdomsg(ump
->sldesc
, slmsg
);
843 if (error
&& error
!= ENOENT
)
845 par
= &slmsg
->rep
->msg
->sm_head
;
846 if (par
->se_cmd
!= (SLVFS_CMD_VOP_NRESOLVE
|SE_CMDF_REPLY
)) {
852 * Parse reply - returns inode number of resolved vnode
856 SL_FOREACH_ELEMENT(par
, elm
) {
857 switch(elm
->se_cmd
) {
861 case SLVFS_ELM_NCPFLAG
:
862 /* flags = & NCF_WHITEOUT */
871 /*vp = user_getvp(inum);*/
872 /* XXX construct vp cache_setvp(nch, vp); */
874 ncp
->nc_flag
|= flags
;
875 cache_setvp(ap
->a_nch
, NULL
);
878 syslink_kfreemsg(ump
->sldesc
, slmsg
);
880 kprintf("error %d\n", error
);
885 * vop_nlookupdotdot(struct vnode *dvp, struct vnode **vpp, struct ucred *cred)
887 * Lookup the parent of dvp. dvp is ref'd but not locked. The returned
888 * vnode should be ref'd and locked.
892 user_vop_nlookupdotdot (struct vop_nlookupdotdot_args
*ap
)
894 struct user_mount
*ump
;
895 struct user_inode
*ip
;
911 slmsg
= syslink_kallocmsg();
912 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
913 SLVFS_CMD_VOP_NLOOKUPDOTDOT
);
914 sl_msg_fini(slmsg
->msg
);
916 kprintf("userfs_nlookupdotdot\n");
917 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
919 par
= &slmsg
->rep
->msg
->sm_head
;
921 if (par
->se_cmd
!= (SLVFS_CMD_VOP_NLOOKUPDOTDOT
|SE_CMDF_REPLY
)) {
927 * Parse reply - inumber of parent directory
930 SL_FOREACH_ELEMENT(par
, elm
) {
931 switch(elm
->se_cmd
) {
935 case SLVFS_ELM_NCPFLAG
:
936 /* flags = & NCF_WHITEOUT */
943 /* construct parent vnode */
946 syslink_kfreemsg(ump
->sldesc
, slmsg
);
947 kprintf("error %d\n", error
);
952 * vop_nlink(struct nchandle *nch, struct vnode *dvp, struct vnode *vp,
953 * struct ucred *cred)
957 user_vop_nlink (struct vop_nlink_args
*ap
)
959 struct user_mount
*ump
;
960 struct user_inode
*ip
;
970 slmsg
= syslink_kallocmsg();
971 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
972 SLVFS_CMD_VOP_NLINK
);
973 sl_msg_fini(slmsg
->msg
);
975 kprintf("userfs_nlink\n");
976 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
977 par
= &slmsg
->rep
->msg
->sm_head
;
979 if (par
->se_cmd
== (SLVFS_CMD_VOP_NLINK
|SE_CMDF_REPLY
)) {
985 syslink_kfreemsg(ump
->sldesc
, slmsg
);
986 kprintf("error %d\n", error
);
991 * vop_nmkdir(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
992 * struct ucred *cred, struct vattr *vap)
996 user_vop_nmkdir (struct vop_nmkdir_args
*ap
)
998 struct user_mount
*ump
;
999 struct user_inode
*ip
;
1000 struct namecache
*ncp
;
1004 struct slmsg
*slmsg
;
1009 ncp
= ap
->a_nch
->ncp
;
1011 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
1014 vp
= NULL
; /* XXX */
1019 slmsg
= syslink_kallocmsg();
1020 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1021 SLVFS_CMD_VOP_NMKDIR
);
1022 sl_msg_fini(slmsg
->msg
);
1024 kprintf("userfs_nmkdir\n");
1025 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1026 par
= &slmsg
->rep
->msg
->sm_head
;
1028 if (par
->se_cmd
== (SLVFS_CMD_VOP_NMKDIR
|SE_CMDF_REPLY
)) {
1034 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1035 kprintf("error %d\n", error
);
1041 * vop_nmknod(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
1042 * struct ucred *cred, struct vattr *vap)
1046 user_vop_nmknod (struct vop_nmknod_args
*ap
)
1048 struct user_mount
*ump
;
1049 struct user_inode
*ip
;
1050 struct namecache
*ncp
;
1054 struct slmsg
*slmsg
;
1059 ncp
= ap
->a_nch
->ncp
;
1060 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1062 vp
= NULL
; /* XXX */
1067 slmsg
= syslink_kallocmsg();
1068 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1069 SLVFS_CMD_VOP_NMKNOD
);
1070 sl_msg_fini(slmsg
->msg
);
1072 kprintf("userfs_nmknod\n");
1073 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1074 par
= &slmsg
->rep
->msg
->sm_head
;
1076 if (par
->se_cmd
== (SLVFS_CMD_VOP_NMKNOD
|SE_CMDF_REPLY
)) {
1082 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1083 kprintf("error %d\n", error
);
1088 * vop_nremove(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
1092 user_vop_nremove (struct vop_nremove_args
*ap
)
1094 struct user_mount
*ump
;
1095 struct user_inode
*ip
;
1096 struct namecache
*ncp
;
1100 struct slmsg
*slmsg
;
1105 ncp
= ap
->a_nch
->ncp
;
1106 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1108 vp
= NULL
; /* XXX */
1113 slmsg
= syslink_kallocmsg();
1114 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1115 SLVFS_CMD_VOP_NREMOVE
);
1116 sl_msg_fini(slmsg
->msg
);
1118 kprintf("userfs_nremove\n");
1119 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1120 par
= &slmsg
->rep
->msg
->sm_head
;
1122 if (par
->se_cmd
== (SLVFS_CMD_VOP_NREMOVE
|SE_CMDF_REPLY
)) {
1128 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1129 kprintf("error %d\n", error
);
1134 * vop_nrename(struct nchandle *fnch, struct nchandle *tnch,
1135 * struct vnode *fdvp, struct vnode *tdvp,
1136 * struct ucred *cred)
1140 user_vop_nrename (struct vop_nrename_args
*ap
)
1142 struct user_mount
*ump
;
1143 struct user_inode
*ip
;
1144 struct namecache
*fncp
;
1145 struct namecache
*tncp
;
1150 struct slmsg
*slmsg
;
1155 fncp
= ap
->a_fnch
->ncp
;
1156 fdvp
= ap
->a_fdvp
; /* XXX needs vget */
1157 tncp
= ap
->a_tnch
->ncp
;
1158 tdvp
= ap
->a_tdvp
; /* XXX needs vget */
1160 vp
= NULL
; /* XXX */
1165 slmsg
= syslink_kallocmsg();
1166 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1167 SLVFS_CMD_VOP_NRENAME
);
1168 sl_msg_fini(slmsg
->msg
);
1170 kprintf("userfs_nrename\n");
1171 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1172 par
= &slmsg
->rep
->msg
->sm_head
;
1174 if (par
->se_cmd
== (SLVFS_CMD_VOP_NRENAME
|SE_CMDF_REPLY
)) {
1180 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1181 kprintf("error %d\n", error
);
1186 * vop_nrmdir(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
1190 user_vop_nrmdir (struct vop_nrmdir_args
*ap
)
1192 struct user_mount
*ump
;
1193 struct user_inode
*ip
;
1194 struct namecache
*ncp
;
1198 struct slmsg
*slmsg
;
1203 ncp
= ap
->a_nch
->ncp
;
1204 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1206 vp
= NULL
; /* XXX */
1211 slmsg
= syslink_kallocmsg();
1212 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1213 SLVFS_CMD_VOP_NRMDIR
);
1214 sl_msg_fini(slmsg
->msg
);
1216 kprintf("userfs_nrmdir\n");
1217 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1218 par
= &slmsg
->rep
->msg
->sm_head
;
1220 if (par
->se_cmd
== (SLVFS_CMD_VOP_NRMDIR
|SE_CMDF_REPLY
)) {
1226 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1227 kprintf("error %d\n", error
);
1233 user_vop_nsymlink (struct vop_nsymlink_args
*ap
)
1235 struct user_mount
*ump
;
1236 struct user_inode
*ip
;
1237 struct namecache
*ncp
;
1241 struct slmsg
*slmsg
;
1246 ncp
= ap
->a_nch
->ncp
;
1247 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1249 vp
= NULL
; /* XXX */
1254 slmsg
= syslink_kallocmsg();
1255 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1256 SLVFS_CMD_VOP_NSYMLINK
);
1257 sl_msg_fini(slmsg
->msg
);
1259 kprintf("userfs_nsymlink\n");
1260 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1261 par
= &slmsg
->rep
->msg
->sm_head
;
1263 if (par
->se_cmd
== (SLVFS_CMD_VOP_NSYMLINK
|SE_CMDF_REPLY
)) {
1269 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1270 kprintf("error %d\n", error
);
1276 user_vop_nwhiteout (struct vop_nwhiteout_args
*ap
)
1278 struct user_mount
*ump
;
1279 struct user_inode
*ip
;
1280 struct namecache
*ncp
;
1284 struct slmsg
*slmsg
;
1289 ncp
= ap
->a_nch
->ncp
;
1290 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1292 vp
= NULL
; /* XXX */
1297 slmsg
= syslink_kallocmsg();
1298 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1299 SLVFS_CMD_VOP_NWHITEOUT
);
1300 sl_msg_fini(slmsg
->msg
);
1302 kprintf("userfs_nwhiteout\n");
1303 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1304 par
= &slmsg
->rep
->msg
->sm_head
;
1306 if (par
->se_cmd
== (SLVFS_CMD_VOP_NWHITEOUT
|SE_CMDF_REPLY
)) {
1312 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1313 kprintf("error %d\n", error
);