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)
 
   97         res = access(path, 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);
 
int(* fuse_fill_dir_t)(void *buf, const char *name, const struct stat *stbuf, off_t off, enum fuse_fill_dir_flags flags)
#define fuse_main(argc, argv, op, private_data)
void *(* init)(struct fuse_conn_info *conn, struct fuse_config *cfg)