2 * Copyright (c) 2019 Tomohiro Kusumi <tkusumi@netbsd.org>
3 * Copyright (c) 2019 The DragonFly Project
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 #include <sys/fcntl.h>
31 #include <sys/dirent.h>
34 #include <sys/mountctl.h>
35 #include <sys/kern_syscall.h>
36 #include <vm/vm_pager.h>
37 #include <vm/vm_extern.h>
38 #include <vm/vnode_pager.h>
39 #include <vm/vm_pageout.h>
42 #include <vm/vm_page2.h>
44 static int fuse_reg_resize(struct vnode
*vp
, off_t newsize
, int trivial
);
45 static void fuse_io_execute(struct fuse_mount
*fmp
, struct bio
*bio
);
46 static void fuse_release(struct fuse_mount
*fmp
, struct fuse_node
*fnp
);
49 fuse_set_attr(struct fuse_node
*fnp
, struct fuse_attr
*fat
)
51 struct vattr
*vap
= &fnp
->attr
;
56 vap
->va_type
= IFTOVT(fat
->mode
);
57 vap
->va_size
= (fnp
->sizeoverride
? fnp
->size
: fat
->size
);
58 vap
->va_bytes
= fat
->blocks
* S_BLKSIZE
;
59 vap
->va_mode
= fat
->mode
& ~S_IFMT
;
60 if (!fat
->nlink
) /* XXX .fuse_hidden* has 0 link */
63 vap
->va_nlink
= fat
->nlink
;
64 vap
->va_uid
= fat
->uid
;
65 vap
->va_gid
= fat
->gid
;
66 vap
->va_fsid
= fnp
->fmp
->mp
->mnt_stat
.f_fsid
.val
[0];
67 vap
->va_fileid
= fat
->ino
;
68 vap
->va_blocksize
= FUSE_BLKSIZE
;
69 vap
->va_rmajor
= VNOVAL
;
70 vap
->va_rminor
= VNOVAL
;
71 vap
->va_atime
.tv_sec
= fat
->atime
;
72 vap
->va_atime
.tv_nsec
= fat
->atimensec
;
73 vap
->va_mtime
.tv_sec
= fat
->mtime
;
74 vap
->va_mtime
.tv_nsec
= fat
->mtimensec
;
75 vap
->va_ctime
.tv_sec
= fat
->ctime
;
76 vap
->va_ctime
.tv_nsec
= fat
->ctimensec
;
81 KKASSERT(vap
->va_type
== fnp
->type
);
83 if (fnp
->vp
->v_object
&& fnp
->sizeoverride
== 0 &&
84 fnp
->size
!= vap
->va_size
)
86 error
= fuse_node_truncate(fnp
, fnp
->size
, vap
->va_size
);
95 fuse_vop_access(struct vop_access_args
*ap
)
97 struct vnode
*vp
= ap
->a_vp
;
98 mode_t mode
= ap
->a_mode
;
99 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
100 struct fuse_ipc
*fip
;
101 struct fuse_access_in
*fai
;
105 if (fuse_test_dead(fmp
))
108 if (fuse_test_nosys(fmp
, FUSE_ACCESS
))
111 switch (vp
->v_type
) {
115 if ((mode
& VWRITE
) && (vp
->v_mount
->mnt_flag
& MNT_RDONLY
))
135 fip
= fuse_ipc_get(fmp
, sizeof(*fai
));
136 fai
= fuse_ipc_fill(fip
, FUSE_ACCESS
, VTOI(vp
)->ino
, ap
->a_cred
);
139 error
= fuse_ipc_tx(fip
);
143 if (error
== ENOTCONN
&& (vp
->v_flag
& VROOT
))
154 fuse_vop_open(struct vop_open_args
*ap
)
156 struct vnode
*vp
= ap
->a_vp
;
157 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
158 struct fuse_node
*fnp
= VTOI(vp
);
159 struct fuse_ipc
*fip
;
160 struct fuse_open_in
*foi
;
161 struct fuse_open_out
*foo
;
164 if (fuse_test_dead(fmp
))
167 if (fuse_test_nosys(fmp
, FUSE_OPEN
))
171 * Reopen with userland process if the vnode doesn't have a
172 * file-handle. This can occur if the vnode is new or if it
173 * was previously deactivated.
176 if (vp
->v_type
== VDIR
)
181 fip
= fuse_ipc_get(fmp
, sizeof(*foi
));
182 foi
= fuse_ipc_fill(fip
, op
, fnp
->ino
, ap
->a_cred
);
183 foi
->flags
= OFLAGS(ap
->a_mode
);
184 fuse_dbg("flags=%X\n", foi
->flags
);
185 if (foi
->flags
& O_CREAT
) {
186 fuse_dbg("drop O_CREAT\n");
187 foi
->flags
&= ~O_CREAT
;
190 error
= fuse_ipc_tx(fip
);
195 foo
= fuse_out_data(fip
);
196 if (foo
->open_flags
& FOPEN_DIRECT_IO
)
198 else if (foo
->open_flags
& FOPEN_KEEP_CACHE
)
200 else if (foo
->open_flags
& FOPEN_NONSEEKABLE
)
202 else if (foo
->open_flags
& FOPEN_CACHE_DIR
)
210 return vop_stdopen(ap
);
214 * NOTE: We do not release the file-handle on close() as the vnode
215 * may still be in active use as an active directory or memory-mapped.
217 * However, to reduce overhead we issue vfinalize() to tell the kernel
218 * to attempt to finalize (deactivate) the vnode as soon as it can.
221 fuse_vop_close(struct vop_close_args
*ap
)
223 struct vnode
*vp
= ap
->a_vp
;
224 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
226 if (fuse_test_dead(fmp
))
229 if (fuse_test_nosys(fmp
, FUSE_RELEASE
) ||
230 fuse_test_nosys(fmp
, FUSE_RELEASEDIR
))
236 * Finalize immediately if not dirty, otherwise we will check
237 * during the fsync and try to finalize then.
239 if ((vp
->v_flag
& VISDIRTY
) == 0 &&
240 RB_EMPTY(&vp
->v_rbdirty_tree
))
245 return vop_stdclose(ap
);
249 fuse_vop_fsync(struct vop_fsync_args
*ap
)
251 struct vnode
*vp
= ap
->a_vp
;
252 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
253 struct fuse_ipc
*fip
;
254 struct fuse_fsync_in
*fsi
;
255 struct fuse_node
*fnp
= VTOI(vp
);
258 if (fuse_test_dead(fmp
))
261 if (fuse_test_nosys(fmp
, FUSE_FSYNC
))
265 * fsync any dirty buffers, wait for completion.
268 vfsync(vp
, ap
->a_waitfor
, 1, NULL
, NULL
);
269 bio_track_wait(&vp
->v_track_write
, 0, 0);
270 fnp
->sizeoverride
= 0;
273 * Ask DragonFly to deactivate the vnode ASAP if it is no longer
276 if (vp
->v_opencount
== 0)
280 if (vp
->v_type
== VDIR
)
285 fip
= fuse_ipc_get(fmp
, sizeof(*fsi
));
286 fsi
= fuse_ipc_fill(fip
, op
, VTOI(vp
)->ino
, NULL
);
288 fsi
->fsync_flags
= 1; /* datasync */
290 error
= fuse_ipc_tx(fip
);
301 fuse_vop_getattr(struct vop_getattr_args
*ap
)
303 struct vnode
*vp
= ap
->a_vp
;
304 struct vattr
*vap
= ap
->a_vap
;
305 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
306 struct fuse_node
*fnp
= VTOI(vp
);
307 struct fuse_ipc
*fip
;
308 struct fuse_getattr_in
*fgi
;
309 struct fuse_attr_out
*fao
;
312 if (fuse_test_dead(fmp
))
315 if (fuse_test_nosys(fmp
, FUSE_GETATTR
))
318 if (fnp
->attrgood
== 0) {
320 * Acquire new attribute
322 fip
= fuse_ipc_get(fmp
, sizeof(*fgi
));
323 fgi
= fuse_ipc_fill(fip
, FUSE_GETATTR
, fnp
->ino
, NULL
);
325 /* this may be called before open when fh is 0 */
326 fgi
->getattr_flags
|= FUSE_GETATTR_FH
;
329 error
= fuse_ipc_tx(fip
);
333 if (error
== ENOTCONN
&& (vp
->v_flag
& VROOT
)) {
334 memset(vap
, 0, sizeof(*vap
));
335 vap
->va_type
= vp
->v_type
;
341 fao
= fuse_out_data(fip
);
342 mtx_lock(&fnp
->node_lock
);
343 fuse_set_attr(fnp
, &fao
->attr
);
344 memcpy(vap
, &fnp
->attr
, sizeof(*vap
));
347 //fao->attr_valid_nsec;
348 mtx_unlock(&fnp
->node_lock
);
353 * Use cached attribute
355 memcpy(vap
, &fnp
->attr
, sizeof(*vap
));
358 if (vap
->va_type
!= vp
->v_type
)
365 fuse_vop_setattr(struct vop_setattr_args
*ap
)
367 struct vnode
*vp
= ap
->a_vp
;
368 struct vattr
*vap
= ap
->a_vap
;
369 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
370 struct fuse_node
*fnp
= VTOI(vp
);
371 struct fuse_ipc
*fip
;
372 struct fuse_setattr_in
*fsi
, arg
;
373 struct fuse_attr_out
*fao
;
377 if (fuse_test_dead(fmp
))
380 if (fuse_test_nosys(fmp
, FUSE_SETATTR
))
383 if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)
386 memset(&arg
, 0, sizeof(arg
));
387 mtx_lock(&fnp
->node_lock
);
389 if (!error
&& (vap
->va_flags
!= VNOVAL
)) {
390 mtx_unlock(&fnp
->node_lock
);
391 kflags
|= NOTE_ATTRIB
;
392 return EOPNOTSUPP
; /* XXX */
395 if (!error
&& (vap
->va_size
!= VNOVAL
)) {
396 if (vp
->v_type
== VDIR
) {
397 mtx_unlock(&fnp
->node_lock
);
400 if (vp
->v_type
== VREG
&&
401 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)) {
402 mtx_unlock(&fnp
->node_lock
);
405 arg
.size
= vap
->va_size
;
406 arg
.valid
|= FATTR_SIZE
;
407 if (vap
->va_size
> fnp
->size
)
408 kflags
|= NOTE_WRITE
| NOTE_EXTEND
;
410 kflags
|= NOTE_WRITE
;
413 if (!error
&& (vap
->va_uid
!= (uid_t
)VNOVAL
||
414 vap
->va_gid
!= (gid_t
)VNOVAL
)) {
416 error
= vop_helper_chown(vp
, vap
->va_uid
, vap
->va_gid
,
417 ap
->a_cred
, &arg
.uid
, &arg
.gid
, &mode
);
418 arg
.valid
|= FATTR_UID
;
419 arg
.valid
|= FATTR_GID
;
420 kflags
|= NOTE_ATTRIB
;
423 if (!error
&& (vap
->va_mode
!= (mode_t
)VNOVAL
)) {
424 error
= vop_helper_chmod(vp
, vap
->va_mode
, ap
->a_cred
,
425 vap
->va_uid
, vap
->va_gid
, (mode_t
*)&arg
.mode
);
426 arg
.valid
|= FATTR_MODE
;
427 kflags
|= NOTE_ATTRIB
;
430 if (!error
&& (vap
->va_atime
.tv_sec
!= VNOVAL
&&
431 vap
->va_atime
.tv_nsec
!= VNOVAL
)) {
432 arg
.atime
= vap
->va_atime
.tv_sec
;
433 arg
.atimensec
= vap
->va_atime
.tv_nsec
;
434 arg
.valid
|= FATTR_ATIME
;
435 kflags
|= NOTE_ATTRIB
;
438 if (!error
&& (vap
->va_mtime
.tv_sec
!= VNOVAL
&&
439 vap
->va_mtime
.tv_nsec
!= VNOVAL
)) {
440 arg
.mtime
= vap
->va_mtime
.tv_sec
;
441 arg
.mtimensec
= vap
->va_mtime
.tv_nsec
;
442 arg
.valid
|= FATTR_MTIME
;
443 kflags
|= NOTE_ATTRIB
;
446 if (!error
&& (vap
->va_ctime
.tv_sec
!= VNOVAL
&&
447 vap
->va_ctime
.tv_nsec
!= VNOVAL
)) {
448 arg
.ctime
= vap
->va_ctime
.tv_sec
;
449 arg
.ctimensec
= vap
->va_ctime
.tv_nsec
;
450 arg
.valid
|= FATTR_CTIME
;
451 kflags
|= NOTE_ATTRIB
;
454 mtx_unlock(&fnp
->node_lock
);
461 fip
= fuse_ipc_get(fmp
, sizeof(*fsi
));
462 fsi
= fuse_ipc_fill(fip
, FUSE_SETATTR
, fnp
->ino
, ap
->a_cred
);
463 memcpy(fsi
, &arg
, sizeof(arg
));
465 fsi
->valid
|= FATTR_FH
;
468 error
= fuse_ipc_tx(fip
);
472 fao
= fuse_out_data(fip
);
473 if (IFTOVT(fao
->attr
.mode
) != vp
->v_type
) {
477 mtx_lock(&fnp
->node_lock
);
478 fuse_set_attr(fnp
, &fao
->attr
);
481 //fao->attr_valid_nsec;
482 mtx_unlock(&fnp
->node_lock
);
485 fuse_knote(vp
, kflags
);
491 fuse_vop_nresolve(struct vop_nresolve_args
*ap
)
493 struct vnode
*dvp
= ap
->a_dvp
;
495 struct namecache
*ncp
= ap
->a_nch
->ncp
;
496 struct fuse_mount
*fmp
= VFSTOFUSE(dvp
->v_mount
);
497 struct fuse_node
*dfnp
= VTOI(dvp
);
498 struct fuse_node
*fnp
;
499 struct fuse_ipc
*fip
;
500 struct fuse_entry_out
*feo
;
507 if (fuse_test_dead(fmp
))
510 if (fuse_test_nosys(fmp
, FUSE_LOOKUP
))
513 fip
= fuse_ipc_get(fmp
, ncp
->nc_nlen
+ 1);
514 p
= fuse_ipc_fill(fip
, FUSE_LOOKUP
, dfnp
->ino
, ap
->a_cred
);
516 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
517 p
[ncp
->nc_nlen
] = '\0';
518 strlcpy(tmp
, p
, sizeof(tmp
));
521 * "." and ".." are not ref-counted by the fuse userland
522 * (their API is basically broken but, meh).
525 if (strcmp(p
, ".") != 0 && strcmp(p
, "..") != 0)
528 error
= fuse_ipc_tx(fip
);
529 if (error
== ENOENT
) {
530 cache_setvp(ap
->a_nch
, NULL
);
531 fuse_dbg("lookup \"%s\" ENOENT\n", tmp
);
534 fuse_dbg("lookup \"%s\" error=%d\n", tmp
, error
);
538 feo
= fuse_out_data(fip
);
539 fuse_dbg("lookup \"%s\" ino=%ju/%ju\n", p
, feo
->nodeid
, feo
->attr
.ino
);
542 * Apparently in later FUSEs this means a cacheable ENOENT
544 if (feo
->nodeid
== 0) {
546 cache_setvp(ap
->a_nch
, NULL
);
549 if (feo
->nodeid
== 1)
552 mode
= feo
->attr
.mode
;
556 else if (S_ISDIR(mode
))
558 else if (S_ISBLK(mode
))
560 else if (S_ISCHR(mode
))
562 else if (S_ISLNK(mode
))
564 else if (S_ISSOCK(mode
))
566 else if (S_ISFIFO(mode
))
571 error
= fuse_alloc_node(fmp
, dfnp
, feo
->nodeid
, vtyp
, &vp
);
574 KKASSERT(vn_islocked(vp
));
577 cache_setvp(ap
->a_nch
, vp
);
584 //feo->entry_valid_nsec;
585 //feo->attr_valid_nsec;
589 atomic_add_64(&fnp
->nlookup
, 1);
592 /* sshfs fails utterly if we issue FUSE_FORGET */
594 fuse_forget_node(fmp
, feo
->nodeid
, 1, NULL
);
603 fuse_vop_nlink(struct vop_nlink_args
*ap
)
605 struct vnode
*dvp
= ap
->a_dvp
;
606 struct vnode
*vp
= ap
->a_vp
;
607 struct namecache
*ncp
= ap
->a_nch
->ncp
;
608 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
609 struct fuse_node
*dfnp
= VTOI(dvp
);
610 struct fuse_node
*fnp
= VTOI(vp
);
611 struct fuse_ipc
*fip
;
612 struct fuse_link_in
*fli
;
613 struct fuse_entry_out
*feo
;
617 if (fuse_test_dead(fmp
))
620 if (fuse_test_nosys(fmp
, FUSE_LINK
))
623 if (vp
->v_type
== VDIR
)
625 if (dvp
->v_mount
!= vp
->v_mount
)
628 fip
= fuse_ipc_get(fmp
, sizeof(fli
) + ncp
->nc_nlen
+ 1);
629 fli
= fuse_ipc_fill(fip
, FUSE_LINK
, dfnp
->ino
, ap
->a_cred
);
630 fli
->oldnodeid
= fnp
->ino
;
632 p
= (char*)(fli
+ 1);
633 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
634 p
[ncp
->nc_nlen
] = '\0';
636 error
= fuse_ipc_tx(fip
);
640 feo
= fuse_out_data(fip
);
641 if (IFTOVT(feo
->attr
.mode
) != vp
->v_type
) {
646 mtx_lock(&dfnp
->node_lock
);
647 mtx_lock(&fnp
->node_lock
);
648 fuse_set_attr(fnp
, &feo
->attr
);
649 mtx_unlock(&fnp
->node_lock
);
650 mtx_unlock(&dfnp
->node_lock
);
652 cache_setunresolved(ap
->a_nch
);
653 cache_setvp(ap
->a_nch
, vp
);
654 fuse_knote(dvp
, NOTE_WRITE
);
655 fuse_knote(vp
, NOTE_LINK
);
662 //feo->entry_valid_nsec;
663 //feo->attr_valid_nsec;
671 fuse_vop_ncreate(struct vop_ncreate_args
*ap
)
673 struct vnode
*dvp
= ap
->a_dvp
;
675 struct namecache
*ncp
= ap
->a_nch
->ncp
;
676 struct fuse_mount
*fmp
= VFSTOFUSE(dvp
->v_mount
);
677 struct fuse_node
*dfnp
= VTOI(dvp
);
678 struct fuse_node
*fnp
;
679 struct fuse_ipc
*fip
;
680 struct fuse_create_in
*fci
;
681 struct fuse_entry_out
*feo
;
682 struct fuse_open_out
*foo
;
687 if (fuse_test_dead(fmp
))
690 if (fuse_test_nosys(fmp
, FUSE_CREATE
))
693 fip
= fuse_ipc_get(fmp
, sizeof(*fci
) + ncp
->nc_nlen
+ 1);
694 fci
= fuse_ipc_fill(fip
, FUSE_CREATE
, dfnp
->ino
, ap
->a_cred
);
695 fci
->flags
= OFLAGS(ap
->a_vap
->va_fuseflags
);
696 fci
->mode
= MAKEIMODE(ap
->a_vap
->va_type
, ap
->a_vap
->va_mode
);
699 fuse_dbg("flags=%X mode=%X\n", fci
->flags
, fci
->mode
);
701 p
= (char*)(fci
+ 1);
702 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
703 p
[ncp
->nc_nlen
] = '\0';
705 error
= fuse_ipc_tx(fip
);
709 feo
= fuse_out_data(fip
);
710 foo
= (struct fuse_open_out
*)(feo
+ 1);
711 vtyp
= IFTOVT(feo
->attr
.mode
);
712 if (vtyp
!= VREG
&& vtyp
!= VSOCK
) {
717 error
= fuse_alloc_node(fmp
, dfnp
, feo
->nodeid
, VREG
, &vp
);
720 KKASSERT(vn_islocked(vp
));
723 mtx_lock(&fnp
->node_lock
);
724 fuse_set_attr(fnp
, &feo
->attr
);
725 mtx_unlock(&fnp
->node_lock
);
728 cache_setunresolved(ap
->a_nch
);
729 cache_setvp(ap
->a_nch
, vp
);
731 fuse_knote(dvp
, NOTE_WRITE
);
737 //feo->entry_valid_nsec;
738 //feo->attr_valid_nsec;
748 fuse_vop_nmknod(struct vop_nmknod_args
*ap
)
750 struct vnode
*dvp
= ap
->a_dvp
;
752 struct namecache
*ncp
= ap
->a_nch
->ncp
;
753 struct fuse_mount
*fmp
= VFSTOFUSE(dvp
->v_mount
);
754 struct fuse_node
*dfnp
= VTOI(dvp
);
755 struct fuse_node
*fnp
;
756 struct fuse_ipc
*fip
;
757 struct fuse_mknod_in
*fmi
;
758 struct fuse_entry_out
*feo
;
763 if (fuse_test_dead(fmp
))
766 if (fuse_test_nosys(fmp
, FUSE_MKNOD
))
769 fip
= fuse_ipc_get(fmp
, sizeof(*fmi
) + ncp
->nc_nlen
+ 1);
770 fmi
= fuse_ipc_fill(fip
, FUSE_MKNOD
, dfnp
->ino
, ap
->a_cred
);
771 fmi
->mode
= MAKEIMODE(ap
->a_vap
->va_type
, ap
->a_vap
->va_mode
);
776 p
= (char*)(fmi
+ 1);
777 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
778 p
[ncp
->nc_nlen
] = '\0';
780 error
= fuse_ipc_tx(fip
);
784 feo
= fuse_out_data(fip
);
785 vtyp
= IFTOVT(feo
->attr
.mode
);
786 if (vtyp
!= VBLK
&& vtyp
!= VCHR
&& vtyp
!= VFIFO
) {
791 error
= fuse_alloc_node(fmp
, dfnp
, feo
->nodeid
,
792 ap
->a_vap
->va_type
, &vp
);
795 KKASSERT(vn_islocked(vp
));
798 mtx_lock(&fnp
->node_lock
);
799 fuse_set_attr(fnp
, &feo
->attr
);
800 mtx_unlock(&fnp
->node_lock
);
802 cache_setunresolved(ap
->a_nch
);
803 cache_setvp(ap
->a_nch
, vp
);
805 fuse_knote(dvp
, NOTE_WRITE
);
811 //feo->entry_valid_nsec;
812 //feo->attr_valid_nsec;
820 fuse_vop_nremove(struct vop_nremove_args
*ap
)
822 struct vnode
*dvp
= ap
->a_dvp
;
824 struct namecache
*ncp
= ap
->a_nch
->ncp
;
825 struct fuse_mount
*fmp
= VFSTOFUSE(dvp
->v_mount
);
826 struct fuse_node
*dfnp
= VTOI(dvp
);
827 struct fuse_node
*fnp
;
828 struct fuse_ipc
*fip
;
832 if (fuse_test_dead(fmp
))
835 if (fuse_test_nosys(fmp
, FUSE_UNLINK
))
838 error
= cache_vget(ap
->a_nch
, ap
->a_cred
, LK_SHARED
, &vp
);
841 KKASSERT(vp
->v_mount
== dvp
->v_mount
);
844 * Clean-up the deletion target to avoid .fuse_hidden*
847 * NOTE: XXX v_opencount check does not take mmap/filepointers
850 vinvalbuf(vp
, V_SAVE
, 0, 0);
851 if (vp
->v_opencount
== 0) {
853 fuse_release(fmp
, fnp
);
857 fip
= fuse_ipc_get(fmp
, ncp
->nc_nlen
+ 1);
858 p
= fuse_ipc_fill(fip
, FUSE_UNLINK
, dfnp
->ino
, ap
->a_cred
);
860 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
861 p
[ncp
->nc_nlen
] = '\0';
863 error
= fuse_ipc_tx(fip
);
871 cache_unlink(ap
->a_nch
);
872 fuse_knote(dvp
, NOTE_WRITE
);
873 fuse_knote(vp
, NOTE_DELETE
);
882 fuse_vop_nmkdir(struct vop_nmkdir_args
*ap
)
884 struct vnode
*dvp
= ap
->a_dvp
;
886 struct namecache
*ncp
= ap
->a_nch
->ncp
;
887 struct fuse_mount
*fmp
= VFSTOFUSE(dvp
->v_mount
);
888 struct fuse_node
*dfnp
= VTOI(dvp
);
889 struct fuse_node
*fnp
;
890 struct fuse_ipc
*fip
;
891 struct fuse_mkdir_in
*fmi
;
892 struct fuse_entry_out
*feo
;
896 if (fuse_test_dead(fmp
))
899 if (fuse_test_nosys(fmp
, FUSE_MKDIR
))
902 fip
= fuse_ipc_get(fmp
, sizeof(*fmi
) + ncp
->nc_nlen
+ 1);
903 fmi
= fuse_ipc_fill(fip
, FUSE_MKDIR
, dfnp
->ino
, ap
->a_cred
);
904 fmi
->mode
= MAKEIMODE(ap
->a_vap
->va_type
, ap
->a_vap
->va_mode
);
906 p
= (char*)(fmi
+ 1);
907 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
908 p
[ncp
->nc_nlen
] = '\0';
910 error
= fuse_ipc_tx(fip
);
914 feo
= fuse_out_data(fip
);
915 if (IFTOVT(feo
->attr
.mode
) != VDIR
) {
920 error
= fuse_alloc_node(fmp
, dfnp
, feo
->nodeid
, VDIR
, &vp
);
923 KKASSERT(vn_islocked(vp
));
926 mtx_lock(&fnp
->node_lock
);
927 fuse_set_attr(fnp
, &feo
->attr
);
928 mtx_unlock(&fnp
->node_lock
);
930 cache_setunresolved(ap
->a_nch
);
931 cache_setvp(ap
->a_nch
, vp
);
933 fuse_knote(dvp
, NOTE_WRITE
| NOTE_LINK
);
939 //feo->entry_valid_nsec;
940 //feo->attr_valid_nsec;
948 fuse_vop_nrmdir(struct vop_nrmdir_args
*ap
)
950 struct vnode
*dvp
= ap
->a_dvp
;
952 struct namecache
*ncp
= ap
->a_nch
->ncp
;
953 struct fuse_mount
*fmp
= VFSTOFUSE(dvp
->v_mount
);
954 struct fuse_node
*dfnp
= VTOI(dvp
);
955 struct fuse_node
*fnp
;
956 struct fuse_ipc
*fip
;
960 if (fuse_test_dead(fmp
))
963 if (fuse_test_nosys(fmp
, FUSE_RMDIR
))
966 error
= cache_vget(ap
->a_nch
, ap
->a_cred
, LK_SHARED
, &vp
);
967 KKASSERT(vp
->v_mount
== dvp
->v_mount
);
968 KKASSERT(!error
); /* from tmpfs */
971 fip
= fuse_ipc_get(fmp
, ncp
->nc_nlen
+ 1);
972 p
= fuse_ipc_fill(fip
, FUSE_RMDIR
, dfnp
->ino
, ap
->a_cred
);
974 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
975 p
[ncp
->nc_nlen
] = '\0';
977 error
= fuse_ipc_tx(fip
);
985 cache_unlink(ap
->a_nch
);
986 fuse_knote(dvp
, NOTE_WRITE
| NOTE_LINK
);
995 fuse_vop_pathconf(struct vop_pathconf_args
*ap
)
997 switch (ap
->a_name
) {
998 case _PC_FILESIZEBITS
:
1005 return vop_stdpathconf(ap
);
1012 fuse_vop_readdir(struct vop_readdir_args
*ap
)
1014 struct vnode
*vp
= ap
->a_vp
;
1015 struct uio
*uio
= ap
->a_uio
;
1016 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
1017 struct fuse_ipc
*fip
;
1018 struct fuse_read_in
*fri
;
1021 off_t cur_offset
= 0;
1024 if (fuse_test_dead(fmp
))
1027 if (fuse_test_nosys(fmp
, FUSE_READDIR
))
1030 fip
= fuse_ipc_get(fmp
, sizeof(*fri
));
1031 fri
= fuse_ipc_fill(fip
, FUSE_READDIR
, VTOI(vp
)->ino
, ap
->a_cred
);
1032 fri
->fh
= VTOI(vp
)->fh
;
1035 * XXX This needs to be large enough to read all entries at once.
1036 * FUSE filesystems typically just opendir/readdir and return entries.
1038 fri
->size
= FUSE_BLKSIZE
* 10;
1040 //fri->read_flags = ...;
1041 //fri->lock_owner = ...;
1044 error
= fuse_ipc_tx(fip
);
1048 buf
= fuse_out_data(fip
);
1049 len
= fuse_out_data_size(fip
);
1052 const struct fuse_dirent
*fde
;
1055 fuse_dbg("uio_offset=%ju uio_resid=%ju\n",
1056 uio
->uio_offset
, uio
->uio_resid
);
1058 if (len
< FUSE_NAME_OFFSET
) {
1063 if (uio
->uio_resid
< FUSE_NAME_OFFSET
)
1066 fde
= (const struct fuse_dirent
*)buf
;
1067 if (!fde
->namelen
) {
1071 freclen
= FUSE_DIRENT_SIZE(fde
);
1075 * getdirentries(2) in sys/kern/vfs_syscalls.c
1076 * readdir(3) in lib/libc/gen/readdir.c
1078 if (cur_offset
>= uio
->uio_offset
) {
1080 if (vop_write_dirent(&error
, uio
, fde
->ino
, fde
->type
,
1081 fde
->namelen
, fde
->name
))
1085 fuse_dbg("ino=%ju type=%d name=%s len=%u\n",
1086 fde
->ino
, fde
->type
, fde
->name
, fde
->namelen
);
1089 cur_offset
+= _DIRENT_RECLEN(fde
->namelen
);
1099 fuse_vop_readlink(struct vop_readlink_args
*ap
)
1101 struct vnode
*vp
= ap
->a_vp
;
1102 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
1103 struct fuse_ipc
*fip
;
1106 if (fuse_test_dead(fmp
))
1109 if (fuse_test_nosys(fmp
, FUSE_READLINK
))
1112 if (vp
->v_type
!= VLNK
)
1115 fip
= fuse_ipc_get(fmp
, 0);
1116 fuse_ipc_fill(fip
, FUSE_READLINK
, VTOI(vp
)->ino
, ap
->a_cred
);
1118 error
= fuse_ipc_tx(fip
);
1122 error
= uiomove(fuse_out_data(fip
), fuse_out_data_size(fip
), ap
->a_uio
);
1130 fuse_vop_nrename(struct vop_nrename_args
*ap
)
1132 struct namecache
*fncp
= ap
->a_fnch
->ncp
;
1133 struct namecache
*tncp
= ap
->a_tnch
->ncp
;
1134 struct vnode
*fdvp
= ap
->a_fdvp
;
1135 struct vnode
*fvp
= fncp
->nc_vp
;
1136 struct vnode
*tdvp
= ap
->a_tdvp
;
1138 struct fuse_mount
*fmp
= VFSTOFUSE(fdvp
->v_mount
);
1139 struct fuse_node
*fdfnp
= VTOI(fdvp
);
1140 struct fuse_node
*ffnp
= VTOI(fvp
);
1141 struct fuse_node
*tdfnp
= VTOI(tdvp
);
1142 struct fuse_node
*tfnp
;
1143 struct fuse_ipc
*fip
;
1144 struct fuse_rename_in
*fri
;
1148 KKASSERT(fdvp
->v_mount
== fvp
->v_mount
);
1150 if (fuse_test_dead(fmp
))
1153 if (fuse_test_nosys(fmp
, FUSE_RENAME
))
1156 error
= cache_vget(ap
->a_tnch
, ap
->a_cred
, LK_SHARED
, &tvp
);
1161 * Clean-up the deletion target to avoid .fuse_hidden*
1163 * NOTE: XXX v_opencount check does not take mmap/filepointers
1166 if (tvp
->v_opencount
== 0) {
1167 vinvalbuf(tvp
, V_SAVE
, 0, 0);
1168 fuse_release(fmp
, tfnp
);
1175 /* Disallow cross-device renames.
1176 * Why isn't this done by the caller? */
1177 if (fvp
->v_mount
!= tdvp
->v_mount
||
1178 (tvp
&& fvp
->v_mount
!= tvp
->v_mount
)) {
1190 if (ffnp
->type
== VDIR
&& tfnp
->type
== VDIR
) {
1191 /* depend on RPC to check if empty */
1192 } else if (ffnp
->type
== VDIR
&& tfnp
->type
!= VDIR
) {
1195 } else if (ffnp
->type
!= VDIR
&& tfnp
->type
== VDIR
) {
1199 KKASSERT(ffnp
->type
!= VDIR
&& tfnp
->type
!= VDIR
);
1202 fip
= fuse_ipc_get(fmp
, sizeof(*fri
) + fncp
->nc_nlen
+
1204 /* There is also fuse_rename2_in with flags. */
1205 fri
= fuse_ipc_fill(fip
, FUSE_RENAME
, fdfnp
->ino
, ap
->a_cred
);
1206 fri
->newdir
= tdfnp
->ino
;
1208 p
= (char*)(fri
+ 1);
1209 memcpy(p
, fncp
->nc_name
, fncp
->nc_nlen
);
1210 p
[fncp
->nc_nlen
] = '\0';
1211 memcpy(p
+ fncp
->nc_nlen
+ 1, tncp
->nc_name
, tncp
->nc_nlen
);
1212 p
[fncp
->nc_nlen
+ 1 + tncp
->nc_nlen
] = '\0';
1214 error
= fuse_ipc_tx(fip
);
1219 if (fncp
->nc_nlen
!= tncp
->nc_nlen
||
1220 memcmp(fncp
->nc_name
, tncp
->nc_name
, fncp
->nc_nlen
)) {
1221 newname
= kmalloc(tncp
->nc_nlen
+ 1, M_TEMP
, M_WAITOK
| M_ZERO
);
1223 memcpy(newname
, tncp
->nc_name
, tncp
->nc_nlen
);
1224 newname
[tncp
->nc_nlen
] = '\0';
1225 fuse_dbg("newname=\"%s\"\n", newname
);
1229 mtx_lock(&tdfnp
->node_lock
);
1230 mtx_lock(&fdfnp
->node_lock
);
1231 mtx_lock(&ffnp
->node_lock
);
1234 fuse_knote(tdvp
, NOTE_DELETE
);
1237 mtx_unlock(&ffnp
->node_lock
);
1238 mtx_unlock(&fdfnp
->node_lock
);
1239 mtx_unlock(&tdfnp
->node_lock
);
1241 cache_rename(ap
->a_fnch
, ap
->a_tnch
);
1242 fuse_knote(fdvp
, NOTE_WRITE
);
1243 fuse_knote(tdvp
, NOTE_WRITE
);
1244 fuse_knote(fvp
, NOTE_RENAME
);
1253 fuse_vop_nsymlink(struct vop_nsymlink_args
*ap
)
1255 struct vnode
*dvp
= ap
->a_dvp
;
1257 struct namecache
*ncp
= ap
->a_nch
->ncp
;
1258 struct fuse_mount
*fmp
= VFSTOFUSE(dvp
->v_mount
);
1259 struct fuse_node
*dfnp
= VTOI(dvp
);
1260 struct fuse_node
*fnp
;
1261 struct fuse_ipc
*fip
;
1262 struct fuse_entry_out
*feo
;
1266 if (fuse_test_dead(fmp
))
1269 if (fuse_test_nosys(fmp
, FUSE_SYMLINK
))
1272 fip
= fuse_ipc_get(fmp
, strlen(ap
->a_target
) + 1 + ncp
->nc_nlen
+ 1);
1273 p
= fuse_ipc_fill(fip
, FUSE_SYMLINK
, dfnp
->ino
, ap
->a_cred
);
1275 memcpy(p
, ncp
->nc_name
, ncp
->nc_nlen
);
1276 p
[ncp
->nc_nlen
] = '\0';
1277 memcpy(p
+ ncp
->nc_nlen
+ 1, ap
->a_target
, strlen(ap
->a_target
) + 1);
1279 error
= fuse_ipc_tx(fip
);
1283 feo
= fuse_out_data(fip
);
1284 if (IFTOVT(feo
->attr
.mode
) != VLNK
) {
1289 error
= fuse_alloc_node(fmp
, dfnp
, feo
->nodeid
, VLNK
, &vp
);
1292 KKASSERT(vn_islocked(vp
));
1295 mtx_lock(&fnp
->node_lock
);
1296 fuse_set_attr(fnp
, &feo
->attr
);
1297 mtx_unlock(&fnp
->node_lock
);
1299 cache_setunresolved(ap
->a_nch
);
1300 cache_setvp(ap
->a_nch
, vp
);
1302 fuse_knote(vp
, NOTE_WRITE
);
1308 //feo->entry_valid_nsec;
1309 //feo->attr_valid_nsec;
1317 fuse_vop_read(struct vop_read_args
*ap
)
1320 struct vnode
*vp
= ap
->a_vp
;
1321 struct uio
*uio
= ap
->a_uio
;
1322 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
1323 struct fuse_node
*fnp
;
1334 if (fuse_test_dead(fmp
))
1336 if (fuse_test_nosys(fmp
, FUSE_READ
))
1338 if (uio
->uio_offset
< 0)
1340 if (vp
->v_type
!= VREG
)
1344 * Extract node, try to shortcut the operation through
1345 * the vM page cache, allowing us to avoid buffer cache
1349 resid
= uio
->uio_resid
;
1350 seqcount
= ap
->a_ioflag
>> IO_SEQSHIFT
;
1351 error
= vop_helper_read_shortcut(ap
);
1354 if (uio
->uio_resid
== 0) {
1361 * Fall-through to our normal read code.
1363 while (uio
->uio_resid
> 0 && uio
->uio_offset
< fnp
->size
) {
1365 * Use buffer cache I/O (via fuse_vop_strategy)
1367 offset
= (size_t)uio
->uio_offset
& FUSE_BLKMASK64
;
1368 base_offset
= (off_t
)uio
->uio_offset
- offset
;
1369 bp
= getcacheblk(vp
, base_offset
,
1370 FUSE_BLKSIZE
, GETBLK_KVABIO
);
1372 if (1 /* fuse_cluster_rd_enable XXX sysctl */) {
1373 error
= cluster_readx(vp
, fnp
->size
,
1376 B_NOTMETA
| B_KVABIO
,
1378 seqcount
* MAXBSIZE
,
1381 error
= bread_kvabio(vp
, base_offset
,
1386 kprintf("fuse_vop_read bread error %d\n",
1392 * Only do this if the VOP is coming from a normal
1393 * read/write. The VM system handles the case for
1396 if (uio
->uio_segflg
!= UIO_NOCOPY
)
1399 bp
->b_flags
|= B_CLUSTEROK
;
1403 * Figure out how many bytes we can actually copy this loop.
1405 len
= FUSE_BLKSIZE
- offset
;
1406 if (len
> uio
->uio_resid
)
1407 len
= uio
->uio_resid
;
1408 if (len
> fnp
->size
- uio
->uio_offset
)
1409 len
= (size_t)(fnp
->size
- uio
->uio_offset
);
1411 error
= uiomovebp(bp
, (char *)bp
->b_data
+ offset
, len
, uio
);
1414 kprintf("fuse_vop_read uiomove error %d\n", error
);
1420 if (fnp
->accessed
== 0) {
1421 mtx_lock(&fnp
->node_lock
);
1423 mtx_unlock(&fnp
->node_lock
);
1429 fuse_vop_write(struct vop_write_args
*ap
)
1431 struct vnode
*vp
= ap
->a_vp
;
1432 struct uio
*uio
= ap
->a_uio
;
1433 struct thread
*td
= uio
->uio_td
;
1434 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
1435 struct fuse_node
*fnp
;
1443 struct rlimit limit
;
1446 int ioflag
= ap
->a_ioflag
;
1450 if (fuse_test_dead(fmp
))
1453 if (fuse_test_nosys(fmp
, FUSE_WRITE
))
1457 if (uio
->uio_resid
== 0)
1462 if (vp
->v_type
!= VREG
)
1464 seqcount
= ioflag
>> IO_SEQSHIFT
;
1466 mtx_lock(&fnp
->node_lock
);
1468 oldsize
= fnp
->size
;
1469 newsize
= uio
->uio_offset
+ uio
->uio_resid
;
1470 if (newsize
< oldsize
)
1472 if (ioflag
& IO_APPEND
)
1473 uio
->uio_offset
= fnp
->size
;
1476 * Check for illegal write offsets.
1478 if (newsize
> FUSE_MAXFILESIZE
) {
1484 * NOTE: Ignore if UIO does not come from a user thread (e.g. VN).
1486 if (vp
->v_type
== VREG
&& td
!= NULL
&& td
->td_lwp
!= NULL
) {
1487 error
= kern_getrlimit(RLIMIT_FSIZE
, &limit
);
1490 if (newsize
> limit
.rlim_cur
) {
1491 ksignal(td
->td_proc
, SIGXFSZ
);
1498 * Extend the file's size if necessary
1500 extended
= (newsize
> fnp
->size
);
1502 while (uio
->uio_resid
> 0) {
1506 * Don't completely blow out running buffer I/O
1507 * when being hit from the pageout daemon.
1509 if (uio
->uio_segflg
== UIO_NOCOPY
&&
1510 (ioflag
& IO_RECURSE
) == 0)
1512 bwillwrite(FUSE_BLKSIZE
);
1516 * Use buffer cache I/O (via fuse_vop_strategy)
1518 * Calculate the maximum bytes we can write to the buffer at
1519 * this offset (after resizing).
1521 offset
= (size_t)uio
->uio_offset
& FUSE_BLKMASK64
;
1522 base_offset
= (off_t
)uio
->uio_offset
- offset
;
1523 len
= uio
->uio_resid
;
1524 if (len
> FUSE_BLKSIZE
- offset
)
1525 len
= FUSE_BLKSIZE
- offset
;
1529 if ((uio
->uio_offset
+ len
) > fnp
->size
) {
1530 trivial
= (uio
->uio_offset
<= fnp
->size
);
1531 error
= fuse_reg_resize(vp
, uio
->uio_offset
+ len
,
1533 kflags
|= NOTE_EXTEND
;
1537 if (base_offset
+ len
== FUSE_BLKSIZE
)
1544 if (uio
->uio_segflg
== UIO_NOCOPY
) {
1546 * Issue a write with the same data backing
1550 base_offset
, FUSE_BLKSIZE
,
1551 GETBLK_BHEAVY
| GETBLK_KVABIO
, 0);
1552 if ((bp
->b_flags
& B_CACHE
) == 0) {
1554 error
= bread_kvabio(vp
,
1555 base_offset
, FUSE_BLKSIZE
,
1558 } else if (trivial
) {
1560 * We are entirely overwriting the buffer, but
1561 * may still have to zero it.
1564 base_offset
, FUSE_BLKSIZE
,
1565 GETBLK_BHEAVY
| GETBLK_KVABIO
, 0);
1566 if ((bp
->b_flags
& B_CACHE
) == 0)
1570 * Partial overwrite, read in any missing bits
1571 * then replace the portion being overwritten.
1573 error
= bread_kvabio(vp
, base_offset
, FUSE_BLKSIZE
, &bp
);
1584 * Ok, copy the data in
1587 error
= uiomovebp(bp
, (char *)bp
->b_data
+ offset
, len
, uio
);
1588 kflags
|= NOTE_WRITE
;
1591 kprintf("fuse_vop_write uiomove error %d\n", error
);
1596 if (ioflag
& IO_SYNC
) {
1598 } else if ((ioflag
& IO_DIRECT
) && endofblk
) {
1600 } else if (ioflag
& IO_ASYNC
) {
1602 } else if (vp
->v_mount
->mnt_flag
& MNT_NOCLUSTERW
) {
1605 bp
->b_flags
|= B_CLUSTEROK
;
1606 cluster_write(bp
, fnp
->size
, FUSE_BLKSIZE
, seqcount
);
1614 (void)fuse_reg_resize(vp
, oldsize
, trivial
);
1615 kflags
&= ~NOTE_EXTEND
;
1621 * Currently we don't set the mtime on files modified via mmap()
1622 * because we can't tell the difference between those modifications
1623 * and an attempt by the pageout daemon to flush fuse pages to
1626 if (uio
->uio_segflg
== UIO_NOCOPY
) {
1627 if (vp
->v_flag
& VLASTWRITETS
) {
1628 fnp
->attr
.va_mtime
.tv_sec
= vp
->v_lastwrite_ts
.tv_sec
;
1629 fnp
->attr
.va_mtime
.tv_nsec
= vp
->v_lastwrite_ts
.tv_nsec
;
1633 vclrflags(vp
, VLASTWRITETS
);
1639 if (fnp
->attr
.va_mode
& (S_ISUID
| S_ISGID
)) {
1640 if (caps_priv_check(ap
->a_cred
, SYSCAP_NOVFS_RETAINSUGID
))
1641 fnp
->attr
.va_mode
&= ~(S_ISUID
| S_ISGID
);
1644 mtx_unlock(&fnp
->node_lock
);
1647 fuse_knote(vp
, kflags
);
1653 * Issue I/O RPC to support thread. This can be issued from sensitive
1654 * kernel threads such as the pageout daemon, so we have to queue the
1655 * I/O to our support thread and return. We cannot block in here.
1658 fuse_vop_strategy(struct vop_strategy_args
*ap
)
1660 struct bio
*bio
= ap
->a_bio
;
1661 struct buf
*bp
= bio
->bio_buf
;
1662 struct vnode
*vp
= ap
->a_vp
;
1663 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
1664 //struct fuse_node *fnp = VTOI(vp);
1666 fuse_dbg("ino=%ju b_cmd=%d\n", VTOI(ap
->a_vp
)->ino
, bp
->b_cmd
);
1668 if (vp
->v_type
!= VREG
) {
1669 bp
->b_resid
= bp
->b_bcount
;
1670 bp
->b_flags
|= B_ERROR
| B_INVAL
;
1671 bp
->b_error
= EINVAL
;
1676 bp
->b_flags
&= ~(B_ERROR
| B_INVAL
);
1680 if (vn_cache_strategy(vp
, bio
) == 0) {
1681 bio
->bio_driver_info
= vp
;
1682 spin_lock(&fmp
->helper_spin
);
1683 TAILQ_INSERT_TAIL(&fmp
->bioq
, bio
, bio_act
);
1684 spin_unlock(&fmp
->helper_spin
);
1685 wakeup(&fmp
->helper_td
);
1689 bio
->bio_driver_info
= vp
;
1690 spin_lock(&fmp
->helper_spin
);
1691 TAILQ_INSERT_TAIL(&fmp
->bioq
, bio
, bio_act
);
1692 spin_unlock(&fmp
->helper_spin
);
1693 wakeup(&fmp
->helper_td
);
1696 bp
->b_flags
|= B_INVAL
;
1697 bp
->b_error
= EINVAL
;
1705 * Just make the backing store appear to be contiguous so write clustering
1706 * works. The strategy function will take it from there. Use MAXBSIZE
1707 * chunks as a micro-optimization to make random flushes use reasonable
1711 fuse_bmap(struct vop_bmap_args
*ap
)
1713 if (ap
->a_doffsetp
!= NULL
)
1714 *ap
->a_doffsetp
= ap
->a_loffset
;
1715 if (ap
->a_runp
!= NULL
)
1716 *ap
->a_runp
= MAXBSIZE
- (ap
->a_loffset
& (MAXBSIZE
- 1));
1717 if (ap
->a_runb
!= NULL
)
1718 *ap
->a_runb
= ap
->a_loffset
& (MAXBSIZE
- 1);
1724 fuse_advlock(struct vop_advlock_args
*ap
)
1726 struct vnode
*vp
= ap
->a_vp
;
1727 struct fuse_node
*fnp
= VTOI(vp
);
1730 error
= lf_advlock(ap
, &fnp
->advlock
, fnp
->size
);
1736 fuse_vop_print(struct vop_print_args
*ap
)
1738 struct fuse_node
*fnp
= VTOI(ap
->a_vp
);
1740 fuse_print("tag VT_FUSE, node %p, ino %ju\n",
1741 fnp
, VTOI(ap
->a_vp
)->ino
);
1747 fuse_vop_inactive(struct vop_inactive_args
*ap
)
1749 struct vnode
*vp
= ap
->a_vp
;
1750 struct mount
*mp
= vp
->v_mount
;
1751 struct fuse_node
*fnp
= VTOI(vp
);
1752 struct fuse_mount
*fmp
= VFSTOFUSE(mp
);
1753 struct vm_object
*obj
;
1761 * For now synchronize all dirty data on INACTIVE instead
1764 * Get all dirty data out... mmap'd pages and the buffer cache,
1765 * so we can issue FUSE_RELEASE here.
1767 fuse_dbg("ino=%ju\n", fnp
->ino
);
1769 if ((obj
= vp
->v_object
) != NULL
)
1770 vm_object_page_clean(obj
, 0, 0, 0);
1771 VOP_FSYNC(vp
, MNT_WAIT
, 0);
1776 fuse_release(fmp
, fnp
);
1782 * Reclaim inactive vnode and destroy the related fuse_node. We
1783 * never destroy the root fuse_node here.
1786 fuse_vop_reclaim(struct vop_reclaim_args
*ap
)
1788 struct vnode
*vp
= ap
->a_vp
;
1789 struct fuse_mount
*fmp
= VFSTOFUSE(vp
->v_mount
);
1790 struct fuse_node
*fnp
= VTOI(vp
);
1795 fuse_dbg("ino=%ju\n", fnp
->ino
);
1797 if (fnp
!= fmp
->rfnp
)
1798 fuse_node_free(fmp
, fnp
);
1806 fuse_vop_mountctl(struct vop_mountctl_args
*ap
)
1811 mp
= ap
->a_head
.a_ops
->head
.vv_mount
;
1812 lwkt_gettoken(&mp
->mnt_token
);
1815 //case MOUNTCTL_MOUNTFLAGS:
1819 res
= vop_stdmountctl(ap
);
1823 lwkt_reltoken(&mp
->mnt_token
);
1827 static void filt_fusedetach(struct knote
*);
1828 static int filt_fuseread(struct knote
*, long);
1829 static int filt_fusewrite(struct knote
*, long);
1830 static int filt_fusevnode(struct knote
*, long);
1832 static struct filterops fuseread_filtops
=
1833 { FILTEROP_ISFD
| FILTEROP_MPSAFE
,
1834 NULL
, filt_fusedetach
, filt_fuseread
};
1835 static struct filterops fusewrite_filtops
=
1836 { FILTEROP_ISFD
| FILTEROP_MPSAFE
,
1837 NULL
, filt_fusedetach
, filt_fusewrite
};
1838 static struct filterops fusevnode_filtops
=
1839 { FILTEROP_ISFD
| FILTEROP_MPSAFE
,
1840 NULL
, filt_fusedetach
, filt_fusevnode
};
1843 fuse_kqfilter(struct vop_kqfilter_args
*ap
)
1845 struct vnode
*vp
= ap
->a_vp
;
1846 struct knote
*kn
= ap
->a_kn
;
1848 switch (kn
->kn_filter
) {
1850 kn
->kn_fop
= &fuseread_filtops
;
1853 kn
->kn_fop
= &fusewrite_filtops
;
1856 kn
->kn_fop
= &fusevnode_filtops
;
1862 kn
->kn_hook
= (caddr_t
)vp
;
1863 knote_insert(&vp
->v_pollinfo
.vpi_kqinfo
.ki_note
, kn
);
1869 filt_fusedetach(struct knote
*kn
)
1871 struct vnode
*vp
= (void*)kn
->kn_hook
;
1873 knote_remove(&vp
->v_pollinfo
.vpi_kqinfo
.ki_note
, kn
);
1877 filt_fuseread(struct knote
*kn
, long hint
)
1879 struct vnode
*vp
= (void*)kn
->kn_hook
;
1880 struct fuse_node
*fnp
= VTOI(vp
);
1883 if (hint
== NOTE_REVOKE
) {
1884 kn
->kn_flags
|= (EV_EOF
| EV_NODATA
| EV_ONESHOT
);
1889 * Interlock against MP races when performing this function.
1891 mtx_lock(&fnp
->node_lock
);
1892 off
= fnp
->size
- kn
->kn_fp
->f_offset
;
1893 kn
->kn_data
= (off
< INTPTR_MAX
) ? off
: INTPTR_MAX
;
1894 if (kn
->kn_sfflags
& NOTE_OLDAPI
) {
1895 mtx_unlock(&fnp
->node_lock
);
1899 kn
->kn_data
= (off
< INTPTR_MAX
) ? off
: INTPTR_MAX
;
1900 mtx_unlock(&fnp
->node_lock
);
1902 return kn
->kn_data
!= 0;
1906 filt_fusewrite(struct knote
*kn
, long hint
)
1908 if (hint
== NOTE_REVOKE
)
1909 kn
->kn_flags
|= (EV_EOF
| EV_NODATA
| EV_ONESHOT
);
1916 filt_fusevnode(struct knote
*kn
, long hint
)
1918 if (kn
->kn_sfflags
& hint
)
1919 kn
->kn_fflags
|= hint
;
1920 if (hint
== NOTE_REVOKE
) {
1921 kn
->kn_flags
|= (EV_EOF
| EV_NODATA
);
1925 return kn
->kn_fflags
!= 0;
1929 fuse_vop_getpages(struct vop_getpages_args
*ap
)
1931 if (!ap
->a_vp
->v_mount
)
1932 return VM_PAGER_BAD
;
1934 return vnode_pager_generic_getpages(ap
->a_vp
, ap
->a_m
, ap
->a_count
,
1935 ap
->a_reqpage
, ap
->a_seqaccess
);
1939 fuse_vop_putpages(struct vop_putpages_args
*ap
)
1941 if (!ap
->a_vp
->v_mount
)
1942 return VM_PAGER_BAD
;
1944 return vnode_pager_generic_putpages(ap
->a_vp
, ap
->a_m
, ap
->a_count
,
1945 ap
->a_flags
, ap
->a_rtvals
);
1949 * Resizes the object associated to the regular file pointed to by vp to
1950 * the size newsize. 'vp' must point to a vnode that represents a regular
1951 * file. 'newsize' must be positive.
1953 * pass NVEXTF_TRIVIAL when buf content will be overwritten, otherwise set 0
1954 * to be zero filled.
1956 * Returns zero on success or an appropriate error code on failure.
1958 * Caller must hold the node exclusively locked.
1961 fuse_reg_resize(struct vnode
*vp
, off_t newsize
, int trivial
)
1963 struct fuse_node
*fnp
;
1969 KKASSERT(vp
->v_type
== VREG
);
1970 KKASSERT(newsize
>= 0);
1975 oldsize
= fnp
->size
;
1976 fnp
->size
= newsize
;
1977 fnp
->attr
.va_size
= newsize
;
1978 fnp
->sizeoverride
= 1;
1983 * The backing VM object may contain VM pages as well as swap
1984 * assignments if we previously renamed main object pages into
1985 * it during deactivation.
1987 if (newsize
< oldsize
) {
1988 error
= nvtruncbuf(vp
, newsize
, FUSE_BLKSIZE
, -1, nvextflags
);
1992 nblksize
= FUSE_BLKSIZE
;
1995 nvextflags
|= NVEXTF_TRIVIAL
;
1997 error
= nvextendbuf(vp
, oldsize
, newsize
,
1998 FUSE_BLKSIZE
, nblksize
,
1999 -1, -1, nvextflags
);
2005 * Fuse strategy helper thread
2008 fuse_io_thread(void *arg
)
2010 struct fuse_mount
*fmp
= arg
;
2013 while (fmp
->dead
== 0) {
2014 tsleep(&fmp
->helper_td
, 0, "fuse_wio", 0);
2015 spin_lock(&fmp
->helper_spin
);
2016 while ((bio
= TAILQ_FIRST(&fmp
->bioq
)) != NULL
) {
2017 TAILQ_REMOVE(&fmp
->bioq
, bio
, bio_act
);
2018 spin_unlock(&fmp
->helper_spin
);
2019 fuse_io_execute(fmp
, bio
);
2020 spin_lock(&fmp
->helper_spin
);
2022 spin_unlock(&fmp
->helper_spin
);
2024 fmp
->helper_td
= NULL
;
2025 wakeup(&fmp
->helper_td
);
2032 fuse_io_execute(struct fuse_mount
*fmp
, struct bio
*bio
)
2034 struct buf
*bp
= bio
->bio_buf
;
2035 struct vnode
*vp
= bio
->bio_driver_info
;
2036 struct fuse_node
*fnp
= VTOI(vp
);
2037 struct fuse_ipc
*fip
;
2038 struct fuse_read_in
*fri
;
2039 struct fuse_write_in
*fwi
;
2040 struct fuse_write_out
*fwo
;
2045 fip
= fuse_ipc_get(fmp
, sizeof(*fri
));
2046 fri
= fuse_ipc_fill(fip
, FUSE_READ
, fnp
->ino
, proc0
.p_ucred
);
2047 fri
->offset
= bp
->b_loffset
;
2048 fri
->size
= bp
->b_bcount
;
2051 error
= fuse_ipc_tx(fip
);
2054 memcpy(bp
->b_data
, fuse_out_data(fip
),
2055 fuse_out_data_size(fip
));
2060 bp
->b_resid
= bp
->b_bcount
;
2061 bp
->b_flags
|= B_ERROR
| B_INVAL
;
2062 bp
->b_error
= EINVAL
;
2067 fip
= fuse_ipc_get(fmp
, sizeof(*fwi
) + bp
->b_bcount
);
2068 fwi
= fuse_ipc_fill(fip
, FUSE_WRITE
, fnp
->ino
, proc0
.p_ucred
);
2069 fwi
->offset
= bp
->b_loffset
;
2070 fwi
->size
= bp
->b_bcount
;
2074 * Handle truncated buffer at file EOF
2076 if (fwi
->offset
+ fwi
->size
> fnp
->size
) {
2077 if (fwi
->offset
>= fnp
->size
) {
2081 fwi
->size
= fnp
->size
- fwi
->offset
;
2084 memcpy((void *)(fwi
+ 1), bp
->b_data
, bp
->b_bcount
);
2086 error
= fuse_ipc_tx(fip
);
2088 fwo
= fuse_out_data(fip
);
2090 bp
->b_resid
= bp
->b_bcount
- fwo
->size
;
2095 bp
->b_resid
= bp
->b_bcount
;
2096 bp
->b_flags
|= B_ERROR
| B_INVAL
;
2097 bp
->b_error
= EINVAL
;
2102 bp
->b_resid
= bp
->b_bcount
;
2103 bp
->b_flags
|= B_ERROR
| B_INVAL
;
2104 bp
->b_error
= EINVAL
;
2111 bp
->b_resid
= bp
->b_bcount
;
2112 bp
->b_flags
|= B_ERROR
| B_INVAL
;
2113 bp
->b_error
= EINVAL
;
2118 fuse_release(struct fuse_mount
*fmp
, struct fuse_node
*fnp
)
2120 struct fuse_ipc
*fip
;
2121 struct fuse_release_in
*fri
;
2126 * Release the file-handle to clean-up the userland side.
2128 if (fnp
->type
== VDIR
)
2129 op
= FUSE_RELEASEDIR
;
2133 fip
= fuse_ipc_get(fmp
, sizeof(*fri
));
2134 fri
= fuse_ipc_fill(fip
, op
, fnp
->ino
, NULL
);
2137 fri
->release_flags
= FUSE_RELEASE_FLUSH
;
2138 //fri->lock_owner = ...;
2141 error
= fuse_ipc_tx(fip
);
2147 fip
= fuse_ipc_get(fmp
, sizeof(*fri
));
2148 fri
= fuse_ipc_fill(fip
, op
, fnp
->ino
, NULL
);
2149 error
= fuse_ipc_tx(fip
);
2155 if (fnp
->nlookup
&& fnp
->ino
!= 1) {
2157 /* sshfs fails utterly if we issue FUSE_FORGET */
2158 error
= fuse_forget_node(fmp
, fnp
->ino
, fnp
->nlookup
, NULL
);
2166 struct vop_ops fuse_vnode_vops
= {
2167 .vop_default
= vop_defaultop
,
2168 .vop_access
= fuse_vop_access
,
2169 .vop_open
= fuse_vop_open
,
2170 .vop_close
= fuse_vop_close
,
2171 .vop_fsync
= fuse_vop_fsync
,
2172 .vop_getattr
= fuse_vop_getattr
,
2173 .vop_setattr
= fuse_vop_setattr
,
2174 .vop_nresolve
= fuse_vop_nresolve
,
2175 //.vop_nlookupdotdot = fuse_nlookupdotdot,
2176 .vop_nlink
= fuse_vop_nlink
,
2177 .vop_ncreate
= fuse_vop_ncreate
,
2178 .vop_nmknod
= fuse_vop_nmknod
,
2179 .vop_nremove
= fuse_vop_nremove
,
2180 .vop_nmkdir
= fuse_vop_nmkdir
,
2181 .vop_nrmdir
= fuse_vop_nrmdir
,
2182 .vop_pathconf
= fuse_vop_pathconf
,
2183 .vop_readdir
= fuse_vop_readdir
,
2184 .vop_readlink
= fuse_vop_readlink
,
2185 .vop_nrename
= fuse_vop_nrename
,
2186 .vop_nsymlink
= fuse_vop_nsymlink
,
2187 .vop_read
= fuse_vop_read
,
2188 .vop_write
= fuse_vop_write
,
2189 .vop_strategy
= fuse_vop_strategy
,
2190 .vop_bmap
= fuse_bmap
,
2191 .vop_advlock
= fuse_advlock
,
2192 .vop_print
= fuse_vop_print
,
2193 .vop_inactive
= fuse_vop_inactive
,
2194 .vop_reclaim
= fuse_vop_reclaim
,
2195 .vop_mountctl
= fuse_vop_mountctl
,
2196 .vop_kqfilter
= fuse_kqfilter
,
2197 .vop_getpages
= fuse_vop_getpages
,
2198 .vop_putpages
= fuse_vop_putpages
,
2201 struct vop_ops fuse_spec_vops
= {
2202 .vop_default
= vop_defaultop
,
2203 .vop_access
= fuse_vop_access
,
2204 .vop_close
= fuse_vop_close
,
2205 .vop_fsync
= fuse_vop_fsync
,
2206 .vop_getattr
= fuse_vop_getattr
,
2207 .vop_setattr
= fuse_vop_setattr
,
2208 .vop_read
= vop_stdnoread
,
2209 .vop_write
= vop_stdnowrite
,
2210 //.vop_markatime = fuse_vop_markatime,
2211 .vop_print
= fuse_vop_print
,
2212 .vop_inactive
= fuse_vop_inactive
,
2213 .vop_reclaim
= fuse_vop_reclaim
,