2 fuse_xattrs - Add xattrs support using sidecar files
4 Copyright (C) 2016 Felipe Barriga Richards <felipe {at} felipebarriga.cl>
6 Based on passthrough.c (libfuse example)
8 This program can be distributed under the terms of the GNU GPL.
12 #define FUSE_USE_VERSION 30
14 /* For pread()/pwrite()/utimensat() */
15 #define _XOPEN_SOURCE 700
24 int xmp_getattr(const char *path, struct stat *stbuf) {
27 res = lstat(path, stbuf);
34 int xmp_access(const char *path, int mask) {
37 res = access(path, mask);
44 int xmp_readlink(const char *path, char *buf, size_t size) {
47 res = readlink(path, buf, size - 1);
55 int xmp_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
56 off_t offset, struct fuse_file_info *fi)
68 while ((de = readdir(dp)) != NULL) {
70 memset(&st, 0, sizeof(st));
71 st.st_ino = de->d_ino;
72 st.st_mode = de->d_type << 12;
73 if (filler(buf, de->d_name, &st, 0))
81 int xmp_mknod(const char *path, mode_t mode, dev_t rdev) {
84 /* On Linux this could just be 'mknod(path, mode, rdev)' but this
87 res = open(path, O_CREAT | O_EXCL | O_WRONLY, mode);
90 } else if (S_ISFIFO(mode))
91 res = mkfifo(path, mode);
93 res = mknod(path, mode, rdev);
100 int xmp_mkdir(const char *path, mode_t mode) {
103 res = mkdir(path, mode);
110 int xmp_unlink(const char *path) {
120 int xmp_rmdir(const char *path) {
130 int xmp_symlink(const char *from, const char *to) {
133 res = symlink(from, to);
140 int xmp_rename(const char *from, const char *to) {
143 res = rename(from, to);
150 int xmp_link(const char *from, const char *to) {
153 res = link(from, to);
160 int xmp_chmod(const char *path, mode_t mode) {
163 res = chmod(path, mode);
170 int xmp_chown(const char *path, uid_t uid, gid_t gid) {
173 res = lchown(path, uid, gid);
180 int xmp_truncate(const char *path, off_t size) {
183 res = truncate(path, size);
190 #ifdef HAVE_UTIMENSAT
191 int xmp_utimens(const char *path, const struct timespec ts[2],
192 struct fuse_file_info *fi)
197 /* don't use utime/utimes since they follow symlinks */
198 res = utimensat(0, path, ts, AT_SYMLINK_NOFOLLOW);
206 int xmp_open(const char *path, struct fuse_file_info *fi) {
209 res = open(path, fi->flags);
217 int xmp_read(const char *path, char *buf, size_t size, off_t offset,
218 struct fuse_file_info *fi) {
223 fd = open(path, O_RDONLY);
227 res = pread(fd, buf, size, offset);
235 int xmp_write(const char *path, const char *buf, size_t size,
236 off_t offset, struct fuse_file_info *fi) {
241 fd = open(path, O_WRONLY);
245 res = pwrite(fd, buf, size, offset);
253 int xmp_statfs(const char *path, struct statvfs *stbuf) {
256 res = statvfs(path, stbuf);
263 int xmp_release(const char *path, struct fuse_file_info *fi) {
264 /* Just a stub. This method is optional and can safely be left
272 int xmp_fsync(const char *path, int isdatasync,
273 struct fuse_file_info *fi) {
274 /* Just a stub. This method is optional and can safely be left
283 #ifdef HAVE_POSIX_FALLOCATE
284 int xmp_fallocate(const char *path, int mode,
285 off_t offset, off_t length, struct fuse_file_info *fi)
295 fd = open(path, O_WRONLY);
299 res = -posix_fallocate(fd, offset, length);