2 * FUSE: Filesystem in Userspace
3 * Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
5 * This program can be distributed under the terms of the GNU GPLv2.
6 * See the file COPYING.
11 * This file system mirrors the existing file system hierarchy of the
12 * system, starting at the root file system. This is implemented by
13 * just "passing through" all requests to the corresponding user-space
14 * libc functions. In contrast to passthrough.c and passthrough_fh.c,
15 * this implementation uses the low-level API. Its performance should
16 * be the least bad among the three, but many operations are not
17 * implemented. In particular, it is not possible to remove files (or
18 * directories) because the code necessary to defer actual removal
19 * until the file is not opened anymore would make the example much
22 * When writeback caching is enabled (-o writeback mount option), it
23 * is only possible to write to files for which the mounting user has
24 * read permissions. This is because the writeback cache requires the
25 * kernel to be able to issue read requests for all files (which the
26 * passthrough filesystem cannot satisfy if it can't read the file in
27 * the underlying filesystem).
31 * gcc -Wall passthrough_ll.c `pkg-config fuse3 --cflags --libs` -o
35 * \include passthrough_ll.c
38 #include "qemu/osdep.h"
39 #include "fuse_virtio.h"
40 #include "fuse_lowlevel.h"
53 #include <sys/syscall.h>
54 #include <sys/xattr.h>
57 #include "passthrough_helpers.h"
61 struct lo_inode
*inode
;
69 /* Maps FUSE fh or ino values to internal objects */
71 struct lo_map_elem
*elems
;
77 struct lo_inode
*next
; /* protected by lo->mutex */
78 struct lo_inode
*prev
; /* protected by lo->mutex */
83 uint64_t refcount
; /* protected by lo->mutex */
99 pthread_mutex_t mutex
;
109 struct lo_inode root
; /* protected by lo->mutex */
110 struct lo_map ino_map
; /* protected by lo->mutex */
111 struct lo_map dirp_map
; /* protected by lo->mutex */
112 struct lo_map fd_map
; /* protected by lo->mutex */
115 static const struct fuse_opt lo_opts
[] = {
116 { "writeback", offsetof(struct lo_data
, writeback
), 1 },
117 { "no_writeback", offsetof(struct lo_data
, writeback
), 0 },
118 { "source=%s", offsetof(struct lo_data
, source
), 0 },
119 { "flock", offsetof(struct lo_data
, flock
), 1 },
120 { "no_flock", offsetof(struct lo_data
, flock
), 0 },
121 { "xattr", offsetof(struct lo_data
, xattr
), 1 },
122 { "no_xattr", offsetof(struct lo_data
, xattr
), 0 },
123 { "timeout=%lf", offsetof(struct lo_data
, timeout
), 0 },
124 { "timeout=", offsetof(struct lo_data
, timeout_set
), 1 },
125 { "cache=never", offsetof(struct lo_data
, cache
), CACHE_NEVER
},
126 { "cache=auto", offsetof(struct lo_data
, cache
), CACHE_NORMAL
},
127 { "cache=always", offsetof(struct lo_data
, cache
), CACHE_ALWAYS
},
128 { "norace", offsetof(struct lo_data
, norace
), 1 },
132 static void unref_inode(struct lo_data
*lo
, struct lo_inode
*inode
, uint64_t n
);
134 static struct lo_inode
*lo_find(struct lo_data
*lo
, struct stat
*st
);
136 static int is_dot_or_dotdot(const char *name
)
138 return name
[0] == '.' &&
139 (name
[1] == '\0' || (name
[1] == '.' && name
[2] == '\0'));
142 /* Is `path` a single path component that is not "." or ".."? */
143 static int is_safe_path_component(const char *path
)
145 if (strchr(path
, '/')) {
149 return !is_dot_or_dotdot(path
);
152 static struct lo_data
*lo_data(fuse_req_t req
)
154 return (struct lo_data
*)fuse_req_userdata(req
);
157 static void lo_map_init(struct lo_map
*map
)
164 static void lo_map_destroy(struct lo_map
*map
)
169 static int lo_map_grow(struct lo_map
*map
, size_t new_nelems
)
171 struct lo_map_elem
*new_elems
;
174 if (new_nelems
<= map
->nelems
) {
178 new_elems
= realloc(map
->elems
, sizeof(map
->elems
[0]) * new_nelems
);
183 for (i
= map
->nelems
; i
< new_nelems
; i
++) {
184 new_elems
[i
].freelist
= i
+ 1;
185 new_elems
[i
].in_use
= false;
187 new_elems
[new_nelems
- 1].freelist
= -1;
189 map
->elems
= new_elems
;
190 map
->freelist
= map
->nelems
;
191 map
->nelems
= new_nelems
;
195 static struct lo_map_elem
*lo_map_alloc_elem(struct lo_map
*map
)
197 struct lo_map_elem
*elem
;
199 if (map
->freelist
== -1 && !lo_map_grow(map
, map
->nelems
+ 256)) {
203 elem
= &map
->elems
[map
->freelist
];
204 map
->freelist
= elem
->freelist
;
211 static struct lo_map_elem
*lo_map_reserve(struct lo_map
*map
, size_t key
)
215 if (!lo_map_grow(map
, key
+ 1)) {
219 for (prev
= &map
->freelist
; *prev
!= -1;
220 prev
= &map
->elems
[*prev
].freelist
) {
222 struct lo_map_elem
*elem
= &map
->elems
[key
];
224 *prev
= elem
->freelist
;
232 static struct lo_map_elem
*lo_map_get(struct lo_map
*map
, size_t key
)
234 if (key
>= map
->nelems
) {
237 if (!map
->elems
[key
].in_use
) {
240 return &map
->elems
[key
];
243 static void lo_map_remove(struct lo_map
*map
, size_t key
)
245 struct lo_map_elem
*elem
;
247 if (key
>= map
->nelems
) {
251 elem
= &map
->elems
[key
];
256 elem
->in_use
= false;
258 elem
->freelist
= map
->freelist
;
262 /* Assumes lo->mutex is held */
263 static ssize_t
lo_add_fd_mapping(fuse_req_t req
, int fd
)
265 struct lo_map_elem
*elem
;
267 elem
= lo_map_alloc_elem(&lo_data(req
)->fd_map
);
273 return elem
- lo_data(req
)->fd_map
.elems
;
276 /* Assumes lo->mutex is held */
277 static ssize_t
lo_add_dirp_mapping(fuse_req_t req
, struct lo_dirp
*dirp
)
279 struct lo_map_elem
*elem
;
281 elem
= lo_map_alloc_elem(&lo_data(req
)->dirp_map
);
287 return elem
- lo_data(req
)->dirp_map
.elems
;
290 /* Assumes lo->mutex is held */
291 static ssize_t
lo_add_inode_mapping(fuse_req_t req
, struct lo_inode
*inode
)
293 struct lo_map_elem
*elem
;
295 elem
= lo_map_alloc_elem(&lo_data(req
)->ino_map
);
301 return elem
- lo_data(req
)->ino_map
.elems
;
304 static struct lo_inode
*lo_inode(fuse_req_t req
, fuse_ino_t ino
)
306 struct lo_data
*lo
= lo_data(req
);
307 struct lo_map_elem
*elem
;
309 pthread_mutex_lock(&lo
->mutex
);
310 elem
= lo_map_get(&lo
->ino_map
, ino
);
311 pthread_mutex_unlock(&lo
->mutex
);
320 static int lo_fd(fuse_req_t req
, fuse_ino_t ino
)
322 struct lo_inode
*inode
= lo_inode(req
, ino
);
323 return inode
? inode
->fd
: -1;
326 static bool lo_debug(fuse_req_t req
)
328 return lo_data(req
)->debug
!= 0;
331 static void lo_init(void *userdata
, struct fuse_conn_info
*conn
)
333 struct lo_data
*lo
= (struct lo_data
*)userdata
;
335 if (conn
->capable
& FUSE_CAP_EXPORT_SUPPORT
) {
336 conn
->want
|= FUSE_CAP_EXPORT_SUPPORT
;
339 if (lo
->writeback
&& conn
->capable
& FUSE_CAP_WRITEBACK_CACHE
) {
341 fuse_log(FUSE_LOG_DEBUG
, "lo_init: activating writeback\n");
343 conn
->want
|= FUSE_CAP_WRITEBACK_CACHE
;
345 if (lo
->flock
&& conn
->capable
& FUSE_CAP_FLOCK_LOCKS
) {
347 fuse_log(FUSE_LOG_DEBUG
, "lo_init: activating flock locks\n");
349 conn
->want
|= FUSE_CAP_FLOCK_LOCKS
;
353 static void lo_getattr(fuse_req_t req
, fuse_ino_t ino
,
354 struct fuse_file_info
*fi
)
358 struct lo_data
*lo
= lo_data(req
);
363 fstatat(lo_fd(req
, ino
), "", &buf
, AT_EMPTY_PATH
| AT_SYMLINK_NOFOLLOW
);
365 return (void)fuse_reply_err(req
, errno
);
368 fuse_reply_attr(req
, &buf
, lo
->timeout
);
371 static int lo_parent_and_name(struct lo_data
*lo
, struct lo_inode
*inode
,
372 char path
[PATH_MAX
], struct lo_inode
**parent
)
382 sprintf(procname
, "/proc/self/fd/%i", inode
->fd
);
384 res
= readlink(procname
, path
, PATH_MAX
);
386 fuse_log(FUSE_LOG_WARNING
, "%s: readlink failed: %m\n", __func__
);
390 if (res
>= PATH_MAX
) {
391 fuse_log(FUSE_LOG_WARNING
, "%s: readlink overflowed\n", __func__
);
396 last
= strrchr(path
, '/');
398 /* Shouldn't happen */
401 "%s: INTERNAL ERROR: bad path read from proc\n", __func__
);
406 pthread_mutex_lock(&lo
->mutex
);
408 pthread_mutex_unlock(&lo
->mutex
);
411 res
= fstatat(AT_FDCWD
, last
== path
? "/" : path
, &stat
, 0);
414 fuse_log(FUSE_LOG_WARNING
,
415 "%s: failed to stat parent: %m\n", __func__
);
419 p
= lo_find(lo
, &stat
);
422 fuse_log(FUSE_LOG_WARNING
,
423 "%s: failed to find parent\n", __func__
);
429 res
= fstatat(p
->fd
, last
, &stat
, AT_SYMLINK_NOFOLLOW
);
432 fuse_log(FUSE_LOG_WARNING
,
433 "%s: failed to stat last\n", __func__
);
437 if (stat
.st_dev
!= inode
->dev
|| stat
.st_ino
!= inode
->ino
) {
439 fuse_log(FUSE_LOG_WARNING
,
440 "%s: failed to match last\n", __func__
);
445 memmove(path
, last
, strlen(last
) + 1);
450 unref_inode(lo
, p
, 1);
461 static int utimensat_empty(struct lo_data
*lo
, struct lo_inode
*inode
,
462 const struct timespec
*tv
)
465 struct lo_inode
*parent
;
468 if (inode
->is_symlink
) {
469 res
= utimensat(inode
->fd
, "", tv
, AT_EMPTY_PATH
);
470 if (res
== -1 && errno
== EINVAL
) {
471 /* Sorry, no race free way to set times on symlink. */
480 sprintf(path
, "/proc/self/fd/%i", inode
->fd
);
482 return utimensat(AT_FDCWD
, path
, tv
, 0);
485 res
= lo_parent_and_name(lo
, inode
, path
, &parent
);
487 res
= utimensat(parent
->fd
, path
, tv
, AT_SYMLINK_NOFOLLOW
);
488 unref_inode(lo
, parent
, 1);
494 static int lo_fi_fd(fuse_req_t req
, struct fuse_file_info
*fi
)
496 struct lo_data
*lo
= lo_data(req
);
497 struct lo_map_elem
*elem
;
499 pthread_mutex_lock(&lo
->mutex
);
500 elem
= lo_map_get(&lo
->fd_map
, fi
->fh
);
501 pthread_mutex_unlock(&lo
->mutex
);
510 static void lo_setattr(fuse_req_t req
, fuse_ino_t ino
, struct stat
*attr
,
511 int valid
, struct fuse_file_info
*fi
)
515 struct lo_data
*lo
= lo_data(req
);
516 struct lo_inode
*inode
;
521 inode
= lo_inode(req
, ino
);
523 fuse_reply_err(req
, EBADF
);
529 /* If fi->fh is invalid we'll report EBADF later */
531 fd
= lo_fi_fd(req
, fi
);
534 if (valid
& FUSE_SET_ATTR_MODE
) {
536 res
= fchmod(fd
, attr
->st_mode
);
538 sprintf(procname
, "/proc/self/fd/%i", ifd
);
539 res
= chmod(procname
, attr
->st_mode
);
545 if (valid
& (FUSE_SET_ATTR_UID
| FUSE_SET_ATTR_GID
)) {
546 uid_t uid
= (valid
& FUSE_SET_ATTR_UID
) ? attr
->st_uid
: (uid_t
)-1;
547 gid_t gid
= (valid
& FUSE_SET_ATTR_GID
) ? attr
->st_gid
: (gid_t
)-1;
549 res
= fchownat(ifd
, "", uid
, gid
, AT_EMPTY_PATH
| AT_SYMLINK_NOFOLLOW
);
554 if (valid
& FUSE_SET_ATTR_SIZE
) {
556 res
= ftruncate(fd
, attr
->st_size
);
558 sprintf(procname
, "/proc/self/fd/%i", ifd
);
559 res
= truncate(procname
, attr
->st_size
);
565 if (valid
& (FUSE_SET_ATTR_ATIME
| FUSE_SET_ATTR_MTIME
)) {
566 struct timespec tv
[2];
570 tv
[0].tv_nsec
= UTIME_OMIT
;
571 tv
[1].tv_nsec
= UTIME_OMIT
;
573 if (valid
& FUSE_SET_ATTR_ATIME_NOW
) {
574 tv
[0].tv_nsec
= UTIME_NOW
;
575 } else if (valid
& FUSE_SET_ATTR_ATIME
) {
576 tv
[0] = attr
->st_atim
;
579 if (valid
& FUSE_SET_ATTR_MTIME_NOW
) {
580 tv
[1].tv_nsec
= UTIME_NOW
;
581 } else if (valid
& FUSE_SET_ATTR_MTIME
) {
582 tv
[1] = attr
->st_mtim
;
586 res
= futimens(fd
, tv
);
588 res
= utimensat_empty(lo
, inode
, tv
);
595 return lo_getattr(req
, ino
, fi
);
599 fuse_reply_err(req
, saverr
);
602 static struct lo_inode
*lo_find(struct lo_data
*lo
, struct stat
*st
)
605 struct lo_inode
*ret
= NULL
;
607 pthread_mutex_lock(&lo
->mutex
);
608 for (p
= lo
->root
.next
; p
!= &lo
->root
; p
= p
->next
) {
609 if (p
->ino
== st
->st_ino
&& p
->dev
== st
->st_dev
) {
610 assert(p
->refcount
> 0);
616 pthread_mutex_unlock(&lo
->mutex
);
620 static int lo_do_lookup(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
621 struct fuse_entry_param
*e
)
626 struct lo_data
*lo
= lo_data(req
);
627 struct lo_inode
*inode
, *dir
= lo_inode(req
, parent
);
629 memset(e
, 0, sizeof(*e
));
630 e
->attr_timeout
= lo
->timeout
;
631 e
->entry_timeout
= lo
->timeout
;
633 /* Do not allow escaping root directory */
634 if (dir
== &lo
->root
&& strcmp(name
, "..") == 0) {
638 newfd
= openat(lo_fd(req
, parent
), name
, O_PATH
| O_NOFOLLOW
);
643 res
= fstatat(newfd
, "", &e
->attr
, AT_EMPTY_PATH
| AT_SYMLINK_NOFOLLOW
);
648 inode
= lo_find(lo_data(req
), &e
->attr
);
653 struct lo_inode
*prev
, *next
;
656 inode
= calloc(1, sizeof(struct lo_inode
));
661 inode
->is_symlink
= S_ISLNK(e
->attr
.st_mode
);
664 inode
->ino
= e
->attr
.st_ino
;
665 inode
->dev
= e
->attr
.st_dev
;
667 pthread_mutex_lock(&lo
->mutex
);
668 inode
->fuse_ino
= lo_add_inode_mapping(req
, inode
);
675 pthread_mutex_unlock(&lo
->mutex
);
677 e
->ino
= inode
->fuse_ino
;
680 fuse_log(FUSE_LOG_DEBUG
, " %lli/%s -> %lli\n",
681 (unsigned long long)parent
, name
, (unsigned long long)e
->ino
);
694 static void lo_lookup(fuse_req_t req
, fuse_ino_t parent
, const char *name
)
696 struct fuse_entry_param e
;
700 fuse_log(FUSE_LOG_DEBUG
, "lo_lookup(parent=%" PRIu64
", name=%s)\n",
705 * Don't use is_safe_path_component(), allow "." and ".." for NFS export
708 if (strchr(name
, '/')) {
709 fuse_reply_err(req
, EINVAL
);
713 err
= lo_do_lookup(req
, parent
, name
, &e
);
715 fuse_reply_err(req
, err
);
717 fuse_reply_entry(req
, &e
);
722 * On some archs, setres*id is limited to 2^16 but they
723 * provide setres*id32 variants that allow 2^32.
724 * Others just let setres*id do 2^32 anyway.
726 #ifdef SYS_setresgid32
727 #define OURSYS_setresgid SYS_setresgid32
729 #define OURSYS_setresgid SYS_setresgid
732 #ifdef SYS_setresuid32
733 #define OURSYS_setresuid SYS_setresuid32
735 #define OURSYS_setresuid SYS_setresuid
739 * Change to uid/gid of caller so that file is created with
740 * ownership of caller.
741 * TODO: What about selinux context?
743 static int lo_change_cred(fuse_req_t req
, struct lo_cred
*old
)
747 old
->euid
= geteuid();
748 old
->egid
= getegid();
750 res
= syscall(OURSYS_setresgid
, -1, fuse_req_ctx(req
)->gid
, -1);
755 res
= syscall(OURSYS_setresuid
, -1, fuse_req_ctx(req
)->uid
, -1);
757 int errno_save
= errno
;
759 syscall(OURSYS_setresgid
, -1, old
->egid
, -1);
766 /* Regain Privileges */
767 static void lo_restore_cred(struct lo_cred
*old
)
771 res
= syscall(OURSYS_setresuid
, -1, old
->euid
, -1);
773 fuse_log(FUSE_LOG_ERR
, "seteuid(%u): %m\n", old
->euid
);
777 res
= syscall(OURSYS_setresgid
, -1, old
->egid
, -1);
779 fuse_log(FUSE_LOG_ERR
, "setegid(%u): %m\n", old
->egid
);
784 static void lo_mknod_symlink(fuse_req_t req
, fuse_ino_t parent
,
785 const char *name
, mode_t mode
, dev_t rdev
,
790 struct lo_inode
*dir
;
791 struct fuse_entry_param e
;
792 struct lo_cred old
= {};
794 if (!is_safe_path_component(name
)) {
795 fuse_reply_err(req
, EINVAL
);
799 dir
= lo_inode(req
, parent
);
801 fuse_reply_err(req
, EBADF
);
807 saverr
= lo_change_cred(req
, &old
);
812 res
= mknod_wrapper(dir
->fd
, name
, link
, mode
, rdev
);
816 lo_restore_cred(&old
);
822 saverr
= lo_do_lookup(req
, parent
, name
, &e
);
828 fuse_log(FUSE_LOG_DEBUG
, " %lli/%s -> %lli\n",
829 (unsigned long long)parent
, name
, (unsigned long long)e
.ino
);
832 fuse_reply_entry(req
, &e
);
836 fuse_reply_err(req
, saverr
);
839 static void lo_mknod(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
840 mode_t mode
, dev_t rdev
)
842 lo_mknod_symlink(req
, parent
, name
, mode
, rdev
, NULL
);
845 static void lo_mkdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
848 lo_mknod_symlink(req
, parent
, name
, S_IFDIR
| mode
, 0, NULL
);
851 static void lo_symlink(fuse_req_t req
, const char *link
, fuse_ino_t parent
,
854 lo_mknod_symlink(req
, parent
, name
, S_IFLNK
, 0, link
);
857 static int linkat_empty_nofollow(struct lo_data
*lo
, struct lo_inode
*inode
,
858 int dfd
, const char *name
)
861 struct lo_inode
*parent
;
864 if (inode
->is_symlink
) {
865 res
= linkat(inode
->fd
, "", dfd
, name
, AT_EMPTY_PATH
);
866 if (res
== -1 && (errno
== ENOENT
|| errno
== EINVAL
)) {
867 /* Sorry, no race free way to hard-link a symlink. */
877 sprintf(path
, "/proc/self/fd/%i", inode
->fd
);
879 return linkat(AT_FDCWD
, path
, dfd
, name
, AT_SYMLINK_FOLLOW
);
882 res
= lo_parent_and_name(lo
, inode
, path
, &parent
);
884 res
= linkat(parent
->fd
, path
, dfd
, name
, 0);
885 unref_inode(lo
, parent
, 1);
891 static void lo_link(fuse_req_t req
, fuse_ino_t ino
, fuse_ino_t parent
,
895 struct lo_data
*lo
= lo_data(req
);
896 struct lo_inode
*inode
;
897 struct fuse_entry_param e
;
900 if (!is_safe_path_component(name
)) {
901 fuse_reply_err(req
, EINVAL
);
905 inode
= lo_inode(req
, ino
);
907 fuse_reply_err(req
, EBADF
);
911 memset(&e
, 0, sizeof(struct fuse_entry_param
));
912 e
.attr_timeout
= lo
->timeout
;
913 e
.entry_timeout
= lo
->timeout
;
915 res
= linkat_empty_nofollow(lo
, inode
, lo_fd(req
, parent
), name
);
920 res
= fstatat(inode
->fd
, "", &e
.attr
, AT_EMPTY_PATH
| AT_SYMLINK_NOFOLLOW
);
925 pthread_mutex_lock(&lo
->mutex
);
927 pthread_mutex_unlock(&lo
->mutex
);
928 e
.ino
= inode
->fuse_ino
;
931 fuse_log(FUSE_LOG_DEBUG
, " %lli/%s -> %lli\n",
932 (unsigned long long)parent
, name
, (unsigned long long)e
.ino
);
935 fuse_reply_entry(req
, &e
);
940 fuse_reply_err(req
, saverr
);
943 static void lo_rmdir(fuse_req_t req
, fuse_ino_t parent
, const char *name
)
946 if (!is_safe_path_component(name
)) {
947 fuse_reply_err(req
, EINVAL
);
951 res
= unlinkat(lo_fd(req
, parent
), name
, AT_REMOVEDIR
);
953 fuse_reply_err(req
, res
== -1 ? errno
: 0);
956 static void lo_rename(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
957 fuse_ino_t newparent
, const char *newname
,
962 if (!is_safe_path_component(name
) || !is_safe_path_component(newname
)) {
963 fuse_reply_err(req
, EINVAL
);
968 fuse_reply_err(req
, EINVAL
);
972 res
= renameat(lo_fd(req
, parent
), name
, lo_fd(req
, newparent
), newname
);
974 fuse_reply_err(req
, res
== -1 ? errno
: 0);
977 static void lo_unlink(fuse_req_t req
, fuse_ino_t parent
, const char *name
)
981 if (!is_safe_path_component(name
)) {
982 fuse_reply_err(req
, EINVAL
);
986 res
= unlinkat(lo_fd(req
, parent
), name
, 0);
988 fuse_reply_err(req
, res
== -1 ? errno
: 0);
991 static void unref_inode(struct lo_data
*lo
, struct lo_inode
*inode
, uint64_t n
)
997 pthread_mutex_lock(&lo
->mutex
);
998 assert(inode
->refcount
>= n
);
999 inode
->refcount
-= n
;
1000 if (!inode
->refcount
) {
1001 struct lo_inode
*prev
, *next
;
1008 lo_map_remove(&lo
->ino_map
, inode
->fuse_ino
);
1009 pthread_mutex_unlock(&lo
->mutex
);
1013 pthread_mutex_unlock(&lo
->mutex
);
1017 static void lo_forget_one(fuse_req_t req
, fuse_ino_t ino
, uint64_t nlookup
)
1019 struct lo_data
*lo
= lo_data(req
);
1020 struct lo_inode
*inode
;
1022 inode
= lo_inode(req
, ino
);
1027 if (lo_debug(req
)) {
1028 fuse_log(FUSE_LOG_DEBUG
, " forget %lli %lli -%lli\n",
1029 (unsigned long long)ino
, (unsigned long long)inode
->refcount
,
1030 (unsigned long long)nlookup
);
1033 unref_inode(lo
, inode
, nlookup
);
1036 static void lo_forget(fuse_req_t req
, fuse_ino_t ino
, uint64_t nlookup
)
1038 lo_forget_one(req
, ino
, nlookup
);
1039 fuse_reply_none(req
);
1042 static void lo_forget_multi(fuse_req_t req
, size_t count
,
1043 struct fuse_forget_data
*forgets
)
1047 for (i
= 0; i
< count
; i
++) {
1048 lo_forget_one(req
, forgets
[i
].ino
, forgets
[i
].nlookup
);
1050 fuse_reply_none(req
);
1053 static void lo_readlink(fuse_req_t req
, fuse_ino_t ino
)
1055 char buf
[PATH_MAX
+ 1];
1058 res
= readlinkat(lo_fd(req
, ino
), "", buf
, sizeof(buf
));
1060 return (void)fuse_reply_err(req
, errno
);
1063 if (res
== sizeof(buf
)) {
1064 return (void)fuse_reply_err(req
, ENAMETOOLONG
);
1069 fuse_reply_readlink(req
, buf
);
1074 struct dirent
*entry
;
1078 static struct lo_dirp
*lo_dirp(fuse_req_t req
, struct fuse_file_info
*fi
)
1080 struct lo_data
*lo
= lo_data(req
);
1081 struct lo_map_elem
*elem
;
1083 pthread_mutex_lock(&lo
->mutex
);
1084 elem
= lo_map_get(&lo
->dirp_map
, fi
->fh
);
1085 pthread_mutex_unlock(&lo
->mutex
);
1093 static void lo_opendir(fuse_req_t req
, fuse_ino_t ino
,
1094 struct fuse_file_info
*fi
)
1097 struct lo_data
*lo
= lo_data(req
);
1102 d
= calloc(1, sizeof(struct lo_dirp
));
1107 fd
= openat(lo_fd(req
, ino
), ".", O_RDONLY
);
1112 d
->dp
= fdopendir(fd
);
1113 if (d
->dp
== NULL
) {
1120 pthread_mutex_lock(&lo
->mutex
);
1121 fh
= lo_add_dirp_mapping(req
, d
);
1122 pthread_mutex_unlock(&lo
->mutex
);
1128 if (lo
->cache
== CACHE_ALWAYS
) {
1131 fuse_reply_open(req
, fi
);
1146 fuse_reply_err(req
, error
);
1149 static void lo_do_readdir(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
1150 off_t offset
, struct fuse_file_info
*fi
, int plus
)
1152 struct lo_data
*lo
= lo_data(req
);
1154 struct lo_inode
*dinode
;
1160 dinode
= lo_inode(req
, ino
);
1165 d
= lo_dirp(req
, fi
);
1171 buf
= calloc(1, size
);
1177 if (offset
!= d
->offset
) {
1178 seekdir(d
->dp
, offset
);
1189 d
->entry
= readdir(d
->dp
);
1191 if (errno
) { /* Error */
1194 } else { /* End of stream */
1199 nextoff
= d
->entry
->d_off
;
1200 name
= d
->entry
->d_name
;
1202 fuse_ino_t entry_ino
= 0;
1203 struct fuse_entry_param e
= (struct fuse_entry_param
){
1204 .attr
.st_ino
= d
->entry
->d_ino
,
1205 .attr
.st_mode
= d
->entry
->d_type
<< 12,
1208 /* Hide root's parent directory */
1209 if (dinode
== &lo
->root
&& strcmp(name
, "..") == 0) {
1210 e
.attr
.st_ino
= lo
->root
.ino
;
1211 e
.attr
.st_mode
= DT_DIR
<< 12;
1215 if (!is_dot_or_dotdot(name
)) {
1216 err
= lo_do_lookup(req
, ino
, name
, &e
);
1223 entsize
= fuse_add_direntry_plus(req
, p
, rem
, name
, &e
, nextoff
);
1225 entsize
= fuse_add_direntry(req
, p
, rem
, name
, &e
.attr
, nextoff
);
1227 if (entsize
> rem
) {
1228 if (entry_ino
!= 0) {
1229 lo_forget_one(req
, entry_ino
, 1);
1238 d
->offset
= nextoff
;
1244 * If there's an error, we can only signal it if we haven't stored
1245 * any entries yet - otherwise we'd end up with wrong lookup
1246 * counts for the entries that are already in the buffer. So we
1247 * return what we've collected until that point.
1249 if (err
&& rem
== size
) {
1250 fuse_reply_err(req
, err
);
1252 fuse_reply_buf(req
, buf
, size
- rem
);
1257 static void lo_readdir(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
1258 off_t offset
, struct fuse_file_info
*fi
)
1260 lo_do_readdir(req
, ino
, size
, offset
, fi
, 0);
1263 static void lo_readdirplus(fuse_req_t req
, fuse_ino_t ino
, size_t size
,
1264 off_t offset
, struct fuse_file_info
*fi
)
1266 lo_do_readdir(req
, ino
, size
, offset
, fi
, 1);
1269 static void lo_releasedir(fuse_req_t req
, fuse_ino_t ino
,
1270 struct fuse_file_info
*fi
)
1272 struct lo_data
*lo
= lo_data(req
);
1277 d
= lo_dirp(req
, fi
);
1279 fuse_reply_err(req
, EBADF
);
1283 pthread_mutex_lock(&lo
->mutex
);
1284 lo_map_remove(&lo
->dirp_map
, fi
->fh
);
1285 pthread_mutex_unlock(&lo
->mutex
);
1289 fuse_reply_err(req
, 0);
1292 static void lo_create(fuse_req_t req
, fuse_ino_t parent
, const char *name
,
1293 mode_t mode
, struct fuse_file_info
*fi
)
1296 struct lo_data
*lo
= lo_data(req
);
1297 struct fuse_entry_param e
;
1299 struct lo_cred old
= {};
1301 if (lo_debug(req
)) {
1302 fuse_log(FUSE_LOG_DEBUG
, "lo_create(parent=%" PRIu64
", name=%s)\n",
1306 if (!is_safe_path_component(name
)) {
1307 fuse_reply_err(req
, EINVAL
);
1311 err
= lo_change_cred(req
, &old
);
1316 fd
= openat(lo_fd(req
, parent
), name
, (fi
->flags
| O_CREAT
) & ~O_NOFOLLOW
,
1318 err
= fd
== -1 ? errno
: 0;
1319 lo_restore_cred(&old
);
1324 pthread_mutex_lock(&lo
->mutex
);
1325 fh
= lo_add_fd_mapping(req
, fd
);
1326 pthread_mutex_unlock(&lo
->mutex
);
1329 fuse_reply_err(req
, ENOMEM
);
1334 err
= lo_do_lookup(req
, parent
, name
, &e
);
1336 if (lo
->cache
== CACHE_NEVER
) {
1338 } else if (lo
->cache
== CACHE_ALWAYS
) {
1344 fuse_reply_err(req
, err
);
1346 fuse_reply_create(req
, &e
, fi
);
1350 static void lo_fsyncdir(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
1351 struct fuse_file_info
*fi
)
1359 d
= lo_dirp(req
, fi
);
1361 fuse_reply_err(req
, EBADF
);
1367 res
= fdatasync(fd
);
1371 fuse_reply_err(req
, res
== -1 ? errno
: 0);
1374 static void lo_open(fuse_req_t req
, fuse_ino_t ino
, struct fuse_file_info
*fi
)
1379 struct lo_data
*lo
= lo_data(req
);
1381 if (lo_debug(req
)) {
1382 fuse_log(FUSE_LOG_DEBUG
, "lo_open(ino=%" PRIu64
", flags=%d)\n", ino
,
1387 * With writeback cache, kernel may send read requests even
1388 * when userspace opened write-only
1390 if (lo
->writeback
&& (fi
->flags
& O_ACCMODE
) == O_WRONLY
) {
1391 fi
->flags
&= ~O_ACCMODE
;
1392 fi
->flags
|= O_RDWR
;
1396 * With writeback cache, O_APPEND is handled by the kernel.
1397 * This breaks atomicity (since the file may change in the
1398 * underlying filesystem, so that the kernel's idea of the
1399 * end of the file isn't accurate anymore). In this example,
1400 * we just accept that. A more rigorous filesystem may want
1401 * to return an error here
1403 if (lo
->writeback
&& (fi
->flags
& O_APPEND
)) {
1404 fi
->flags
&= ~O_APPEND
;
1407 sprintf(buf
, "/proc/self/fd/%i", lo_fd(req
, ino
));
1408 fd
= open(buf
, fi
->flags
& ~O_NOFOLLOW
);
1410 return (void)fuse_reply_err(req
, errno
);
1413 pthread_mutex_lock(&lo
->mutex
);
1414 fh
= lo_add_fd_mapping(req
, fd
);
1415 pthread_mutex_unlock(&lo
->mutex
);
1418 fuse_reply_err(req
, ENOMEM
);
1423 if (lo
->cache
== CACHE_NEVER
) {
1425 } else if (lo
->cache
== CACHE_ALWAYS
) {
1428 fuse_reply_open(req
, fi
);
1431 static void lo_release(fuse_req_t req
, fuse_ino_t ino
,
1432 struct fuse_file_info
*fi
)
1434 struct lo_data
*lo
= lo_data(req
);
1439 fd
= lo_fi_fd(req
, fi
);
1441 pthread_mutex_lock(&lo
->mutex
);
1442 lo_map_remove(&lo
->fd_map
, fi
->fh
);
1443 pthread_mutex_unlock(&lo
->mutex
);
1446 fuse_reply_err(req
, 0);
1449 static void lo_flush(fuse_req_t req
, fuse_ino_t ino
, struct fuse_file_info
*fi
)
1453 res
= close(dup(lo_fi_fd(req
, fi
)));
1454 fuse_reply_err(req
, res
== -1 ? errno
: 0);
1457 static void lo_fsync(fuse_req_t req
, fuse_ino_t ino
, int datasync
,
1458 struct fuse_file_info
*fi
)
1465 fuse_log(FUSE_LOG_DEBUG
, "lo_fsync(ino=%" PRIu64
", fi=0x%p)\n", ino
,
1469 res
= asprintf(&buf
, "/proc/self/fd/%i", lo_fd(req
, ino
));
1471 return (void)fuse_reply_err(req
, errno
);
1474 fd
= open(buf
, O_RDWR
);
1477 return (void)fuse_reply_err(req
, errno
);
1480 fd
= lo_fi_fd(req
, fi
);
1484 res
= fdatasync(fd
);
1491 fuse_reply_err(req
, res
== -1 ? errno
: 0);
1494 static void lo_read(fuse_req_t req
, fuse_ino_t ino
, size_t size
, off_t offset
,
1495 struct fuse_file_info
*fi
)
1497 struct fuse_bufvec buf
= FUSE_BUFVEC_INIT(size
);
1499 if (lo_debug(req
)) {
1500 fuse_log(FUSE_LOG_DEBUG
,
1501 "lo_read(ino=%" PRIu64
", size=%zd, "
1503 ino
, size
, (unsigned long)offset
);
1506 buf
.buf
[0].flags
= FUSE_BUF_IS_FD
| FUSE_BUF_FD_SEEK
;
1507 buf
.buf
[0].fd
= lo_fi_fd(req
, fi
);
1508 buf
.buf
[0].pos
= offset
;
1510 fuse_reply_data(req
, &buf
);
1513 static void lo_write_buf(fuse_req_t req
, fuse_ino_t ino
,
1514 struct fuse_bufvec
*in_buf
, off_t off
,
1515 struct fuse_file_info
*fi
)
1519 struct fuse_bufvec out_buf
= FUSE_BUFVEC_INIT(fuse_buf_size(in_buf
));
1521 out_buf
.buf
[0].flags
= FUSE_BUF_IS_FD
| FUSE_BUF_FD_SEEK
;
1522 out_buf
.buf
[0].fd
= lo_fi_fd(req
, fi
);
1523 out_buf
.buf
[0].pos
= off
;
1525 if (lo_debug(req
)) {
1526 fuse_log(FUSE_LOG_DEBUG
,
1527 "lo_write(ino=%" PRIu64
", size=%zd, off=%lu)\n", ino
,
1528 out_buf
.buf
[0].size
, (unsigned long)off
);
1531 res
= fuse_buf_copy(&out_buf
, in_buf
);
1533 fuse_reply_err(req
, -res
);
1535 fuse_reply_write(req
, (size_t)res
);
1539 static void lo_statfs(fuse_req_t req
, fuse_ino_t ino
)
1542 struct statvfs stbuf
;
1544 res
= fstatvfs(lo_fd(req
, ino
), &stbuf
);
1546 fuse_reply_err(req
, errno
);
1548 fuse_reply_statfs(req
, &stbuf
);
1552 static void lo_fallocate(fuse_req_t req
, fuse_ino_t ino
, int mode
, off_t offset
,
1553 off_t length
, struct fuse_file_info
*fi
)
1555 int err
= EOPNOTSUPP
;
1558 #ifdef CONFIG_FALLOCATE
1559 err
= fallocate(lo_fi_fd(req
, fi
), mode
, offset
, length
);
1564 #elif defined(CONFIG_POSIX_FALLOCATE)
1566 fuse_reply_err(req
, EOPNOTSUPP
);
1570 err
= posix_fallocate(lo_fi_fd(req
, fi
), offset
, length
);
1573 fuse_reply_err(req
, err
);
1576 static void lo_flock(fuse_req_t req
, fuse_ino_t ino
, struct fuse_file_info
*fi
,
1582 res
= flock(lo_fi_fd(req
, fi
), op
);
1584 fuse_reply_err(req
, res
== -1 ? errno
: 0);
1587 static void lo_getxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
1592 struct lo_inode
*inode
;
1596 inode
= lo_inode(req
, ino
);
1598 fuse_reply_err(req
, EBADF
);
1603 if (!lo_data(req
)->xattr
) {
1607 if (lo_debug(req
)) {
1608 fuse_log(FUSE_LOG_DEBUG
,
1609 "lo_getxattr(ino=%" PRIu64
", name=%s size=%zd)\n", ino
, name
,
1613 if (inode
->is_symlink
) {
1614 /* Sorry, no race free way to getxattr on symlink. */
1619 sprintf(procname
, "/proc/self/fd/%i", inode
->fd
);
1622 value
= malloc(size
);
1627 ret
= getxattr(procname
, name
, value
, size
);
1636 fuse_reply_buf(req
, value
, ret
);
1638 ret
= getxattr(procname
, name
, NULL
, 0);
1643 fuse_reply_xattr(req
, ret
);
1652 fuse_reply_err(req
, saverr
);
1656 static void lo_listxattr(fuse_req_t req
, fuse_ino_t ino
, size_t size
)
1660 struct lo_inode
*inode
;
1664 inode
= lo_inode(req
, ino
);
1666 fuse_reply_err(req
, EBADF
);
1671 if (!lo_data(req
)->xattr
) {
1675 if (lo_debug(req
)) {
1676 fuse_log(FUSE_LOG_DEBUG
, "lo_listxattr(ino=%" PRIu64
", size=%zd)\n",
1680 if (inode
->is_symlink
) {
1681 /* Sorry, no race free way to listxattr on symlink. */
1686 sprintf(procname
, "/proc/self/fd/%i", inode
->fd
);
1689 value
= malloc(size
);
1694 ret
= listxattr(procname
, value
, size
);
1703 fuse_reply_buf(req
, value
, ret
);
1705 ret
= listxattr(procname
, NULL
, 0);
1710 fuse_reply_xattr(req
, ret
);
1719 fuse_reply_err(req
, saverr
);
1723 static void lo_setxattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
,
1724 const char *value
, size_t size
, int flags
)
1727 struct lo_inode
*inode
;
1731 inode
= lo_inode(req
, ino
);
1733 fuse_reply_err(req
, EBADF
);
1738 if (!lo_data(req
)->xattr
) {
1742 if (lo_debug(req
)) {
1743 fuse_log(FUSE_LOG_DEBUG
,
1744 "lo_setxattr(ino=%" PRIu64
", name=%s value=%s size=%zd)\n",
1745 ino
, name
, value
, size
);
1748 if (inode
->is_symlink
) {
1749 /* Sorry, no race free way to setxattr on symlink. */
1754 sprintf(procname
, "/proc/self/fd/%i", inode
->fd
);
1756 ret
= setxattr(procname
, name
, value
, size
, flags
);
1757 saverr
= ret
== -1 ? errno
: 0;
1760 fuse_reply_err(req
, saverr
);
1763 static void lo_removexattr(fuse_req_t req
, fuse_ino_t ino
, const char *name
)
1766 struct lo_inode
*inode
;
1770 inode
= lo_inode(req
, ino
);
1772 fuse_reply_err(req
, EBADF
);
1777 if (!lo_data(req
)->xattr
) {
1781 if (lo_debug(req
)) {
1782 fuse_log(FUSE_LOG_DEBUG
, "lo_removexattr(ino=%" PRIu64
", name=%s)\n",
1786 if (inode
->is_symlink
) {
1787 /* Sorry, no race free way to setxattr on symlink. */
1792 sprintf(procname
, "/proc/self/fd/%i", inode
->fd
);
1794 ret
= removexattr(procname
, name
);
1795 saverr
= ret
== -1 ? errno
: 0;
1798 fuse_reply_err(req
, saverr
);
1801 #ifdef HAVE_COPY_FILE_RANGE
1802 static void lo_copy_file_range(fuse_req_t req
, fuse_ino_t ino_in
, off_t off_in
,
1803 struct fuse_file_info
*fi_in
, fuse_ino_t ino_out
,
1804 off_t off_out
, struct fuse_file_info
*fi_out
,
1805 size_t len
, int flags
)
1810 in_fd
= lo_fi_fd(req
, fi_in
);
1811 out_fd
= lo_fi_fd(req
, fi_out
);
1813 fuse_log(FUSE_LOG_DEBUG
,
1814 "lo_copy_file_range(ino=%" PRIu64
"/fd=%d, "
1815 "off=%lu, ino=%" PRIu64
"/fd=%d, "
1816 "off=%lu, size=%zd, flags=0x%x)\n",
1817 ino_in
, in_fd
, off_in
, ino_out
, out_fd
, off_out
, len
, flags
);
1819 res
= copy_file_range(in_fd
, &off_in
, out_fd
, &off_out
, len
, flags
);
1821 fuse_reply_err(req
, -errno
);
1823 fuse_reply_write(req
, res
);
1828 static void lo_lseek(fuse_req_t req
, fuse_ino_t ino
, off_t off
, int whence
,
1829 struct fuse_file_info
*fi
)
1834 res
= lseek(lo_fi_fd(req
, fi
), off
, whence
);
1836 fuse_reply_lseek(req
, res
);
1838 fuse_reply_err(req
, errno
);
1842 static struct fuse_lowlevel_ops lo_oper
= {
1844 .lookup
= lo_lookup
,
1847 .symlink
= lo_symlink
,
1849 .unlink
= lo_unlink
,
1851 .rename
= lo_rename
,
1852 .forget
= lo_forget
,
1853 .forget_multi
= lo_forget_multi
,
1854 .getattr
= lo_getattr
,
1855 .setattr
= lo_setattr
,
1856 .readlink
= lo_readlink
,
1857 .opendir
= lo_opendir
,
1858 .readdir
= lo_readdir
,
1859 .readdirplus
= lo_readdirplus
,
1860 .releasedir
= lo_releasedir
,
1861 .fsyncdir
= lo_fsyncdir
,
1862 .create
= lo_create
,
1864 .release
= lo_release
,
1868 .write_buf
= lo_write_buf
,
1869 .statfs
= lo_statfs
,
1870 .fallocate
= lo_fallocate
,
1872 .getxattr
= lo_getxattr
,
1873 .listxattr
= lo_listxattr
,
1874 .setxattr
= lo_setxattr
,
1875 .removexattr
= lo_removexattr
,
1876 #ifdef HAVE_COPY_FILE_RANGE
1877 .copy_file_range
= lo_copy_file_range
,
1882 /* Print vhost-user.json backend program capabilities */
1883 static void print_capabilities(void)
1886 printf(" \"type\": \"fs\"\n");
1890 int main(int argc
, char *argv
[])
1892 struct fuse_args args
= FUSE_ARGS_INIT(argc
, argv
);
1893 struct fuse_session
*se
;
1894 struct fuse_cmdline_opts opts
;
1895 struct lo_data lo
= { .debug
= 0, .writeback
= 0 };
1896 struct lo_map_elem
*root_elem
;
1899 /* Don't mask creation mode, kernel already did that */
1902 pthread_mutex_init(&lo
.mutex
, NULL
);
1903 lo
.root
.next
= lo
.root
.prev
= &lo
.root
;
1905 lo
.root
.fuse_ino
= FUSE_ROOT_ID
;
1906 lo
.cache
= CACHE_NORMAL
;
1909 * Set up the ino map like this:
1910 * [0] Reserved (will not be used)
1913 lo_map_init(&lo
.ino_map
);
1914 lo_map_reserve(&lo
.ino_map
, 0)->in_use
= false;
1915 root_elem
= lo_map_reserve(&lo
.ino_map
, lo
.root
.fuse_ino
);
1916 root_elem
->inode
= &lo
.root
;
1918 lo_map_init(&lo
.dirp_map
);
1919 lo_map_init(&lo
.fd_map
);
1921 if (fuse_parse_cmdline(&args
, &opts
) != 0) {
1924 if (opts
.show_help
) {
1925 printf("usage: %s [options]\n\n", argv
[0]);
1926 fuse_cmdline_help();
1927 printf(" -o source=PATH shared directory tree\n");
1928 fuse_lowlevel_help();
1931 } else if (opts
.show_version
) {
1932 fuse_lowlevel_version();
1935 } else if (opts
.print_capabilities
) {
1936 print_capabilities();
1941 if (fuse_opt_parse(&args
, &lo
, lo_opts
, NULL
) == -1) {
1945 lo
.debug
= opts
.debug
;
1946 lo
.root
.refcount
= 2;
1951 res
= lstat(lo
.source
, &stat
);
1953 fuse_log(FUSE_LOG_ERR
, "failed to stat source (\"%s\"): %m\n",
1957 if (!S_ISDIR(stat
.st_mode
)) {
1958 fuse_log(FUSE_LOG_ERR
, "source is not a directory\n");
1965 lo
.root
.is_symlink
= false;
1966 if (!lo
.timeout_set
) {
1977 lo
.timeout
= 86400.0;
1980 } else if (lo
.timeout
< 0) {
1981 fuse_log(FUSE_LOG_ERR
, "timeout is negative (%lf)\n", lo
.timeout
);
1985 lo
.root
.fd
= open(lo
.source
, O_PATH
);
1986 if (lo
.root
.fd
== -1) {
1987 fuse_log(FUSE_LOG_ERR
, "open(\"%s\", O_PATH): %m\n", lo
.source
);
1991 se
= fuse_session_new(&args
, &lo_oper
, sizeof(lo_oper
), &lo
);
1996 if (fuse_set_signal_handlers(se
) != 0) {
2000 if (fuse_session_mount(se
) != 0) {
2004 fuse_daemonize(opts
.foreground
);
2006 /* Block until ctrl+c or fusermount -u */
2007 ret
= virtio_loop(se
);
2009 fuse_session_unmount(se
);
2011 fuse_remove_signal_handlers(se
);
2013 fuse_session_destroy(se
);
2015 fuse_opt_free_args(&args
);
2017 lo_map_destroy(&lo
.fd_map
);
2018 lo_map_destroy(&lo
.dirp_map
);
2019 lo_map_destroy(&lo
.ino_map
);
2021 if (lo
.root
.fd
>= 0) {