26 #define FUSE_USE_VERSION 31    36 #define _XOPEN_SOURCE 700    48 #include <sys/socket.h>    53 #include <sys/xattr.h>    56 #include "passthrough_helpers.h"    58 static int fill_dir_plus = 0;
    80 static int xmp_getattr(
const char *path, 
struct stat *stbuf,
    86         res = lstat(path, stbuf);
    93 static int xmp_access(
const char *path, 
int mask)
   104 static int xmp_readlink(
const char *path, 
char *buf, 
size_t size)
   108         res = 
readlink(path, buf, size - 1);
   117 static int xmp_readdir(
const char *path, 
void *buf, 
fuse_fill_dir_t filler,
   132         while ((de = readdir(dp)) != NULL) {
   134                 memset(&st, 0, 
sizeof(st));
   135                 st.st_ino = de->d_ino;
   136                 st.st_mode = de->d_type << 12;
   137                 if (filler(buf, de->d_name, &st, 0, fill_dir_plus))
   145 static int xmp_mknod(
const char *path, mode_t mode, dev_t rdev)
   149         res = mknod_wrapper(AT_FDCWD, path, NULL, mode, rdev);
   156 static int xmp_mkdir(
const char *path, mode_t mode)
   160         res = mkdir(path, mode);
   167 static int xmp_unlink(
const char *path)
   178 static int xmp_rmdir(
const char *path)
   189 static int xmp_symlink(
const char *from, 
const char *to)
   193         res = symlink(from, to);
   200 static int xmp_rename(
const char *from, 
const char *to, 
unsigned int flags)
   207         res = rename(from, to);
   214 static int xmp_link(
const char *from, 
const char *to)
   218         res = link(from, to);
   225 static int xmp_chmod(
const char *path, mode_t mode,
   231         res = chmod(path, mode);
   238 static int xmp_chown(
const char *path, uid_t uid, gid_t gid,
   244         res = lchown(path, uid, gid);
   251 static int xmp_truncate(
const char *path, off_t size,
   257                 res = ftruncate(fi->
fh, size);
   259                 res = truncate(path, size);
   266 #ifdef HAVE_UTIMENSAT   267 static int xmp_utimens(
const char *path, 
const struct timespec ts[2],
   274         res = utimensat(0, path, ts, AT_SYMLINK_NOFOLLOW);
   282 static int xmp_create(
const char *path, mode_t mode,
   287         res = open(path, fi->
flags, mode);
   299         res = open(path, fi->
flags);
   307 static int xmp_read(
const char *path, 
char *buf, 
size_t size, off_t offset,
   314                 fd = open(path, O_RDONLY);
   321         res = pread(fd, buf, size, offset);
   330 static int xmp_write(
const char *path, 
const char *buf, 
size_t size,
   338                 fd = open(path, O_WRONLY);
   345         res = pwrite(fd, buf, size, offset);
   354 static int xmp_statfs(
const char *path, 
struct statvfs *stbuf)
   358         res = statvfs(path, stbuf);
   365 static int xmp_release(
const char *path, 
struct fuse_file_info *fi)
   372 static int xmp_fsync(
const char *path, 
int isdatasync,
   384 #ifdef HAVE_POSIX_FALLOCATE   385 static int xmp_fallocate(
const char *path, 
int mode,
   397                 fd = open(path, O_WRONLY);
   404         res = -posix_fallocate(fd, offset, length);
   414 static int xmp_setxattr(
const char *path, 
const char *name, 
const char *value,
   415                         size_t size, 
int flags)
   417         int res = lsetxattr(path, name, value, size, flags);
   423 static int xmp_getxattr(
const char *path, 
const char *name, 
char *value,
   426         int res = lgetxattr(path, name, value, size);
   432 static int xmp_listxattr(
const char *path, 
char *list, 
size_t size)
   434         int res = llistxattr(path, list, size);
   440 static int xmp_removexattr(
const char *path, 
const char *name)
   442         int res = lremovexattr(path, name);
   449 #ifdef HAVE_COPY_FILE_RANGE   450 static ssize_t xmp_copy_file_range(
const char *path_in,
   452                                    off_t offset_in, 
const char *path_out,
   454                                    off_t offset_out, 
size_t len, 
int flags)
   460                 fd_in = open(path_in, O_RDONLY);
   468                 fd_out = open(path_out, O_WRONLY);
   477         res = copy_file_range(fd_in, &offset_in, fd_out, &offset_out, len,
   491 static off_t xmp_lseek(
const char *path, off_t off, 
int whence, 
struct fuse_file_info *fi)
   497                 fd = open(path, O_RDONLY);
   504         res = lseek(fd, off, whence);
   515         .getattr        = xmp_getattr,
   516         .access         = xmp_access,
   517         .readlink       = xmp_readlink,
   518         .readdir        = xmp_readdir,
   521         .symlink        = xmp_symlink,
   522         .unlink         = xmp_unlink,
   524         .rename         = xmp_rename,
   528         .truncate       = xmp_truncate,
   529 #ifdef HAVE_UTIMENSAT   530         .utimens        = xmp_utimens,
   533         .create         = xmp_create,
   536         .statfs         = xmp_statfs,
   537         .release        = xmp_release,
   539 #ifdef HAVE_POSIX_FALLOCATE   540         .fallocate      = xmp_fallocate,
   543         .setxattr       = xmp_setxattr,
   544         .getxattr       = xmp_getxattr,
   545         .listxattr      = xmp_listxattr,
   546         .removexattr    = xmp_removexattr,
   548 #ifdef HAVE_COPY_FILE_RANGE   549         .copy_file_range = xmp_copy_file_range,
   554 int main(
int argc, 
char *argv[])
   556         enum { MAX_ARGS = 10 };
   558         char *new_argv[MAX_ARGS];
   562         for (i=0, new_argc=0; (i<argc) && (new_argc<MAX_ARGS); i++) {
   563                 if (!strcmp(argv[i], 
"--plus")) {
   566                         new_argv[new_argc++] = argv[i];
   569         return fuse_main(new_argc, new_argv, &xmp_oper, NULL);
 
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)
#define fuse_main(argc, argv, op, private_data)
int(* readlink)(const char *, char *, size_t)
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
int(* access)(const char *, int)