26#define FUSE_USE_VERSION FUSE_MAKE_VERSION(3, 18)
32#define _XOPEN_SOURCE 700
48#include "passthrough_helpers.h"
50static int fill_dir_plus = 0;
51static int readdir_zero_ino;
57 cfg->
use_ino = !readdir_zero_ino;
82static int xmp_getattr(
const char *path,
struct stat *stbuf,
88 res = lstat(path, stbuf);
95static int xmp_access(
const char *path,
int mask)
99 res = access(path, mask);
106static int xmp_readlink(
const char *path,
char *buf,
size_t size)
110 res = readlink(path, buf, size - 1);
119static int xmp_readdir(
const char *path,
void *buf,
fuse_fill_dir_t filler,
134 while ((de = readdir(dp)) != NULL) {
137 fstatat(dirfd(dp), de->d_name, &st,
138 AT_SYMLINK_NOFOLLOW);
140 memset(&st, 0,
sizeof(st));
141 st.st_ino = de->d_ino;
142 st.st_mode = de->d_type << 12;
144 if (readdir_zero_ino)
146 if (filler(buf, de->d_name, &st, 0, fill_dir_plus))
154static int xmp_mknod(
const char *path, mode_t mode, dev_t rdev)
158 res = mknod_wrapper(AT_FDCWD, path, NULL, mode, rdev);
165static int xmp_mkdir(
const char *path, mode_t mode)
169 res = mkdir(path, mode);
176static int xmp_unlink(
const char *path)
187static int xmp_rmdir(
const char *path)
198static int xmp_symlink(
const char *from,
const char *to)
202 res = symlink(from, to);
209static int xmp_rename(
const char *from,
const char *to,
unsigned int flags)
216 res = rename(from, to);
223static int xmp_link(
const char *from,
const char *to)
227 res = link(from, to);
234static int xmp_chmod(
const char *path, mode_t mode,
240 res = chmod(path, mode);
247static int xmp_chown(
const char *path, uid_t uid, gid_t gid,
253 res = lchown(path, uid, gid);
260static int xmp_truncate(
const char *path, off_t size,
266 res = ftruncate(fi->
fh, size);
268 res = truncate(path, size);
276static int xmp_utimens(
const char *path,
const struct timespec ts[2],
283 res = utimensat(0, path, ts, AT_SYMLINK_NOFOLLOW);
291static int xmp_create(
const char *path, mode_t mode,
296 res = open(path, fi->
flags, mode);
308 res = open(path, fi->
flags);
315 if (fi->
flags & O_DIRECT) {
324static int xmp_read(
const char *path,
char *buf,
size_t size, off_t offset,
331 fd = open(path, O_RDONLY);
338 res = pread(fd, buf, size, offset);
347static int xmp_write(
const char *path,
const char *buf,
size_t size,
355 fd = open(path, O_WRONLY);
362 res = pwrite(fd, buf, size, offset);
371static int xmp_statfs(
const char *path,
struct statvfs *stbuf)
375 res = statvfs(path, stbuf);
382static int xmp_release(
const char *path,
struct fuse_file_info *fi)
389static int xmp_fsync(
const char *path,
int isdatasync,
401static int xmp_fallocate(
const char *path,
int mode,
410 fd = open(path, O_WRONLY);
417 res = do_fallocate(fd, mode, offset, length);
426static int xmp_setxattr(
const char *path,
const char *name,
const char *value,
427 size_t size,
int flags)
429 int res = lsetxattr(path, name, value, size, flags);
435static int xmp_getxattr(
const char *path,
const char *name,
char *value,
438 int res = lgetxattr(path, name, value, size);
444static int xmp_listxattr(
const char *path,
char *list,
size_t size)
446 int res = llistxattr(path, list, size);
452static int xmp_removexattr(
const char *path,
const char *name)
454 int res = lremovexattr(path, name);
461#ifdef HAVE_COPY_FILE_RANGE
462static ssize_t xmp_copy_file_range(
const char *path_in,
464 off_t offset_in,
const char *path_out,
466 off_t offset_out,
size_t len,
int flags)
472 fd_in = open(path_in, O_RDONLY);
480 fd_out = open(path_out, O_WRONLY);
489 res = copy_file_range(fd_in, &offset_in, fd_out, &offset_out, len,
503static off_t xmp_lseek(
const char *path, off_t off,
int whence,
struct fuse_file_info *fi)
509 fd = open(path, O_RDONLY);
516 res = lseek(fd, off, whence);
526static int xmp_statx(
const char *path,
int flags,
int mask,
struct statx *stxbuf,
535 res = statx(fd, path, flags | AT_SYMLINK_NOFOLLOW, mask, stxbuf);
545 .getattr = xmp_getattr,
546 .access = xmp_access,
547 .readlink = xmp_readlink,
548 .readdir = xmp_readdir,
551 .symlink = xmp_symlink,
552 .unlink = xmp_unlink,
554 .rename = xmp_rename,
558 .truncate = xmp_truncate,
560 .utimens = xmp_utimens,
563 .create = xmp_create,
566 .statfs = xmp_statfs,
567 .release = xmp_release,
569 .fallocate = xmp_fallocate,
571 .setxattr = xmp_setxattr,
572 .getxattr = xmp_getxattr,
573 .listxattr = xmp_listxattr,
574 .removexattr = xmp_removexattr,
576#ifdef HAVE_COPY_FILE_RANGE
577 .copy_file_range = xmp_copy_file_range,
585int main(
int argc,
char *argv[])
587 enum { MAX_ARGS = 10 };
589 char *new_argv[MAX_ARGS];
593 for (i=0, new_argc=0; (i<argc) && (new_argc<MAX_ARGS); i++) {
594 if (!strcmp(argv[i],
"--plus")) {
595 fill_dir_plus = FUSE_FILL_DIR_PLUS;
596 }
else if (!strcmp(argv[i],
"--readdir-zero-inodes")) {
598 readdir_zero_ino = 1;
600 new_argv[new_argc++] = argv[i];
603 return fuse_main(new_argc, new_argv, &xmp_oper, NULL);
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
int32_t parallel_direct_writes
uint32_t parallel_direct_writes
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)