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>
58 /*static int user_vop_vnoperate(struct vop_generic_args *);*/
59 static int user_vop_fsync (struct vop_fsync_args *);
60 static int user_vop_read (struct vop_read_args *);
61 static int user_vop_write (struct vop_write_args *);
62 static int user_vop_access (struct vop_access_args *);
63 static int user_vop_advlock (struct vop_advlock_args *);
64 static int user_vop_close (struct vop_close_args *);
65 static int user_vop_ncreate (struct vop_ncreate_args *);
66 static int user_vop_getattr (struct vop_getattr_args *);
67 static int user_vop_nresolve (struct vop_nresolve_args *);
68 static int user_vop_nlookupdotdot (struct vop_nlookupdotdot_args *);
69 static int user_vop_nlink (struct vop_nlink_args *);
70 static int user_vop_nmkdir (struct vop_nmkdir_args *);
71 static int user_vop_nmknod (struct vop_nmknod_args *);
72 static int user_vop_open (struct vop_open_args *);
73 static int user_vop_pathconf (struct vop_pathconf_args *);
74 static int user_vop_print (struct vop_print_args *);
75 static int user_vop_readdir (struct vop_readdir_args *);
76 static int user_vop_readlink (struct vop_readlink_args *);
77 static int user_vop_nremove (struct vop_nremove_args *);
78 static int user_vop_nrename (struct vop_nrename_args *);
79 static int user_vop_nrmdir (struct vop_nrmdir_args *);
80 static int user_vop_setattr (struct vop_setattr_args *);
81 static int user_vop_strategy (struct vop_strategy_args *);
82 static int user_vop_nsymlink (struct vop_nsymlink_args *);
83 static int user_vop_nwhiteout (struct vop_nwhiteout_args *);
84 static int user_vop_bmap (struct vop_bmap_args *);
86 struct vop_ops userfs_vnode_vops = {
87 .vop_default = vop_defaultop,
88 .vop_fsync = user_vop_fsync,
89 .vop_getpages = vop_stdgetpages,
90 .vop_putpages = vop_stdputpages,
91 .vop_read = user_vop_read,
92 .vop_write = user_vop_write,
93 .vop_access = user_vop_access,
94 .vop_advlock = user_vop_advlock,
95 .vop_close = user_vop_close,
96 .vop_ncreate = user_vop_ncreate,
97 .vop_getattr = user_vop_getattr,
98 .vop_inactive = user_vop_inactive,
99 .vop_reclaim = user_vop_reclaim,
100 .vop_nresolve = user_vop_nresolve,
101 .vop_nlookupdotdot = user_vop_nlookupdotdot,
102 .vop_nlink = user_vop_nlink,
103 .vop_nmkdir = user_vop_nmkdir,
104 .vop_nmknod = user_vop_nmknod,
105 .vop_open = user_vop_open,
106 .vop_pathconf = user_vop_pathconf,
107 .vop_print = user_vop_print,
108 .vop_readdir = user_vop_readdir,
109 .vop_readlink = user_vop_readlink,
110 .vop_nremove = user_vop_nremove,
111 .vop_nrename = user_vop_nrename,
112 .vop_nrmdir = user_vop_nrmdir,
113 .vop_setattr = user_vop_setattr,
114 .vop_strategy = user_vop_strategy,
115 .vop_nsymlink = user_vop_nsymlink,
116 .vop_nwhiteout = user_vop_nwhiteout,
117 .vop_bmap = user_vop_bmap
123 user_vop_vnoperate(struct vop_generic_args *)
125 return (VOCALL(&userfs_vnode_vops, ap));
130 * vop_fsync(struct vnode *vp, int waitfor)
134 user_vop_fsync (struct vop_fsync_args *ap)
136 struct user_mount *ump;
137 struct user_inode *ip;
147 slmsg = syslink_kallocmsg();
148 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
149 SLVFS_CMD_VOP_FSYNC);
150 user_elm_push_vnode(par, ap->a_vp);
151 sl_msg_fini(slmsg->msg);
153 kprintf("userfs_fsync\n");
154 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
155 par = &slmsg->rep->msg->sm_head;
157 if (par->se_cmd == (SLVFS_CMD_VOP_FSYNC|SE_CMDF_REPLY)) {
163 syslink_kfreemsg(ump->sldesc, slmsg);
164 kprintf("error %d\n", error);
169 * vop_read(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
173 user_vop_read (struct vop_read_args *ap)
175 struct user_mount *ump;
176 struct user_inode *ip;
189 if (uio->uio_offset < 0)
191 if (vp->v_type != VREG)
194 kprintf("userfs_read\n");
196 while (uio->uio_resid > 0 && uio->uio_offset < ip->filesize) {
198 * Use buffer cache I/O (via user_vop_strategy), aligned
199 * on USERFS_BSIZE boundaries.
201 offset = (int)uio->uio_offset & USERFS_BMASK;
202 error = bread(vp, uio->uio_offset - offset, USERFS_BSIZE, &bp);
209 * Figure out how many bytes we can actually copy this loop.
211 n = USERFS_BSIZE - offset;
212 if (n > uio->uio_resid)
214 if (n > ip->filesize - uio->uio_offset)
215 n = (int)(ip->filesize - uio->uio_offset);
217 error = uiomove((char *)bp->b_data + offset, n, uio);
222 kprintf("userfs_read error %d\n", error);
227 * vop_write(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
231 user_vop_write (struct vop_write_args *ap)
233 struct user_mount *ump;
234 struct user_inode *ip;
248 if (vp->v_type != VREG)
250 if (ap->a_ioflag & IO_APPEND)
251 uio->uio_offset = ip->filesize;
254 * Check for illegal write offsets. Valid range is 0...2^63-1
256 loffset = uio->uio_offset;
259 if (uio->uio_resid) {
260 /* GCC4 - workaround optimization */
261 loffset += uio->uio_resid;
266 kprintf("userfs_write\n");
268 while (uio->uio_resid > 0) {
270 * Use buffer cache I/O (via user_vop_strategy), aligned
271 * on USERFS_BSIZE boundaries.
273 * XXX not optimized for complete write-overs or file
274 * extensions. Note: must bread on UIO_NOCOPY writes.
276 * XXX No need to read if strictly appending.
278 offset = (size_t)uio->uio_offset & USERFS_BMASK;
279 /* if offset == ip->filesize use getblk instead */
280 error = bread(vp, uio->uio_offset - offset, USERFS_BSIZE, &bp);
287 * Figure out how many bytes we can actually copy this loop.
289 n = USERFS_BSIZE - offset;
290 if (n > uio->uio_resid)
292 if (n > ip->filesize - uio->uio_offset)
293 n = (size_t)(ip->filesize - uio->uio_offset);
295 error = uiomove((char *)bp->b_data + offset, n, uio);
302 * Extend the file's size if necessary
304 if (ip->filesize < uio->uio_offset)
305 ip->filesize = uio->uio_offset;
308 * The data has been loaded into the buffer, write it out.
310 if (ap->a_ioflag & IO_SYNC) {
312 } else if (ap->a_ioflag & IO_DIRECT) {
313 bp->b_flags |= B_CLUSTEROK;
316 bp->b_flags |= B_CLUSTEROK;
320 kprintf("userfs_write error %d\n", error);
325 * vop_access(struct vnode *vp, int mode, struct ucred *cred)
329 user_vop_access (struct vop_access_args *ap)
331 struct user_mount *ump;
332 struct user_inode *ip;
342 slmsg = syslink_kallocmsg();
343 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
344 SLVFS_CMD_VOP_ACCESS);
345 user_elm_push_vnode(par, vp);
346 user_elm_push_mode(par, ap->a_mode);
347 user_elm_push_cred(par, ap->a_cred);
348 sl_msg_fini(slmsg->msg);
351 * Issue the request and do basic validation of the response
353 kprintf("userfs_access\n");
354 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) != 0)
356 par = &slmsg->rep->msg->sm_head;
357 if (par->se_cmd != (SLVFS_CMD_VOP_ACCESS|SE_CMDF_REPLY)) {
363 syslink_kfreemsg(ump->sldesc, slmsg);
364 kprintf("error %d\n", error);
369 * vop_advlock(struct vnode *vp, caddr_t id, int op, struct flock *fl,
372 * This vop is handled directly by the kernel.
376 user_vop_advlock (struct vop_advlock_args *ap)
378 struct user_inode *ip;
384 return (lf_advlock(ap, &ip->lockf, ip->filesize));
388 * vop_open(struct vnode *vp, int mode, struct ucred *cred, struct file *file)
390 * This vop is handled directly by the kernel.
394 user_vop_open (struct vop_open_args *ap)
396 return (vop_stdopen(ap));
400 * vop_close(struct vnode *vp, int fflag)
402 * This vop is handled directly by the kernel.
406 user_vop_close (struct vop_close_args *ap)
408 return (vop_stdclose(ap));
412 * vop_getattr(struct vnode *vp, struct vattr *vap)
416 user_vop_getattr (struct vop_getattr_args *ap)
418 struct user_mount *ump;
419 struct user_inode *ip;
430 slmsg = syslink_kallocmsg();
431 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
432 SLVFS_CMD_VOP_GETATTR);
433 sl_msg_fini(slmsg->msg);
435 kprintf("userfs_getattr\n");
436 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) != 0)
438 par = &slmsg->rep->msg->sm_head;
439 if (par->se_cmd != (SLVFS_CMD_VOP_GETATTR|SE_CMDF_REPLY)) {
445 * Parse reply content
447 SL_FOREACH_ELEMENT(par, elm) {
448 switch(elm->se_cmd) {
449 case SLVFS_ELM_VATTR:
450 error = user_elm_parse_vattr(elm, ap->a_vap);
459 syslink_kfreemsg(ump->sldesc, slmsg);
460 kprintf("error %d\n", error);
465 * vop_pathconf(int name, int *retval)
467 * This vop is handled directly by the kernel.
471 user_vop_pathconf (struct vop_pathconf_args *ap)
477 *ap->a_retval = LINK_MAX;
480 *ap->a_retval = MAX_CANON;
483 *ap->a_retval = MAX_INPUT;
486 *ap->a_retval = PIPE_BUF;
488 case _PC_CHOWN_RESTRICTED:
492 *ap->a_retval = _POSIX_VDISABLE;
502 * vop_print(int name, int *retval)
504 * This vop is handled directly by the kernel.
508 user_vop_print (struct vop_print_args *ap)
514 * vop_readdir(struct vnode *vp, struct uio *uio, struct ucred *cred,
515 * int *eofflag, int *ncookies, off_t **a_cookies)
519 user_vop_readdir (struct vop_readdir_args *ap)
521 struct user_mount *ump;
522 struct user_inode *ip;
532 slmsg = syslink_kallocmsg();
533 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
534 SLVFS_CMD_VOP_READDIR);
535 sl_msg_fini(slmsg->msg);
537 kprintf("userfs_readdir\n");
538 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
539 par = &slmsg->rep->msg->sm_head;
541 if (par->se_cmd == (SLVFS_CMD_VOP_READDIR|SE_CMDF_REPLY)) {
547 syslink_kfreemsg(ump->sldesc, slmsg);
548 kprintf("error %d\n", error);
553 * vop_readlink(struct vnode *vp, struct uio *uio, struct ucred *cred)
557 user_vop_readlink (struct vop_readlink_args *ap)
559 struct user_mount *ump;
560 struct user_inode *ip;
570 slmsg = syslink_kallocmsg();
571 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
572 SLVFS_CMD_VOP_READLINK);
573 sl_msg_fini(slmsg->msg);
575 kprintf("userfs_readlink\n");
576 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
577 par = &slmsg->rep->msg->sm_head;
579 if (par->se_cmd == (SLVFS_CMD_VOP_READLINK|SE_CMDF_REPLY)) {
585 syslink_kfreemsg(ump->sldesc, slmsg);
586 kprintf("error %d\n", error);
591 * vop_setattr(struct vnode *vp, struct vattr *vap, struct ucred *cred)
595 user_vop_setattr (struct vop_setattr_args *ap)
597 struct user_mount *ump;
598 struct user_inode *ip;
608 slmsg = syslink_kallocmsg();
609 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
610 SLVFS_CMD_VOP_SETATTR);
611 sl_msg_fini(slmsg->msg);
613 kprintf("userfs_setattr\n");
614 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
615 par = &slmsg->rep->msg->sm_head;
617 if (par->se_cmd == (SLVFS_CMD_VOP_SETATTR|SE_CMDF_REPLY)) {
623 syslink_kfreemsg(ump->sldesc, slmsg);
624 kprintf("error %d\n", error);
629 * user_vop_strategy() - I/O strategy routine.
631 * Note that userfs interfaces fake-up BMAP so the strategy call just
632 * uses the passed bio instead of pushing a bio to get to the (faked)
633 * device block cache.
635 static void user_strategy_callback(struct slmsg *msg, void *arg, int error);
639 user_vop_strategy (struct vop_strategy_args *ap)
641 struct user_mount *ump;
642 struct user_inode *ip;
656 bio->bio_driver_info = ump;
658 slmsg = syslink_kallocmsg();
661 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
662 SLVFS_CMD_VOP_STRATEGY_READ);
665 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
666 SLVFS_CMD_VOP_STRATEGY_WRITE);
669 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
670 SLVFS_CMD_VOP_STRATEGY_MISC);
673 user_elm_push_vnode(par, vp);
674 user_elm_push_offset(par, bio->bio_offset);
675 user_elm_push_bio(par, bp->b_cmd, bp->b_bcount);
676 syslink_kdmabuf_data(slmsg, bp->b_data, bp->b_bcount);
677 sl_msg_fini(slmsg->msg);
679 kprintf("userfs_strategy\n");
680 error = syslink_ksendmsg(ump->sldesc, slmsg,
681 user_strategy_callback, bio);
683 syslink_kfreemsg(ump->sldesc, slmsg);
684 kprintf("error %d\n", error);
689 * This callback is made in the context of the responding process which
690 * may or may not be the process the message was sent to.
693 user_strategy_callback(struct slmsg *slmsg, void *arg, int error)
695 struct bio *bio = arg;
696 struct buf *bp = bio->bio_buf;
697 struct user_mount *ump;
700 kprintf("user_strategy_callback\n");
702 par = &slmsg->rep->msg->sm_head;
703 if (par->se_cmd != (slmsg->msg->sm_head.se_cmd | SE_CMDF_REPLY)) {
709 bp->b_flags |= B_ERROR;
711 ump = bio->bio_driver_info;
712 syslink_kfreemsg(ump->sldesc, slmsg);
717 * vop_bmap(struct vnode *vp, off_t loffset, off_t *doffsetp,
718 * int *runp, int *runb)
720 * Dummy up the bmap op so the kernel will cluster I/Os. The strategy
721 * code will ignore the dummied up device block translation.
725 user_vop_bmap(struct vop_bmap_args *ap)
729 *ap->a_doffsetp = ap->a_loffset;
730 cluster_off = (int)(*ap->a_doffsetp & (MAXPHYS - 1));
733 *ap->a_runp = MAXPHYS - cluster_off;
735 *ap->a_runb = cluster_off;
741 * vop_ncreate(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
742 * struct ucred *cred, struct vattr *vap)
746 user_vop_ncreate (struct vop_ncreate_args *ap)
748 struct user_mount *ump;
749 struct user_inode *ip;
750 struct namecache *ncp;
759 ncp = ap->a_nch->ncp;
762 if ((error = vget(dvp, LK_SHARED)) != 0)
768 slmsg = syslink_kallocmsg();
769 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
770 SLVFS_CMD_VOP_NCREATE);
771 user_elm_push_nch(par, ap->a_nch);
772 user_elm_push_vnode(par, dvp);
773 user_elm_push_cred(par, ap->a_cred);
774 user_elm_push_vattr(par, ap->a_vap);
775 sl_msg_fini(slmsg->msg);
777 kprintf("userfs_ncreate\n");
778 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) != 0)
780 par = &slmsg->rep->msg->sm_head;
781 if (par->se_cmd != (SLVFS_CMD_VOP_NCREATE|SE_CMDF_REPLY)) {
787 * Parse reply - extract the inode number of the newly created
788 * object and construct a vnode using it.
790 SL_FOREACH_ELEMENT(par, elm) {
791 switch(elm->se_cmd) {
801 /* XXX construct vnode using fileid */
805 syslink_kfreemsg(ump->sldesc, slmsg);
806 kprintf("error %d\n", error);
812 * vop_nresolve(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
816 user_vop_nresolve (struct vop_nresolve_args *ap)
818 struct user_mount *ump;
819 struct user_inode *ip;
820 struct namecache *ncp;
831 ncp = ap->a_nch->ncp;
833 if ((error = vget(dvp, LK_SHARED)) != 0)
840 slmsg = syslink_kallocmsg();
841 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
842 SLVFS_CMD_VOP_NRESOLVE);
843 user_elm_push_nch(par, ap->a_nch);
844 user_elm_push_vnode(par, dvp);
845 user_elm_push_cred(par, ap->a_cred);
846 sl_msg_fini(slmsg->msg);
849 * Run the RPC. The response must still be parsed for a ENOENT
850 * error to extract the whiteout flag.
852 kprintf("userfs_nresolve\n");
853 error = syslink_kdomsg(ump->sldesc, slmsg);
854 if (error && error != ENOENT)
856 par = &slmsg->rep->msg->sm_head;
857 if (par->se_cmd != (SLVFS_CMD_VOP_NRESOLVE|SE_CMDF_REPLY)) {
863 * Parse reply - returns inode number of resolved vnode
867 SL_FOREACH_ELEMENT(par, elm) {
868 switch(elm->se_cmd) {
872 case SLVFS_ELM_NCPFLAG:
873 /* flags = & NCF_WHITEOUT */
882 /*vp = user_getvp(inum);*/
883 /* XXX construct vp cache_setvp(nch, vp); */
885 ncp->nc_flag |= flags;
886 cache_setvp(ap->a_nch, NULL);
889 syslink_kfreemsg(ump->sldesc, slmsg);
891 kprintf("error %d\n", error);
896 * vop_nlookupdotdot(struct vnode *dvp, struct vnode **vpp, struct ucred *cred)
898 * Lookup the parent of dvp. dvp is ref'd but not locked. The returned
899 * vnode should be ref'd and locked.
903 user_vop_nlookupdotdot (struct vop_nlookupdotdot_args *ap)
905 struct user_mount *ump;
906 struct user_inode *ip;
922 slmsg = syslink_kallocmsg();
923 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
924 SLVFS_CMD_VOP_NLOOKUPDOTDOT);
925 sl_msg_fini(slmsg->msg);
927 kprintf("userfs_nlookupdotdot\n");
928 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) != 0)
930 par = &slmsg->rep->msg->sm_head;
932 if (par->se_cmd != (SLVFS_CMD_VOP_NLOOKUPDOTDOT|SE_CMDF_REPLY)) {
938 * Parse reply - inumber of parent directory
941 SL_FOREACH_ELEMENT(par, elm) {
942 switch(elm->se_cmd) {
946 case SLVFS_ELM_NCPFLAG:
947 /* flags = & NCF_WHITEOUT */
954 /* construct parent vnode */
957 syslink_kfreemsg(ump->sldesc, slmsg);
958 kprintf("error %d\n", error);
963 * vop_nlink(struct nchandle *nch, struct vnode *dvp, struct vnode *vp,
964 * struct ucred *cred)
968 user_vop_nlink (struct vop_nlink_args *ap)
970 struct user_mount *ump;
971 struct user_inode *ip;
981 slmsg = syslink_kallocmsg();
982 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
983 SLVFS_CMD_VOP_NLINK);
984 sl_msg_fini(slmsg->msg);
986 kprintf("userfs_nlink\n");
987 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
988 par = &slmsg->rep->msg->sm_head;
990 if (par->se_cmd == (SLVFS_CMD_VOP_NLINK|SE_CMDF_REPLY)) {
996 syslink_kfreemsg(ump->sldesc, slmsg);
997 kprintf("error %d\n", error);
1002 * vop_nmkdir(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
1003 * struct ucred *cred, struct vattr *vap)
1007 user_vop_nmkdir (struct vop_nmkdir_args *ap)
1009 struct user_mount *ump;
1010 struct user_inode *ip;
1011 struct namecache *ncp;
1015 struct slmsg *slmsg;
1020 ncp = ap->a_nch->ncp;
1022 if ((error = vget(dvp, LK_SHARED)) != 0)
1025 vp = NULL; /* XXX */
1030 slmsg = syslink_kallocmsg();
1031 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1032 SLVFS_CMD_VOP_NMKDIR);
1033 sl_msg_fini(slmsg->msg);
1035 kprintf("userfs_nmkdir\n");
1036 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1037 par = &slmsg->rep->msg->sm_head;
1039 if (par->se_cmd == (SLVFS_CMD_VOP_NMKDIR|SE_CMDF_REPLY)) {
1045 syslink_kfreemsg(ump->sldesc, slmsg);
1046 kprintf("error %d\n", error);
1052 * vop_nmknod(struct nchandle *nch, struct vnode *dvp, struct vnode **vpp,
1053 * struct ucred *cred, struct vattr *vap)
1057 user_vop_nmknod (struct vop_nmknod_args *ap)
1059 struct user_mount *ump;
1060 struct user_inode *ip;
1061 struct namecache *ncp;
1065 struct slmsg *slmsg;
1070 ncp = ap->a_nch->ncp;
1071 dvp = ncp->nc_parent->nc_vp; /* needs vget */
1073 vp = NULL; /* XXX */
1078 slmsg = syslink_kallocmsg();
1079 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1080 SLVFS_CMD_VOP_NMKNOD);
1081 sl_msg_fini(slmsg->msg);
1083 kprintf("userfs_nmknod\n");
1084 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1085 par = &slmsg->rep->msg->sm_head;
1087 if (par->se_cmd == (SLVFS_CMD_VOP_NMKNOD|SE_CMDF_REPLY)) {
1093 syslink_kfreemsg(ump->sldesc, slmsg);
1094 kprintf("error %d\n", error);
1099 * vop_nremove(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
1103 user_vop_nremove (struct vop_nremove_args *ap)
1105 struct user_mount *ump;
1106 struct user_inode *ip;
1107 struct namecache *ncp;
1111 struct slmsg *slmsg;
1116 ncp = ap->a_nch->ncp;
1117 dvp = ncp->nc_parent->nc_vp; /* needs vget */
1119 vp = NULL; /* XXX */
1124 slmsg = syslink_kallocmsg();
1125 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1126 SLVFS_CMD_VOP_NREMOVE);
1127 sl_msg_fini(slmsg->msg);
1129 kprintf("userfs_nremove\n");
1130 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1131 par = &slmsg->rep->msg->sm_head;
1133 if (par->se_cmd == (SLVFS_CMD_VOP_NREMOVE|SE_CMDF_REPLY)) {
1139 syslink_kfreemsg(ump->sldesc, slmsg);
1140 kprintf("error %d\n", error);
1145 * vop_nrename(struct nchandle *fnch, struct nchandle *tnch,
1146 * struct vnode *fdvp, struct vnode *tdvp,
1147 * struct ucred *cred)
1151 user_vop_nrename (struct vop_nrename_args *ap)
1153 struct user_mount *ump;
1154 struct user_inode *ip;
1155 struct namecache *fncp;
1156 struct namecache *tncp;
1161 struct slmsg *slmsg;
1166 fncp = ap->a_fnch->ncp;
1167 fdvp = ap->a_fdvp; /* XXX needs vget */
1168 tncp = ap->a_tnch->ncp;
1169 tdvp = ap->a_tdvp; /* XXX needs vget */
1171 vp = NULL; /* XXX */
1176 slmsg = syslink_kallocmsg();
1177 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1178 SLVFS_CMD_VOP_NRENAME);
1179 sl_msg_fini(slmsg->msg);
1181 kprintf("userfs_nrename\n");
1182 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1183 par = &slmsg->rep->msg->sm_head;
1185 if (par->se_cmd == (SLVFS_CMD_VOP_NRENAME|SE_CMDF_REPLY)) {
1191 syslink_kfreemsg(ump->sldesc, slmsg);
1192 kprintf("error %d\n", error);
1197 * vop_nrmdir(struct nchandle *nch, struct vnode *dvp, struct ucred *cred)
1201 user_vop_nrmdir (struct vop_nrmdir_args *ap)
1203 struct user_mount *ump;
1204 struct user_inode *ip;
1205 struct namecache *ncp;
1209 struct slmsg *slmsg;
1214 ncp = ap->a_nch->ncp;
1215 dvp = ncp->nc_parent->nc_vp; /* needs vget */
1217 vp = NULL; /* XXX */
1222 slmsg = syslink_kallocmsg();
1223 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1224 SLVFS_CMD_VOP_NRMDIR);
1225 sl_msg_fini(slmsg->msg);
1227 kprintf("userfs_nrmdir\n");
1228 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1229 par = &slmsg->rep->msg->sm_head;
1231 if (par->se_cmd == (SLVFS_CMD_VOP_NRMDIR|SE_CMDF_REPLY)) {
1237 syslink_kfreemsg(ump->sldesc, slmsg);
1238 kprintf("error %d\n", error);
1244 user_vop_nsymlink (struct vop_nsymlink_args *ap)
1246 struct user_mount *ump;
1247 struct user_inode *ip;
1248 struct namecache *ncp;
1252 struct slmsg *slmsg;
1257 ncp = ap->a_nch->ncp;
1258 dvp = ncp->nc_parent->nc_vp; /* needs vget */
1260 vp = NULL; /* XXX */
1265 slmsg = syslink_kallocmsg();
1266 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1267 SLVFS_CMD_VOP_NSYMLINK);
1268 sl_msg_fini(slmsg->msg);
1270 kprintf("userfs_nsymlink\n");
1271 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1272 par = &slmsg->rep->msg->sm_head;
1274 if (par->se_cmd == (SLVFS_CMD_VOP_NSYMLINK|SE_CMDF_REPLY)) {
1280 syslink_kfreemsg(ump->sldesc, slmsg);
1281 kprintf("error %d\n", error);
1287 user_vop_nwhiteout (struct vop_nwhiteout_args *ap)
1289 struct user_mount *ump;
1290 struct user_inode *ip;
1291 struct namecache *ncp;
1295 struct slmsg *slmsg;
1300 ncp = ap->a_nch->ncp;
1301 dvp = ncp->nc_parent->nc_vp; /* needs vget */
1303 vp = NULL; /* XXX */
1308 slmsg = syslink_kallocmsg();
1309 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1310 SLVFS_CMD_VOP_NWHITEOUT);
1311 sl_msg_fini(slmsg->msg);
1313 kprintf("userfs_nwhiteout\n");
1314 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1315 par = &slmsg->rep->msg->sm_head;
1317 if (par->se_cmd == (SLVFS_CMD_VOP_NWHITEOUT|SE_CMDF_REPLY)) {
1323 syslink_kfreemsg(ump->sldesc, slmsg);
1324 kprintf("error %d\n", error);