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
;
245 if (vp
->v_type
!= VREG
)
247 if (ap
->a_ioflag
& IO_APPEND
)
248 uio
->uio_offset
= ip
->filesize
;
251 * Check for illegal write offsets. Valid range is 0...2^63-1
253 loffset
= uio
->uio_offset
;
256 if (uio
->uio_resid
) {
257 /* GCC4 - workaround optimization */
258 loffset
+= uio
->uio_resid
;
263 kprintf("userfs_write\n");
265 while (uio
->uio_resid
> 0) {
267 * Use buffer cache I/O (via user_vop_strategy), aligned
268 * on USERFS_BSIZE boundaries.
270 * XXX not optimized for complete write-overs or file
271 * extensions. Note: must bread on UIO_NOCOPY writes.
273 * XXX No need to read if strictly appending.
275 offset
= (size_t)uio
->uio_offset
& USERFS_BMASK
;
276 /* if offset == ip->filesize use getblk instead */
277 error
= bread(vp
, uio
->uio_offset
- offset
, USERFS_BSIZE
, &bp
);
284 * Figure out how many bytes we can actually copy this loop.
286 n
= USERFS_BSIZE
- offset
;
287 if (n
> uio
->uio_resid
)
289 if (n
> ip
->filesize
- uio
->uio_offset
)
290 n
= (size_t)(ip
->filesize
- uio
->uio_offset
);
292 error
= uiomove((char *)bp
->b_data
+ offset
, n
, uio
);
299 * Extend the file's size if necessary
301 if (ip
->filesize
< uio
->uio_offset
)
302 ip
->filesize
= uio
->uio_offset
;
305 * The data has been loaded into the buffer, write it out.
307 if (ap
->a_ioflag
& IO_SYNC
) {
309 } else if (ap
->a_ioflag
& IO_DIRECT
) {
310 bp
->b_flags
|= B_CLUSTEROK
;
313 bp
->b_flags
|= B_CLUSTEROK
;
317 kprintf("userfs_write error %d\n", error
);
322 * vop_access(struct vnode *vp, int mode, struct ucred *cred)
326 user_vop_access (struct vop_access_args
*ap
)
328 struct user_mount
*ump
;
329 struct user_inode
*ip
;
339 slmsg
= syslink_kallocmsg();
340 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
341 SLVFS_CMD_VOP_ACCESS
);
342 user_elm_push_vnode(par
, vp
);
343 user_elm_push_mode(par
, ap
->a_mode
);
344 user_elm_push_cred(par
, ap
->a_cred
);
345 sl_msg_fini(slmsg
->msg
);
348 * Issue the request and do basic validation of the response
350 kprintf("userfs_access\n");
351 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
353 par
= &slmsg
->rep
->msg
->sm_head
;
354 if (par
->se_cmd
!= (SLVFS_CMD_VOP_ACCESS
|SE_CMDF_REPLY
)) {
360 syslink_kfreemsg(ump
->sldesc
, slmsg
);
361 kprintf("error %d\n", error
);
366 * vop_advlock(struct vnode *vp, caddr_t id, int op, struct flock *fl,
369 * This vop is handled directly by the kernel.
373 user_vop_advlock (struct vop_advlock_args
*ap
)
375 struct user_inode
*ip
;
381 return (lf_advlock(ap
, &ip
->lockf
, ip
->filesize
));
385 * vop_open(struct vnode *vp, int mode, struct ucred *cred, struct file *file)
387 * This vop is handled directly by the kernel.
391 user_vop_open (struct vop_open_args
*ap
)
393 return (vop_stdopen(ap
));
397 * vop_close(struct vnode *vp, int fflag)
399 * This vop is handled directly by the kernel.
403 user_vop_close (struct vop_close_args
*ap
)
405 return (vop_stdclose(ap
));
409 * vop_getattr(struct vnode *vp, struct vattr *vap)
413 user_vop_getattr (struct vop_getattr_args
*ap
)
415 struct user_mount
*ump
;
416 struct user_inode
*ip
;
427 slmsg
= syslink_kallocmsg();
428 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
429 SLVFS_CMD_VOP_GETATTR
);
430 sl_msg_fini(slmsg
->msg
);
432 kprintf("userfs_getattr\n");
433 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
435 par
= &slmsg
->rep
->msg
->sm_head
;
436 if (par
->se_cmd
!= (SLVFS_CMD_VOP_GETATTR
|SE_CMDF_REPLY
)) {
442 * Parse reply content
444 SL_FOREACH_ELEMENT(par
, elm
) {
445 switch(elm
->se_cmd
) {
446 case SLVFS_ELM_VATTR
:
447 error
= user_elm_parse_vattr(elm
, ap
->a_vap
);
456 syslink_kfreemsg(ump
->sldesc
, slmsg
);
457 kprintf("error %d\n", error
);
462 * vop_pathconf(int name, int *retval)
464 * This vop is handled directly by the kernel.
468 user_vop_pathconf (struct vop_pathconf_args
*ap
)
474 *ap
->a_retval
= LINK_MAX
;
477 *ap
->a_retval
= MAX_CANON
;
480 *ap
->a_retval
= MAX_INPUT
;
483 *ap
->a_retval
= PIPE_BUF
;
485 case _PC_CHOWN_RESTRICTED
:
489 *ap
->a_retval
= _POSIX_VDISABLE
;
499 * vop_print(int name, int *retval)
501 * This vop is handled directly by the kernel.
505 user_vop_print (struct vop_print_args
*ap
)
511 * vop_readdir(struct vnode *vp, struct uio *uio, struct ucred *cred,
512 * int *eofflag, int *ncookies, off_t **a_cookies)
516 user_vop_readdir (struct vop_readdir_args
*ap
)
518 struct user_mount
*ump
;
519 struct user_inode
*ip
;
529 slmsg
= syslink_kallocmsg();
530 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
531 SLVFS_CMD_VOP_READDIR
);
532 sl_msg_fini(slmsg
->msg
);
534 kprintf("userfs_readdir\n");
535 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
536 par
= &slmsg
->rep
->msg
->sm_head
;
538 if (par
->se_cmd
== (SLVFS_CMD_VOP_READDIR
|SE_CMDF_REPLY
)) {
544 syslink_kfreemsg(ump
->sldesc
, slmsg
);
545 kprintf("error %d\n", error
);
550 * vop_readlink(struct vnode *vp, struct uio *uio, struct ucred *cred)
554 user_vop_readlink (struct vop_readlink_args
*ap
)
556 struct user_mount
*ump
;
557 struct user_inode
*ip
;
567 slmsg
= syslink_kallocmsg();
568 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
569 SLVFS_CMD_VOP_READLINK
);
570 sl_msg_fini(slmsg
->msg
);
572 kprintf("userfs_readlink\n");
573 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
574 par
= &slmsg
->rep
->msg
->sm_head
;
576 if (par
->se_cmd
== (SLVFS_CMD_VOP_READLINK
|SE_CMDF_REPLY
)) {
582 syslink_kfreemsg(ump
->sldesc
, slmsg
);
583 kprintf("error %d\n", error
);
588 * vop_setattr(struct vnode *vp, struct vattr *vap, struct ucred *cred)
592 user_vop_setattr (struct vop_setattr_args
*ap
)
594 struct user_mount
*ump
;
595 struct user_inode
*ip
;
605 slmsg
= syslink_kallocmsg();
606 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
607 SLVFS_CMD_VOP_SETATTR
);
608 sl_msg_fini(slmsg
->msg
);
610 kprintf("userfs_setattr\n");
611 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
612 par
= &slmsg
->rep
->msg
->sm_head
;
614 if (par
->se_cmd
== (SLVFS_CMD_VOP_SETATTR
|SE_CMDF_REPLY
)) {
620 syslink_kfreemsg(ump
->sldesc
, slmsg
);
621 kprintf("error %d\n", error
);
626 * user_vop_strategy() - I/O strategy routine.
628 * Note that userfs interfaces fake-up BMAP so the strategy call just
629 * uses the passed bio instead of pushing a bio to get to the (faked)
630 * device block cache.
632 static void user_strategy_callback(struct slmsg
*msg
, void *arg
, int error
);
636 user_vop_strategy (struct vop_strategy_args
*ap
)
638 struct user_mount
*ump
;
639 struct user_inode
*ip
;
653 bio
->bio_driver_info
= ump
;
655 slmsg
= syslink_kallocmsg();
658 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
659 SLVFS_CMD_VOP_STRATEGY_READ
);
662 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
663 SLVFS_CMD_VOP_STRATEGY_WRITE
);
666 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
667 SLVFS_CMD_VOP_STRATEGY_MISC
);
670 user_elm_push_vnode(par
, vp
);
671 user_elm_push_offset(par
, bio
->bio_offset
);
672 user_elm_push_bio(par
, bp
->b_cmd
, bp
->b_bcount
);
673 syslink_kdmabuf_data(slmsg
, bp
->b_data
, bp
->b_bcount
);
674 sl_msg_fini(slmsg
->msg
);
676 kprintf("userfs_strategy\n");
677 error
= syslink_ksendmsg(ump
->sldesc
, slmsg
,
678 user_strategy_callback
, bio
);
680 syslink_kfreemsg(ump
->sldesc
, slmsg
);
681 kprintf("error %d\n", error
);
686 * This callback is made in the context of the responding process which
687 * may or may not be the process the message was sent to.
690 user_strategy_callback(struct slmsg
*slmsg
, void *arg
, int error
)
692 struct bio
*bio
= arg
;
693 struct buf
*bp
= bio
->bio_buf
;
694 struct user_mount
*ump
;
697 kprintf("user_strategy_callback\n");
699 par
= &slmsg
->rep
->msg
->sm_head
;
700 if (par
->se_cmd
!= (slmsg
->msg
->sm_head
.se_cmd
| SE_CMDF_REPLY
)) {
706 bp
->b_flags
|= B_ERROR
;
708 ump
= bio
->bio_driver_info
;
709 syslink_kfreemsg(ump
->sldesc
, slmsg
);
714 * vop_bmap(struct vnode *vp, off_t loffset, off_t *doffsetp,
715 * int *runp, int *runb)
717 * Dummy up the bmap op so the kernel will cluster I/Os. The strategy
718 * code will ignore the dummied up device block translation.
722 user_vop_bmap(struct vop_bmap_args
*ap
)
726 *ap
->a_doffsetp
= ap
->a_loffset
;
727 cluster_off
= (int)(*ap
->a_doffsetp
& (MAXPHYS
- 1));
730 *ap
->a_runp
= MAXPHYS
- cluster_off
;
732 *ap
->a_runb
= cluster_off
;
738 * vop_ncreate(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
739 * struct ucred *cred, struct vattr *vap)
743 user_vop_ncreate (struct vop_ncreate_args
*ap
)
745 struct user_mount
*ump
;
746 struct user_inode
*ip
;
747 struct namecache
*ncp
;
756 ncp
= ap
->a_nch
->ncp
;
759 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
765 slmsg
= syslink_kallocmsg();
766 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
767 SLVFS_CMD_VOP_NCREATE
);
768 user_elm_push_nch(par
, ap
->a_nch
);
769 user_elm_push_vnode(par
, dvp
);
770 user_elm_push_cred(par
, ap
->a_cred
);
771 user_elm_push_vattr(par
, ap
->a_vap
);
772 sl_msg_fini(slmsg
->msg
);
774 kprintf("userfs_ncreate\n");
775 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
777 par
= &slmsg
->rep
->msg
->sm_head
;
778 if (par
->se_cmd
!= (SLVFS_CMD_VOP_NCREATE
|SE_CMDF_REPLY
)) {
784 * Parse reply - extract the inode number of the newly created
785 * object and construct a vnode using it.
787 SL_FOREACH_ELEMENT(par
, elm
) {
788 switch(elm
->se_cmd
) {
798 /* XXX construct vnode using fileid */
802 syslink_kfreemsg(ump
->sldesc
, slmsg
);
803 kprintf("error %d\n", error
);
809 * vop_nresolve(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
813 user_vop_nresolve (struct vop_nresolve_args
*ap
)
815 struct user_mount
*ump
;
816 struct user_inode
*ip
;
817 struct namecache
*ncp
;
828 ncp
= ap
->a_nch
->ncp
;
830 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
837 slmsg
= syslink_kallocmsg();
838 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
839 SLVFS_CMD_VOP_NRESOLVE
);
840 user_elm_push_nch(par
, ap
->a_nch
);
841 user_elm_push_vnode(par
, dvp
);
842 user_elm_push_cred(par
, ap
->a_cred
);
843 sl_msg_fini(slmsg
->msg
);
846 * Run the RPC. The response must still be parsed for a ENOENT
847 * error to extract the whiteout flag.
849 kprintf("userfs_nresolve\n");
850 error
= syslink_kdomsg(ump
->sldesc
, slmsg
);
851 if (error
&& error
!= ENOENT
)
853 par
= &slmsg
->rep
->msg
->sm_head
;
854 if (par
->se_cmd
!= (SLVFS_CMD_VOP_NRESOLVE
|SE_CMDF_REPLY
)) {
860 * Parse reply - returns inode number of resolved vnode
864 SL_FOREACH_ELEMENT(par
, elm
) {
865 switch(elm
->se_cmd
) {
869 case SLVFS_ELM_NCPFLAG
:
870 /* flags = & NCF_WHITEOUT */
879 /*vp = user_getvp(inum);*/
880 /* XXX construct vp cache_setvp(nch, vp); */
882 ncp
->nc_flag
|= flags
;
883 cache_setvp(ap
->a_nch
, NULL
);
886 syslink_kfreemsg(ump
->sldesc
, slmsg
);
888 kprintf("error %d\n", error
);
893 * vop_nlookupdotdot(struct vnode *dvp, struct vnode **vpp, struct ucred *cred)
895 * Lookup the parent of dvp. dvp is ref'd but not locked. The returned
896 * vnode should be ref'd and locked.
900 user_vop_nlookupdotdot (struct vop_nlookupdotdot_args
*ap
)
902 struct user_mount
*ump
;
903 struct user_inode
*ip
;
919 slmsg
= syslink_kallocmsg();
920 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
921 SLVFS_CMD_VOP_NLOOKUPDOTDOT
);
922 sl_msg_fini(slmsg
->msg
);
924 kprintf("userfs_nlookupdotdot\n");
925 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) != 0)
927 par
= &slmsg
->rep
->msg
->sm_head
;
929 if (par
->se_cmd
!= (SLVFS_CMD_VOP_NLOOKUPDOTDOT
|SE_CMDF_REPLY
)) {
935 * Parse reply - inumber of parent directory
938 SL_FOREACH_ELEMENT(par
, elm
) {
939 switch(elm
->se_cmd
) {
943 case SLVFS_ELM_NCPFLAG
:
944 /* flags = & NCF_WHITEOUT */
951 /* construct parent vnode */
954 syslink_kfreemsg(ump
->sldesc
, slmsg
);
955 kprintf("error %d\n", error
);
960 * vop_nlink(struct nchandle *nch, struct vnode *dvp, struct vnode *vp,
961 * struct ucred *cred)
965 user_vop_nlink (struct vop_nlink_args
*ap
)
967 struct user_mount
*ump
;
968 struct user_inode
*ip
;
978 slmsg
= syslink_kallocmsg();
979 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
980 SLVFS_CMD_VOP_NLINK
);
981 sl_msg_fini(slmsg
->msg
);
983 kprintf("userfs_nlink\n");
984 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
985 par
= &slmsg
->rep
->msg
->sm_head
;
987 if (par
->se_cmd
== (SLVFS_CMD_VOP_NLINK
|SE_CMDF_REPLY
)) {
993 syslink_kfreemsg(ump
->sldesc
, slmsg
);
994 kprintf("error %d\n", error
);
999 * vop_nmkdir(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
1000 * struct ucred *cred, struct vattr *vap)
1004 user_vop_nmkdir (struct vop_nmkdir_args
*ap
)
1006 struct user_mount
*ump
;
1007 struct user_inode
*ip
;
1008 struct namecache
*ncp
;
1012 struct slmsg
*slmsg
;
1017 ncp
= ap
->a_nch
->ncp
;
1019 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
1022 vp
= NULL
; /* XXX */
1027 slmsg
= syslink_kallocmsg();
1028 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1029 SLVFS_CMD_VOP_NMKDIR
);
1030 sl_msg_fini(slmsg
->msg
);
1032 kprintf("userfs_nmkdir\n");
1033 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1034 par
= &slmsg
->rep
->msg
->sm_head
;
1036 if (par
->se_cmd
== (SLVFS_CMD_VOP_NMKDIR
|SE_CMDF_REPLY
)) {
1042 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1043 kprintf("error %d\n", error
);
1049 * vop_nmknod(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
1050 * struct ucred *cred, struct vattr *vap)
1054 user_vop_nmknod (struct vop_nmknod_args
*ap
)
1056 struct user_mount
*ump
;
1057 struct user_inode
*ip
;
1058 struct namecache
*ncp
;
1062 struct slmsg
*slmsg
;
1067 ncp
= ap
->a_nch
->ncp
;
1068 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1070 vp
= NULL
; /* XXX */
1075 slmsg
= syslink_kallocmsg();
1076 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1077 SLVFS_CMD_VOP_NMKNOD
);
1078 sl_msg_fini(slmsg
->msg
);
1080 kprintf("userfs_nmknod\n");
1081 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1082 par
= &slmsg
->rep
->msg
->sm_head
;
1084 if (par
->se_cmd
== (SLVFS_CMD_VOP_NMKNOD
|SE_CMDF_REPLY
)) {
1090 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1091 kprintf("error %d\n", error
);
1096 * vop_nremove(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
1100 user_vop_nremove (struct vop_nremove_args
*ap
)
1102 struct user_mount
*ump
;
1103 struct user_inode
*ip
;
1104 struct namecache
*ncp
;
1108 struct slmsg
*slmsg
;
1113 ncp
= ap
->a_nch
->ncp
;
1114 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1116 vp
= NULL
; /* XXX */
1121 slmsg
= syslink_kallocmsg();
1122 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1123 SLVFS_CMD_VOP_NREMOVE
);
1124 sl_msg_fini(slmsg
->msg
);
1126 kprintf("userfs_nremove\n");
1127 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1128 par
= &slmsg
->rep
->msg
->sm_head
;
1130 if (par
->se_cmd
== (SLVFS_CMD_VOP_NREMOVE
|SE_CMDF_REPLY
)) {
1136 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1137 kprintf("error %d\n", error
);
1142 * vop_nrename(struct nchandle *fnch, struct nchandle *tnch,
1143 * struct vnode *fdvp, struct vnode *tdvp,
1144 * struct ucred *cred)
1148 user_vop_nrename (struct vop_nrename_args
*ap
)
1150 struct user_mount
*ump
;
1151 struct user_inode
*ip
;
1152 struct namecache
*fncp
;
1153 struct namecache
*tncp
;
1158 struct slmsg
*slmsg
;
1163 fncp
= ap
->a_fnch
->ncp
;
1164 fdvp
= ap
->a_fdvp
; /* XXX needs vget */
1165 tncp
= ap
->a_tnch
->ncp
;
1166 tdvp
= ap
->a_tdvp
; /* XXX needs vget */
1168 vp
= NULL
; /* XXX */
1173 slmsg
= syslink_kallocmsg();
1174 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1175 SLVFS_CMD_VOP_NRENAME
);
1176 sl_msg_fini(slmsg
->msg
);
1178 kprintf("userfs_nrename\n");
1179 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1180 par
= &slmsg
->rep
->msg
->sm_head
;
1182 if (par
->se_cmd
== (SLVFS_CMD_VOP_NRENAME
|SE_CMDF_REPLY
)) {
1188 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1189 kprintf("error %d\n", error
);
1194 * vop_nrmdir(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
1198 user_vop_nrmdir (struct vop_nrmdir_args
*ap
)
1200 struct user_mount
*ump
;
1201 struct user_inode
*ip
;
1202 struct namecache
*ncp
;
1206 struct slmsg
*slmsg
;
1211 ncp
= ap
->a_nch
->ncp
;
1212 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1214 vp
= NULL
; /* XXX */
1219 slmsg
= syslink_kallocmsg();
1220 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1221 SLVFS_CMD_VOP_NRMDIR
);
1222 sl_msg_fini(slmsg
->msg
);
1224 kprintf("userfs_nrmdir\n");
1225 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1226 par
= &slmsg
->rep
->msg
->sm_head
;
1228 if (par
->se_cmd
== (SLVFS_CMD_VOP_NRMDIR
|SE_CMDF_REPLY
)) {
1234 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1235 kprintf("error %d\n", error
);
1241 user_vop_nsymlink (struct vop_nsymlink_args
*ap
)
1243 struct user_mount
*ump
;
1244 struct user_inode
*ip
;
1245 struct namecache
*ncp
;
1249 struct slmsg
*slmsg
;
1254 ncp
= ap
->a_nch
->ncp
;
1255 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1257 vp
= NULL
; /* XXX */
1262 slmsg
= syslink_kallocmsg();
1263 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1264 SLVFS_CMD_VOP_NSYMLINK
);
1265 sl_msg_fini(slmsg
->msg
);
1267 kprintf("userfs_nsymlink\n");
1268 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1269 par
= &slmsg
->rep
->msg
->sm_head
;
1271 if (par
->se_cmd
== (SLVFS_CMD_VOP_NSYMLINK
|SE_CMDF_REPLY
)) {
1277 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1278 kprintf("error %d\n", error
);
1284 user_vop_nwhiteout (struct vop_nwhiteout_args
*ap
)
1286 struct user_mount
*ump
;
1287 struct user_inode
*ip
;
1288 struct namecache
*ncp
;
1292 struct slmsg
*slmsg
;
1297 ncp
= ap
->a_nch
->ncp
;
1298 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1300 vp
= NULL
; /* XXX */
1305 slmsg
= syslink_kallocmsg();
1306 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1307 SLVFS_CMD_VOP_NWHITEOUT
);
1308 sl_msg_fini(slmsg
->msg
);
1310 kprintf("userfs_nwhiteout\n");
1311 if ((error
= syslink_kdomsg(ump
->sldesc
, slmsg
)) == 0) {
1312 par
= &slmsg
->rep
->msg
->sm_head
;
1314 if (par
->se_cmd
== (SLVFS_CMD_VOP_NWHITEOUT
|SE_CMDF_REPLY
)) {
1320 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1321 kprintf("error %d\n", error
);