Part 1/many USERFS support. Bring in the initial userfs infrastructure.
[dfdiff.git] / sys / vfs / userfs / userfs_vnops.c
blob9fe9fe4971775876ed949b7e63a831704dc50834
1 /*
2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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
16 * distribution.
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
32 * SUCH DAMAGE.
34 * $DragonFly: src/sys/vfs/userfs/userfs_vnops.c,v 1.1 2007/08/13 17:49:17 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>
45 #include <sys/stat.h>
46 #include <sys/syslink.h>
47 #include <sys/syslink_vfs.h>
48 #include <vm/vnode_pager.h>
49 #include "userfs.h"
52 * USERFS VNOPS
54 /*static int user_vop_vnoperate(struct vop_generic_args *);*/
55 static int user_vop_fsync (struct vop_fsync_args *);
56 static int user_vop_getpages (struct vop_getpages_args *);
57 static int user_vop_putpages (struct vop_putpages_args *);
58 static int user_vop_read (struct vop_read_args *);
59 static int user_vop_write (struct vop_write_args *);
60 static int user_vop_access (struct vop_access_args *);
61 static int user_vop_advlock (struct vop_advlock_args *);
62 static int user_vop_close (struct vop_close_args *);
63 static int user_vop_ncreate (struct vop_ncreate_args *);
64 static int user_vop_getattr (struct vop_getattr_args *);
65 static int user_vop_nresolve (struct vop_nresolve_args *);
66 static int user_vop_nlookupdotdot (struct vop_nlookupdotdot_args *);
67 static int user_vop_nlink (struct vop_nlink_args *);
68 static int user_vop_nmkdir (struct vop_nmkdir_args *);
69 static int user_vop_nmknod (struct vop_nmknod_args *);
70 static int user_vop_open (struct vop_open_args *);
71 static int user_vop_pathconf (struct vop_pathconf_args *);
72 static int user_vop_print (struct vop_print_args *);
73 static int user_vop_readdir (struct vop_readdir_args *);
74 static int user_vop_readlink (struct vop_readlink_args *);
75 static int user_vop_nremove (struct vop_nremove_args *);
76 static int user_vop_nrename (struct vop_nrename_args *);
77 static int user_vop_nrmdir (struct vop_nrmdir_args *);
78 static int user_vop_setattr (struct vop_setattr_args *);
79 static int user_vop_strategy (struct vop_strategy_args *);
80 static int user_vop_nsymlink (struct vop_nsymlink_args *);
81 static int user_vop_nwhiteout (struct vop_nwhiteout_args *);
82 static int user_vop_bmap (struct vop_bmap_args *);
84 struct vop_ops userfs_vnode_vops = {
85 .vop_default = vop_defaultop,
86 .vop_fsync = user_vop_fsync,
87 .vop_getpages = user_vop_getpages,
88 .vop_putpages = user_vop_putpages,
89 .vop_read = user_vop_read,
90 .vop_write = user_vop_write,
91 .vop_access = user_vop_access,
92 .vop_advlock = user_vop_advlock,
93 .vop_close = user_vop_close,
94 .vop_ncreate = user_vop_ncreate,
95 .vop_getattr = user_vop_getattr,
96 .vop_inactive = user_vop_inactive,
97 .vop_reclaim = user_vop_reclaim,
98 .vop_nresolve = user_vop_nresolve,
99 .vop_nlookupdotdot = user_vop_nlookupdotdot,
100 .vop_nlink = user_vop_nlink,
101 .vop_nmkdir = user_vop_nmkdir,
102 .vop_nmknod = user_vop_nmknod,
103 .vop_open = user_vop_open,
104 .vop_pathconf = user_vop_pathconf,
105 .vop_print = user_vop_print,
106 .vop_readdir = user_vop_readdir,
107 .vop_readlink = user_vop_readlink,
108 .vop_nremove = user_vop_nremove,
109 .vop_nrename = user_vop_nrename,
110 .vop_nrmdir = user_vop_nrmdir,
111 .vop_setattr = user_vop_setattr,
112 .vop_strategy = user_vop_strategy,
113 .vop_nsymlink = user_vop_nsymlink,
114 .vop_nwhiteout = user_vop_nwhiteout,
115 .vop_bmap = user_vop_bmap
118 #if 0
119 static
121 user_vop_vnoperate(struct vop_generic_args *)
123 return (VOCALL(&userfs_vnode_vops, ap));
125 #endif
127 static
129 user_vop_fsync (struct vop_fsync_args *ap)
131 struct user_mount *ump;
132 struct user_inode *ip;
133 struct vnode *vp;
134 struct slmsg *slmsg;
135 syslink_elm_t par;
136 int error;
138 vp = ap->a_vp;
139 ip = vp->v_data;
140 ump = ip->ump;
142 slmsg = syslink_kallocmsg();
143 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
144 SLVFS_CMD_VOP_FSYNC);
145 user_elm_push_vnode(par, ap->a_vp);
146 sl_msg_fini(slmsg->msg);
148 kprintf("userfs_fsync\n");
149 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
150 par = &slmsg->rep->msg->sm_head;
152 if (par->se_cmd == (SLVFS_CMD_VOP_FSYNC|SE_CMDF_REPLY)) {
154 } else {
155 error = EBADRPC;
158 syslink_kfreemsg(ump->sldesc, slmsg);
159 kprintf("error %d\n", error);
160 return(error);
163 static
165 user_vop_getpages (struct vop_getpages_args *ap)
167 int error;
169 error = vnode_pager_generic_getpages(ap->a_vp, ap->a_m, ap->a_count,
170 ap->a_reqpage);
171 return(error);
174 static
176 user_vop_putpages (struct vop_putpages_args *ap)
178 int error;
180 error = vnode_pager_generic_putpages(ap->a_vp, ap->a_m, ap->a_count,
181 ap->a_sync, ap->a_rtvals);
182 return(error);
186 * VOP_READ - read into uio
188 static
190 user_vop_read (struct vop_read_args *ap)
192 struct user_mount *ump;
193 struct user_inode *ip;
194 struct vnode *vp;
195 struct uio *uio;
196 struct buf *bp;
197 int error;
198 int offset;
199 int n;
201 vp = ap->a_vp;
202 ip = vp->v_data;
203 ump = ip->ump;
204 uio = ap->a_uio;
206 kprintf("userfs_read\n");
207 error = 0;
208 while (uio->uio_resid > 0 && uio->uio_offset < ip->filesize) {
210 * Use buffer cache I/O (via user_vop_strategy), aligned
211 * on USERFS_BSIZE boundaries.
213 offset = (int)uio->uio_offset & USERFS_BMASK;
214 error = bread(vp, uio->uio_offset - offset, USERFS_BSIZE, &bp);
215 if (error) {
216 brelse(bp);
217 break;
221 * Figure out how many bytes we can actually copy this loop.
223 n = USERFS_BSIZE - offset;
224 if (n > uio->uio_resid)
225 n = uio->uio_resid;
226 if (n > ip->filesize - uio->uio_offset)
227 n = (int)(ip->filesize - uio->uio_offset);
229 error = uiomove((char *)bp->b_data + offset, n, uio);
230 bqrelse(bp);
231 if (error)
232 break;
234 kprintf("userfs_read error %d\n", error);
235 return(error);
238 static
240 user_vop_write (struct vop_write_args *ap)
242 struct user_mount *ump;
243 struct user_inode *ip;
244 struct vnode *vp;
245 struct buf *bp;
246 struct uio *uio;
247 int error;
248 int offset;
249 int n;
251 vp = ap->a_vp;
252 ip = vp->v_data;
253 ump = ip->ump;
254 uio = ap->a_uio;
256 switch(vp->v_type) {
257 case VREG:
258 if (ap->a_ioflag & IO_APPEND)
259 uio->uio_offset = ip->filesize;
260 /* XXX check append-only file flag */
261 /* fall through */
262 case VLNK:
263 break;
264 case VDIR:
265 return (EINVAL);
266 default:
267 return (EINVAL);
271 * Check for illegal write offsets. Valid range is 0...2^63-1
273 if (uio->uio_offset < 0 || uio->uio_offset + uio->uio_resid <= 0) {
274 return (EFBIG);
277 kprintf("userfs_write\n");
278 error = 0;
279 while (uio->uio_resid > 0) {
281 * Use buffer cache I/O (via user_vop_strategy), aligned
282 * on USERFS_BSIZE boundaries.
284 * XXX not optimized for complete write-overs or file
285 * extensions.
287 offset = (int)uio->uio_offset & USERFS_BMASK;
288 error = bread(vp, uio->uio_offset - offset, USERFS_BSIZE, &bp);
289 if (error) {
290 brelse(bp);
291 break;
295 * Figure out how many bytes we can actually copy this loop.
297 n = USERFS_BSIZE - offset;
298 if (n > uio->uio_resid)
299 n = uio->uio_resid;
300 if (n > ip->filesize - uio->uio_offset)
301 n = (int)(ip->filesize - uio->uio_offset);
303 error = uiomove((char *)bp->b_data + offset, n, uio);
304 if (error) {
305 brelse(bp);
306 break;
310 * Extend the file's size if necessary
312 if (ip->filesize < uio->uio_offset)
313 ip->filesize = uio->uio_offset;
316 * The data has been loaded into the buffer, write it out.
318 if (ap->a_ioflag & IO_SYNC) {
319 bwrite(bp);
320 } else if (ap->a_ioflag & IO_DIRECT) {
321 bp->b_flags |= B_CLUSTEROK;
322 bawrite(bp);
323 } else {
324 bp->b_flags |= B_CLUSTEROK;
325 bdwrite(bp);
328 kprintf("userfs_write error %d\n", error);
329 return(error);
332 static
334 user_vop_access (struct vop_access_args *ap)
336 struct user_mount *ump;
337 struct user_inode *ip;
338 struct vnode *vp;
339 struct slmsg *slmsg;
340 syslink_elm_t par;
341 int error;
343 vp = ap->a_vp;
344 ip = vp->v_data;
345 ump = ip->ump;
347 slmsg = syslink_kallocmsg();
348 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
349 SLVFS_CMD_VOP_ACCESS);
350 sl_msg_fini(slmsg->msg);
352 kprintf("userfs_access\n");
353 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
354 par = &slmsg->rep->msg->sm_head;
356 if (par->se_cmd == (SLVFS_CMD_VOP_ACCESS|SE_CMDF_REPLY)) {
358 } else {
359 error = EBADRPC;
362 syslink_kfreemsg(ump->sldesc, slmsg);
363 kprintf("error %d\n", error);
364 return(error);
367 static
369 user_vop_advlock (struct vop_advlock_args *ap)
371 struct user_inode *ip;
372 struct vnode *vp;
374 vp = ap->a_vp;
375 ip = vp->v_data;
377 return (lf_advlock(ap, &ip->lockf, ip->filesize));
380 static
382 user_vop_open (struct vop_open_args *ap)
384 return (vop_stdopen(ap));
387 static
389 user_vop_close (struct vop_close_args *ap)
391 return (vop_stdclose(ap));
394 static
396 user_vop_ncreate (struct vop_ncreate_args *ap)
398 struct user_mount *ump;
399 struct user_inode *ip;
400 struct namecache *ncp;
401 struct ucred *cred;
402 struct vnode *dvp;
403 struct vnode *vp;
404 struct slmsg *slmsg;
405 syslink_elm_t par;
406 int error;
408 cred = ap->a_cred;
409 ncp = ap->a_nch->ncp;
410 dvp = ap->a_dvp;
412 if ((error = vget(dvp, LK_SHARED)) != 0)
413 return (error);
415 vp = NULL; /* XXX */
417 ip = vp->v_data;
418 ump = ip->ump;
420 slmsg = syslink_kallocmsg();
421 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
422 SLVFS_CMD_VOP_NCREATE);
423 sl_msg_fini(slmsg->msg);
425 kprintf("userfs_ncreate\n");
426 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
427 par = &slmsg->rep->msg->sm_head;
429 if (par->se_cmd == (SLVFS_CMD_VOP_NCREATE|SE_CMDF_REPLY)) {
431 } else {
432 error = EBADRPC;
435 syslink_kfreemsg(ump->sldesc, slmsg);
436 kprintf("error %d\n", error);
437 vput(dvp);
438 return(error);
441 static
443 user_vop_getattr (struct vop_getattr_args *ap)
445 struct user_mount *ump;
446 struct user_inode *ip;
447 struct vnode *vp;
448 struct slmsg *slmsg;
449 syslink_elm_t par;
450 int error;
452 kprintf("X1\n");
453 vp = ap->a_vp;
454 kprintf("X2\n");
455 ip = vp->v_data;
456 kprintf("X3\n");
457 ump = ip->ump;
458 kprintf("X4\n");
460 slmsg = syslink_kallocmsg();
461 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
462 SLVFS_CMD_VOP_GETATTR);
463 sl_msg_fini(slmsg->msg);
465 kprintf("userfs_getattr\n");
466 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
467 par = &slmsg->rep->msg->sm_head;
469 if (par->se_cmd == (SLVFS_CMD_VOP_GETATTR|SE_CMDF_REPLY)) {
471 } else {
472 error = EBADRPC;
475 syslink_kfreemsg(ump->sldesc, slmsg);
476 kprintf("error %d\n", error);
477 return(error);
480 static
482 user_vop_nresolve (struct vop_nresolve_args *ap)
484 struct user_mount *ump;
485 struct user_inode *ip;
486 struct namecache *ncp;
487 struct ucred *cred;
488 struct vnode *vp;
489 struct vnode *dvp;
490 struct slmsg *slmsg;
491 syslink_elm_t par;
492 int error;
494 cred = ap->a_cred;
495 ncp = ap->a_nch->ncp;
496 vp = NULL; /* XXX */
497 ip = vp->v_data;
498 ump = ip->ump;
500 dvp = ap->a_dvp;
501 if ((error = vget(dvp, LK_SHARED)) != 0)
502 return (error);
503 vn_unlock(dvp);
505 slmsg = syslink_kallocmsg();
506 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
507 SLVFS_CMD_VOP_NRESOLVE);
508 sl_msg_fini(slmsg->msg);
510 kprintf("userfs_nresolve\n");
511 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
512 par = &slmsg->rep->msg->sm_head;
514 if (par->se_cmd == (SLVFS_CMD_VOP_NRESOLVE|SE_CMDF_REPLY)) {
516 } else {
517 error = EBADRPC;
520 syslink_kfreemsg(ump->sldesc, slmsg);
521 vrele(dvp);
522 kprintf("error %d\n", error);
523 return(error);
526 static
528 user_vop_nlookupdotdot (struct vop_nlookupdotdot_args *ap)
530 struct user_mount *ump;
531 struct user_inode *ip;
532 struct ucred *cred;
533 struct vnode *dvp;
534 struct vnode *vp;
535 struct slmsg *slmsg;
536 syslink_elm_t par;
537 int error;
539 cred = ap->a_cred;
540 dvp = ap->a_dvp;
541 vp = NULL; /* XXX */
542 ip = vp->v_data;
543 ump = ip->ump;
545 slmsg = syslink_kallocmsg();
546 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
547 SLVFS_CMD_VOP_NLOOKUPDOTDOT);
548 sl_msg_fini(slmsg->msg);
550 kprintf("userfs_nlookupdotdot\n");
551 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
552 par = &slmsg->rep->msg->sm_head;
554 if (par->se_cmd == (SLVFS_CMD_VOP_NLOOKUPDOTDOT|SE_CMDF_REPLY)) {
556 } else {
557 error = EBADRPC;
560 syslink_kfreemsg(ump->sldesc, slmsg);
561 kprintf("error %d\n", error);
562 return(error);
565 static
567 user_vop_nlink (struct vop_nlink_args *ap)
569 struct user_mount *ump;
570 struct user_inode *ip;
571 struct vnode *vp;
572 struct slmsg *slmsg;
573 syslink_elm_t par;
574 int error;
576 vp = ap->a_vp;
577 ip = vp->v_data;
578 ump = ip->ump;
580 slmsg = syslink_kallocmsg();
581 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
582 SLVFS_CMD_VOP_NLINK);
583 sl_msg_fini(slmsg->msg);
585 kprintf("userfs_nlink\n");
586 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
587 par = &slmsg->rep->msg->sm_head;
589 if (par->se_cmd == (SLVFS_CMD_VOP_NLINK|SE_CMDF_REPLY)) {
591 } else {
592 error = EBADRPC;
595 syslink_kfreemsg(ump->sldesc, slmsg);
596 kprintf("error %d\n", error);
597 return(error);
600 static
602 user_vop_nmkdir (struct vop_nmkdir_args *ap)
604 struct user_mount *ump;
605 struct user_inode *ip;
606 struct namecache *ncp;
607 struct ucred *cred;
608 struct vnode *dvp;
609 struct vnode *vp;
610 struct slmsg *slmsg;
611 syslink_elm_t par;
612 int error;
614 cred = ap->a_cred;
615 ncp = ap->a_nch->ncp;
616 dvp = ap->a_dvp;
617 if ((error = vget(dvp, LK_SHARED)) != 0)
618 return (error);
620 vp = NULL; /* XXX */
622 ip = vp->v_data;
623 ump = ip->ump;
625 slmsg = syslink_kallocmsg();
626 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
627 SLVFS_CMD_VOP_NMKDIR);
628 sl_msg_fini(slmsg->msg);
630 kprintf("userfs_nmkdir\n");
631 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
632 par = &slmsg->rep->msg->sm_head;
634 if (par->se_cmd == (SLVFS_CMD_VOP_NMKDIR|SE_CMDF_REPLY)) {
636 } else {
637 error = EBADRPC;
640 syslink_kfreemsg(ump->sldesc, slmsg);
641 kprintf("error %d\n", error);
642 vput(dvp);
643 return(error);
646 static
648 user_vop_nmknod (struct vop_nmknod_args *ap)
650 struct user_mount *ump;
651 struct user_inode *ip;
652 struct namecache *ncp;
653 struct ucred *cred;
654 struct vnode *dvp;
655 struct vnode *vp;
656 struct slmsg *slmsg;
657 syslink_elm_t par;
658 int error;
660 cred = ap->a_cred;
661 ncp = ap->a_nch->ncp;
662 dvp = ncp->nc_parent->nc_vp; /* needs vget */
664 vp = NULL; /* XXX */
666 ip = vp->v_data;
667 ump = ip->ump;
669 slmsg = syslink_kallocmsg();
670 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
671 SLVFS_CMD_VOP_NMKNOD);
672 sl_msg_fini(slmsg->msg);
674 kprintf("userfs_nmknod\n");
675 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
676 par = &slmsg->rep->msg->sm_head;
678 if (par->se_cmd == (SLVFS_CMD_VOP_NMKNOD|SE_CMDF_REPLY)) {
680 } else {
681 error = EBADRPC;
684 syslink_kfreemsg(ump->sldesc, slmsg);
685 kprintf("error %d\n", error);
686 return(error);
689 static
691 user_vop_pathconf (struct vop_pathconf_args *ap)
693 struct user_mount *ump;
694 struct user_inode *ip;
695 struct vnode *vp;
696 struct slmsg *slmsg;
697 syslink_elm_t par;
698 int error;
700 vp = ap->a_vp;
701 ip = vp->v_data;
702 ump = ip->ump;
704 slmsg = syslink_kallocmsg();
705 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
706 SLVFS_CMD_VOP_PATHCONF);
707 sl_msg_fini(slmsg->msg);
709 kprintf("userfs_pathconf\n");
710 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
711 par = &slmsg->rep->msg->sm_head;
713 if (par->se_cmd == (SLVFS_CMD_VOP_PATHCONF|SE_CMDF_REPLY)) {
715 } else {
716 error = EBADRPC;
719 syslink_kfreemsg(ump->sldesc, slmsg);
720 kprintf("error %d\n", error);
721 return(error);
724 static
726 user_vop_print (struct vop_print_args *ap)
728 struct user_mount *ump;
729 struct user_inode *ip;
730 struct vnode *vp;
731 struct slmsg *slmsg;
732 syslink_elm_t par;
733 int error;
735 vp = ap->a_vp;
736 ip = vp->v_data;
737 ump = ip->ump;
739 slmsg = syslink_kallocmsg();
740 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
741 SLVFS_CMD_VOP_PRINT);
742 sl_msg_fini(slmsg->msg);
744 kprintf("userfs_print\n");
745 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
746 par = &slmsg->rep->msg->sm_head;
748 if (par->se_cmd == (SLVFS_CMD_VOP_PRINT|SE_CMDF_REPLY)) {
750 } else {
751 error = EBADRPC;
754 syslink_kfreemsg(ump->sldesc, slmsg);
755 kprintf("error %d\n", error);
756 return(error);
759 static
761 user_vop_readdir (struct vop_readdir_args *ap)
763 struct user_mount *ump;
764 struct user_inode *ip;
765 struct vnode *vp;
766 struct slmsg *slmsg;
767 syslink_elm_t par;
768 int error;
770 vp = ap->a_vp;
771 ip = vp->v_data;
772 ump = ip->ump;
774 slmsg = syslink_kallocmsg();
775 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
776 SLVFS_CMD_VOP_READDIR);
777 sl_msg_fini(slmsg->msg);
779 kprintf("userfs_readdir\n");
780 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
781 par = &slmsg->rep->msg->sm_head;
783 if (par->se_cmd == (SLVFS_CMD_VOP_READDIR|SE_CMDF_REPLY)) {
785 } else {
786 error = EBADRPC;
789 syslink_kfreemsg(ump->sldesc, slmsg);
790 kprintf("error %d\n", error);
791 return(error);
794 static
796 user_vop_readlink (struct vop_readlink_args *ap)
798 struct user_mount *ump;
799 struct user_inode *ip;
800 struct vnode *vp;
801 struct slmsg *slmsg;
802 syslink_elm_t par;
803 int error;
805 vp = ap->a_vp;
806 ip = vp->v_data;
807 ump = ip->ump;
809 slmsg = syslink_kallocmsg();
810 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
811 SLVFS_CMD_VOP_READLINK);
812 sl_msg_fini(slmsg->msg);
814 kprintf("userfs_readlink\n");
815 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
816 par = &slmsg->rep->msg->sm_head;
818 if (par->se_cmd == (SLVFS_CMD_VOP_READLINK|SE_CMDF_REPLY)) {
820 } else {
821 error = EBADRPC;
824 syslink_kfreemsg(ump->sldesc, slmsg);
825 kprintf("error %d\n", error);
826 return(error);
829 static
831 user_vop_nremove (struct vop_nremove_args *ap)
833 struct user_mount *ump;
834 struct user_inode *ip;
835 struct namecache *ncp;
836 struct ucred *cred;
837 struct vnode *dvp;
838 struct vnode *vp;
839 struct slmsg *slmsg;
840 syslink_elm_t par;
841 int error;
843 cred = ap->a_cred;
844 ncp = ap->a_nch->ncp;
845 dvp = ncp->nc_parent->nc_vp; /* needs vget */
847 vp = NULL; /* XXX */
849 ip = vp->v_data;
850 ump = ip->ump;
852 slmsg = syslink_kallocmsg();
853 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
854 SLVFS_CMD_VOP_NREMOVE);
855 sl_msg_fini(slmsg->msg);
857 kprintf("userfs_nremove\n");
858 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
859 par = &slmsg->rep->msg->sm_head;
861 if (par->se_cmd == (SLVFS_CMD_VOP_NREMOVE|SE_CMDF_REPLY)) {
863 } else {
864 error = EBADRPC;
867 syslink_kfreemsg(ump->sldesc, slmsg);
868 kprintf("error %d\n", error);
869 return(error);
872 static
874 user_vop_nrename (struct vop_nrename_args *ap)
876 struct user_mount *ump;
877 struct user_inode *ip;
878 struct namecache *fncp;
879 struct namecache *tncp;
880 struct ucred *cred;
881 struct vnode *fdvp;
882 struct vnode *tdvp;
883 struct vnode *vp;
884 struct slmsg *slmsg;
885 syslink_elm_t par;
886 int error;
888 cred = ap->a_cred;
889 fncp = ap->a_fnch->ncp;
890 fdvp = ap->a_fdvp; /* XXX needs vget */
891 tncp = ap->a_tnch->ncp;
892 tdvp = ap->a_tdvp; /* XXX needs vget */
894 vp = NULL; /* XXX */
896 ip = vp->v_data;
897 ump = ip->ump;
899 slmsg = syslink_kallocmsg();
900 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
901 SLVFS_CMD_VOP_NRENAME);
902 sl_msg_fini(slmsg->msg);
904 kprintf("userfs_nrename\n");
905 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
906 par = &slmsg->rep->msg->sm_head;
908 if (par->se_cmd == (SLVFS_CMD_VOP_NRENAME|SE_CMDF_REPLY)) {
910 } else {
911 error = EBADRPC;
914 syslink_kfreemsg(ump->sldesc, slmsg);
915 kprintf("error %d\n", error);
916 return(error);
919 static
921 user_vop_nrmdir (struct vop_nrmdir_args *ap)
923 struct user_mount *ump;
924 struct user_inode *ip;
925 struct namecache *ncp;
926 struct ucred *cred;
927 struct vnode *dvp;
928 struct vnode *vp;
929 struct slmsg *slmsg;
930 syslink_elm_t par;
931 int error;
933 cred = ap->a_cred;
934 ncp = ap->a_nch->ncp;
935 dvp = ncp->nc_parent->nc_vp; /* needs vget */
937 vp = NULL; /* XXX */
939 ip = vp->v_data;
940 ump = ip->ump;
942 slmsg = syslink_kallocmsg();
943 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
944 SLVFS_CMD_VOP_NRMDIR);
945 sl_msg_fini(slmsg->msg);
947 kprintf("userfs_nrmdir\n");
948 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
949 par = &slmsg->rep->msg->sm_head;
951 if (par->se_cmd == (SLVFS_CMD_VOP_NRMDIR|SE_CMDF_REPLY)) {
953 } else {
954 error = EBADRPC;
957 syslink_kfreemsg(ump->sldesc, slmsg);
958 kprintf("error %d\n", error);
959 return(error);
962 static
964 user_vop_setattr (struct vop_setattr_args *ap)
966 struct user_mount *ump;
967 struct user_inode *ip;
968 struct vnode *vp;
969 struct slmsg *slmsg;
970 syslink_elm_t par;
971 int error;
973 vp = ap->a_vp;
974 ip = vp->v_data;
975 ump = ip->ump;
977 slmsg = syslink_kallocmsg();
978 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
979 SLVFS_CMD_VOP_SETATTR);
980 sl_msg_fini(slmsg->msg);
982 kprintf("userfs_setattr\n");
983 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
984 par = &slmsg->rep->msg->sm_head;
986 if (par->se_cmd == (SLVFS_CMD_VOP_SETATTR|SE_CMDF_REPLY)) {
988 } else {
989 error = EBADRPC;
992 syslink_kfreemsg(ump->sldesc, slmsg);
993 kprintf("error %d\n", error);
994 return(error);
998 * user_vop_strategy() - I/O strategy routine.
1000 * Note that userfs interfaces fake-up BMAP so the strategy call just
1001 * uses the passed bio instead of pushing a bio to get to the (faked)
1002 * device block cache.
1004 static void user_strategy_callback(struct slmsg *msg, void *arg, int error);
1006 static
1008 user_vop_strategy (struct vop_strategy_args *ap)
1010 struct user_mount *ump;
1011 struct user_inode *ip;
1012 struct vnode *vp;
1013 struct bio *bio;
1014 struct buf *bp;
1015 struct slmsg *slmsg;
1016 syslink_elm_t par;
1017 int error;
1019 vp = ap->a_vp;
1020 ip = vp->v_data;
1021 ump = ip->ump;
1022 bio = ap->a_bio;
1023 bp = bio->bio_buf;
1025 bio->bio_driver_info = ump;
1027 slmsg = syslink_kallocmsg();
1028 switch(bp->b_cmd) {
1029 case BUF_CMD_READ:
1030 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1031 SLVFS_CMD_VOP_STRATEGY_READ);
1032 break;
1033 case BUF_CMD_WRITE:
1034 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1035 SLVFS_CMD_VOP_STRATEGY_WRITE);
1036 break;
1037 default:
1038 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1039 SLVFS_CMD_VOP_STRATEGY_MISC);
1040 break;
1042 user_elm_push_vnode(par, vp);
1043 user_elm_push_offset(par, bio->bio_offset);
1044 user_elm_push_bio(par, bp->b_cmd, bp->b_bcount);
1045 syslink_kdmabuf_data(slmsg, bp->b_data, bp->b_bcount);
1046 sl_msg_fini(slmsg->msg);
1048 kprintf("userfs_strategy\n");
1049 error = syslink_ksendmsg(ump->sldesc, slmsg,
1050 user_strategy_callback, bio);
1051 if (error)
1052 syslink_kfreemsg(ump->sldesc, slmsg);
1053 kprintf("error %d\n", error);
1054 return(error);
1058 * This callback is made in the context of the responding process which
1059 * may or may not be the process the message was sent to.
1061 static void
1062 user_strategy_callback(struct slmsg *slmsg, void *arg, int error)
1064 struct bio *bio = arg;
1065 struct buf *bp = bio->bio_buf;
1066 struct user_mount *ump;
1067 syslink_elm_t par;
1069 kprintf("user_strategy_callback\n");
1070 if (error == 0) {
1071 par = &slmsg->rep->msg->sm_head;
1072 if (par->se_cmd != (slmsg->msg->sm_head.se_cmd | SE_CMDF_REPLY)) {
1073 error = EBADRPC;
1076 if (error) {
1077 bp->b_error = error;
1078 bp->b_flags |= B_ERROR;
1080 ump = bio->bio_driver_info;
1081 syslink_kfreemsg(ump->sldesc, slmsg);
1082 biodone(bio);
1085 static
1087 user_vop_nsymlink (struct vop_nsymlink_args *ap)
1089 struct user_mount *ump;
1090 struct user_inode *ip;
1091 struct namecache *ncp;
1092 struct ucred *cred;
1093 struct vnode *dvp;
1094 struct vnode *vp;
1095 struct slmsg *slmsg;
1096 syslink_elm_t par;
1097 int error;
1099 cred = ap->a_cred;
1100 ncp = ap->a_nch->ncp;
1101 dvp = ncp->nc_parent->nc_vp; /* needs vget */
1103 vp = NULL; /* XXX */
1105 ip = vp->v_data;
1106 ump = ip->ump;
1108 slmsg = syslink_kallocmsg();
1109 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1110 SLVFS_CMD_VOP_NSYMLINK);
1111 sl_msg_fini(slmsg->msg);
1113 kprintf("userfs_nsymlink\n");
1114 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1115 par = &slmsg->rep->msg->sm_head;
1117 if (par->se_cmd == (SLVFS_CMD_VOP_NSYMLINK|SE_CMDF_REPLY)) {
1119 } else {
1120 error = EBADRPC;
1123 syslink_kfreemsg(ump->sldesc, slmsg);
1124 kprintf("error %d\n", error);
1125 return(error);
1128 static
1130 user_vop_nwhiteout (struct vop_nwhiteout_args *ap)
1132 struct user_mount *ump;
1133 struct user_inode *ip;
1134 struct namecache *ncp;
1135 struct ucred *cred;
1136 struct vnode *dvp;
1137 struct vnode *vp;
1138 struct slmsg *slmsg;
1139 syslink_elm_t par;
1140 int error;
1142 cred = ap->a_cred;
1143 ncp = ap->a_nch->ncp;
1144 dvp = ncp->nc_parent->nc_vp; /* needs vget */
1146 vp = NULL; /* XXX */
1148 ip = vp->v_data;
1149 ump = ip->ump;
1151 slmsg = syslink_kallocmsg();
1152 par = sl_msg_init_cmd(slmsg->msg, SMPROTO_BSDVFS,
1153 SLVFS_CMD_VOP_NWHITEOUT);
1154 sl_msg_fini(slmsg->msg);
1156 kprintf("userfs_nwhiteout\n");
1157 if ((error = syslink_kdomsg(ump->sldesc, slmsg)) == 0) {
1158 par = &slmsg->rep->msg->sm_head;
1160 if (par->se_cmd == (SLVFS_CMD_VOP_NWHITEOUT|SE_CMDF_REPLY)) {
1162 } else {
1163 error = EBADRPC;
1166 syslink_kfreemsg(ump->sldesc, slmsg);
1167 kprintf("error %d\n", error);
1168 return(error);
1172 * Dummy up the bmap op so the kernel will cluster I/Os. The strategy
1173 * code will ignore the dummied up device block translation.
1175 static
1177 user_vop_bmap(struct vop_bmap_args *ap)
1179 int cluster_off;
1181 *ap->a_doffsetp = ap->a_loffset;
1182 cluster_off = (int)(*ap->a_doffsetp & (MAXPHYS - 1));
1184 if (ap->a_runp)
1185 *ap->a_runp = MAXPHYS - cluster_off;
1186 if (ap->a_runb)
1187 *ap->a_runb = cluster_off;
1188 return(0);