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.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>
46 #include <sys/syslink.h>
47 #include <sys/syslink_vfs.h>
48 #include <vm/vnode_pager.h>
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
121 user_vop_vnoperate(struct vop_generic_args
*)
123 return (VOCALL(&userfs_vnode_vops
, ap
));
129 user_vop_fsync (struct vop_fsync_args
*ap
)
131 struct user_mount
*ump
;
132 struct user_inode
*ip
;
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
)) {
158 syslink_kfreemsg(ump
->sldesc
, slmsg
);
159 kprintf("error %d\n", error
);
165 user_vop_getpages (struct vop_getpages_args
*ap
)
169 error
= vnode_pager_generic_getpages(ap
->a_vp
, ap
->a_m
, ap
->a_count
,
176 user_vop_putpages (struct vop_putpages_args
*ap
)
180 error
= vnode_pager_generic_putpages(ap
->a_vp
, ap
->a_m
, ap
->a_count
,
181 ap
->a_sync
, ap
->a_rtvals
);
186 * VOP_READ - read into uio
190 user_vop_read (struct vop_read_args
*ap
)
192 struct user_mount
*ump
;
193 struct user_inode
*ip
;
206 kprintf("userfs_read\n");
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
);
221 * Figure out how many bytes we can actually copy this loop.
223 n
= USERFS_BSIZE
- offset
;
224 if (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
);
234 kprintf("userfs_read error %d\n", error
);
240 user_vop_write (struct vop_write_args
*ap
)
242 struct user_mount
*ump
;
243 struct user_inode
*ip
;
258 if (ap
->a_ioflag
& IO_APPEND
)
259 uio
->uio_offset
= ip
->filesize
;
260 /* XXX check append-only file flag */
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) {
277 kprintf("userfs_write\n");
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
287 offset
= (int)uio
->uio_offset
& USERFS_BMASK
;
288 error
= bread(vp
, uio
->uio_offset
- offset
, USERFS_BSIZE
, &bp
);
295 * Figure out how many bytes we can actually copy this loop.
297 n
= USERFS_BSIZE
- offset
;
298 if (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
);
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
) {
320 } else if (ap
->a_ioflag
& IO_DIRECT
) {
321 bp
->b_flags
|= B_CLUSTEROK
;
324 bp
->b_flags
|= B_CLUSTEROK
;
328 kprintf("userfs_write error %d\n", error
);
334 user_vop_access (struct vop_access_args
*ap
)
336 struct user_mount
*ump
;
337 struct user_inode
*ip
;
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
)) {
362 syslink_kfreemsg(ump
->sldesc
, slmsg
);
363 kprintf("error %d\n", error
);
369 user_vop_advlock (struct vop_advlock_args
*ap
)
371 struct user_inode
*ip
;
377 return (lf_advlock(ap
, &ip
->lockf
, ip
->filesize
));
382 user_vop_open (struct vop_open_args
*ap
)
384 return (vop_stdopen(ap
));
389 user_vop_close (struct vop_close_args
*ap
)
391 return (vop_stdclose(ap
));
396 user_vop_ncreate (struct vop_ncreate_args
*ap
)
398 struct user_mount
*ump
;
399 struct user_inode
*ip
;
400 struct namecache
*ncp
;
409 ncp
= ap
->a_nch
->ncp
;
412 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
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
)) {
435 syslink_kfreemsg(ump
->sldesc
, slmsg
);
436 kprintf("error %d\n", error
);
443 user_vop_getattr (struct vop_getattr_args
*ap
)
445 struct user_mount
*ump
;
446 struct user_inode
*ip
;
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
)) {
475 syslink_kfreemsg(ump
->sldesc
, slmsg
);
476 kprintf("error %d\n", error
);
482 user_vop_nresolve (struct vop_nresolve_args
*ap
)
484 struct user_mount
*ump
;
485 struct user_inode
*ip
;
486 struct namecache
*ncp
;
495 ncp
= ap
->a_nch
->ncp
;
501 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
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
)) {
520 syslink_kfreemsg(ump
->sldesc
, slmsg
);
522 kprintf("error %d\n", error
);
528 user_vop_nlookupdotdot (struct vop_nlookupdotdot_args
*ap
)
530 struct user_mount
*ump
;
531 struct user_inode
*ip
;
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
)) {
560 syslink_kfreemsg(ump
->sldesc
, slmsg
);
561 kprintf("error %d\n", error
);
567 user_vop_nlink (struct vop_nlink_args
*ap
)
569 struct user_mount
*ump
;
570 struct user_inode
*ip
;
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
)) {
595 syslink_kfreemsg(ump
->sldesc
, slmsg
);
596 kprintf("error %d\n", error
);
602 user_vop_nmkdir (struct vop_nmkdir_args
*ap
)
604 struct user_mount
*ump
;
605 struct user_inode
*ip
;
606 struct namecache
*ncp
;
615 ncp
= ap
->a_nch
->ncp
;
617 if ((error
= vget(dvp
, LK_SHARED
)) != 0)
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
)) {
640 syslink_kfreemsg(ump
->sldesc
, slmsg
);
641 kprintf("error %d\n", error
);
648 user_vop_nmknod (struct vop_nmknod_args
*ap
)
650 struct user_mount
*ump
;
651 struct user_inode
*ip
;
652 struct namecache
*ncp
;
661 ncp
= ap
->a_nch
->ncp
;
662 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
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
)) {
684 syslink_kfreemsg(ump
->sldesc
, slmsg
);
685 kprintf("error %d\n", error
);
691 user_vop_pathconf (struct vop_pathconf_args
*ap
)
693 struct user_mount
*ump
;
694 struct user_inode
*ip
;
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
)) {
719 syslink_kfreemsg(ump
->sldesc
, slmsg
);
720 kprintf("error %d\n", error
);
726 user_vop_print (struct vop_print_args
*ap
)
728 struct user_mount
*ump
;
729 struct user_inode
*ip
;
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
)) {
754 syslink_kfreemsg(ump
->sldesc
, slmsg
);
755 kprintf("error %d\n", error
);
761 user_vop_readdir (struct vop_readdir_args
*ap
)
763 struct user_mount
*ump
;
764 struct user_inode
*ip
;
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
)) {
789 syslink_kfreemsg(ump
->sldesc
, slmsg
);
790 kprintf("error %d\n", error
);
796 user_vop_readlink (struct vop_readlink_args
*ap
)
798 struct user_mount
*ump
;
799 struct user_inode
*ip
;
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
)) {
824 syslink_kfreemsg(ump
->sldesc
, slmsg
);
825 kprintf("error %d\n", error
);
831 user_vop_nremove (struct vop_nremove_args
*ap
)
833 struct user_mount
*ump
;
834 struct user_inode
*ip
;
835 struct namecache
*ncp
;
844 ncp
= ap
->a_nch
->ncp
;
845 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
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
)) {
867 syslink_kfreemsg(ump
->sldesc
, slmsg
);
868 kprintf("error %d\n", error
);
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
;
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 */
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
)) {
914 syslink_kfreemsg(ump
->sldesc
, slmsg
);
915 kprintf("error %d\n", error
);
921 user_vop_nrmdir (struct vop_nrmdir_args
*ap
)
923 struct user_mount
*ump
;
924 struct user_inode
*ip
;
925 struct namecache
*ncp
;
934 ncp
= ap
->a_nch
->ncp
;
935 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
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
)) {
957 syslink_kfreemsg(ump
->sldesc
, slmsg
);
958 kprintf("error %d\n", error
);
964 user_vop_setattr (struct vop_setattr_args
*ap
)
966 struct user_mount
*ump
;
967 struct user_inode
*ip
;
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
)) {
992 syslink_kfreemsg(ump
->sldesc
, slmsg
);
993 kprintf("error %d\n", 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
);
1008 user_vop_strategy (struct vop_strategy_args
*ap
)
1010 struct user_mount
*ump
;
1011 struct user_inode
*ip
;
1015 struct slmsg
*slmsg
;
1025 bio
->bio_driver_info
= ump
;
1027 slmsg
= syslink_kallocmsg();
1030 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1031 SLVFS_CMD_VOP_STRATEGY_READ
);
1034 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1035 SLVFS_CMD_VOP_STRATEGY_WRITE
);
1038 par
= sl_msg_init_cmd(slmsg
->msg
, SMPROTO_BSDVFS
,
1039 SLVFS_CMD_VOP_STRATEGY_MISC
);
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
);
1052 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1053 kprintf("error %d\n", 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.
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
;
1069 kprintf("user_strategy_callback\n");
1071 par
= &slmsg
->rep
->msg
->sm_head
;
1072 if (par
->se_cmd
!= (slmsg
->msg
->sm_head
.se_cmd
| SE_CMDF_REPLY
)) {
1077 bp
->b_error
= error
;
1078 bp
->b_flags
|= B_ERROR
;
1080 ump
= bio
->bio_driver_info
;
1081 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1087 user_vop_nsymlink (struct vop_nsymlink_args
*ap
)
1089 struct user_mount
*ump
;
1090 struct user_inode
*ip
;
1091 struct namecache
*ncp
;
1095 struct slmsg
*slmsg
;
1100 ncp
= ap
->a_nch
->ncp
;
1101 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1103 vp
= NULL
; /* XXX */
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
)) {
1123 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1124 kprintf("error %d\n", error
);
1130 user_vop_nwhiteout (struct vop_nwhiteout_args
*ap
)
1132 struct user_mount
*ump
;
1133 struct user_inode
*ip
;
1134 struct namecache
*ncp
;
1138 struct slmsg
*slmsg
;
1143 ncp
= ap
->a_nch
->ncp
;
1144 dvp
= ncp
->nc_parent
->nc_vp
; /* needs vget */
1146 vp
= NULL
; /* XXX */
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
)) {
1166 syslink_kfreemsg(ump
->sldesc
, slmsg
);
1167 kprintf("error %d\n", 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.
1177 user_vop_bmap(struct vop_bmap_args
*ap
)
1181 *ap
->a_doffsetp
= ap
->a_loffset
;
1182 cluster_off
= (int)(*ap
->a_doffsetp
& (MAXPHYS
- 1));
1185 *ap
->a_runp
= MAXPHYS
- cluster_off
;
1187 *ap
->a_runb
= cluster_off
;