Compare commits

...
21 Commits
Author SHA1 Message Date
Antonio SJ Musumeci f6e37672b8 reset dentry buffer when rewind'ed 2021-02-09 18:09:28 -05:00
trapexit 2e4c6c5fd1 Merge pull request #856 from trapexit/dirname
dirname should not return an empty string
2020-12-18 17:03:43 -05:00
Antonio SJ Musumeci f50812a9ce dirname should not return an empty string 2020-12-18 16:04:17 -05:00
trapexit 861edff49a Merge pull request #855 from trapexit/builds
update cirrus-ci builds
2020-12-17 20:18:16 -05:00
Antonio SJ Musumeci 5e08357f0e update cirrus-ci builds 2020-12-17 20:17:16 -05:00
trapexit 411ee36c90 Merge pull request #854 from trapexit/mspfix
msp policies stopped before root path
2020-12-17 20:14:54 -05:00
Antonio SJ Musumeci 44a98910ba msp policies stopped before root path 2020-12-17 19:55:49 -05:00
trapexit 8a335d8a6e Merge pull request #851 from trapexit/fix
fix segv: zero out data structures
2020-12-13 16:56:55 -05:00
Antonio SJ Musumeci 3900543970 fix segv: zero out data structures 2020-12-13 13:40:04 -05:00
trapexit 2e34c7598a Merge pull request #845 from trapexit/configfile
config: fix invalid error check when parsing config file
2020-11-28 21:49:51 -05:00
Antonio SJ Musumeci 7edd3c6cf3 config: fix invalid error check when parsing config file 2020-11-28 20:26:18 -05:00
trapexit ddf0075938 Merge pull request #844 from trapexit/cleanup
general cleanup, slight memory reduction
2020-11-19 23:30:48 -05:00
Antonio SJ Musumeci 1b26f4908e general cleanup, slight memory reduction 2020-11-19 22:58:52 -05:00
trapexit 2d8fab534a Merge pull request #843 from trapexit/policyfixes
msp policies: used wrong path to check existance
2020-11-19 20:34:51 -05:00
Antonio SJ Musumeci c3fffefbc1 msp policies: used wrong path to check existance 2020-11-19 18:34:28 -05:00
trapexit eaa2593a4b Merge pull request #837 from renkoh/rsync-script-readme
Update percentage full expiring script
2020-10-03 01:05:54 -04:00
Ren Koh 7e583e3f48 use relative option for rsync 2020-10-03 14:45:51 +10:00
trapexit 2ad4891617 Merge pull request #835 from trapexit/readme
README.md: add details on per branch minfreespace
2020-09-29 18:51:30 -04:00
Antonio SJ Musumeci 8990e24c0f README.md: add details on per branch minfreespace 2020-09-29 18:50:25 -04:00
trapexit 88b80234c7 Merge pull request #834 from trapexit/readme
README.md: add details about error handling
2020-09-27 00:30:05 -04:00
Antonio SJ Musumeci f6e37c57fe README.md: add details about error handling 2020-09-27 00:28:00 -04:00
68 changed files with 4813 additions and 3794 deletions
+15 -19
View File
@@ -27,16 +27,15 @@ linux_task:
- make STATIC=1 LTO=1
linux_task:
name: "centos:6"
name: "alpine:3.12"
container:
image: centos:6
image: alpine:3.12
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
- make STATIC=1 LTO=1
linux_task:
name: "centos:7"
@@ -98,6 +97,18 @@ linux_task:
- make
- make rpm
linux_task:
name: "fedora:33"
container:
image: fedora:33
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "ubuntu:14.04"
container:
@@ -143,21 +154,6 @@ linux_task:
- dpkg -i ../*.deb
- mergerfs -v || true
linux_task:
name: "ubuntu:19.10"
container:
image: ubuntu:19.10
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- git fetch
- make deb
- apt-get -y install fuse
- dpkg -i ../*.deb
- mergerfs -v || true
linux_task:
name: "ubuntu:20.04"
container:
+67 -20
View File
@@ -95,7 +95,7 @@ See the mergerfs [wiki for real world deployments](https://github.com/trapexit/m
* **config**: Path to a config file. Same arguments as below in key=val format.
* **branches**: Colon delimited list of branches.
* **allow_other**: A libfuse option which allows users besides the one which ran mergerfs to see the filesystem. This is required for most use-cases.
* **minfreespace=SIZE**: The minimum space value used for creation policies. Understands 'K', 'M', and 'G' to represent kilobyte, megabyte, and gigabyte respectively. (default: 4G)
* **minfreespace=SIZE**: The minimum space value used for creation policies. Can be overridden by branch specific option. Understands 'K', 'M', and 'G' to represent kilobyte, megabyte, and gigabyte respectively. (default: 4G)
* **moveonenospc=BOOL|POLICY**: When enabled if a **write** fails with **ENOSPC** (no space left on device) or **EDQUOT** (disk quota exceeded) the policy selected will run to find a new location for the file. An attempt to move the file to that branch will occur (keeping all metadata possible) and if successful the original is unlinked and the write retried. (default: false, true = mfs)
* **use_ino**: Causes mergerfs to supply file/directory inodes rather than libfuse. While not a default it is recommended it be enabled so that linked files share the same inode value.
* **inodecalc=passthrough|path-hash|devino-hash|hybrid-hash**: Selects the inode calculation algorithm. (default: hybrid-hash)
@@ -149,11 +149,27 @@ See the mergerfs [wiki for real world deployments](https://github.com/trapexit/m
### branches
The 'branches' (formerly 'srcmounts') argument is a colon (':') delimited list of paths to be pooled together. It does not matter if the paths are on the same or different drives nor does it matter the filesystem. Used and available space will not be duplicated for paths on the same device and any features which aren't supported by the underlying filesystem (such as file attributes or extended attributes) will return the appropriate errors.
The 'branches' (formerly 'srcmounts') argument is a colon (':') delimited list of paths to be pooled together. It does not matter if the paths are on the same or different drives nor does it matter the filesystem (within reason). Used and available space will not be duplicated for paths on the same device and any features which aren't supported by the underlying filesystem (such as file attributes or extended attributes) will return the appropriate errors.
Branches currently have two options which can be set. A type which impacts whether or not the branch is included in a policy calculation and a individual minfreespace value. The values are set by prepending an `=` at the end of a branch designation and using commas as delimiters. Example: /mnt/drive=RW,1234
#### branch type
* RW: (read/write) - Default behavior. Will be eligible in all policy categories.
* RO: (read-only) - Will be excluded from `create` and `action` policies. Same as a read-only mounted filesystem would be (though faster to process).
* NC: (no-create) - Will be excluded from `create` policies. You can't create on that branch but you can change or delete.
#### minfreespace
Same purpose as the global option but specific to the branch. If not set the global value is used.
#### globbing
To make it easier to include multiple branches mergerfs supports [globbing](http://linux.die.net/man/7/glob). **The globbing tokens MUST be escaped when using via the shell else the shell itself will apply the glob itself.**
Each branch can have a suffix of `=RW` (read / write), `=RO` (read-only), or `=NC` (no create). These suffixes work with globs as well and will apply to each path found. `RW` is the default behavior and those paths will be eligible for all policy categories. `RO` will exclude those paths from `create` and `action` policies (just as a filesystem being mounted `ro` would). `NC` will exclude those paths from `create` policies (you can't create but you can change / delete).
```
# mergerfs -o allow_other,use_ino /mnt/disk\*:/mnt/cdrom /media/drives
@@ -168,7 +184,7 @@ To have the pool mounted at boot or otherwise accessible from related tools use
/mnt/disk*:/mnt/cdrom /mnt/pool fuse.mergerfs allow_other,use_ino 0 0
```
**NOTE:** the globbing is done at mount or xattr update time (see below). If a new directory is added matching the glob after the fact it will not be automatically included.
**NOTE:** the globbing is done at mount or when updated using the runtime API. If a new directory is added matching the glob after the fact it will not be automatically included.
**NOTE:** for mounting via **fstab** to work you must have **mount.fuse** installed. For Ubuntu/Debian it is included in the **fuse** package.
@@ -410,6 +426,35 @@ The above behavior will help minimize the likelihood of EXDEV being returned but
The options `statfs` and `statfs_ignore` can be used to modify `statfs` behavior.
# ERROR HANDLING
POSIX filesystem functions offer a single return code meaning that there is some complication regarding the handling of multiple branches as mergerfs does. It tries to handle errors in a way that would generally return meaningful values for that particular function.
### chmod, chown, removexattr, setxattr, truncate, utimens
1) if no error: return 0 (success)
2) if no successes: return first error
3) if one of the files acted on was the same as the related search function: return its value
4) return 0 (success)
While doing this increases the complexity and cost of error handling, particularly step 3, this provides probably the most reasonable return value.
### unlink, rmdir
1) if no errors: return 0 (success)
2) return first error
Older version of mergerfs would return success if any success occurred but for unlink and rmdir there are downstream assumptions that, while not impossible to occur, can confuse some software.
### others
For search functions there is always a single thing acted on and as such whatever return value that comes from the single function call is returned.
For create functions `mkdir`, `mknod`, and `symlink` which don't return a file descriptor and therefore can have `all` or `epall` policies it will return success if any of the calls succeed and an error otherwise.
# BUILD / UPDATE
**NOTE:** Prebuilt packages can be found at and recommended for most users: https://github.com/trapexit/mergerfs/releases
@@ -462,6 +507,23 @@ make LTO=1 - build with link time optimization
```
# UPGRADE
mergerfs can be upgraded live by mounting on top of the previous instance. Simply install the new version of mergerfs and follow the instructions below.
Add `nonempty` to your mergerfs option list and call mergerfs again or if using `/etc/fstab` call for it to mount again. Existing open files and such will continue to work fine though they won't see runtime changes since any such change would be the new mount. If you plan on changing settings with the new mount you should / could apply those before mounting the new version.
```
$ sudo mount /mnt/mergerfs
$ mount | grep mergerfs
media on /mnt/mergerfs type fuse.mergerfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
media on /mnt/mergerfs type fuse.mergerfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
```
A problem with this approach is that the underlying instance will continue to run even if the software using it stop or are restarted. To work around this you can use a "lazy umount". Before mounting over top the mount point with the new instance of mergerfs issue: `umount -l <mergerfs_mountpoint>`.
# RUNTIME CONFIG
#### ioctl
@@ -593,20 +655,6 @@ A B C
```
# UPGRADE
mergerfs can be upgraded live by mounting on top of the previous version. Simply install the new version of mergerfs and follow the instructions below.
Add `nonempty` to your mergerfs option list and call mergerfs again or if using `/etc/fstab` call for it to mount again. Existing open files and such will continue to work fine though they won't see runtime changes since any such change would be the new mount. If you plan on changing settings with the new mount you should / could apply those before mounting the new version.
```
$ sudo mount /mnt/mergerfs
$ mount | grep mergerfs
media on /mnt/mergerfs type fuse.mergerfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
media on /mnt/mergerfs type fuse.mergerfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
```
# TOOLING
* https://github.com/trapexit/mergerfs-tools
@@ -757,7 +805,7 @@ do
head -n 1 | \
cut -d' ' -f2-)
test -n "${FILE}"
rsync -axqHAXWES --preallocate --remove-source-files "${CACHE}/./${FILE}" "${BACKING}/"
rsync -axqHAXWESR --preallocate --remove-source-files "${CACHE}/./${FILE}" "${BACKING}/"
done
```
@@ -826,7 +874,6 @@ $ dd if=/mnt/mergerfs/1GB.file of=/dev/null bs=1M count=1024 iflag=nocache conv=
* https://github.com/trapexit/backup-and-recovery-howtos : A set of guides / howtos on creating a data storage system, backing it up, maintaining it, and recovering from failure.
* If you don't see some directories and files you expect in a merged point or policies seem to skip drives be sure the user has permission to all the underlying directories. Use `mergerfs.fsck` to audit the drive for out of sync permissions.
* Do **not** use `cache.files=off` if you expect applications (such as rtorrent) to use [mmap](http://linux.die.net/man/2/mmap) files. Shared mmap is not currently supported in FUSE w/ page caching disabled. Enabling `dropcacheonclose` is recommended when `cache.files=partial|full|auto-full`.
* Since POSIX functions give only a singular error or success its difficult to determine the proper behavior when applying the function to multiple targets. **mergerfs** will return an error only if all attempts of an action fail. Any success will lead to a success returned. This means however that some odd situations may arise.
* [Kodi](http://kodi.tv), [Plex](http://plex.tv), [Subsonic](http://subsonic.org), etc. can use directory [mtime](http://linux.die.net/man/2/stat) to more efficiently determine whether to scan for new content rather than simply performing a full scan. If using the default **getattr** policy of **ff** it's possible those programs will miss an update on account of it returning the first directory found's **stat** info and its a later directory on another mount which had the **mtime** recently updated. To fix this you will want to set **func.getattr=newest**. Remember though that this is just **stat**. If the file is later **open**'ed or **unlink**'ed and the policy is different for those then a completely different file or directory could be acted on.
* Some policies mixed with some functions may result in strange behaviors. Not that some of these behaviors and race conditions couldn't happen outside **mergerfs** but that they are far more likely to occur on account of the attempt to merge together multiple sources of data which could be out of sync due to the different policies.
* For consistency its generally best to set **category** wide policies rather than individual **func**'s. This will help limit the confusion of tools such as [rsync](http://linux.die.net/man/1/rsync). However, the flexibility is there if needed.
+76 -66
View File
@@ -131,11 +131,11 @@ struct fuse_operations
/** Change the permission bits of a file */
int (*chmod) (const char *, mode_t);
int (*fchmod)(const struct fuse_file_info *, const mode_t);
int (*fchmod)(const fuse_file_info_t *, const mode_t);
/** Change the owner and group of a file */
int (*chown) (const char *, uid_t, gid_t);
int (*fchown)(const struct fuse_file_info *, const uid_t, const gid_t);
int (*fchown)(const fuse_file_info_t *, const uid_t, const gid_t);
/** Change the size of a file */
int (*truncate) (const char *, off_t);
@@ -163,7 +163,7 @@ struct fuse_operations
*
* Changed in version 2.2
*/
int (*open) (const char *, struct fuse_file_info *);
int (*open) (const char *, fuse_file_info_t *);
/** Read data from an open file
*
@@ -176,8 +176,10 @@ struct fuse_operations
*
* Changed in version 2.2
*/
int (*read) (char *, size_t, off_t,
struct fuse_file_info *);
int (*read) (const fuse_file_info_t *,
char *,
size_t,
off_t);
/** Write data to an open file
*
@@ -187,8 +189,10 @@ struct fuse_operations
*
* Changed in version 2.2
*/
int (*write) (const char *, size_t, off_t,
struct fuse_file_info *);
int (*write) (const fuse_file_info_t *,
const char *,
size_t,
off_t);
/** Get file system statistics
*
@@ -222,7 +226,7 @@ struct fuse_operations
*
* Changed in version 2.2
*/
int (*flush) (struct fuse_file_info *);
int (*flush) (const fuse_file_info_t *);
/** Release an open file
*
@@ -238,7 +242,7 @@ struct fuse_operations
*
* Changed in version 2.2
*/
int (*release) (struct fuse_file_info *);
int (*release) (const fuse_file_info_t *);
/** Synchronize file contents
*
@@ -247,7 +251,7 @@ struct fuse_operations
*
* Changed in version 2.2
*/
int (*fsync) (int, struct fuse_file_info *);
int (*fsync) (const fuse_file_info_t *, int);
/** Set extended attributes */
int (*setxattr) (const char *, const char *, const char *, size_t, int);
@@ -271,7 +275,8 @@ struct fuse_operations
*
* Introduced in version 2.3
*/
int (*opendir) (const char *, struct fuse_file_info *);
int (*opendir) (const char *,
fuse_file_info_t *);
/** Read directory
*
@@ -294,10 +299,10 @@ struct fuse_operations
*
* Introduced in version 2.3
*/
int (*readdir)(struct fuse_file_info *,
int (*readdir)(const fuse_file_info_t *,
fuse_dirents_t *);
int (*readdir_plus)(struct fuse_file_info *,
int (*readdir_plus)(const fuse_file_info_t *,
fuse_dirents_t *);
@@ -305,7 +310,7 @@ struct fuse_operations
*
* Introduced in version 2.3
*/
int (*releasedir) (struct fuse_file_info *);
int (*releasedir) (const fuse_file_info_t *);
/** Synchronize directory contents
*
@@ -314,7 +319,7 @@ struct fuse_operations
*
* Introduced in version 2.3
*/
int (*fsyncdir) (int, struct fuse_file_info *);
int (*fsyncdir) (const fuse_file_info_t *, int);
/**
* Initialize filesystem
@@ -362,7 +367,7 @@ struct fuse_operations
*
* Introduced in version 2.5
*/
int (*create) (const char *, mode_t, struct fuse_file_info *);
int (*create) (const char *, mode_t, fuse_file_info_t *);
/**
* Change the size of an open file
@@ -376,7 +381,7 @@ struct fuse_operations
*
* Introduced in version 2.5
*/
int (*ftruncate) (off_t, struct fuse_file_info *);
int (*ftruncate) (const fuse_file_info_t *, off_t);
/**
* Get attributes from an open file
@@ -390,7 +395,7 @@ struct fuse_operations
*
* Introduced in version 2.5
*/
int (*fgetattr) (struct stat *, struct fuse_file_info *, fuse_timeouts_t *);
int (*fgetattr) (const fuse_file_info_t *, struct stat *, fuse_timeouts_t *);
/**
* Perform POSIX file locking operation
@@ -424,7 +429,8 @@ struct fuse_operations
*
* Introduced in version 2.6
*/
int (*lock) (struct fuse_file_info *, int cmd,
int (*lock) (const fuse_file_info_t *,
int cmd,
struct flock *);
/**
@@ -439,7 +445,7 @@ struct fuse_operations
* Introduced in version 2.6
*/
int (*utimens)(const char *, const struct timespec tv[2]);
int (*futimens)(const struct fuse_file_info *ffi_, const struct timespec tv_[2]);
int (*futimens)(const fuse_file_info_t *ffi_, const struct timespec tv_[2]);
/**
* Map block index within file to block index within device
@@ -466,12 +472,12 @@ struct fuse_operations
*
* Introduced in version 2.8
*/
int (*ioctl) (unsigned long cmd,
void *arg,
struct fuse_file_info *ffi,
unsigned int flags,
void *data,
uint32_t *out_bufsz);
int (*ioctl) (const fuse_file_info_t *ffi,
unsigned long cmd,
void *arg,
unsigned int flags,
void *data,
uint32_t *out_bufsz);
/**
* Poll for IO readiness events
@@ -490,8 +496,9 @@ struct fuse_operations
*
* Introduced in version 2.8
*/
int (*poll) (struct fuse_file_info *,
struct fuse_pollhandle *ph, unsigned *reventsp);
int (*poll) (const fuse_file_info_t *ffi,
fuse_pollhandle_t *ph,
unsigned *reventsp);
/** Write contents of buffer to an open file
*
@@ -501,8 +508,9 @@ struct fuse_operations
*
* Introduced in version 2.9
*/
int (*write_buf) (struct fuse_bufvec *buf, off_t off,
struct fuse_file_info *);
int (*write_buf) (const fuse_file_info_t *ffi,
struct fuse_bufvec *buf,
off_t off);
/** Store data from an open file in a buffer
*
@@ -520,8 +528,10 @@ struct fuse_operations
*
* Introduced in version 2.9
*/
int (*read_buf) (struct fuse_bufvec **bufp,
size_t size, off_t off, struct fuse_file_info *);
int (*read_buf) (const fuse_file_info_t *ffi,
struct fuse_bufvec **bufp,
size_t size,
off_t off);
/**
* Perform BSD file locking operation
*
@@ -542,7 +552,7 @@ struct fuse_operations
*
* Introduced in version 2.9
*/
int (*flock) (struct fuse_file_info *, int op);
int (*flock) (const fuse_file_info_t *, int op);
/**
* Allocates space for an open file
@@ -554,7 +564,7 @@ struct fuse_operations
*
* Introduced in version 2.9.1
*/
int (*fallocate) (int, off_t, off_t,struct fuse_file_info *);
int (*fallocate) (const fuse_file_info_t *, int, off_t, off_t);
/**
* Copy a range of data from one file to another
@@ -569,12 +579,12 @@ struct fuse_operations
* destination. Effectively doing an inefficient copy of the
* data.
*/
ssize_t (*copy_file_range)(struct fuse_file_info *fi_in,
off_t offset_in,
struct fuse_file_info *fi_out,
off_t offset_out,
size_t size,
int flags);
ssize_t (*copy_file_range)(const fuse_file_info_t *fi_in,
off_t offset_in,
const fuse_file_info_t *fi_out,
off_t offset_out,
size_t size,
int flags);
};
/** Extra context that may be needed by some filesystems
@@ -775,10 +785,10 @@ int fuse_fs_getattr(struct fuse_fs *fs,
struct stat *buf,
fuse_timeouts_t *timeout);
int fuse_fs_fgetattr(struct fuse_fs *fs,
struct stat *buf,
struct fuse_file_info *fi,
fuse_timeouts_t *timeout);
int fuse_fs_fgetattr(struct fuse_fs *fs,
struct stat *buf,
fuse_file_info_t *fi,
fuse_timeouts_t *timeout);
int fuse_fs_rename(struct fuse_fs *fs, const char *oldpath,
const char *newpath);
@@ -788,44 +798,44 @@ int fuse_fs_symlink(struct fuse_fs *fs, const char *linkname,
const char *path);
int fuse_fs_link(struct fuse_fs *fs, const char *oldpath, const char *newpath);
int fuse_fs_release(struct fuse_fs *fs,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_open(struct fuse_fs *fs, const char *path,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_read(struct fuse_fs *fs, char *buf, size_t size,
off_t off, struct fuse_file_info *fi);
off_t off, fuse_file_info_t *fi);
int fuse_fs_read_buf(struct fuse_fs *fs,
struct fuse_bufvec **bufp, size_t size, off_t off,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_write(struct fuse_fs *fs, const char *buf,
size_t size, off_t off, struct fuse_file_info *fi);
size_t size, off_t off, fuse_file_info_t *fi);
int fuse_fs_write_buf(struct fuse_fs *fs,
struct fuse_bufvec *buf, off_t off,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_fsync(struct fuse_fs *fs, int datasync,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_flush(struct fuse_fs *fs,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_statfs(struct fuse_fs *fs, const char *path, struct statvfs *buf);
int fuse_fs_opendir(struct fuse_fs *fs, const char *path,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_readdir(struct fuse_fs *fs,
struct fuse_file_info *fi,
fuse_file_info_t *fi,
fuse_dirents_t *buf);
int fuse_fs_fsyncdir(struct fuse_fs *fs, int datasync,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_releasedir(struct fuse_fs *fs,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_lock(struct fuse_fs *fs,
struct fuse_file_info *fi, int cmd, struct flock *lock);
fuse_file_info_t *fi, int cmd, struct flock *lock);
int fuse_fs_flock(struct fuse_fs *fs,
struct fuse_file_info *fi, int op);
fuse_file_info_t *fi, int op);
int fuse_fs_chmod(struct fuse_fs *fs, const char *path, mode_t mode);
int fuse_fs_chown(struct fuse_fs *fs, const char *path, uid_t uid, gid_t gid);
int fuse_fs_truncate(struct fuse_fs *fs, const char *path, off_t size);
int fuse_fs_ftruncate(struct fuse_fs *fs, off_t size,
struct fuse_file_info *fi);
fuse_file_info_t *fi);
int fuse_fs_utimens(struct fuse_fs *fs, const char *path,
const struct timespec tv[2]);
int fuse_fs_access(struct fuse_fs *fs, const char *path, int mask);
@@ -845,24 +855,24 @@ int fuse_fs_removexattr(struct fuse_fs *fs, const char *path,
int fuse_fs_bmap(struct fuse_fs *fs, const char *path, size_t blocksize,
uint64_t *idx);
int fuse_fs_ioctl(struct fuse_fs *fs, unsigned long cmd, void *arg,
struct fuse_file_info *fi, unsigned int flags,
fuse_file_info_t *fi, unsigned int flags,
void *data, uint32_t *out_bufsz);
int fuse_fs_poll(struct fuse_fs *fs,
struct fuse_file_info *fi, struct fuse_pollhandle *ph,
fuse_file_info_t *fi, fuse_pollhandle_t *ph,
unsigned *reventsp);
int fuse_fs_fallocate(struct fuse_fs *fs, int mode,
off_t offset, off_t length, struct fuse_file_info *fi);
off_t offset, off_t length, fuse_file_info_t *fi);
void fuse_fs_init(struct fuse_fs *fs, struct fuse_conn_info *conn);
void fuse_fs_destroy(struct fuse_fs *fs);
int fuse_fs_prepare_hide(struct fuse_fs *fs, const char *path, uint64_t *fh);
int fuse_fs_free_hide(struct fuse_fs *fs, uint64_t fh);
ssize_t fuse_fs_copy_file_range(struct fuse_fs *fs,
struct fuse_file_info *fi_in, off_t off_in,
struct fuse_file_info *fi_out, off_t off_out,
fuse_file_info_t *fi_in, off_t off_in,
fuse_file_info_t *fi_out, off_t off_out,
size_t len, int flags);
int fuse_notify_poll(struct fuse_pollhandle *ph);
int fuse_notify_poll(fuse_pollhandle_t *ph);
/**
* Create a new fuse filesystem object
+5 -4
View File
@@ -46,8 +46,8 @@ EXTERN_C_BEGIN
*
* Changed in version 2.5
*/
struct
fuse_file_info
typedef struct fuse_file_info_t fuse_file_info_t;
struct fuse_file_info_t
{
/** Open flags. Available in open() and release() */
int flags;
@@ -205,7 +205,8 @@ struct fuse_conn_info {
struct fuse_session;
struct fuse_chan;
struct fuse_pollhandle;
struct fuse_pollhandle_t;
typedef struct fuse_pollhandle_t fuse_pollhandle_t;
/**
* Create a FUSE mountpoint
@@ -271,7 +272,7 @@ int fuse_version(void);
*
* @param ph the poll handle
*/
void fuse_pollhandle_destroy(struct fuse_pollhandle *ph);
void fuse_pollhandle_destroy(fuse_pollhandle_t *ph);
/* ----------------------------------------------------------- *
* Data buffer *
+200 -198
View File
@@ -67,63 +67,63 @@ struct fuse_chan;
/** Directory entry parameters supplied to fuse_reply_entry() */
struct fuse_entry_param
{
/** Unique inode number
*
* In lookup, zero means negative entry (from version 2.5)
* Returning ENOENT also means negative entry, but by setting zero
* ino the kernel may cache negative entries for entry_timeout
* seconds.
*/
fuse_ino_t ino;
/** Unique inode number
*
* In lookup, zero means negative entry (from version 2.5)
* Returning ENOENT also means negative entry, but by setting zero
* ino the kernel may cache negative entries for entry_timeout
* seconds.
*/
fuse_ino_t ino;
/** Generation number for this entry.
*
* If the file system will be exported over NFS, the
* ino/generation pairs need to be unique over the file
* system's lifetime (rather than just the mount time). So if
* the file system reuses an inode after it has been deleted,
* it must assign a new, previously unused generation number
* to the inode at the same time.
*
* The generation must be non-zero, otherwise FUSE will treat
* it as an error.
*
*/
uint64_t generation;
/** Generation number for this entry.
*
* If the file system will be exported over NFS, the
* ino/generation pairs need to be unique over the file
* system's lifetime (rather than just the mount time). So if
* the file system reuses an inode after it has been deleted,
* it must assign a new, previously unused generation number
* to the inode at the same time.
*
* The generation must be non-zero, otherwise FUSE will treat
* it as an error.
*
*/
uint64_t generation;
/** Inode attributes.
*
* Even if attr_timeout == 0, attr must be correct. For example,
* for open(), FUSE uses attr.st_size from lookup() to determine
* how many bytes to request. If this value is not correct,
* incorrect data will be returned.
*/
struct stat attr;
/** Inode attributes.
*
* Even if attr_timeout == 0, attr must be correct. For example,
* for open(), FUSE uses attr.st_size from lookup() to determine
* how many bytes to request. If this value is not correct,
* incorrect data will be returned.
*/
struct stat attr;
fuse_timeouts_t timeout;
fuse_timeouts_t timeout;
};
/** Additional context associated with requests */
struct fuse_ctx
{
/** User ID of the calling process */
uid_t uid;
/** User ID of the calling process */
uid_t uid;
/** Group ID of the calling process */
gid_t gid;
/** Group ID of the calling process */
gid_t gid;
/** Thread ID of the calling process */
pid_t pid;
/** Thread ID of the calling process */
pid_t pid;
/** Umask of the calling process (introduced in version 2.8) */
mode_t umask;
/** Umask of the calling process (introduced in version 2.8) */
mode_t umask;
};
struct fuse_forget_data
{
fuse_ino_t ino;
uint64_t nlookup;
fuse_ino_t ino;
uint64_t nlookup;
};
/* ----------------------------------------------------------- *
@@ -153,78 +153,78 @@ uint64_t nlookup;
*/
struct fuse_lowlevel_ops
{
/**
* Initialize filesystem
*
* Called before any other filesystem method
*
* There's no reply to this function
*
* @param userdata the user data passed to fuse_lowlevel_new()
*/
void (*init) (void *userdata, struct fuse_conn_info *conn);
/**
* Initialize filesystem
*
* Called before any other filesystem method
*
* There's no reply to this function
*
* @param userdata the user data passed to fuse_lowlevel_new()
*/
void (*init)(void *userdata, struct fuse_conn_info *conn);
/**
* Clean up filesystem
*
* Called on filesystem exit
*
* There's no reply to this function
*
* @param userdata the user data passed to fuse_lowlevel_new()
*/
void (*destroy) (void *userdata);
/**
* Clean up filesystem
*
* Called on filesystem exit
*
* There's no reply to this function
*
* @param userdata the user data passed to fuse_lowlevel_new()
*/
void (*destroy)(void *userdata);
/**
* Look up a directory entry by name and get its attributes.
*
* Valid replies:
* fuse_reply_entry
* fuse_reply_err
*
* @param req request handle
* @param parent inode number of the parent directory
* @param name the name to look up
*/
void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
/**
* Look up a directory entry by name and get its attributes.
*
* Valid replies:
* fuse_reply_entry
* fuse_reply_err
*
* @param req request handle
* @param parent inode number of the parent directory
* @param name the name to look up
*/
void (*lookup)(fuse_req_t req, fuse_ino_t parent, const char *name);
/**
* Forget about an inode
*
* This function is called when the kernel removes an inode
* from its internal caches.
*
* The inode's lookup count increases by one for every call to
* fuse_reply_entry and fuse_reply_create. The nlookup parameter
* indicates by how much the lookup count should be decreased.
*
* Inodes with a non-zero lookup count may receive request from
* the kernel even after calls to unlink, rmdir or (when
* overwriting an existing file) rename. Filesystems must handle
* such requests properly and it is recommended to defer removal
* of the inode until the lookup count reaches zero. Calls to
* unlink, remdir or rename will be followed closely by forget
* unless the file or directory is open, in which case the
* kernel issues forget only after the release or releasedir
* calls.
*
* Note that if a file system will be exported over NFS the
* inodes lifetime must extend even beyond forget. See the
* generation field in struct fuse_entry_param above.
*
* On unmount the lookup count for all inodes implicitly drops
* to zero. It is not guaranteed that the file system will
* receive corresponding forget messages for the affected
* inodes.
*
* Valid replies:
* fuse_reply_none
*
* @param req request handle
* @param ino the inode number
* @param nlookup the number of lookups to forget
*/
void (*forget) (fuse_req_t req, fuse_ino_t ino, uint64_t nlookup);
/**
* Forget about an inode
*
* This function is called when the kernel removes an inode
* from its internal caches.
*
* The inode's lookup count increases by one for every call to
* fuse_reply_entry and fuse_reply_create. The nlookup parameter
* indicates by how much the lookup count should be decreased.
*
* Inodes with a non-zero lookup count may receive request from
* the kernel even after calls to unlink, rmdir or (when
* overwriting an existing file) rename. Filesystems must handle
* such requests properly and it is recommended to defer removal
* of the inode until the lookup count reaches zero. Calls to
* unlink, remdir or rename will be followed closely by forget
* unless the file or directory is open, in which case the
* kernel issues forget only after the release or releasedir
* calls.
*
* Note that if a file system will be exported over NFS the
* inodes lifetime must extend even beyond forget. See the
* generation field in struct fuse_entry_param above.
*
* On unmount the lookup count for all inodes implicitly drops
* to zero. It is not guaranteed that the file system will
* receive corresponding forget messages for the affected
* inodes.
*
* Valid replies:
* fuse_reply_none
*
* @param req request handle
* @param ino the inode number
* @param nlookup the number of lookups to forget
*/
void (*forget)(fuse_req_t req, fuse_ino_t ino, uint64_t nlookup);
/**
* Get file attributes
@@ -237,8 +237,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param fi for future use, currently always NULL
*/
void (*getattr) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
void (*getattr)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi);
/**
* Set file attributes
@@ -267,8 +267,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* Changed in version 2.5:
* file information filled in for ftruncate
*/
void (*setattr) (fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, struct fuse_file_info *fi);
void (*setattr)(fuse_req_t req, fuse_ino_t ino, struct stat *attr,
int to_set, fuse_file_info_t *fi);
/**
* Read symbolic link
@@ -280,7 +280,7 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param req request handle
* @param ino the inode number
*/
void (*readlink) (fuse_req_t req, fuse_ino_t ino);
void (*readlink)(fuse_req_t req, fuse_ino_t ino);
/**
* Create file node
@@ -298,8 +298,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param mode file type and mode with which to create the new file
* @param rdev the device number (only valid if created file is a device)
*/
void (*mknod) (fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, dev_t rdev);
void (*mknod)(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, dev_t rdev);
/**
* Create a directory
@@ -313,8 +313,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param name to create
* @param mode with which to create the new file
*/
void (*mkdir) (fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode);
void (*mkdir)(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode);
/**
* Remove a file
@@ -331,7 +331,7 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param parent inode number of the parent directory
* @param name to remove
*/
void (*unlink) (fuse_req_t req, fuse_ino_t parent, const char *name);
void (*unlink)(fuse_req_t req, fuse_ino_t parent, const char *name);
/**
* Remove a directory
@@ -348,7 +348,7 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param parent inode number of the parent directory
* @param name to remove
*/
void (*rmdir) (fuse_req_t req, fuse_ino_t parent, const char *name);
void (*rmdir)(fuse_req_t req, fuse_ino_t parent, const char *name);
/**
* Create a symbolic link
@@ -362,8 +362,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param parent inode number of the parent directory
* @param name to create
*/
void (*symlink) (fuse_req_t req, const char *link, fuse_ino_t parent,
const char *name);
void (*symlink)(fuse_req_t req, const char *link, fuse_ino_t parent,
const char *name);
/** Rename a file
*
@@ -382,8 +382,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param newparent inode number of the new parent directory
* @param newname new name
*/
void (*rename) (fuse_req_t req, fuse_ino_t parent, const char *name,
fuse_ino_t newparent, const char *newname);
void (*rename)(fuse_req_t req, fuse_ino_t parent, const char *name,
fuse_ino_t newparent, const char *newname);
/**
* Create a hard link
@@ -397,8 +397,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param newparent inode number of the new parent directory
* @param newname new name to create
*/
void (*link) (fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
const char *newname);
void (*link)(fuse_req_t req, fuse_ino_t ino, fuse_ino_t newparent,
const char *newname);
/**
* Open a file
@@ -425,8 +425,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param fi file information
*/
void (*open) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
void (*open)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi);
/**
* Read data
@@ -453,8 +453,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param off offset to read from
* @param fi file information
*/
void (*read) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
struct fuse_file_info *fi);
void (*read)(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
fuse_file_info_t *fi);
/**
* Write data
@@ -479,8 +479,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param off offset to write to
* @param fi file information
*/
void (*write) (fuse_req_t req, fuse_ino_t ino, const char *buf,
size_t size, off_t off, struct fuse_file_info *fi);
void (*write)(fuse_req_t req, fuse_ino_t ino, const char *buf,
size_t size, off_t off, fuse_file_info_t *fi);
/**
* Flush method
@@ -511,8 +511,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param fi file information
*/
void (*flush) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
void (*flush)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi);
/**
* Release an open file
@@ -538,8 +538,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param fi file information
*/
void (*release) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
void (*release)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi);
/**
* Synchronize file contents
@@ -555,8 +555,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param datasync flag indicating if only data should be flushed
* @param fi file information
*/
void (*fsync) (fuse_req_t req, fuse_ino_t ino, int datasync,
struct fuse_file_info *fi);
void (*fsync)(fuse_req_t req, fuse_ino_t ino, int datasync,
fuse_file_info_t *fi);
/**
* Open a directory
@@ -579,8 +579,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param fi file information
*/
void (*opendir) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
void (*opendir)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi);
/**
* Read directory
@@ -603,12 +603,12 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param off offset to continue reading the directory stream
* @param fi file information
*/
void (*readdir) (fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
struct fuse_file_info *llffi);
void (*readdir)(fuse_req_t req, fuse_ino_t ino, size_t size, off_t off,
fuse_file_info_t *llffi);
void (*readdir_plus)(fuse_req_t req, fuse_ino_t ino,
size_t size, off_t off,
struct fuse_file_info *ffi);
fuse_file_info_t *ffi);
/**
* Release an open directory
@@ -626,8 +626,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param fi file information
*/
void (*releasedir) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi);
void (*releasedir)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi);
/**
* Synchronize directory contents
@@ -646,8 +646,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param datasync flag indicating if only data should be flushed
* @param fi file information
*/
void (*fsyncdir) (fuse_req_t req, fuse_ino_t ino, int datasync,
struct fuse_file_info *fi);
void (*fsyncdir)(fuse_req_t req, fuse_ino_t ino, int datasync,
fuse_file_info_t *fi);
/**
* Get file system statistics
@@ -659,7 +659,7 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param req request handle
* @param ino the inode number, zero means "undefined"
*/
void (*statfs) (fuse_req_t req, fuse_ino_t ino);
void (*statfs)(fuse_req_t req, fuse_ino_t ino);
/**
* Set an extended attribute
@@ -667,8 +667,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* Valid replies:
* fuse_reply_err
*/
void (*setxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
const char *value, size_t size, int flags);
void (*setxattr)(fuse_req_t req, fuse_ino_t ino, const char *name,
const char *value, size_t size, int flags);
/**
* Get an extended attribute
@@ -693,8 +693,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param name of the extended attribute
* @param size maximum size of the value to send
*/
void (*getxattr) (fuse_req_t req, fuse_ino_t ino, const char *name,
size_t size);
void (*getxattr)(fuse_req_t req, fuse_ino_t ino, const char *name,
size_t size);
/**
* List extended attribute names
@@ -719,7 +719,7 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param size maximum size of the list to send
*/
void (*listxattr) (fuse_req_t req, fuse_ino_t ino, size_t size);
void (*listxattr)(fuse_req_t req, fuse_ino_t ino, size_t size);
/**
* Remove an extended attribute
@@ -731,7 +731,7 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param name of the extended attribute
*/
void (*removexattr) (fuse_req_t req, fuse_ino_t ino, const char *name);
void (*removexattr)(fuse_req_t req, fuse_ino_t ino, const char *name);
/**
* Check file access permissions
@@ -751,7 +751,7 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param ino the inode number
* @param mask requested access mode
*/
void (*access) (fuse_req_t req, fuse_ino_t ino, int mask);
void (*access)(fuse_req_t req, fuse_ino_t ino, int mask);
/**
* Create and open a file
@@ -786,8 +786,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param mode file type and mode with which to create the new file
* @param fi file information
*/
void (*create) (fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, struct fuse_file_info *fi);
void (*create)(fuse_req_t req, fuse_ino_t parent, const char *name,
mode_t mode, fuse_file_info_t *fi);
/**
* Test for a POSIX file lock
@@ -803,8 +803,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param fi file information
* @param lock the region/type to test
*/
void (*getlk) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi, struct flock *lock);
void (*getlk)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi, struct flock *lock);
/**
* Acquire, modify or release a POSIX file lock
@@ -830,9 +830,9 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param lock the region/type to set
* @param sleep locking operation may sleep
*/
void (*setlk) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi,
struct flock *lock, int sleep);
void (*setlk)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi,
struct flock *lock, int sleep);
/**
* Map block index within file to block index within device
@@ -851,8 +851,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param blocksize unit of block index
* @param idx block index within file
*/
void (*bmap) (fuse_req_t req, fuse_ino_t ino, size_t blocksize,
uint64_t idx);
void (*bmap)(fuse_req_t req, fuse_ino_t ino, size_t blocksize,
uint64_t idx);
/**
* Ioctl
@@ -881,9 +881,9 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param in_bufsz number of fetched bytes
* @param out_bufsz maximum size of output data
*/
void (*ioctl) (fuse_req_t req, fuse_ino_t ino, unsigned long cmd, void *arg,
struct fuse_file_info *fi, unsigned flags,
const void *in_buf, uint32_t in_bufsz, uint32_t out_bufsz);
void (*ioctl)(fuse_req_t req, fuse_ino_t ino, unsigned long cmd, void *arg,
fuse_file_info_t *fi, unsigned flags,
const void *in_buf, uint32_t in_bufsz, uint32_t out_bufsz);
/**
* Poll for IO readiness
@@ -911,8 +911,10 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param fi file information
* @param ph poll handle to be used for notification
*/
void (*poll) (fuse_req_t req, fuse_ino_t ino, struct fuse_file_info *fi,
struct fuse_pollhandle *ph);
void (*poll)(fuse_req_t req,
fuse_ino_t ino,
fuse_file_info_t *fi,
fuse_pollhandle_t *ph);
/**
* Write data made available in a buffer
@@ -940,9 +942,9 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param off offset to write to
* @param fi file information
*/
void (*write_buf) (fuse_req_t req, fuse_ino_t ino,
struct fuse_bufvec *bufv, off_t off,
struct fuse_file_info *fi);
void (*write_buf)(fuse_req_t req, fuse_ino_t ino,
struct fuse_bufvec *bufv, off_t off,
fuse_file_info_t *fi);
/**
* Callback function for the retrieve request
@@ -958,8 +960,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param offset the offset supplied to fuse_lowlevel_notify_retrieve()
* @param bufv the buffer containing the returned data
*/
void (*retrieve_reply) (fuse_req_t req, void *cookie, fuse_ino_t ino,
off_t offset, struct fuse_bufvec *bufv);
void (*retrieve_reply)(fuse_req_t req, void *cookie, fuse_ino_t ino,
off_t offset, struct fuse_bufvec *bufv);
/**
* Forget about multiple inodes
@@ -974,8 +976,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
*
* @param req request handle
*/
void (*forget_multi) (fuse_req_t req, size_t count,
struct fuse_forget_data *forgets);
void (*forget_multi)(fuse_req_t req, size_t count,
struct fuse_forget_data *forgets);
/**
* Acquire, modify or release a BSD file lock
@@ -994,8 +996,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param fi file information
* @param op the locking operation, see flock(2)
*/
void (*flock) (fuse_req_t req, fuse_ino_t ino,
struct fuse_file_info *fi, int op);
void (*flock)(fuse_req_t req, fuse_ino_t ino,
fuse_file_info_t *fi, int op);
/**
* Allocate requested space. If this function returns success then
@@ -1014,8 +1016,8 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param mode determines the operation to be performed on the given range,
* see fallocate(2)
*/
void (*fallocate) (fuse_req_t req, fuse_ino_t ino, int mode,
off_t offset, off_t length, struct fuse_file_info *fi);
void (*fallocate)(fuse_req_t req, fuse_ino_t ino, int mode,
off_t offset, off_t length, fuse_file_info_t *fi);
/**
* Copy a range of data from one file to another
@@ -1053,15 +1055,15 @@ void (*lookup) (fuse_req_t req, fuse_ino_t parent, const char *name);
* @param len maximum size of the data to copy
* @param flags passed along with the copy_file_range() syscall
*/
void (*copy_file_range)(fuse_req_t req,
fuse_ino_t ino_in,
off_t off_in,
struct fuse_file_info *fi_in,
fuse_ino_t ino_out,
off_t off_out,
struct fuse_file_info *fi_out,
size_t len,
int flags);
void (*copy_file_range)(fuse_req_t req,
fuse_ino_t ino_in,
off_t off_in,
fuse_file_info_t *fi_in,
fuse_ino_t ino_out,
off_t off_out,
fuse_file_info_t *fi_out,
size_t len,
int flags);
};
/**
@@ -1122,7 +1124,7 @@ int fuse_reply_entry(fuse_req_t req, const struct fuse_entry_param *e);
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_create(fuse_req_t req, const struct fuse_entry_param *e,
const struct fuse_file_info *fi);
const fuse_file_info_t *fi);
/**
* Reply with attributes
@@ -1164,7 +1166,7 @@ int fuse_reply_readlink(fuse_req_t req, const char *link);
* @param fi file information
* @return zero for success, -errno for failure to send reply
*/
int fuse_reply_open(fuse_req_t req, const struct fuse_file_info *fi);
int fuse_reply_open(fuse_req_t req, const fuse_file_info_t *fi);
/**
* Reply with number of bytes written
@@ -1331,7 +1333,7 @@ int fuse_reply_poll(fuse_req_t req, unsigned revents);
*
* @param ph poll handle to notify IO readiness event for
*/
int fuse_lowlevel_notify_poll(struct fuse_pollhandle *ph);
int fuse_lowlevel_notify_poll(fuse_pollhandle_t *ph);
/**
* Notify to invalidate cache for an inode
@@ -1549,8 +1551,8 @@ struct fuse_session_ops
* @param len request length
* @param ch channel on which the request was received
*/
void (*process) (void *data, const char *buf, size_t len,
struct fuse_chan *ch);
void (*process)(void *data, const char *buf, size_t len,
struct fuse_chan *ch);
/**
* Hook for session exit and reset (optional)
@@ -1558,7 +1560,7 @@ struct fuse_session_ops
* @param data user data passed to fuse_session_new()
* @param val exited status (1 - exited, 0 - not exited)
*/
void (*exit) (void *data, int val);
void (*exit)(void *data, int val);
/**
* Hook for querying the current exited status (optional)
@@ -1566,14 +1568,14 @@ struct fuse_session_ops
* @param data user data passed to fuse_session_new()
* @return 1 if exited, 0 if not exited
*/
int (*exited) (void *data);
int (*exited)(void *data);
/**
* Hook for cleaning up the channel on destroy (optional)
*
* @param data user data passed to fuse_session_new()
*/
void (*destroy) (void *data);
void (*destroy)(void *data);
};
/**
+2616 -2232
View File
File diff suppressed because it is too large Load Diff
+73 -66
View File
@@ -6,25 +6,26 @@
See the file COPYING.LIB.
*/
#include "fuse_i.h"
#include "fuse_kernel.h"
#include "fuse_lowlevel.h"
#include "fuse_misc.h"
#include "fuse_kernel.h"
#include "fuse_i.h"
#include <errno.h>
#include <semaphore.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <semaphore.h>
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include <unistd.h>
/* Environment var controlling the thread stack size */
#define ENVNAME_THREAD_STACK "FUSE_THREAD_STACK"
struct fuse_worker {
struct fuse_worker
{
struct fuse_worker *prev;
struct fuse_worker *next;
pthread_t thread_id;
@@ -33,7 +34,8 @@ struct fuse_worker {
struct fuse_mt *mt;
};
struct fuse_mt {
struct fuse_mt
{
struct fuse_session *se;
struct fuse_chan *prevch;
struct fuse_worker main;
@@ -42,7 +44,10 @@ struct fuse_mt {
int error;
};
static void list_add_worker(struct fuse_worker *w, struct fuse_worker *next)
static
void
list_add_worker(struct fuse_worker *w,
struct fuse_worker *next)
{
struct fuse_worker *prev = next->prev;
w->next = next;
@@ -61,38 +66,41 @@ static void list_del_worker(struct fuse_worker *w)
static int fuse_loop_start_thread(struct fuse_mt *mt);
static void *fuse_do_work(void *data)
static
void*
fuse_do_work(void *data)
{
struct fuse_worker *w = (struct fuse_worker *) data;
struct fuse_mt *mt = w->mt;
while (!fuse_session_exited(mt->se)) {
struct fuse_chan *ch = mt->prevch;
struct fuse_buf fbuf = {
.mem = w->buf,
.size = w->bufsize,
};
int res;
while(!fuse_session_exited(mt->se))
{
int res;
struct fuse_buf fbuf;
struct fuse_chan *ch = mt->prevch;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
res = fuse_session_receive_buf(mt->se, &fbuf, &ch);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if (res == -EINTR)
continue;
if (res <= 0) {
if (res < 0) {
fuse_session_exit(mt->se);
mt->error = -1;
fbuf.mem = w->buf;
fbuf.size = w->bufsize;
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
res = fuse_session_receive_buf(mt->se, &fbuf, &ch);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
if(res == -EINTR)
continue;
if(res <= 0) {
if(res < 0) {
fuse_session_exit(mt->se);
mt->error = -1;
}
break;
}
break;
if(mt->exit)
return NULL;
fuse_session_process_buf(mt->se, &fbuf, ch);
}
if (mt->exit)
return NULL;
fuse_session_process_buf(mt->se, &fbuf, ch);
}
sem_post(&mt->finish);
return NULL;
@@ -109,20 +117,16 @@ int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg)
/* Override default stack size */
pthread_attr_init(&attr);
stack_size = getenv(ENVNAME_THREAD_STACK);
if (stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size)))
if(stack_size && pthread_attr_setstacksize(&attr, atoi(stack_size)))
fprintf(stderr, "fuse: invalid stack size: %s\n", stack_size);
/* Disallow signal reception in worker threads */
sigemptyset(&newset);
sigaddset(&newset, SIGTERM);
sigaddset(&newset, SIGINT);
sigaddset(&newset, SIGHUP);
sigaddset(&newset, SIGQUIT);
pthread_sigmask(SIG_BLOCK, &newset, &oldset);
sigfillset(&newset);
pthread_sigmask(SIG_BLOCK,&newset,&oldset);
res = pthread_create(thread_id, &attr, func, arg);
pthread_sigmask(SIG_SETMASK, &oldset, NULL);
pthread_sigmask(SIG_SETMASK,&oldset,NULL);
pthread_attr_destroy(&attr);
if (res != 0) {
if(res != 0) {
fprintf(stderr, "fuse: error creating thread: %s\n",
strerror(res));
return -1;
@@ -135,7 +139,7 @@ static int fuse_loop_start_thread(struct fuse_mt *mt)
{
int res;
struct fuse_worker *w = malloc(sizeof(struct fuse_worker));
if (!w) {
if(!w) {
fprintf(stderr, "fuse: failed to allocate worker structure\n");
return -1;
}
@@ -143,14 +147,14 @@ static int fuse_loop_start_thread(struct fuse_mt *mt)
w->bufsize = fuse_chan_bufsize(mt->prevch);
w->buf = calloc(w->bufsize,1);
w->mt = mt;
if (!w->buf) {
if(!w->buf) {
fprintf(stderr, "fuse: failed to allocate read buffer\n");
free(w);
return -1;
}
res = fuse_start_thread(&w->thread_id, fuse_do_work, w);
if (res == -1) {
if(res == -1) {
free(w->buf);
free(w);
return -1;
@@ -177,8 +181,9 @@ static int number_of_threads(void)
return 4;
}
int fuse_session_loop_mt(struct fuse_session *se,
const int _threads)
int
fuse_session_loop_mt(struct fuse_session *se_,
const int threads_)
{
int i;
int err;
@@ -186,17 +191,17 @@ int fuse_session_loop_mt(struct fuse_session *se,
struct fuse_mt mt;
struct fuse_worker *w;
memset(&mt, 0, sizeof(struct fuse_mt));
mt.se = se;
mt.prevch = fuse_session_next_chan(se, NULL);
memset(&mt,0,sizeof(struct fuse_mt));
mt.se = se_;
mt.prevch = fuse_session_next_chan(se_,NULL);
mt.error = 0;
mt.main.thread_id = pthread_self();
mt.main.prev = mt.main.next = &mt.main;
sem_init(&mt.finish, 0, 0);
sem_init(&mt.finish,0,0);
threads = ((_threads > 0) ? _threads : number_of_threads());
if(_threads < 0)
threads /= -_threads;
threads = ((threads_ > 0) ? threads_ : number_of_threads());
if(threads_ < 0)
threads /= -threads_;
if(threads == 0)
threads = 1;
@@ -204,22 +209,24 @@ int fuse_session_loop_mt(struct fuse_session *se,
for(i = 0; (i < threads) && !err; i++)
err = fuse_loop_start_thread(&mt);
if (!err) {
/* sem_wait() is interruptible */
while (!fuse_session_exited(se))
sem_wait(&mt.finish);
if(!err)
{
/* sem_wait() is interruptible */
while(!fuse_session_exited(se_))
sem_wait(&mt.finish);
for (w = mt.main.next; w != &mt.main; w = w->next)
pthread_cancel(w->thread_id);
mt.exit = 1;
for(w = mt.main.next; w != &mt.main; w = w->next)
pthread_cancel(w->thread_id);
mt.exit = 1;
while (mt.main.next != &mt.main)
fuse_join_worker(mt.main.next);
while(mt.main.next != &mt.main)
fuse_join_worker(mt.main.next);
err = mt.error;
}
err = mt.error;
}
sem_destroy(&mt.finish);
fuse_session_reset(se);
fuse_session_reset(se_);
return err;
}
+1444 -919
View File
File diff suppressed because it is too large Load Diff
+97 -46
View File
@@ -127,6 +127,7 @@ This is required for most use\-cases.
.IP \[bu] 2
\f[B]minfreespace=SIZE\f[]: The minimum space value used for creation
policies.
Can be overridden by branch specific option.
Understands \[aq]K\[aq], \[aq]M\[aq], and \[aq]G\[aq] to represent
kilobyte, megabyte, and gigabyte respectively.
(default: 4G)
@@ -331,28 +332,40 @@ POLICY = mergerfs function policy
The \[aq]branches\[aq] (formerly \[aq]srcmounts\[aq]) argument is a
colon (\[aq]:\[aq]) delimited list of paths to be pooled together.
It does not matter if the paths are on the same or different drives nor
does it matter the filesystem.
does it matter the filesystem (within reason).
Used and available space will not be duplicated for paths on the same
device and any features which aren\[aq]t supported by the underlying
filesystem (such as file attributes or extended attributes) will return
the appropriate errors.
.PP
Branches currently have two options which can be set.
A type which impacts whether or not the branch is included in a policy
calculation and a individual minfreespace value.
The values are set by prepending an \f[C]=\f[] at the end of a branch
designation and using commas as delimiters.
Example: /mnt/drive=RW,1234
.SS branch type
.IP \[bu] 2
RW: (read/write) \- Default behavior.
Will be eligible in all policy categories.
.IP \[bu] 2
RO: (read\-only) \- Will be excluded from \f[C]create\f[] and
\f[C]action\f[] policies.
Same as a read\-only mounted filesystem would be (though faster to
process).
.IP \[bu] 2
NC: (no\-create) \- Will be excluded from \f[C]create\f[] policies.
You can\[aq]t create on that branch but you can change or delete.
.SS minfreespace
.PP
Same purpose as the global option but specific to the branch.
If not set the global value is used.
.SS globbing
.PP
To make it easier to include multiple branches mergerfs supports
globbing (http://linux.die.net/man/7/glob).
\f[B]The globbing tokens MUST be escaped when using via the shell else
the shell itself will apply the glob itself.\f[]
.PP
Each branch can have a suffix of \f[C]=RW\f[] (read / write),
\f[C]=RO\f[] (read\-only), or \f[C]=NC\f[] (no create).
These suffixes work with globs as well and will apply to each path
found.
\f[C]RW\f[] is the default behavior and those paths will be eligible for
all policy categories.
\f[C]RO\f[] will exclude those paths from \f[C]create\f[] and
\f[C]action\f[] policies (just as a filesystem being mounted \f[C]ro\f[]
would).
\f[C]NC\f[] will exclude those paths from \f[C]create\f[] policies (you
can\[aq]t create but you can change / delete).
.IP
.nf
\f[C]
@@ -373,8 +386,8 @@ tools use \f[B]/etc/fstab\f[].
\f[]
.fi
.PP
\f[B]NOTE:\f[] the globbing is done at mount or xattr update time (see
below).
\f[B]NOTE:\f[] the globbing is done at mount or when updated using the
runtime API.
If a new directory is added matching the glob after the fact it will not
be automatically included.
.PP
@@ -1075,6 +1088,46 @@ included when checking the mount\[aq]s stats.
.PP
The options \f[C]statfs\f[] and \f[C]statfs_ignore\f[] can be used to
modify \f[C]statfs\f[] behavior.
.SH ERROR HANDLING
.PP
POSIX filesystem functions offer a single return code meaning that there
is some complication regarding the handling of multiple branches as
mergerfs does.
It tries to handle errors in a way that would generally return
meaningful values for that particular function.
.SS chmod, chown, removexattr, setxattr, truncate, utimens
.IP "1)" 3
if no error: return 0 (success)
.IP "2)" 3
if no successes: return first error
.IP "3)" 3
if one of the files acted on was the same as the related search
function: return its value
.IP "4)" 3
return 0 (success)
.PP
While doing this increases the complexity and cost of error handling,
particularly step 3, this provides probably the most reasonable return
value.
.SS unlink, rmdir
.IP "1)" 3
if no errors: return 0 (success)
.IP "2)" 3
return first error
.PP
Older version of mergerfs would return success if any success occurred
but for unlink and rmdir there are downstream assumptions that, while
not impossible to occur, can confuse some software.
.SS others
.PP
For search functions there is always a single thing acted on and as such
whatever return value that comes from the single function call is
returned.
.PP
For create functions \f[C]mkdir\f[], \f[C]mknod\f[], and
\f[C]symlink\f[] which don\[aq]t return a file descriptor and therefore
can have \f[C]all\f[] or \f[C]epall\f[] policies it will return success
if any of the calls succeed and an error otherwise.
.SH BUILD / UPDATE
.PP
\f[B]NOTE:\f[] Prebuilt packages can be found at and recommended for
@@ -1136,6 +1189,35 @@ make\ STATIC=1\ \ \ \ \ \ \ \ \ \-\ build\ static\ binary
make\ LTO=1\ \ \ \ \ \ \ \ \ \ \ \ \-\ build\ with\ link\ time\ optimization
\f[]
.fi
.SH UPGRADE
.PP
mergerfs can be upgraded live by mounting on top of the previous
instance.
Simply install the new version of mergerfs and follow the instructions
below.
.PP
Add \f[C]nonempty\f[] to your mergerfs option list and call mergerfs
again or if using \f[C]/etc/fstab\f[] call for it to mount again.
Existing open files and such will continue to work fine though they
won\[aq]t see runtime changes since any such change would be the new
mount.
If you plan on changing settings with the new mount you should / could
apply those before mounting the new version.
.IP
.nf
\f[C]
$\ sudo\ mount\ /mnt/mergerfs
$\ mount\ |\ grep\ mergerfs
media\ on\ /mnt/mergerfs\ type\ fuse.mergerfs\ (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
media\ on\ /mnt/mergerfs\ type\ fuse.mergerfs\ (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
\f[]
.fi
.PP
A problem with this approach is that the underlying instance will
continue to run even if the software using it stop or are restarted.
To work around this you can use a "lazy umount".
Before mounting over top the mount point with the new instance of
mergerfs issue: \f[C]umount\ \-l\ <mergerfs_mountpoint>\f[].
.SH RUNTIME CONFIG
.SS ioctl
.PP
@@ -1346,29 +1428,6 @@ A\ B\ C
/mnt/b/full/path/to/A
\f[]
.fi
.SH UPGRADE
.PP
mergerfs can be upgraded live by mounting on top of the previous
version.
Simply install the new version of mergerfs and follow the instructions
below.
.PP
Add \f[C]nonempty\f[] to your mergerfs option list and call mergerfs
again or if using \f[C]/etc/fstab\f[] call for it to mount again.
Existing open files and such will continue to work fine though they
won\[aq]t see runtime changes since any such change would be the new
mount.
If you plan on changing settings with the new mount you should / could
apply those before mounting the new version.
.IP
.nf
\f[C]
$\ sudo\ mount\ /mnt/mergerfs
$\ mount\ |\ grep\ mergerfs
media\ on\ /mnt/mergerfs\ type\ fuse.mergerfs\ (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
media\ on\ /mnt/mergerfs\ type\ fuse.mergerfs\ (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other)
\f[]
.fi
.SH TOOLING
.IP \[bu] 2
https://github.com/trapexit/mergerfs\-tools
@@ -1857,14 +1916,6 @@ Shared mmap is not currently supported in FUSE w/ page caching disabled.
Enabling \f[C]dropcacheonclose\f[] is recommended when
\f[C]cache.files=partial|full|auto\-full\f[].
.IP \[bu] 2
Since POSIX functions give only a singular error or success its
difficult to determine the proper behavior when applying the function to
multiple targets.
\f[B]mergerfs\f[] will return an error only if all attempts of an action
fail.
Any success will lead to a success returned.
This means however that some odd situations may arise.
.IP \[bu] 2
Kodi (http://kodi.tv), Plex (http://plex.tv),
Subsonic (http://subsonic.org), etc.
can use directory mtime (http://linux.die.net/man/2/stat) to more
+1 -1
View File
@@ -31,7 +31,7 @@ namespace fs
dir_has_defaults(const std::string &fullpath_)
{
int rv;
std::string dirpath;
std::string dirpath;
dirpath = fs::path::dirname(fullpath_);
+1 -1
View File
@@ -73,7 +73,7 @@ namespace fs
return 0;
dirname = fs::path::dirname(relative_);
if(!dirname.empty())
if(dirname != "/")
{
rv = fs::clonepath(fromsrc_,tosrc_,dirname,return_metadata_errors_);
if(rv == -1)
+11 -18
View File
@@ -40,32 +40,25 @@ namespace fs
string
dirname(const string &path_)
{
string rv;
string::reverse_iterator i;
string::reverse_iterator ei;
std::size_t i;
rv = path_;
i = path_.size() - 1;
while((i > 0) && (path_[i] == '/'))
i--;
i = rv.rbegin();
ei = rv.rend();
while(*i == '/' && i != ei)
i++;
while((i > 0) && (path_[i] != '/'))
i--;
while(*i != '/' && i != ei)
i++;
while((i > 0) && (path_[i] == '/'))
i--;
while(*i == '/' && i != ei)
i++;
rv.erase(i.base(),rv.end());
return rv;
return path_.substr(0,i+1);
}
string
basename(const string &path)
basename(const string &path_)
{
return path.substr(path.find_last_of('/')+1);
return path_.substr(path_.find_last_of('/')+1);
}
}
}
+6 -6
View File
@@ -49,12 +49,12 @@ namespace l
namespace FUSE
{
ssize_t
copy_file_range(struct fuse_file_info *ffi_in_,
off_t offset_in_,
struct fuse_file_info *ffi_out_,
off_t offset_out_,
size_t size_,
int flags_)
copy_file_range(const fuse_file_info_t *ffi_in_,
off_t offset_in_,
const fuse_file_info_t *ffi_out_,
off_t offset_out_,
size_t size_,
int flags_)
{
FileInfo *fi_in = reinterpret_cast<FileInfo*>(ffi_in_->fh);
FileInfo *fi_out = reinterpret_cast<FileInfo*>(ffi_out_->fh);
+6 -6
View File
@@ -19,10 +19,10 @@
namespace FUSE
{
ssize_t
copy_file_range(struct fuse_file_info *ffi_in,
off_t offset_in,
struct fuse_file_info *ffi_out,
off_t offset_out,
size_t size,
int flags);
copy_file_range(const fuse_file_info_t *ffi_in,
off_t offset_in,
const fuse_file_info_t *ffi_out,
off_t offset_out,
size_t size,
int flags);
}
+5 -5
View File
@@ -54,8 +54,8 @@ namespace l
static
void
config_to_ffi_flags(const Config &config_,
fuse_file_info *ffi_)
config_to_ffi_flags(const Config &config_,
fuse_file_info_t *ffi_)
{
switch(config_.cache_files)
{
@@ -166,9 +166,9 @@ namespace l
namespace FUSE
{
int
create(const char *fusepath_,
mode_t mode_,
fuse_file_info *ffi_)
create(const char *fusepath_,
mode_t mode_,
fuse_file_info_t *ffi_)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
+3 -3
View File
@@ -23,7 +23,7 @@
namespace FUSE
{
int
create(const char *fusepath,
mode_t mode,
fuse_file_info *ffi);
create(const char *fusepath,
mode_t mode,
fuse_file_info_t *ffi);
}
+4 -4
View File
@@ -40,10 +40,10 @@ namespace l
namespace FUSE
{
int
fallocate(int mode_,
off_t offset_,
off_t len_,
fuse_file_info *ffi_)
fallocate(const fuse_file_info_t *ffi_,
int mode_,
off_t offset_,
off_t len_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+4 -4
View File
@@ -21,8 +21,8 @@
namespace FUSE
{
int
fallocate(int mode,
off_t offset,
off_t len,
fuse_file_info *ffi);
fallocate(const fuse_file_info_t *ffi,
int mode,
off_t offset,
off_t len);
}
+2 -2
View File
@@ -40,8 +40,8 @@ namespace l
namespace FUSE
{
int
fchmod(const struct fuse_file_info *ffi_,
const mode_t mode_)
fchmod(const fuse_file_info_t *ffi_,
const mode_t mode_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+2 -2
View File
@@ -23,6 +23,6 @@
namespace FUSE
{
int
fchmod(const fuse_file_info *ffi,
const mode_t mode);
fchmod(const fuse_file_info_t *ffi,
const mode_t mode);
}
+3 -3
View File
@@ -43,9 +43,9 @@ namespace l
namespace FUSE
{
int
fchown(const struct fuse_file_info *ffi_,
const uid_t uid_,
const gid_t gid_)
fchown(const fuse_file_info_t *ffi_,
const uid_t uid_,
const gid_t gid_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+3 -3
View File
@@ -21,7 +21,7 @@
namespace FUSE
{
int
fchown(const fuse_file_info *ffi,
uid_t uid,
gid_t gid);
fchown(const fuse_file_info_t *ffi,
uid_t uid,
gid_t gid);
}
+3 -3
View File
@@ -45,9 +45,9 @@ namespace l
namespace FUSE
{
int
fgetattr(struct stat *st_,
fuse_file_info *ffi_,
fuse_timeouts_t *timeout_)
fgetattr(const fuse_file_info_t *ffi_,
struct stat *st_,
fuse_timeouts_t *timeout_)
{
int rv;
const Config &config = Config::ro();
+3 -3
View File
@@ -25,7 +25,7 @@
namespace FUSE
{
int
fgetattr(struct stat *st,
fuse_file_info *ffi,
fuse_timeouts_t *timeout);
fgetattr(const fuse_file_info_t *ffi,
struct stat *st,
fuse_timeouts_t *timeout);
}
+2 -3
View File
@@ -38,9 +38,8 @@ namespace l
namespace FUSE
{
int
flock(const char *fusepath_,
fuse_file_info *ffi_,
int op_)
flock(const fuse_file_info_t *ffi_,
int op_)
{
FileInfo* fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+2 -3
View File
@@ -21,7 +21,6 @@
namespace FUSE
{
int
flock(const char *fusepath,
fuse_file_info *ffi,
int op);
flock(const fuse_file_info_t *ffi,
int op);
}
+1 -1
View File
@@ -42,7 +42,7 @@ namespace l
namespace FUSE
{
int
flush(fuse_file_info *ffi_)
flush(const fuse_file_info_t *ffi_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+1 -1
View File
@@ -21,5 +21,5 @@
namespace FUSE
{
int
flush(fuse_file_info *ffi);
flush(const fuse_file_info_t *ffi);
}
+2 -2
View File
@@ -44,8 +44,8 @@ namespace l
namespace FUSE
{
int
fsync(int isdatasync_,
fuse_file_info *ffi_)
fsync(const fuse_file_info_t *ffi_,
int isdatasync_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+3 -2
View File
@@ -21,6 +21,7 @@
namespace FUSE
{
int
fsync(int isdatasync,
fuse_file_info *ffi);
fsync(const fuse_file_info_t *ffi,
int isdatasync);
}
+2 -2
View File
@@ -42,8 +42,8 @@ namespace l
namespace FUSE
{
int
fsyncdir(int isdatasync_,
fuse_file_info *ffi_)
fsyncdir(const fuse_file_info_t *ffi_,
int isdatasync_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
+2 -2
View File
@@ -21,6 +21,6 @@
namespace FUSE
{
int
fsyncdir(int isdatasync,
fuse_file_info *ffi);
fsyncdir(const fuse_file_info_t *ffi,
int isdatasync);
}
+2 -2
View File
@@ -38,8 +38,8 @@ namespace l
namespace FUSE
{
int
ftruncate(off_t size_,
fuse_file_info *ffi_)
ftruncate(const fuse_file_info_t *ffi_,
off_t size_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+2 -2
View File
@@ -24,6 +24,6 @@
namespace FUSE
{
int
ftruncate(off_t size,
fuse_file_info *ffi);
ftruncate(const fuse_file_info_t *ffi,
off_t size);
}
+2 -2
View File
@@ -42,8 +42,8 @@ namespace l
namespace FUSE
{
int
futimens(const struct fuse_file_info *ffi_,
const struct timespec ts_[2])
futimens(const fuse_file_info_t *ffi_,
const struct timespec ts_[2])
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+2 -2
View File
@@ -23,6 +23,6 @@
namespace FUSE
{
int
futimens(const fuse_file_info *ffi,
const timespec ts[2]);
futimens(const fuse_file_info_t *ffi,
const timespec ts[2]);
}
+24 -24
View File
@@ -116,10 +116,10 @@ namespace l
static
int
ioctl_file(fuse_file_info *ffi_,
const uint32_t cmd_,
void *data_,
uint32_t *out_bufsz_)
ioctl_file(const fuse_file_info_t *ffi_,
const uint32_t cmd_,
void *data_,
uint32_t *out_bufsz_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
@@ -165,10 +165,10 @@ namespace l
static
int
ioctl_dir(fuse_file_info *ffi_,
const uint32_t cmd_,
void *data_,
uint32_t *out_bufsz_)
ioctl_dir(const fuse_file_info_t *ffi_,
const uint32_t cmd_,
void *data_,
uint32_t *out_bufsz_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
@@ -270,8 +270,8 @@ namespace l
static
int
file_basepath(fuse_file_info *ffi_,
void *data_)
file_basepath(const fuse_file_info_t *ffi_,
void *data_)
{
const Config &config = Config::ro();
std::string &fusepath = reinterpret_cast<FH*>(ffi_->fh)->fusepath;
@@ -284,8 +284,8 @@ namespace l
static
int
file_relpath(fuse_file_info *ffi_,
void *data_)
file_relpath(const fuse_file_info_t *ffi_,
void *data_)
{
std::string &fusepath = reinterpret_cast<FH*>(ffi_->fh)->fusepath;
@@ -314,8 +314,8 @@ namespace l
static
int
file_fullpath(fuse_file_info *ffi_,
void *data_)
file_fullpath(const fuse_file_info_t *ffi_,
void *data_)
{
const Config &config = Config::ro();
std::string &fusepath = reinterpret_cast<FH*>(ffi_->fh)->fusepath;
@@ -328,8 +328,8 @@ namespace l
static
int
file_allpaths(fuse_file_info *ffi_,
void *data_)
file_allpaths(const fuse_file_info_t *ffi_,
void *data_)
{
string concated;
vector<string> paths;
@@ -348,8 +348,8 @@ namespace l
static
int
file_info(fuse_file_info *ffi_,
void *data_)
file_info(const fuse_file_info_t *ffi_,
void *data_)
{
char *key = (char*)data_;
@@ -369,12 +369,12 @@ namespace l
namespace FUSE
{
int
ioctl(unsigned long cmd_,
void *arg_,
fuse_file_info *ffi_,
unsigned int flags_,
void *data_,
uint32_t *out_bufsz_)
ioctl(const fuse_file_info_t *ffi_,
unsigned long cmd_,
void *arg_,
unsigned int flags_,
void *data_,
uint32_t *out_bufsz_)
{
switch(cmd_)
{
+6 -6
View File
@@ -21,10 +21,10 @@
namespace FUSE
{
int
ioctl(unsigned long cmd,
void *arg,
fuse_file_info *ffi,
unsigned int flags,
void *data,
uint32_t *out_bufsz);
ioctl(const fuse_file_info_t *ffi,
unsigned long cmd,
void *arg,
unsigned int flags,
void *data,
uint32_t *out_bufsz);
}
+4 -4
View File
@@ -117,8 +117,8 @@ namespace l
static
void
config_to_ffi_flags(const Config &config_,
fuse_file_info *ffi_)
config_to_ffi_flags(const Config &config_,
fuse_file_info_t *ffi_)
{
switch(config_.cache_files)
{
@@ -203,8 +203,8 @@ namespace l
namespace FUSE
{
int
open(const char *fusepath_,
fuse_file_info *ffi_)
open(const char *fusepath_,
fuse_file_info_t *ffi_)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
+2 -2
View File
@@ -21,6 +21,6 @@
namespace FUSE
{
int
open(const char *fusepath,
fuse_file_info *ffi);
open(const char *fusepath,
fuse_file_info_t *ffi);
}
+2 -2
View File
@@ -22,8 +22,8 @@
namespace FUSE
{
int
opendir(const char *fusepath_,
fuse_file_info *ffi_)
opendir(const char *fusepath_,
fuse_file_info_t *ffi_)
{
const Config &config = Config::ro();
+2 -2
View File
@@ -21,6 +21,6 @@
namespace FUSE
{
int
opendir(const char *fusepath,
fuse_file_info *ffi);
opendir(const char *fusepath,
fuse_file_info_t *ffi);
}
+1 -1
View File
@@ -29,7 +29,7 @@ namespace FUSE
uint64_t *fh_)
{
int rv;
struct fuse_file_info ffi = {0};
fuse_file_info_t ffi = {0};
ffi.flags = O_RDONLY|O_NOFOLLOW;
rv = FUSE::open(fusepath_,&ffi);
+8 -9
View File
@@ -62,10 +62,10 @@ namespace l
namespace FUSE
{
int
read(char *buf_,
size_t count_,
off_t offset_,
fuse_file_info *ffi_)
read(const fuse_file_info_t *ffi_,
char *buf_,
size_t count_,
off_t offset_)
{
FileInfo *fi;
@@ -77,11 +77,10 @@ namespace FUSE
}
int
read_null(char *buf_,
size_t count_,
off_t offset_,
fuse_file_info *ffi_)
read_null(const fuse_file_info_t *ffi_,
char *buf_,
size_t count_,
off_t offset_)
{
return count_;
}
+8 -8
View File
@@ -21,14 +21,14 @@
namespace FUSE
{
int
read(char *buf,
size_t count,
off_t offset,
fuse_file_info *ffi);
read(const fuse_file_info_t *ffi,
char *buf,
size_t count,
off_t offset);
int
read_null(char *buf,
size_t count,
off_t offset,
fuse_file_info *ffi);
read_null(const fuse_file_info_t *ffi,
char *buf,
size_t count,
off_t offset);
}
+4 -4
View File
@@ -54,10 +54,10 @@ namespace l
namespace FUSE
{
int
read_buf(fuse_bufvec **bufp_,
size_t size_,
off_t offset_,
fuse_file_info *ffi_)
read_buf(const fuse_file_info_t *ffi_,
fuse_bufvec **bufp_,
size_t size_,
off_t offset_)
{
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+4 -4
View File
@@ -23,8 +23,8 @@
namespace FUSE
{
int
read_buf(struct fuse_bufvec **buf,
size_t size,
off_t offset,
fuse_file_info *ffi);
read_buf(const fuse_file_info_t *ffi,
struct fuse_bufvec **buf,
size_t size,
off_t offset);
}
+2 -2
View File
@@ -29,8 +29,8 @@
namespace FUSE
{
int
readdir(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
readdir(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
+2 -2
View File
@@ -21,6 +21,6 @@
namespace FUSE
{
int
readdir(fuse_file_info *ffi,
fuse_dirents_t *buf);
readdir(const fuse_file_info_t *ffi,
fuse_dirents_t *buf);
}
+2
View File
@@ -66,6 +66,8 @@ namespace l
uint64_t namelen;
struct linux_dirent64 *d;
fuse_dirents_reset(buf_);
buf = (char*)g_DENTS_BUF_POOL.alloc();
if(buf == NULL)
return -ENOMEM;
+6 -6
View File
@@ -29,13 +29,13 @@
namespace FUSE
{
int
readdir_plus(fuse_file_info *ffi_,
fuse_dirents_t *buf_)
readdir_plus(const fuse_file_info_t *ffi_,
fuse_dirents_t *buf_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::ro();
const ugid::Set ugid(fc->uid,fc->gid);
switch(config.readdir)
{
+2 -2
View File
@@ -21,6 +21,6 @@
namespace FUSE
{
int
readdir_plus(fuse_file_info *ffi,
fuse_dirents_t *buf);
readdir_plus(const fuse_file_info_t *ffi,
fuse_dirents_t *buf);
}
+2
View File
@@ -70,6 +70,8 @@ namespace l
fuse_entry_t entry;
struct linux_dirent64 *d;
fuse_dirents_reset(buf_);
buf = (char*)g_DENTS_BUF_POOL.alloc();
entry.nodeid = 0;
+2
View File
@@ -72,6 +72,8 @@ namespace l
uint64_t namelen;
fuse_entry_t entry;
fuse_dirents_reset(buf_);
entry.nodeid = 0;
entry.generation = 0;
entry.entry_valid = entry_timeout_;
+2
View File
@@ -67,6 +67,8 @@ namespace l
string fullpath;
uint64_t namelen;
fuse_dirents_reset(buf_);
for(size_t i = 0, ei = branches_.size(); i != ei; i++)
{
int rv;
+1 -1
View File
@@ -50,7 +50,7 @@ namespace l
namespace FUSE
{
int
release(fuse_file_info *ffi_)
release(const fuse_file_info_t *ffi_)
{
const Config &config = Config::ro();
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
+1 -1
View File
@@ -21,5 +21,5 @@
namespace FUSE
{
int
release(fuse_file_info *ffi);
release(const fuse_file_info_t *ffi);
}
+1 -1
View File
@@ -34,7 +34,7 @@ namespace l
namespace FUSE
{
int
releasedir(fuse_file_info *ffi_)
releasedir(const fuse_file_info_t *ffi_)
{
DirInfo *di = reinterpret_cast<DirInfo*>(ffi_->fh);
+1 -1
View File
@@ -21,5 +21,5 @@
namespace FUSE
{
int
releasedir(fuse_file_info *ffi);
releasedir(const fuse_file_info_t *ffi);
}
+14 -14
View File
@@ -102,11 +102,11 @@ namespace l
static
int
write(WriteFunc func_,
const char *buf_,
const size_t count_,
const off_t offset_,
fuse_file_info *ffi_)
write(const fuse_file_info_t *ffi_,
WriteFunc func_,
const char *buf_,
const size_t count_,
const off_t offset_)
{
int rv;
FileInfo* fi;
@@ -124,10 +124,10 @@ namespace l
namespace FUSE
{
int
write(const char *buf_,
size_t count_,
off_t offset_,
fuse_file_info *ffi_)
write(const fuse_file_info_t *ffi_,
const char *buf_,
size_t count_,
off_t offset_)
{
WriteFunc wf;
@@ -135,14 +135,14 @@ namespace FUSE
l::write_direct_io :
l::write_regular);
return l::write(wf,buf_,count_,offset_,ffi_);
return l::write(ffi_,wf,buf_,count_,offset_);
}
int
write_null(const char *buf_,
size_t count_,
off_t offset_,
fuse_file_info *ffi_)
write_null(const fuse_file_info_t *ffi_,
const char *buf_,
size_t count_,
off_t offset_)
{
return count_;
}
+8 -8
View File
@@ -21,14 +21,14 @@
namespace FUSE
{
int
write(const char *buf,
size_t count,
off_t offset,
fuse_file_info *ffi);
write(const fuse_file_info_t *ffi,
const char *buf,
size_t count,
off_t offset);
int
write_null(const char *buf,
size_t count,
off_t offset,
fuse_file_info *ffi);
write_null(const fuse_file_info_t *ffi,
const char *buf,
size_t count,
off_t offset);
}
+6 -6
View File
@@ -86,9 +86,9 @@ namespace l
namespace FUSE
{
int
write_buf(fuse_bufvec *src_,
off_t offset_,
fuse_file_info *ffi_)
write_buf(const fuse_file_info_t *ffi_,
fuse_bufvec *src_,
off_t offset_)
{
int rv;
FileInfo *fi = reinterpret_cast<FileInfo*>(ffi_->fh);
@@ -101,9 +101,9 @@ namespace FUSE
}
int
write_buf_null(fuse_bufvec *src_,
off_t offset_,
fuse_file_info *ffi_)
write_buf_null(const fuse_file_info_t *ffi_,
fuse_bufvec *src_,
off_t offset_)
{
return src_->buf[0].size;
}
+6 -6
View File
@@ -23,12 +23,12 @@
namespace FUSE
{
int
write_buf(struct fuse_bufvec *buf,
off_t offset,
fuse_file_info *ffi);
write_buf(const fuse_file_info_t *ffi,
struct fuse_bufvec *buf,
off_t offset);
int
write_buf_null(struct fuse_bufvec *buf,
off_t offset,
fuse_file_info *ffi);
write_buf_null(const fuse_file_info_t *ffi,
struct fuse_bufvec *buf,
off_t offset);
}
+1 -1
View File
@@ -129,7 +129,7 @@ namespace l
else
{
l::read_config(data_,is);
if(is.fail())
if(!is.eof())
data_->errs->push_back("failure reading config file");
is.close();
}
+4 -5
View File
@@ -42,7 +42,6 @@ namespace msplfs
{
int rv;
uint64_t lfs;
string fusepath;
fs::info_t info;
const Branch *branch;
const string *basepath;
@@ -55,7 +54,7 @@ namespace msplfs
if(branch->ro_or_nc())
error_and_continue(*err_,EROFS);
if(!fs::exists(branch->path,fusepath))
if(!fs::exists(branch->path,fusepath_))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch->path,&info);
if(rv == -1)
@@ -86,15 +85,15 @@ namespace msplfs
error = ENOENT;
fusepath = fusepath_;
do
for(;;)
{
basepath = msplfs::create_1(branches_,fusepath,&error);
if(basepath)
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
while(!fusepath.empty());
if(basepath == NULL)
return (errno=error,-1);
+4 -5
View File
@@ -42,7 +42,6 @@ namespace msplus
{
int rv;
uint64_t lus;
string fusepath;
fs::info_t info;
const Branch *branch;
const string *basepath;
@@ -55,7 +54,7 @@ namespace msplus
if(branch->ro_or_nc())
error_and_continue(*err_,EROFS);
if(!fs::exists(branch->path,fusepath))
if(!fs::exists(branch->path,fusepath_))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch->path,&info);
if(rv == -1)
@@ -86,15 +85,15 @@ namespace msplus
error = ENOENT;
fusepath = fusepath_;
do
for(;;)
{
basepath = msplus::create_1(branches_,fusepath,&error);
if(basepath)
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
while(!fusepath.empty());
if(basepath == NULL)
return (errno=error,-1);
+4 -5
View File
@@ -42,7 +42,6 @@ namespace mspmfs
{
int rv;
uint64_t mfs;
string fusepath;
fs::info_t info;
const Branch *branch;
const string *basepath;
@@ -55,7 +54,7 @@ namespace mspmfs
if(branch->ro_or_nc())
error_and_continue(*err_,EROFS);
if(!fs::exists(branch->path,fusepath))
if(!fs::exists(branch->path,fusepath_))
error_and_continue(*err_,ENOENT);
rv = fs::info(branch->path,&info);
if(rv == -1)
@@ -86,15 +85,15 @@ namespace mspmfs
error = ENOENT;
fusepath = fusepath_;
do
for(;;)
{
basepath = mspmfs::create_1(branches_,fusepath,&error);
if(basepath)
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
while(!fusepath.empty());
if(basepath == NULL)
return (errno=error,-1);
+4 -4
View File
@@ -108,15 +108,15 @@ namespace msppfrd
string fusepath;
fusepath = fusepath_;
do
for(;;)
{
error = msppfrd::create_1(branches_,fusepath,branchinfo_,sum_);
if(branchinfo_->size())
return error;
break;
if(fusepath == "/")
break;
fusepath = fs::path::dirname(fusepath);
}
while(!fusepath.empty());
return error;
}