Compare commits

...
656 Commits
Author SHA1 Message Date
Antonio SJ Musumeci 8e87bcbff2 docs: Add Unraid migration guidance for mergerfs
- Add a top-level Migration page covering both migration directions.
- Explain filesystem reuse, parity constraints, partition requirements,
  and unlocking encrypted Unraid disks.
- Describe intact ZFS pool imports and subdirectory branch reuse,
  distinguishing them from cases requiring a data copy.
- Add navigation and link the guide from the Unraid comparison.
2026-10-03 16:52:25 -05:00
Antonio SJ Musumeci fcd7527c9d docs: document mergerfs tradeoffs and web UI management
* Add: a comprehensive downsides FAQ with mitigations and practical
  priorities.
* Document: mergerfs-webui and link it from setup and configuration
  guides.
* Replace: obsolete mergerfs.fsck references with fsck.mergerfs
  guidance.
2026-10-01 20:14:52 -04:00
Antonio SJ Musumeci 83d1630f55 docs: rework and expand project comparisons 2026-09-22 14:50:47 -05:00
Antonio SJ Musumeci cfb925e5ae docs: clarify branch resolution and mount ordering 2026-09-21 13:46:38 -05:00
Antonio SJ Musumeci 515b0549ef docs/performance: explain mergerfs IO performance vs RAID
Describe why mergerfs does not aggregate branch performance like
RAID/ZFS (whose aggregate throughput is also capped by shared
interconnects) and instead provides independent per-branch
performance: best case A+B+C across concurrent streams, worst case
single-stream limited to one branch's speed.
2026-09-05 16:00:43 -04:00
natalefalco 8ea47df13e Include Docker Compose setup for mergerfs
Added Docker Compose configuration for running mergerfs.
2026-07-31 08:13:59 -05:00
shyney7 42ab831d97 docs/setup: link install :z example to SELinux FAQ 2026-05-17 10:14:21 -05:00
shyney7 89b4046d11 docs/faq: add SELinux relabeling entry 2026-05-17 10:14:21 -05:00
Antonio SJ Musumeci 7ec6f8e2f2 Manage cloned /dev/fuse fds in sessions
- Store cloned read-worker fds on fuse_session and close them there.
- Set up clone fallback through session helpers used by the loop.
- Carry per-request fds through receive, process, and reply paths.

Tests show significant performance increases in highly concurrent
workloads on a high core count system. Upto 15% better on reads and
27% on writes.
2026-05-14 20:13:07 -05:00
Antonio SJ Musumeci 5f7fa17ad8 Inline ioprio disabled fast path
- Expose the ioprio enabled flag as an atomic for relaxed inline checks
- Inline SetFrom construction so disabled read/write paths avoid a function call
- Move priority application into a slow helper used only when ioprio is enabled
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 30d59d4458 Use shared_mutex for fuse log config
- Guard fuse_cfg_t log file and filepath shared pointers with a shared mutex
- Replace atomic shared pointer loads and stores with shared and unique locks
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 02dc36080c Use shared_mutex for ReadDir state
- Replace atomic shared pointer loads/stores with shared/unique locking.
- Store the configured readdir mode directly as std::string.
- Copy the active ReadDir implementation under lock before invoking it.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 8734847968 Guard branch snapshots with shared_mutex
Important changes:
- Replace atomic shared_ptr operations with shared_mutex-protected snapshots.
- Retry copy-on-write branch updates when another writer publishes first.
- Keep long-running parsing and read-only filesystem checks outside branch locks.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 608cd00764 Use atomic open file reference counts
- Use relaxed increment under the map bucket lock when duplicating file handles.
- Use acq_rel decrement when releasing and checking for final references.
- Load moved ref_count with relaxed ordering during map insertion.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci b13727abde Document readdir merge mutex scope
- Explain that the mutex is per readdir call.
- Document that only dirent deduplication and list append are serialized.
- Clarify that per-branch opendir and getdents64 work runs outside the critical section.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 231aac15cd Use shared write locks until ENOSPC relocation
- Replace the per-file Mutex with std::shared_mutex for shared write access.
- Run direct and cached writes under a shared lock while the fd is stable.
- Retry failed writes under a unique lock before move-on-ENOSPC relocation.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 8b17d5f35e Synchronize node updates with path release
- Add helpers that release path locks and update node state under f.lock.
- Update getattr and setattr stat-cache invalidation while preserving ESTALE handling.
- Rework create, open, tmpfile, and set_path_info to mutate lookup/open state under the shared lock.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 8608b2be46 Clarify releasedir readdir synchronization barrier
- Document the lock/unlock pair as an acquire/release barrier.
- Explain that releasedir waits for in-flight readdir calls before destroy/free.
- Warn against removing the synchronization despite it not being a critical section.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 1e0bd54989 Move statvfs cache to use shared mutex
Its read heavy and micro benchmarks show no regression on the low end
and 30%+ throughput improvements on the highend.
2026-05-14 00:22:06 -04:00
Antonio SJ Musumeci 56285fc6e5 Pass annobin override to RPM toolset builds
Important changes:
- Add Makefile RPMBUILD and RPMBUILD_FLAGS overrides for the rpm target.
- Detect /opt/rh GCC toolsets before RPM packaging.
- Pass --undefine _annotated_build to avoid Rocky 8 annobin plugin failures.
2026-05-13 17:01:41 -04:00
Antonio SJ Musumeci dfe053a0ae Require C++20-capable build toolchains
Important changes:
- Switch mergerfs and vendored libfuse Makefiles to -std=c++20.
- Select the latest available GCC/G++ or toolset in container builds.
- Verify compiler C++20 support during package installation.
- Fix dynamic SysLog formatting for fmt C++20 checks.
2026-05-13 13:55:43 -05:00
Antonio SJ Musumeci 12ac368e8b Preserve CPPFLAGS in release builds
- Append -DNDEBUG to existing CPPFLAGS in the release target.
- Keep caller-provided build flags for Debian packaging.
2026-05-09 19:28:56 -05:00
Antonio SJ Musumeci c8f32f9f25 update build system and dependency configuration 2026-05-09 18:55:23 -05:00
Antonio SJ Musumeci ce3737ff33 Add new OS build files 2026-05-07 23:35:14 -04:00
Antonio SJ Musumeci 84e4cdeb7e make all integration tests self-contained with ephemeral mounts
- Add mergerfs_mount() context manager in posix_parity.py that creates
  temporary branch dirs in tests/.test_tmp/, mounts an ephemeral mergerfs
  instance, and cleans up after use.
- Add find_mergerfs(), find_fusermount(), mount_mergerfs(), unmount_mergerfs()
  helpers.
- Update run-tests to invoke each TEST_* script without a mountpoint arg.
- Update README.md to document the new `python3 tests/run-tests` invocation.
- Fix 44 tests to use mergerfs_mount() instead of expecting a pre-mounted path.
- Add tempfile import to 10 tests that were missing it.
- Fix TEST_mount_lifecycle to use mergerfs_mount() context manager.
- Fix TEST_posix_tmpfile missing join import.
- Fix TEST_cfg_xattr_modes error message framing (no "(known bug)").
- Fix TEST_posix_copy_file_range: loop-copy full size, compare st_size and
  SHA256 hash; add NativeTmp for space management; route native temp to
  tests/.test_tmp/ to avoid ENOSPC on /tmp.
- Fix TEST_posix_getattr_fgetattr: st_cmp skips st_size for dirs; add
  compare_ino param for safe inode comparison when inodecalc=passthrough.
- Fix TEST_unlink_rename, TEST_use_* tests: namespace cleanup, consistent
  variable naming, None check for cmpfunc.
- Fix TEST_readlink_semantics: remove type annotations to support older
  Python; wrap in mergerfs_mount() try/except.
- Add flush=True to run-tests print so test names show immediately.
2026-05-07 21:47:40 -04:00
Antonio SJ Musumeci 6d6d73c7b3 Use unmount() on FreeBSD for ENOTCONN umount 2026-05-07 17:49:24 -04:00
Antonio SJ Musumeci bea31543a0 update fuse_lib_tmpfile() node management to match fuse_lib_create() 2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci 99835a0178 Document advisory locking limitation and update deprecated options
- Add documentation explaining that advisory file locking is not supported

- Add remember-nodes to deprecated options mapping

- Add comment explaining stat_crc32b fingerprint invalidation behavior

- Fix heading level for Host vs Container identity section
2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci 342a1efcfb Add QEMU binfmt setup and fix static installer
- Fix typo in static.installer: /pkg/ -> /pkgs/

- Add missing mkdir -p /build before makeself

- Mount pkgs directory via podman build -v so static.installer can access

  previously built static tarballs without relying on bind mounts relative

  to the build context

- Register qemu-user-static binfmt handlers for cross-compilation

- Make --git-repo optional when using --setup
2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci c587a127fb add missing <new> include for std::nothrow in fuse_session.cpp 2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci f1034a3ad6 Remove timed node removal 2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci 8117998205 Remove unused lock operation plumbing 2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci cc780bc521 libfuse: remove per-node lock bookkeeping 2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci 14b7c8e607 Use stat fingerprint as cache validity sentinel
- Reserve a zero stat CRC to represent an invalid cache fingerprint.

- Include device, size, inode, mtime, and ctime data in the fingerprint.

- Recompute the fingerprint during auto-cache open before keeping cache.
2026-05-06 20:49:46 -04:00
Antonio SJ Musumeci 3ff9794fff libfuse: fix use-after-free in fuse_lib_ioctl 2026-04-30 12:51:12 -05:00
Antonio SJ Musumeci f71e27644e vendor moodycamel queue and upgrade to 1.0.5 2026-04-30 08:43:42 -04:00
Antonio SJ Musumeci 943f91ff98 Strengthen mergerfs integration tests
- Make the test runner fail on failed tests and report explicit skips
- Strengthen assertions for O_DIRECT, LUP policy, EXDEV fallback, and xattrs
- Fix cleanup and file descriptor handling across test scripts
2026-04-29 20:25:20 -04:00
Antonio SJ Musumeci ef1e01b5a5 Add unit and integration tests for recently changed code
Unit tests (29 new in tests/tests.cpp):
- str::eq() and str::startswith() char* nullptr safety
- str::from() u64/s64/int suffix parsing (K/M/G/T, overflow, invalid)
- num::humanize() byte formatting (0, 512, 1K, 1M, 1G, 1T, non-exact)
- RmdirErr priority error accumulation (ENOTEMPTY/EEXIST override rules)
- HashSet inline-to-heap growth, empty string, and large insertion
- fs::inode algorithm switching (valid/invalid names, passthrough raw ino,
  distinct inodes across algorithms)
- RND::rand64() bounds (range, max, shrink_to_rand_elem)
- Branches::Impl copy and move assignment re-links default_minfreespace

Integration tests (5 new in tests/):
- TEST_policy_lup: LUP policy create and search
- TEST_rmdir_enotempty_priority: rmdir returns ENOTEMPTY for non-empty dirs
- TEST_open_after_unlink: read/write via fd after unlink
- TEST_api_xattr: mergerfs xattr API (fullpath, relpath, basepath, allpaths)
- TEST_movefile_enospc: moveonenospc configuration round-trip

Also: remove xattr nosys checks from TEST_cfg_xattr_modes, reformat
integration test scripts to use temp_dir/cleanup_dir helpers, and
minor parameter alignment changes in fuse_getxattr, fuse_init,
fuse_rename.
2026-04-29 17:41:00 -04:00
Antonio SJ Musumeci 50c0627b2b Better handle make sanitize option 2026-04-29 12:24:10 -04:00
Antonio SJ Musumeci 660f556ac6 Don't return success on ENOTEMPTY rmdir errors 2026-04-29 12:23:49 -04:00
Antonio SJ Musumeci 997b036064 Reject invalid policies 2026-04-29 00:34:00 -04:00
Antonio SJ Musumeci 9308a3729c When file unlinked check open_files map
Inadvertantly removed. Didn't realize that the kernel would not always
send file handle when unlinked.
2026-04-28 16:04:26 -04:00
Antonio SJ Musumeci 7616d8b1ac Rework readlink to not depend on cstr nul termination 2026-04-26 01:37:08 -04:00
Antonio SJ Musumeci a86092b3c2 Don't push docs for RC tags 2026-04-23 20:46:55 -05:00
Antonio SJ Musumeci e613d9415f Better same file check for fsck 2026-04-22 22:28:56 -05:00
Antonio SJ Musumeci 1a8eb326af Tweak docs on NFS and identity management 2026-04-21 13:20:07 -05:00
Antonio SJ Musumeci 9fb1642e93 Fix docs regarding "noforget" 2026-04-20 23:25:47 -05:00
Antonio SJ Musumeci 8be86ee611 Remove mkdocs build github workflow 2026-04-19 23:48:13 -05:00
Antonio S. Musumeci da68cf3a85 Formatting: normalize brace style and parameter alignment
No functional change: libfuse/helper.cpp (fuse_daemonize,
fuse_helper_opt_proc, fuse_parse_cmdline) and mergerfs
fuse_init.cpp (_want helpers) reformatted to match the project's
GNU-style brace placement and aligned parameter lists.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci ec40866091 libfuse: small safety and portability fixes across opt/cpu/fusermount/maintenance_thread
- fuse_opt: reformat process_opt_param to project style; return the
  rv from sscanf through a named local so the error branch prints
  the failing option cleanly.

- cpu.cpp: when parsing /sys/devices/system/cpu/*/topology/core_id,
  bail out cleanly on stream read failure rather than recording an
  uninitialized core_id.

- fusermount: free(copy) on the success path of parsing the mount
  option (previously leaked on every mount), and replace the fixed-
  buffer sprintf into procfile with snprintf bounded by the buffer
  size.

- maintenance_thread: widen the iteration count from int to u64
  so a long-lived daemon doesn't wrap after ~68 years of ticks
  (real effect: silence signed-overflow warnings under UBSan).
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci bd0714272e libfuse: thread_pool/objpool/fuse_loop - safer memory and iteration
- ThreadPool::destroy used to iterate _threads directly while another
  thread could be adjusting the same vector. Snapshot the vector
  under the mutex and iterate the local copy for pthread_cancel /
  pthread_join.

- ObjPool::construct now returns NULL when the pooled allocator
  returns NULL instead of invoking placement-new on a null
  pointer. In destroy, compute to_node(obj) before running the
  destructor - the destructor may scrub bytes the to_node helper
  reads.

- In the async/sync workers in fuse_loop, msgbuf_alloc can return
  NULL under memory pressure. Fail the worker cleanly with a
  diagnostic rather than dereferencing. Also introduce a small
  _nproc() helper that treats hardware_concurrency()==0 as 1, so
  the downstream min/max arithmetic doesn't produce a zero thread
  count.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 27acd9fcc7 libfuse: use atomic fuse_session pointer in signal handler
The signal handler reads the global session pointer from an async-
signal context while another thread installs/removes the session
via set/remove_signal_handlers. Use std::atomic<fuse_session*> with
acquire/release ordering so the handler either sees NULL or a fully
published session, never a torn pointer.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 4516685ca7 libfuse: harden fuse.cpp against NULL nodes; use lock guards; check allocations
Collapse get_node/get_node_nocheck into a single function that
returns NULL when the node is absent rather than abort()ing.
Callers that previously assumed non-NULL now check the return value
and either reply ESTALE/ENOMEM or fall through gracefully; a few
places where the node is load-bearing (e.g. unhash during remove)
use fatal::abort with a descriptive message.

Switch mutex_lock / mutex_unlock pairs to mutex_lockguard so early
returns on error paths no longer leak the lock, and add NULL-safety
around fuse_dh in readdir/readdir_plus, fuse_dirents_init error
returns, the getattr path when both name and fh are empty, and the
msgbuf allocation in fuse_lib_read.

Pull the new xstrdup/xmalloc wrappers from xalloc.hpp for the root
node name so the common-case OOM path terminates with a diagnostic
instead of a silent corrupted node.

Also guard fuse_session_destroy against a NULL session - called
from error-recovery paths.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 0bdbaf1d6c libfuse: remove userdata from init/destroy APIs; drop unused fuse_reply_ioctl_iov
The low-level init/destroy callbacks were passed a userdata pointer
that mergerfs never consumed - the caller threaded it through
fuse_lowlevel_new only to hand it back unchanged. Remove the
parameter from the ops struct, from fuse_lowlevel_new(_common),
and from the internal fuse_ll struct; update fuse_lib_init and
fuse_lib_destroy accordingly.

Also drop fuse_reply_ioctl_iov: no caller in-tree invokes it and
the public API is defined by this vendored libfuse fork.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci e67b7d0825 log: default debug log path to empty; skip set when empty
libfuse previously initialized its debug log filepath to
"/dev/stderr", forcing the config layer to reopen stderr on every
load whether or not the user asked for it. Default the libfuse log
path to "" and have the mergerfs config layer only forward the
request to libfuse when the user supplied an explicit path.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 981d5473ee str: null-safe same() and startswith()
Both helpers previously called strcmp/pointer-dereference directly
on their arguments, so a stray NULL (e.g. an unset env string or an
absent xattr) crashed the process. Guard both helpers: same()
returns true only if both pointers are equal, startswith() returns
false if either side is NULL.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 364f8c4407 fs_movefile_and_open: -ENOSPC when no destination branch available
The create policy can legitimately return success with an empty
destination list (e.g. every candidate rejected). Previously we
then dereferenced dst_branch[0] and faulted. Return -ENOSPC so the
original write that triggered the move propagates a sensible errno
to userspace.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci ef9c7ad5df fuse_statfs: scale with long double to avoid integer overflow
The branch-aggregation code computed
  blocks * f_frsize / min_frsize
as u64 arithmetic. With large filesystems the intermediate product
blocks * f_frsize overflows 64 bits long before the division can
bring the result back into range, producing garbage bavail/bfree
values reported to userspace.

Compute the scale factor once in long double and multiply each
count by it, so the only narrowing happens in the final cast back
to fsblkcnt_t.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 4288a60c5d fuse_readlink: always null-terminate buffer
Old code only null-terminated when the returned/copied length was
strictly less than the caller-supplied bufsize_, leaving the buffer
unterminated on an exact-fill. Since buf_ is consumed as a C string,
reserve one byte for the terminator up front and unconditionally
terminate.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci cf38a37176 fuse_readdir: atomic initialized flag; bound error string; check msgbuf allocation
- ReadDir::_initialized is set by the first thread through the
  lazy-init path and read by every subsequent caller; make it
  std::atomic<bool> so the read/write pair has a happens-before
  relationship.

- The 'no valid mergerfs branch found' error directory entry used
  strcpy into a fixed-size dirent buffer. The message happens to
  fit today but the buffer is only NAME_MAX wide; switch to a
  length-bounded strncpy driven by the constexpr string size.

- The getdents implementations for seq/cor/cosr allocated a msgbuf
  without checking for allocation failure and then dereferenced it.
  Return -ENOMEM when the allocation fails.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci f5d9a60b9d fuse_getattr/statx: populate timeouts in fake_root and controlfile replies
The fake-root and control-file fast paths returned a synthetic stat
without touching the timeout struct. Callers that took those paths
ended up sending whatever the timeout struct happened to hold,
which is uninitialized memory for the control-file path and
whatever a prior call left there for the fake-root path. Kernel
behavior is undefined when the timeout is garbage.

Pass timeout_ into both helpers and set entry/attr from the
configured cache values.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 0c17492c78 FUSE: pass Branches::Ptr by value with empty-branches guards
Previously most FUSE ops took a reference to the live cfg.branches
object. With atomic_load now producing a shared_ptr snapshot, pass
it by value: the op works against a single stable view of the
configuration for its whole lifetime, immune to concurrent
reconfiguration.

Also bail out with -ENOENT when the policy returns an empty branch
set rather than dereferencing branches[0]. This was reachable if a
policy rejected every branch (e.g. everything readonly while
looking for a writable target).

Covers access, chmod, chown, create, getattr, getxattr, ioctl,
link, listxattr, mkdir, mknod, open, readdir (cor/cosr),
readlink, removexattr, rename, rmdir, setxattr, statfs, statx,
symlink, truncate, unlink, utimens.

While here, in _getattr only dereference st_->st_mode when lstat
succeeded (it is otherwise uninitialized).
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 98648ae44b FUSE: require valid file/dir handle; drop open_files fallback
Several FUSE ops fell back to looking up a FileInfo via
state.open_files when the kernel-provided fh was zero, returning
-ENOENT if the lookup failed. This path papered over handle-tracking
bugs and added cost on every call. Use the handle directly and
return -EBADF when it is invalid - the kernel should always hand us
a valid fh for an open resource.

Also simplify FileInfo::from_fh / DirInfo::from_fh and their to_fh
helpers: callers now handle the null-pointer case explicitly so the
ASSERT_NOT_NULL checks are redundant.

Covers fallocate, fchmod, fchown, fgetattr, flock, ftruncate,
futimens, read, release, releasedir, write, statx, ioctl (file +
dir), readdir (sequential, concurrent-on-read,
concurrent-on-search), and the passthrough fast paths in
create/open.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 0dcca0f1a3 branches: re-link default_minfreespace pointer on copy/move; atomically publish branch mode changes
Branches using the default minfreespace held a reference to their
owning Impl's _default_minfreespace. After a copy or move the
pointer still referenced the source Impl, which could become
invalid or diverge after further configuration changes. Switch to
a pointer and re-link it to the destination Impl on copy/move.

While here, convert set_branch_mode to do an atomic_store of a
newly constructed Impl rather than mutating the shared pointer
target in place. Readers holding an atomic_load snapshot are no
longer affected by a concurrent mode change.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci 103cd358f2 state: atomic ref_count in OpenFile
ref_count is read and written from multiple FUSE worker threads
during open/release. Make it std::atomic<int> and provide a move
constructor so OpenFile remains movable when the underlying atomic
is non-movable.
2026-04-18 13:47:23 -05:00
Antonio S. Musumeci aa46001923 Remove unused rwlock.hpp header and includes
rwlock.hpp was left over after migrating to atomic shared pointers
for branches configuration. No code references ReadGuard/WriteGuard
any longer, so drop the header and its stale includes.
2026-04-18 13:47:23 -05:00
Antonio SJ Musumeci ff48ff6047 Handle/ignore SIGHUP 2026-04-17 11:14:05 -05:00
Antonio SJ Musumeci d5a2187713 Fix make race condition 2026-04-16 18:20:00 -05:00
Antonio S. Musumeci 351adc2b20 Add tests for HashSet, rapidhash withSeed consistency, and ReaddirCalc parity with calc 2026-04-12 23:44:23 -05:00
Antonio S. Musumeci a1e681f36b Use ReaddirCalc in all readdir implementations
* avoids per-entry path construction
2026-04-12 23:44:23 -05:00
Antonio S. Musumeci e3a467de80 Refactor fs_inode
* add Algo enum
* ReaddirCalc class
* string_view params
* fs::path overloads
2026-04-12 23:44:23 -05:00
Antonio S. Musumeci cdadda5eb9 Replace khash with custom hash set 2026-04-12 23:44:23 -05:00
Antonio SJ Musumeci 4c9a9d7e15 Upgrade rapidhash 2026-04-12 23:44:23 -05:00
Antonio SJ Musumeci 425e30b50f Use nanosleep rather than yield and return EINTR 2026-04-11 11:30:57 -05:00
Antonio SJ Musumeci 3905355522 Detect OS for release-sample make target 2026-04-08 20:48:02 -05:00
Antonio SJ Musumeci 9e2e1afafa Update docs on limiting drive spinup 2026-04-06 14:01:20 -05:00
Antonio SJ Musumeci 6d218fa87f Misc updates and fixes 2026-04-04 02:46:24 -05:00
Antonio SJ Musumeci 3b10406f95 Add more details to project comparisons 2026-04-04 02:17:06 -05:00
Antonio SJ Musumeci f2c8e5d9eb Add FUSE request_timeout
Not yet hooked up to config parser to set as need to evaluate usage.
2026-04-01 23:20:05 -05:00
Antonio SJ Musumeci b581c5d5e7 Add support for FUSE_COPY_FILE_RANGE_64 2026-04-01 23:20:05 -05:00
Antonio SJ Musumeci 1ebc8cfa5f Enable statx with file handle 2026-03-31 19:53:17 -04:00
Antonio SJ Musumeci acfa797503 Misc formatting changes 2026-03-31 19:53:17 -04:00
Antonio SJ Musumeci 7fc20457ca Rework open file resource management 2026-03-31 19:53:17 -04:00
Antonio SJ Musumeci ecee84b323 Improve proj comparisons + new SnapRAID details 2026-03-31 19:51:28 -04:00
Antonio SJ Musumeci b8776d205d Update docs; add nofs, policyfs and greyhole 2026-03-27 22:54:39 -05:00
Antonio SJ Musumeci 06433a0548 Fallback to fusermount3 where available
Also general cleanup of mount_generic.
2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci f4b602340b Add more integration tests 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci a78aef36e0 Additional check for ENOTCONN on mount 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 0d05523dfd Move maintainence thread func take u64 rather than int
signed rollover is UB
2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 0cfab60f37 replace raw C-strings with std::string in converted libfuse files
util/mount.mergerfs.cpp:
- Remove xstrdup/xrealloc wrappers entirely
- Convert type, source, options, command, setuid to std::string
- Replace add_arg() pointer-rewriting with shell_quote() returning std::string
- Replace add_option() with simple std::string += concatenation
- Fix const_cast UB on string literal assignment

lib/helper.cpp:
- Convert add_default_subtype local subtype_opt: malloc+snprintf+free -> std::string construction

lib/mount_generic.h:
- Convert fuse_mount_sys locals source/type: malloc+strcpy+strcat -> std::string
- Remove 4 unnecessary free() calls (RAII cleanup)
- .c_str() at mount() and fuse_mnt_add_mount() boundaries

lib/mount_util.h:
- Rewrite fuse_mnt_resolve_path internals using std::string: rfind/substr
  instead of manual pointer arithmetic, strrchr, strlen chains
2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 21966ade97 Convert vendored/libfuse C sources to C++17
Convert all C source files in vendored/libfuse/ to C++17:
- lib/crc32b.c    -> crc32b.cpp  (const void* cast)
- lib/fuse_opt.c -> fuse_opt.cpp (designated init, void* arithmetic)
- lib/fuse_signals.c -> fuse_signals.cpp
- lib/helper.c   -> helper.cpp  (void* data cast)
- lib/mount.c    -> mount.cpp  (thin wrapper)
- lib/mount_generic.c -> mount_generic.h (static inline, #pragma once)
- lib/mount_bsd.c -> mount_bsd.h    (static inline, #pragma once)
- lib/mount_util.c -> mount_util.h   (static inline, #pragma once)
- util/fusermount.c -> fusermount.cpp
- util/mount.mergerfs.c -> mount.mergerfs.cpp

Key changes:
- Replace C99 designated initializer in fuse_opt_parse with field-by-field init
- Fix void* pointer arithmetic via char* base + offset pattern
- All C-style (T*)voidptr casts replaced with static_cast/reinterpret_cast
- Remove redundant #define _GNU_SOURCE (already in FUSE_FLAGS)
- Wrap __clone2 declaration in extern "C" for ia64 path
- Update Makefile: empty SRC_C, build utils with $(CXX) instead of $(CC)
- Remove stale .c files now replaced by .cpp/.h counterparts

All binaries build cleanly: mergerfs, mergerfs-fusermount, mount.mergerfs
2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 96eb51eecb Move fuse_session to C++ and make exit flag atomic 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 881147daa2 Fix null ptr handling issue in ioctl processing 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 0f1a8e9b69 Fix error condition in fs_copyfile 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 08f9cc6932 Fix readlink implementation, add more tests 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 3099b15db1 More aggressive error handing with pagesize queries 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 07b1e6bdba Auto-commit fuse_msgbuf.cpp 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 7763c7384a Use fatal::abort() rather than assert in places 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 61365d226d Move scope_guard to vendored/ 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci f33e78bc24 Cleanup procfs and abort on critical issues 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 7f52623536 Cleanup branches and add more unit tests 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci a30a4df9c0 Cleanup config and add tests 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 1e0d5aa91d fs_wait_for_mount cleanup 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci d09fadbc28 fs_inode cleanup 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 21ce889449 Fixup listxattr error handling 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 9d1a4696e9 Small improvements to fs::statvfs_cache 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci ed0cbcf064 Cleanup fuse_readlink 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 076e359891 Improve thread pool 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci bf98d3f3a6 Fix possible error handling issue with errno 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci c45c5ce920 Make cfgfile depth calculation thread friendly 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci e0a892f0d0 Improve error handling when querying pagesize 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 164b7f73c9 Misc fixes and improvements to thread pool 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 3a45be4cd8 Rework string utils, more test cases 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 107a3acf95 Better error handling in pagesize config type 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci a5eafb8972 Check string is not empty before resize in Config::keys 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 8199cc8a8b Fix error handling in fuse chmod, chown, setxattr, removexattr 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci e5d897f3dc Ensure zero initialized timeouts structs 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci c0af09f7d8 Fix incorrect type in fs_read and write 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 1b1e14ca29 Remove dead branch in fuse_reply_data 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 82b89aa099 Change session->exited to sig_atomic_t 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci aa91e1b2ba Initialize stat buffer and add stat call in fuse_mount_sys 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 82e81afcdc Add NULL check for cmsg in receive_fd to prevent segfault 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 1a5c39f813 Fix buffer overflow in readlink by reserving space for null terminator 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci fce1803d42 Use RND class for shrink_to_rand_elem and add assertions 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 5a9a17afcb fix objpool: add size tracking, improve allocation matching; fix msgbuf: clear pool on size change 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 8648de6bb6 fix policy_eppfrd.cpp: return 0 when branchinfo found, -ENOENT only when empty 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci f227a63e15 fix str.cpp: use string_view::npos, fix erase() calls, remove extra whitespace 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci aa47b74dea Remove iterator methods from Branches class 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 206ad1dd53 Fix futimens bugs: stat pointer, variable names, and negation 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 80aead7085 Add null pointer checks for FileInfo/DirInfo 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 1220befacf Fix copydata_copy_file_range bug 2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 01aa888c7a Fix eplus search bug
Not that anyone would ever use this but it was noticed in a scan.
2026-03-24 21:13:34 -04:00
Antonio SJ Musumeci 6a6aa054cd Add support for Arch, btw 2026-03-14 11:39:48 -04:00
Antonio SJ Musumeci 04939bbe72 No longer explicitly error out on broken mount point
If ENOTCONN (broken FUSE mount) umount first and continue to mount.
2026-03-08 00:39:45 -05:00
Antonio SJ Musumeci 2ea6290e4b Update limiting drive spinup doc 2026-03-04 11:05:55 -05:00
Antonio SJ Musumeci c66c68b137 Misc cleanup 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 075a8a6548 Convert some push_back to emplace_back 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 3c6d1b47f6 Remove unused "using"s 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 6f281b9f7f Remove duplicate includes 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 511bf47af9 Convert stdint to short ints 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 53c5a2cf1e Move fmtlib to vendored and upgrade to 12.1.0 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci eb8074ed9a Update vendored/nonstd to latest and fix API usage 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 38c19df95a Update vendored/boost to 1.90.0 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci b1228f11bd Update vendored/acutest to latest master 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci cfafafd7ff Update vendored/CLI11 to v2.6.2 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci c8ce82ce54 Update vendored/subprocess to v2.5 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 05c3d97368 Update vendored/rapidhash to v3 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 2c87e68635 Cleanup ugid.hpp usage 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 8f1ef59770 Move 3rd party libraries to "vendored" directory 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci a460c52861 Remove unused files 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci a4aade6666 Make global inode calculation function pointer atomic 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 1d1bcd3b87 Add extra checks in for file handle lookup 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 099ce2d91d Add more asserts 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 56cd831ec8 Fix str::trim to handle all whitespace characters
Use std::isspace() instead of comparing only to space character.
Now handles tabs, newlines, carriage returns, etc.
2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci e43be3c221 Remove unused PolicyCache implementation 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 2754536727 Fix integer overflow in size suffix parsing
Use __builtin_mul_overflow to detect overflow when applying size
suffixes (K, M, G, T) in str::from for int64_t and uint64_t. Previously,
large values with suffixes could silently wrap around.
2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci a0cff637e1 Misc cleanup 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci a5a6c892b9 Update copyright headers 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 3d50d4a52f Explicitly return EXIT_FAILURE 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci f69c31fd77 Rework objpool 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci a2860c3f1f Use debug mutex more 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 3f70e66ee3 Rework node obj pool to use objpool 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 160d3c832d Fix branches unit test 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 15bcc47d6a Remove "channels" and embed into session 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci e55bb93890 Simplify lowlevel fuse state management and req mem 2026-03-02 01:09:16 -05:00
Antonio SJ Musumeci 5a2a9e4530 Remove fuse_ll_pipe dead code 2026-03-02 01:09:16 -05:00
trapexit b4239495a0 Update docs for logging changes + new video (#1618) 2026-02-12 23:21:43 -06:00
trapexit 3222de6c9c Fixup debug output (#1617) 2026-02-12 22:50:38 -06:00
Aaron Andersen be4d388813 Add support for -n to not update mtab (#1616) 2026-02-12 20:35:48 -06:00
trapexit a47842e2f8 Add MOS to projects and update misc links (#1614) 2026-01-27 11:25:32 -06:00
trapexit f769d7474b Add new links to media docs (#1613) 2026-01-27 07:59:38 -06:00
trapexit 2ae57642f4 Misc documentation updates (#1612) 2026-01-27 07:00:22 -06:00
trapexit 7f1b7ac343 Add lshw to collect info tool (#1610) 2026-01-19 13:57:42 -06:00
trapexit 1290ab9708 Ensure ::exists() call can't throw (#1609) 2026-01-15 17:33:31 -06:00
trapexit 965e26989c Misc documentation updates (#1605) 2025-12-23 23:25:39 -06:00
trapexit 0caae4fbf0 Tag container image to ghcr for convenience (#1604) 2025-12-14 15:21:56 -06:00
trapexit 4d1760cb69 Rework new lup policy to work on 32bit systems (#1603)
__int128 is not available on 32bit platforms. Moved to extended
precision floats.
2025-12-14 14:56:34 -06:00
François-Xavier Payet 22df87c86a Add LUP policy (#1601) 2025-12-14 00:36:12 -06:00
trapexit 72fb6e4aba Update submitting bug reports, improve collect-info (#1598) 2025-12-06 13:55:14 -06:00
trapexit 9b046d9a34 Rework credential handling to support chroot & idmap (#1595)
Run in an elevated credential mode (root) and let the kernel manage
entitlements. Will result in slightly different behavior but should
not be noticed by most.
2025-12-05 21:03:48 -06:00
Emanuel Haupt d8918458bf libfuse: fix narrowing conversion of nsec fields on i386 (#1593)
On 32 bit platforms tv_nsec is a signed long while the FUSE setattr
arguments provide nanoseconds as uint32_t. C++17 treats uint32_t -> long
in a brace initializer as a narrowing conversion and rejects it on ILP32
targets. This surfaced when building on FreeBSD i386 with clang 19 where
the compiler refused the list initialization of struct timespec.

Add explicit static_cast<long>() for the nsec fields to make the
conversion intentional and portable. This avoids build failures on i386
while leaving 64 bit builds unchanged.
2025-11-29 10:45:20 -06:00
trapexit d3a3f65e7b Ignore remote when forcing generation of docs (#1592) 2025-11-25 23:39:13 -06:00
trapexit 411d181473 Add qbittorrent specific section of known issues (#1591) 2025-11-25 23:14:20 -06:00
Emanuel Haupt caf7915003 tools/preload: include correct extended attribute headers on FreeBSD (#1590)
Add conditional includes for extended attribute support. FreeBSD uses
<sys/extattr.h> instead of <sys/xattr.h>, which prevents the preload
module from building. This update selects the proper header based on
the target platform and fixes the build failure on FreeBSD.
2025-11-25 12:09:41 -06:00
trapexit 4c5473d569 Remove cirris builds, codeql; redo mkdocs builds (#1585) 2025-11-19 10:28:38 -06:00
trapexit 104f378c2c Replace 'unknown' distro-codename when building deb from tarball src (#1584) 2025-11-19 07:57:58 -06:00
trapexit a364405cf0 Remove --depth=1 to clone for tarball builder (#1583)
Led to empty changelog
2025-11-19 06:56:23 -06:00
trapexit 960f5fdbba Fix some links in docs (#1582) 2025-11-18 08:35:27 -06:00
trapexit 6813a51fce Ensure cfg references do not also try to initialize the value (#1580) 2025-11-17 17:08:36 -06:00
trapexit f7e86d90ce Add FAQ about lack of create policies about file size (#1578) 2025-11-16 23:44:24 -06:00
trapexit 66d120c721 Add Ubuntu 25.10 build (#1577) 2025-11-16 22:30:32 -06:00
trapexit 01973214bf Slight tweaks to config parsing error handling (#1575) 2025-11-13 16:05:03 -06:00
trapexit af1edadf72 Fix size comparison for returning ERANGE in listxattr (#1574) 2025-11-12 18:58:50 -06:00
trapexit 3bacaa6f7f Add lazy-umount-mountpoint page and mount -a FAQ (#1573) 2025-11-12 12:19:00 -06:00
trapexit b6e1a08aef Add link to container image repo (#1570) 2025-11-11 19:38:18 -06:00
trapexit 47bd4259b8 Add container image details (#1569) 2025-11-08 20:28:10 -06:00
trapexit dc486e79ce Add container image building (#1568) 2025-11-06 23:39:05 -06:00
trapexit 78551049d5 Add ability to passthrough 'nofail' mount option (#1567) 2025-11-06 11:05:19 -06:00
trapexit 4aab008233 Ensure backward compatibility with remember & noforget (#1566) 2025-11-05 19:43:57 -06:00
trapexit 3a7a4a13e7 Improve mergerfs intro in docs (#1563) 2025-11-04 00:02:46 -06:00
trapexit 41b65ae9e8 Misc cleanup for FreeBSD and clang (#1560) 2025-11-02 10:49:22 -06:00
trapexit 2412ae7316 Further tweaks to config parsing and error reporting (#1559)
* Further tweaks to config parsing and error reporting

* Fix static builds
2025-11-01 15:20:30 -05:00
trapexit ec16d07fba Mention how mmap error when direct io is enabled (#1557) 2025-10-31 09:31:37 -05:00
trapexit 37f10888a9 Add more debugging options to makefiles and cleanup (#1556) 2025-10-29 22:42:42 -05:00
Satadru Pramanik, DO, MPH, MEng 0db8a1ed6a Fix manpage links for 2.41.0-rc3 (#1555) 2025-10-29 12:07:49 -05:00
trapexit cfaad60275 Misc updates to arg parsing (#1554)
Ignore "defaults" and add a number of more modern VFS mount switches
2025-10-26 21:05:05 -05:00
trapexit 077484323c Fix variable names of fuse-msg-size and posix-acl (#1553) 2025-10-25 17:00:16 -05:00
trapexit 700fcfccf5 Update fuse-msg-size docs (#1552) 2025-10-24 23:34:28 -05:00
trapexit 4b4801add6 Config options docs updates (#1551) 2025-10-24 22:31:04 -05:00
trapexit 741128cb23 Fix lack of include for fmt (#1550) 2025-10-24 21:00:15 -05:00
trapexit 3bee0f0b57 Misc docs updates (#1549) 2025-10-24 20:47:33 -05:00
trapexit 727c522fb8 Rework config, centralize fuse config (#1547) 2025-10-24 08:20:29 -05:00
trapexit 00e5467e99 Misc docs updates (#1544) 2025-10-13 11:44:53 -05:00
trapexit 0371f03def Rework how fuse request context is handled (#1543) 2025-10-12 23:21:36 -05:00
trapexit d18c273293 Allow setting of passthrough max-stack-depth (#1542) 2025-10-07 21:52:13 -05:00
trapexit 0f24bb29ac Make allow-idmap optional (default: false) (#1541)
This is just to correct default behavior for now. More investigation
is necessary to properly support idmapping.
2025-10-06 14:46:58 -05:00
trapexit 3cb35a3a65 Fix rename path generation (#1540) 2025-10-01 17:47:13 -05:00
trapexit 25b0bc72df Fix dirent64::namelen calculation (#1538)
Worked fine on my machine where padding seemed to be all zeroed out
but that doesn't appear to be the case elsewhere.

Could try
https://codeberg.org/jbruchon/libjodycode/src/branch/master/dir.c#L92-L110
but needs to be tested.
2025-09-30 11:25:19 -05:00
trapexit e6fcebe4f3 Misc build fixes (#1537) 2025-09-29 14:05:07 -05:00
trapexit 46f85c0f6d Misc fixes, mostly for FreeBSD (#1536) 2025-09-28 23:17:51 -05:00
trapexit 7a9c3b7eb2 Remove need for and use of ioprio header (#1535) 2025-09-28 00:01:26 -05:00
trapexit 569a151da2 Add ability to proxy ioprio of client apps (#1534) 2025-09-26 11:36:56 -05:00
trapexit 2f3e807e9d Add getdents based readdir functions for Linux (#1533) 2025-09-23 23:51:21 -05:00
trapexit 95ab37fdd2 Fix typo in visualization and add new vid to docs (#1532) 2025-09-22 16:23:50 -05:00
trapexit 1707dc27e3 Misc doc updates (#1531) 2025-09-21 14:25:24 -05:00
trapexit c4126a0796 Add script to generate docs from scratch and push to github (#1530) 2025-09-21 13:04:55 -05:00
pjv 6acef3a638 Fix typo in moveonenospc.md (#1527)
typo
2025-09-21 11:42:15 -05:00
trapexit b3656a0243 Fix broken doc links (#1525) 2025-09-19 19:25:31 -05:00
trapexit 41b40b94fa Misc docs updates (#1524) 2025-09-19 19:20:28 -05:00
trapexit ca59ae53a5 idmap mount support (#1523)
* Add idmap mount support

* Further replacement of std::filesystem::path to fs::path

* Update docs regarding idmap support
2025-09-18 00:07:28 -05:00
trapexit 8c649d33ee Start using std::filesystem::path for fusepath (#1522) 2025-09-17 22:51:16 -05:00
trapexit f64ff9ca1e Revert removal of readdir init setup, simplify cfg usage (#1520) 2025-09-06 11:03:51 -05:00
trapexit 99c28ad3bc Add Ubuntu 25.04 builds (#1519) 2025-09-04 19:29:47 -05:00
trapexit 5becb334cd Misc updates of docs (#1518) 2025-09-01 20:58:58 -05:00
trapexit 071af2e516 More build process updates (#1516) 2025-08-29 07:51:05 -05:00
trapexit 90b3585347 Update readme to match index of mkdocs (#1515) 2025-08-22 20:53:22 -05:00
trapexit d7549f8d53 Fix string manipulation functions after refactor (#1514) 2025-08-22 19:42:31 -05:00
trapexit 6ac7f389c5 Misc changes (#1513)
* Start moving to string_view where possible
* Rework readdir object to use atomic load/store
2025-08-21 22:42:58 -05:00
trapexit 2101ef5bcc Updates to docs, add nonraid, more intro to fs details (#1512) 2025-08-21 15:09:04 -05:00
Max.-F. HelmandMax-F-Helm dd1bea52cd Allow empty lines in config ini files (#1509)
* Allow empty lines in config files

* Add example comment to ini example in docs/quickstart.md

---------

Co-authored-by: Max-F-Helm <m7t24zklr@relay.firefox.com>
2025-08-13 20:00:05 -05:00
trapexit df19f99976 Fix constructing string from attrval setxattr config (#1508) 2025-08-11 19:50:12 -05:00
trapexit 24e778b95a Rework calculation of branch for release make targets (#1507) 2025-08-10 18:39:18 -05:00
trapexit a8a7b34cf3 Add Debian 13 build targets (#1506) 2025-08-10 17:50:06 -05:00
trapexit 6ae9641bcc Misc documentation updates (#1505) 2025-08-10 17:23:55 -05:00
trapexit 4439c2a030 Add setting of oom_score_adj (#1504)
To limit risk of killing by OOM Killer.
2025-08-07 23:58:06 -05:00
trapexit 9872710720 More makefile tweaks, build log, smaller git clones (#1503) 2025-08-06 12:24:25 -05:00
trapexit b18aba86b6 Build improvements (#1501)
* Remove python dependency
* Remove ecfd
* Improve makefiles
* Make preload.so more 32bit compatible
2025-08-04 23:39:52 -05:00
trapexit 33fc26f81f Cleanup copy functions (#1500) 2025-07-27 16:23:45 -05:00
trapexit e8cd74cab0 Move everything to negative errno return types (#1499) 2025-07-25 17:53:48 -05:00
trapexit 2b500f194a Rework of runtime interface (#1498)
Also have special error handling for when branches are invalid and
ENOENT would be returned for getattr and readdir so users understand
what is going on and the runtime interface can still be used to fix
the problem.
2025-07-21 18:18:59 -05:00
trapexit e87867cd2a Clear O_NOFOLLOW when opening a relative fd (#1494) 2025-07-08 18:25:00 -05:00
trapexit fa851eda3a Ensure passthrough and keep_cache are mutually exclusive (#1493) 2025-07-06 18:31:47 -05:00
trapexit f852474073 Update the secondary group cache (#1492)
* Use concurrent_flat_map to build a global cache rather than per
thread.
* Create global maintanence thread manager for clearing unused cache
entries.
2025-07-05 17:05:53 -05:00
trapexit 9e626228be Add mergerfs.collect-info (#1491)
A tool to collect info for support requests.
2025-07-03 20:18:05 -05:00
trapexit 71ddae8713 Misc documentation changes (#1489) 2025-06-29 19:08:57 -05:00
trapexit e216a81a27 Rework movefile and cow break to use copyfile (#1488) 2025-06-28 17:27:40 -05:00
trapexit 264c5600f8 Misc cleanup (#1486)
* Skip non-directories when loading branches
* Warn if branch doesn't exist
* Add braces to globbing
2025-06-25 22:43:49 -05:00
trapexit be49dbe1bd Remove linux only getdents in favor of readdir for FreeBSD sake (#1485) 2025-06-24 19:31:40 -05:00
trapexit eb124316c9 Set default read thread count to 0 (#1484) 2025-06-23 22:39:42 -05:00
trapexit 77ef88b04c Add fsck.mergerfs tool (#1483) 2025-06-23 21:57:55 -05:00
trapexit 34f07e57f5 Add RHEL/CentOS 10 build support (#1479) 2025-06-09 14:33:55 -05:00
trapexit 095fcf82a3 Misc doc updates 2025-06-08 23:59:17 -05:00
trapexit 1b167d34d8 Spawn "mount" on branches when waiting for mounts enabled 2025-06-08 15:09:47 -05:00
trapexit 23824eaeb4 Misc cleanup 2025-06-06 19:10:19 -05:00
trapexit e310d24615 Add support for FUSE passthrough 2025-06-05 23:47:42 -05:00
trapexit 92312c8507 Add debugging of mutexes (#1470)
When DEBUG defined it will used timed locks which will log when held
too long along with where.
2025-05-26 00:44:39 -05:00
trapexit 4b751c2d37 Fix incorrect dyn cast (#1467) 2025-05-19 22:46:55 -05:00
trapexit 86b50d2d4e Rework policies to return branches rather than path strings 2025-05-17 16:35:18 -05:00
trapexit 7e084ea7db Update README.md to fix link (#1464) 2025-05-12 09:48:19 -05:00
trapexit 6eca711f58 Update mkdocs build action (#1458) 2025-05-10 12:56:10 -05:00
trapexit 923d9608e8 Add details to docs about FreeBSD limitations 2025-05-09 21:18:20 -05:00
trapexit 3a034712f6 Add versioning to docs using 'mike' 2025-05-08 19:53:54 -05:00
Zack Guo 5db04b4b5f Update installation.md for SUSE 2025-05-08 07:44:57 -05:00
trapexit fa3266ca7f Add podman release build tooling + misc build fixes (#1455) 2025-05-08 00:00:53 -05:00
trapexit 344014aa81 Rework thread pool for increased stability + config and doc updates (#1453)
Also updates fmt to 11.2.0 and replaced syslog usage with a wrapper
leveraging fmt.
2025-05-05 18:28:49 -05:00
SolipsistmonkeyandJesse Harwin 455a81290b Fix build instructions typo
the location of install-build-pkgs was in buildtools and not tools
---------

Co-authored-by: Jesse Harwin <jesse@jharwin.com>
2025-04-28 14:00:20 -05:00
trapexit deb54c58d8 Merge pull request #1448 from trapexit/defaultperms
Add config option to control default_permissions
2025-04-25 17:34:16 -05:00
Antonio SJ Musumeci 2b04a791b7 Add config option to control default_permissions
Defaults true but there might be some situations where it is useful to
disable.
2025-04-25 16:34:39 -05:00
trapexit 8ee998e8aa Merge pull request #1447 from trapexit/branchcfg
Improve mount waiting + misc doc improvements
2025-04-23 16:40:26 -05:00
Antonio SJ Musumeci de2a82800a Improve mount waiting + misc doc improvements
Adds user.mergerfs.branch and user.mergerfs.branch_mounts_here
Adds .mergerfs.branch and .mergerfs.branch_mounts_here files.
2025-04-23 15:58:36 -05:00
trapexit 212681ddc5 Merge pull request #1445 from trapexit/docs
Misc doc updates + add logo
2025-04-19 22:45:27 -05:00
Antonio SJ Musumeci 9dac54f223 Misc doc updates + add logo 2025-04-19 22:44:08 -05:00
trapexit 78fa34098e Merge pull request #1444 from trapexit/docs
Add FAQ entry regarding OS support
2025-04-15 23:41:45 -05:00
Antonio SJ Musumeci 54681e885a Add FAQ entry regarding OS support 2025-04-15 23:40:42 -05:00
trapexit de5a871326 Merge pull request #1443 from trapexit/inode
Change the "devino" inode calculation
2025-04-15 19:29:43 -05:00
Antonio SJ Musumeci 77bf16e9ae Change the "devino" inode calculation
Use hashing of branch path rather than use st_dev.
2025-04-15 18:54:51 -05:00
trapexit ad54c8be19 Merge pull request #1441 from trapexit/docs
Add doc pages for minfreespace and moveonenospc + other misc updates
2025-04-10 23:00:43 -05:00
Antonio SJ Musumeci c769e959e8 Add doc pages for minfreespace and moveonenospc + other misc updates 2025-04-10 22:59:49 -05:00
trapexit 1f3ebcf418 Merge pull request #1439 from trapexit/statx
Add statx support
2025-04-04 22:25:30 -05:00
Antonio SJ Musumeci 80085c9844 Add statx support 2025-04-04 22:23:16 -05:00
trapexit b85cc8c370 Merge pull request #1438 from trapexit/docs
Update docs regarding error handling
2025-04-04 18:42:37 -05:00
Antonio SJ Musumeci 95732222d9 Update docs regarding error handling 2025-04-04 18:41:58 -05:00
trapexit 17a551d0a4 Merge pull request #1435 from trapexit/rapidhash
Replace usage of wyhash with rapidhash
2025-03-30 18:03:35 -05:00
Antonio SJ Musumeci f74dc36e92 Replace usage of wyhash with rapidhash
https://github.com/Nicoshev/rapidhash
2025-03-30 17:57:20 -05:00
trapexit 764bd8f7be Merge pull request #1434 from trapexit/change-defaults
Change misc defaults
2025-03-30 17:25:18 -05:00
Antonio SJ Musumeci b7f7f7fa97 Change misc defaults
* category.create=pfrd
* moveonenospc=pfrd
* cache.files=off
* parallel-direct-writes=true

These changes were made to match the recommended settings for most
users to reduce confusion.
2025-03-30 17:22:38 -05:00
trapexit 7f410073d4 Merge pull request #1433 from trapexit/maxpages
Support Linux v6.13 FUSE max_page_limit
2025-03-30 00:09:03 -05:00
Antonio SJ Musumeci 92ae63e842 Support Linux v6.13 FUSE max_page_limit 2025-03-30 00:07:08 -05:00
trapexit d31e97e64c Merge pull request #1431 from trapexit/docs
Add links to options docs page to individual pages
2025-03-27 19:55:19 -05:00
Antonio SJ Musumeci 579690f411 Add links to options docs page to individual pages 2025-03-27 19:47:37 -05:00
trapexit ca449a73be Merge pull request #1429 from trapexit/docs
Update docs on default create policy
2025-03-26 14:34:28 -05:00
Antonio SJ Musumeci 2d86ed946a Update docs on default create policy 2025-03-26 14:33:11 -05:00
trapexit 3e454f528c Merge pull request #1426 from trapexit/docs
Misc doc updates
2025-03-12 18:30:21 -05:00
Antonio SJ Musumeci a4fdbae1ca Misc doc updates 2025-03-12 18:29:38 -05:00
trapexit aff66812c0 Merge pull request #1425 from trapexit/docs-tips
Misc doc updates
2025-03-08 22:03:14 -06:00
Antonio SJ Musumeci 6472ac51e9 Misc doc updates 2025-03-08 22:02:34 -06:00
trapexit d3770802b1 Merge pull request #1423 from trapexit/docs-inotify
Add FAQ entry regarding inotify
2025-03-05 16:59:45 -06:00
Antonio SJ Musumeci bcbff5c82e Add FAQ entry regarding inotify 2025-03-05 16:58:27 -06:00
trapexit 09743ee187 Merge pull request #1416 from trapexit/docs
Add FAQ section on common perceived problems
2025-02-22 22:30:28 -06:00
Antonio SJ Musumeci 3a33a6db2b Add FAQ section on common perceived problems 2025-02-22 22:25:39 -06:00
trapexit c0d5f4795a Merge pull request #1415 from trapexit/docs
Update docs on out-of-band usage
2025-02-19 14:13:32 -06:00
Antonio SJ Musumeci ef9074ab4a Update docs on out-of-band usage 2025-02-19 14:13:06 -06:00
trapexit 2d03b89c2d Merge pull request #1414 from theHenMan/patch-2
Update terminology.md
2025-02-19 00:09:55 -06:00
trapexit 64cc63b2bc Merge pull request #1413 from theHenMan/patch-1
Update quickstart.md
2025-02-18 23:04:59 -06:00
Hennie Botha 514c478a39 Update terminology.md
Fixed typo
2025-02-19 07:04:11 +02:00
Hennie Botha 8179f91c48 Update quickstart.md
Fixed a typo
2025-02-19 07:02:22 +02:00
trapexit 371764d800 Merge pull request #1412 from trapexit/docs
Rework questions on what settings and policies to use
2025-02-11 19:47:18 -06:00
Antonio SJ Musumeci 1c44ef7967 Rework questions on what settings and policies to use 2025-02-11 19:46:33 -06:00
trapexit aa97bac533 Merge pull request #1409 from trapexit/docs
Add details about logging to syslog
2025-01-25 20:58:57 -06:00
Antonio SJ Musumeci 12d6302457 Add details about logging to syslog 2025-01-25 20:56:28 -06:00
trapexit 740fc3f84a Merge pull request #1408 from trapexit/docs
Add details about user namespacing and root squashing
2025-01-25 13:54:43 -06:00
Antonio SJ Musumeci f18719ced2 Add details about user namespacing and root squashing 2025-01-25 13:54:06 -06:00
trapexit 366f5fcc4c Merge pull request #1407 from trapexit/docs
Misc doc updates
2025-01-25 13:02:36 -06:00
Antonio SJ Musumeci 1729835b8c Misc doc updates 2025-01-25 13:00:00 -06:00
trapexit 1180fd6dd3 Merge pull request #1402 from trapexit/docs
Doc and mover script updates
2025-01-20 01:45:51 -06:00
Antonio SJ Musumeci 19509e33d2 Doc and mover script updates 2025-01-20 01:43:58 -06:00
trapexit 8f355d7dd5 Merge pull request #1399 from oregonpillow/master
Readability changes to mkdocs installation
2025-01-18 15:21:20 -06:00
debian 2aa9697c87 re-order OS, shorten Debian based OS instructions 2025-01-18 01:14:50 +01:00
trapexit 978d067921 Merge pull request #1398 from trapexit/freebsd
Improve FreeBSD compatibility
2025-01-15 22:16:13 -06:00
Antonio SJ Musumeci b83bd5fd14 Improve FreeBSD compatibility
First draft. Need to investigate why upstream patches include certain
function that appear to exist in FreeBSD 14.2.
2025-01-15 22:10:02 -06:00
trapexit dd906c8a4c Merge pull request #1395 from oregonpillow/latest-release
fix edit uri
2025-01-11 18:07:15 -06:00
debian 6fb9111c03 fix edit uri 2025-01-12 00:56:39 +01:00
trapexit bc382e0fd2 Merge pull request #1392 from trapexit/usr1
Send invalidate node request outside lock
2025-01-10 00:35:59 -05:00
trapexit 0197984db3 Send invalidate node request outside lock 2025-01-09 23:22:07 -06:00
trapexit 248b1aca1c Merge pull request #1391 from trapexit/cpp
Move fuse.c and fuse_lowlevel.c to C++
2025-01-09 20:10:35 -05:00
Antonio SJ Musumeci 9056898bbf Move fuse.c and fuse_lowlevel.c to C++ 2025-01-09 19:05:32 -06:00
trapexit 5e584f246a Merge pull request #1390 from trapexit/tiered
Add tiered cache details to docs
2025-01-08 00:56:48 -05:00
Antonio SJ Musumeci 7e964283b9 Add tiered cache details to docs 2025-01-07 23:55:13 -06:00
trapexit 03dc17fff2 Merge pull request #1389 from trapexit/misc
Update funding and cirrus builds
2025-01-07 00:18:32 -05:00
Antonio SJ Musumeci 8cb68dce4a Update funding and cirrus builds 2025-01-06 23:07:33 -06:00
trapexit 28260c434a Merge pull request #1388 from trapexit/mkdocs
Update README to point to docs, update project comparisons
2025-01-05 23:40:54 -06:00
Antonio SJ Musumeci fae9b993fe Update README to point to docs, update project comparisons 2025-01-05 23:39:48 -06:00
trapexit 171eb9c7c0 Merge pull request #1387 from trapexit/workflows
Fix pip install in mkdocs workflow
2025-01-03 12:41:47 -06:00
Antonio SJ Musumeci 174e703d2e Fix pip install in mkdocs workflow 2025-01-03 12:40:50 -06:00
trapexit efd0dfaa2f Merge pull request #1386 from trapexit/docs
Rework mkdocs based documentation
2025-01-03 12:33:54 -06:00
Antonio SJ Musumeci 75d7a93724 Rework mkdocs based documentation
Lots of restructoring and extra information.
2025-01-03 12:17:26 -06:00
Timothy Pillow 50fa7ac694 add mkdocs
Initial commit of a mkdocs based docs setup
2024-12-21 09:36:07 -06:00
trapexit 7d64a47b88 Merge pull request #1377 from trapexit/movecopy-readme
Add FAQ entry on 'move' and 'copy'
2024-11-30 00:23:39 -06:00
Antonio SJ Musumeci 5fba42f076 Add FAQ entry on 'move' and 'copy' 2024-11-30 00:12:44 -06:00
trapexit b0bb7ef38c Merge pull request #1346 from grunthos503/master
Add missing --relative flag to rsync in percent-full mover script
2024-07-18 15:28:42 -05:00
Alan Millar 85ce7d6178 Add missing --relative flag to rsync in percent-full mover script 2024-07-18 12:14:02 -07:00
trapexit 40359df453 Merge pull request #1342 from techie2000/patch-2
Update README.md
2024-07-18 13:50:29 -05:00
techie2000 9b2a5a75ee Update README.md
Correcting a couple of typos.
Enhancing readability.
2024-06-28 10:15:02 +01:00
trapexit b21172c609 Merge pull request #1321 from trapexit/allowmmap
Add support for 'direct-io-allow-mmap' if supported by kernel
2024-03-21 21:54:04 -04:00
Antonio SJ Musumeci f0444a1ca9 Add support for 'direct-io-allow-mmap' if supported by kernel 2024-03-21 20:48:42 -05:00
trapexit 977d04229f Merge pull request #1320 from trapexit/readme
Suggest cache.files=auto-full rather than partial
2024-03-21 21:36:27 -04:00
Antonio SJ Musumeci 757ae66327 Suggest cache.files=auto-full rather than partial 2024-03-17 00:47:33 -05:00
trapexit 42d0b5734c Merge pull request #1312 from trapexit/preload-tmpfile
Special case O_TMPFILE in preload
2024-02-29 15:41:22 -05:00
Antonio SJ Musumeci 78050ed6b0 Special case O_TMPFILE in preload 2024-02-29 14:33:27 -06:00
trapexit 19ee44afe7 Merge pull request #1309 from trapexit/root-nodeid
Root nodeid
2024-02-25 18:29:58 -05:00
Antonio SJ Musumeci a234e9446c Update README to remove unnecessary references to export-support for NFS 2024-02-25 17:27:08 -06:00
Antonio SJ Musumeci 951eb9540d Ensure lookups of FUSE_ROOT_ID always return generation=0 2024-02-25 17:14:15 -06:00
trapexit 85a936c95e Merge pull request #1308 from trapexit/readme
Change mount type from fuse.mergerfs to mergerfs in README
2024-02-24 02:09:40 -05:00
Antonio SJ Musumeci 8210e63a66 Change mount type from fuse.mergerfs to mergerfs in README 2024-02-24 01:08:30 -06:00
trapexit facdb66746 Merge pull request #1307 from trapexit/readme
Add NFS options to remote filesystems section of readme
2024-02-19 19:20:41 -06:00
Antonio SJ Musumeci 1916e54a24 Add NFS options to remote filesystems section of readme 2024-02-19 19:19:00 -06:00
trapexit 7fabe515f4 Merge pull request #1306 from trapexit/export-support
Add export-support option as possible workaround for NFS EIO issues
2024-02-19 19:00:54 -06:00
Antonio SJ Musumeci 0ca5d6aad0 Add export-support option as possible workaround for NFS EIO issues 2024-02-19 18:58:50 -06:00
trapexit 0c1aeb411d Merge pull request #1305 from trapexit/lib-updates
Library updates
2024-02-18 17:56:39 -06:00
Antonio SJ Musumeci 17fdbf7f42 Update fuse_kernel.h 2024-02-18 17:50:34 -06:00
Antonio SJ Musumeci 27349e41ef Update fmt 2024-02-18 17:24:18 -06:00
Antonio SJ Musumeci b3ce95c422 Update nonstd::optional 2024-02-18 17:24:18 -06:00
Antonio SJ Musumeci cedc9f0f25 Update ghc::filesystem 2024-02-18 17:24:18 -06:00
trapexit d68ad9ac01 Expand the preload docs (#1299) 2024-01-30 00:03:39 -06:00
trapexit ae6c4f7c25 Rework mergerfs vs X section of readme (#1298) 2024-01-28 18:12:29 -06:00
trapexit 87475098a1 Add credit to nohajc for preload idea (#1295) 2024-01-22 12:52:51 -06:00
trapexit d4dc0701d6 Create ld_preload to reopen files on underlying filesystem (#1294) 2024-01-22 12:42:55 -06:00
0x6d61726b c1c2f075ee Update README.md (#1283)
* Update README.md

Information added that mergerfs v2.35.0 and newer sets `allow_other` (but not 2.33.5, that is used by Debian 12.2)
2023-12-01 15:45:13 -06:00
trapexit 96d34f1eab Merge pull request #1280 from trapexit/getpid
Fix user.mergerfs.pid
2023-11-11 19:48:28 -06:00
Antonio SJ Musumeci f66fb7e2d4 Fix user.mergerfs.pid 2023-11-11 19:03:32 -06:00
trapexit edb3368078 Merge pull request #1277 from trapexit/flushdefault
Set flush-on-close default to opened-for-write
2023-10-31 23:26:08 -05:00
Antonio SJ Musumeci bd70928268 Set flush-on-close default to opened-for-write 2023-10-31 09:23:52 -05:00
trapexit 337aade02d Merge pull request #1276 from trapexit/allowother
Only set allow_other when running as root
2023-10-29 02:54:51 -05:00
Antonio SJ Musumeci d6a2f06797 Only set allow_other when running as root 2023-10-29 01:44:18 -05:00
trapexit 7890a4996c Merge pull request #1275 from trapexit/noflush
Add flushonclose feature
2023-10-28 19:49:17 -05:00
Antonio SJ Musumeci 6aa6452d3e Add flushonclose feature 2023-10-28 19:47:23 -05:00
trapexit 7d6c8e9333 Merge pull request #1271 from trapexit/warn-root
Warn if not running as root
2023-10-22 00:45:41 -05:00
Antonio SJ Musumeci a7069153bd Warn if not running as root 2023-10-22 00:43:19 -05:00
trapexit 5c71a75fdd Merge pull request #1269 from trapexit/wyhash
Update wyhash to 4.2
2023-10-21 18:04:14 -05:00
Antonio SJ Musumeci fd33df04a3 Update wyhash to 4.2 2023-10-21 18:03:05 -05:00
trapexit a9ae36a3e4 Merge pull request #1263 from trapexit/pthread_getname_np
Remove use of pthread_getname_np to work with older musl versions
2023-10-14 01:20:00 -05:00
Antonio SJ Musumeci 569537df9e Remove use of pthread_getname_np to work with older musl versions 2023-10-14 01:15:29 -05:00
trapexit 8534ee7ceb Merge pull request #1262 from trapexit/readdir-errs
Rework thread pool queue depth impl
2023-10-14 01:13:48 -05:00
Antonio SJ Musumeci 620cab2948 Rework thread pool queue depth impl 2023-10-14 00:58:10 -05:00
trapexit 8635456818 Merge pull request #1254 from trapexit/typo
Fix readdir doc typos
2023-09-23 14:54:25 -05:00
Antonio SJ Musumeci 0888f372aa Fix readdir doc typos 2023-09-23 14:53:41 -05:00
trapexit e09b10c55b Merge pull request #1249 from trapexit/tpfix
Fix thread pool destruction where threads don't explicitly exit themselves
2023-09-09 17:07:51 -05:00
Antonio SJ Musumeci 766b923116 Fix thread pool destruction where threads don't explicitly exit themselves 2023-09-09 16:48:47 -05:00
trapexit dd7e9e2aa7 Merge pull request #1244 from trapexit/docs
Add some new questions to FAQ
2023-09-05 22:56:50 -05:00
Antonio SJ Musumeci 3fc0aa3809 Add some new questions to FAQ 2023-09-05 22:56:08 -05:00
trapexit b1dcc94e98 Merge pull request #1242 from trapexit/debug-removal
Remove unneeded debug logging from thread pool
2023-09-04 18:40:38 -05:00
Antonio SJ Musumeci 6d2c99e487 Remove unneeded debug logging from thread pool 2023-09-04 18:39:43 -05:00
trapexit 9d9eacfe7b Merge pull request #1241 from trapexit/version
Add website and license to version option
2023-09-04 16:02:24 -05:00
Antonio SJ Musumeci b91cc1c191 Add website and license to version option 2023-09-04 15:57:47 -05:00
trapexit 6d2f26c60e Merge pull request #1240 from trapexit/dynamic-threadpool
Rework thread pool, add ability to add/remove threads at runtime
2023-09-03 23:37:29 -05:00
Antonio SJ Musumeci 0a94bd7cfc Rework thread pool, add ability to add/remove threads at runtime 2023-09-03 23:36:03 -05:00
trapexit 211e6c7115 Merge pull request #1239 from trapexit/validation
Add proper input validation for readdir policy
2023-09-02 15:48:43 -05:00
Antonio SJ Musumeci 335ca55a6e Add proper input validation for readdir policy 2023-09-02 15:47:49 -05:00
trapexit 69de4de53f Merge pull request #1238 from trapexit/boundedqueue
Change threadpool to use concurrentqueue
2023-09-02 00:47:26 -05:00
Antonio SJ Musumeci 76c8d48dbd Change threadpool to use concurrentqueue 2023-09-02 00:45:47 -05:00
trapexit a927a15e9c Merge pull request #1237 from trapexit/threadfix
Initialize readdir threadpool after daemonizing
2023-08-28 22:48:59 -05:00
Antonio SJ Musumeci 0c555e71a0 Initialize readdir threadpool after daemonizing 2023-08-28 22:47:04 -05:00
trapexit 82781b6ff8 Merge pull request #1235 from DavidFair/readme_direct_parallel
Docs: clarify parallel-direct-writes and cache.files
2023-08-26 18:52:57 -05:00
David Fairbrother b545352712 Nit: cache.files=per-process grammar
Change which 'comm' name -> whose 'comm' name.
Whose implies possession, and the process possess the name we're
matching
2023-08-26 21:27:16 +01:00
David Fairbrother 3d05999db0 State cache.files per-process behaviour w/out match
This makes it clear, along with the previous commit, that per-process will allow
us to use parallel direct writes as they will mount with the equivalent
of cache.files=off (i.e. direct_io)
2023-08-26 21:24:34 +01:00
David Fairbrother f4a8105a42 Clarify parallel direct writes conditions
Clarify that paralell direct can only be enabled where the kernel
version supports it, which is 6.2+.

State the two cache.files modes which can support parallel direct writes
in the description.
2023-08-26 21:22:37 +01:00
trapexit 004b616115 Merge pull request #1234 from trapexit/fixes
Misc fixes for older platforms
2023-08-22 08:13:56 -05:00
Antonio SJ Musumeci 8d7017273f Misc fixes for older platforms 2023-08-22 08:10:55 -05:00
trapexit 51b65cd126 Merge pull request #1233 from trapexit/atomic
Use relaxed memory order for atomic counters
2023-08-21 17:19:09 -05:00
Antonio SJ Musumeci 0ed03a1535 Use relaxed memory order for atomic counters 2023-08-21 15:43:03 -05:00
trapexit b6d3c34d3f Merge pull request #1232 from trapexit/wyhash
Update wyhash to final4
2023-08-21 00:20:04 -05:00
Antonio SJ Musumeci fdecabfaab Update wyhash to final4 2023-08-21 00:18:41 -05:00
trapexit 3a1d8e03a1 Merge pull request #1231 from trapexit/readdir
Fix setting of ugids for concurrent readdir
2023-08-20 23:12:56 -05:00
Antonio SJ Musumeci e586d2fd1e Fix setting of ugids for concurrent readdir 2023-08-20 23:06:05 -05:00
trapexit e0087cd8a7 Merge pull request #1228 from trapexit/threading
Add thread names for easier debugging
2023-08-14 17:52:31 -05:00
Antonio SJ Musumeci 2377cb05b6 Add thread names for easier debugging 2023-08-14 17:51:41 -05:00
trapexit a8ffbc84f6 Merge pull request #1227 from trapexit/gidcache
Add ability to invalidate gid cache on demand
2023-08-13 23:32:33 -05:00
Antonio SJ Musumeci 0aafdefc18 Add ability to invalidate gid cache on demand
SIGUSR2 or ioctl
2023-08-13 23:30:52 -05:00
trapexit 7221fded71 Merge pull request #1226 from feltcat/feltcat-patch-1
Fix a typo in README.md
2023-08-13 23:13:30 -05:00
feltcat 7a09f560f7 Fix a typo in README.md 2023-08-14 03:45:01 +00:00
trapexit 8b769dff7f Merge pull request #1225 from trapexit/new-funcs
Add callbacks for newer functions
2023-08-13 17:46:09 -05:00
Antonio SJ Musumeci 6dcf6111af Add callbacks for newer functions
* setupmapping
* removemapping
* syncfs
* tmpfile
2023-08-13 17:38:13 -05:00
trapexit 9849bcd3cf Merge pull request #1224 from trapexit/readdir
Add readdir policies
2023-08-11 00:05:28 -05:00
Antonio SJ Musumeci c92a10021e Add readdir policies 2023-08-11 00:05:14 -05:00
trapexit d817fa4e97 Merge pull request #1220 from trapexit/fix-logging
Fix logging pin-threads details
2023-07-30 23:14:16 -05:00
Antonio SJ Musumeci eb141c4c4e Fix logging pin-threads details 2023-07-30 23:13:14 -05:00
trapexit 282ce08ddb Merge pull request #1219 from trapexit/fuse-config
Move fuse thread args out of fuse session object
2023-07-30 22:56:27 -05:00
Antonio SJ Musumeci 51d97bb444 Move fuse thread args out of fuse session object 2023-07-30 22:52:43 -05:00
trapexit 539f2221a3 Merge pull request #1213 from trapexit/lib-updates
Lib updates
2023-07-15 18:51:43 -04:00
Antonio SJ Musumeci 2b1804d364 Add a DEPENDENCIES file to list dependencies
Mostly to remind myself which libs to update on occasion
2023-07-15 17:49:57 -05:00
Antonio SJ Musumeci 556c6522c0 Update fmt to v10.0.0 2023-07-15 17:47:36 -05:00
Antonio SJ Musumeci 543603bdfc Update ghc::filesystem to v1.5.14 2023-07-15 14:47:44 -05:00
trapexit 7a86ed6508 Merge pull request #1212 from trapexit/erofs
Create functions can set branches RO on EROFS
2023-07-13 22:34:29 -04:00
Antonio SJ Musumeci 707d298d7c Create functions can set branches RO on EROFS 2023-07-13 21:19:13 -05:00
trapexit 36a4b7a23a Merge pull request #1209 from trapexit/o_direct
Align msg buffer memory to allow O_DIRECT to work
2023-07-09 19:39:52 -04:00
Antonio SJ Musumeci 22833bdfe2 Align msg buffer memory to allow O_DIRECT to work 2023-07-09 15:32:11 -05:00
trapexit 775c3cad90 Merge pull request #1208 from trapexit/syslog
Simplify syslog wrapper a bit
2023-07-06 00:15:57 -05:00
Antonio SJ Musumeci fa537961c5 Simplify syslog wrapper a bit 2023-07-06 00:13:42 -05:00
trapexit ee13810f3b Merge pull request #1207 from trapexit/atomic
Fix build on older distros due to std::atomic definitions
2023-07-02 23:57:45 -05:00
Antonio SJ Musumeci 5d6c9cc56a Fix build on older distros due to std::atomic definitions
std::atomic_uint64_t missing in some older distros
2023-07-02 23:46:46 -05:00
trapexit 832903378e Merge pull request #1206 from trapexit/write-errs
Fix error handling for cached writes
2023-06-29 22:51:34 -05:00
Antonio SJ Musumeci 2722f4f64d Fix error handling for cached writes 2023-06-29 22:50:24 -05:00
trapexit 7cdd12bda4 Merge pull request #1204 from trapexit/gc
Add manual GC triggering + configurable process queue depth
2023-06-26 23:26:47 -05:00
Antonio SJ Musumeci 5ab0fbcaee Add manual GC triggering + configurable process queue depth
Yes, these are unrelated changes but somehow ended up being
prototyped together and I'm too lazy to separate them.
2023-06-26 22:44:23 -05:00
trapexit 42836e0961 Merge pull request #1203 from trapexit/append-move
Fix move when in append mode + fix read/write direct_io vs cached behavior
2023-06-24 23:13:57 -05:00
Antonio SJ Musumeci 6a14a10e6c Fix read/write behavior and return value depending on direct_io
Also add parallel direct write option for 6.2+ kernels.
2023-06-24 23:06:14 -05:00
Antonio SJ Musumeci 82430e1079 Fix moveonenospc when file opened with append mode 2023-06-12 23:40:08 -05:00
trapexit 701f88de43 Merge pull request #1171 from trapexit/srcmounts
Make srcmounts readonly
2023-04-05 22:31:29 -04:00
Antonio SJ Musumeci c72997f298 Make srcmounts readonly
All tools only read from srcmounts and the current setup had a bug
which caused branch mode and minfreespace to be stripped when using
config file.
2023-04-05 22:24:24 -04:00
trapexit c681d6c2fe Merge pull request #1170 from trapexit/fuse_destroy
Fix crash when exiting with open deleted files
2023-04-05 00:35:04 -04:00
Antonio SJ Musumeci 6bc3d77992 Fix crash when exiting with open deleted files 2023-04-05 00:32:30 -04:00
trapexit c266bae96d Merge pull request #1166 from trapexit/docs
Remove duplicate entries in docs
2023-04-01 14:41:33 -04:00
Antonio SJ Musumeci cdcfef2ceb Remove duplicate entries in docs 2023-04-01 14:40:49 -04:00
trapexit 7a62a629b9 Merge pull request #1165 from trapexit/thread-defaults
Change default read-thread-count from -1 to 0 as documented
2023-03-31 13:38:08 -04:00
Antonio SJ Musumeci 0a64d74b4b Change default read-thread-count from -1 to 0 as documented 2023-03-31 12:54:57 -04:00
trapexit 26c8b5c642 Merge pull request #1161 from trapexit/fix
Workaround older gcc bug with namespacing std::hash
2023-03-28 21:57:51 -04:00
Antonio SJ Musumeci 26fd11cb4d Workaround older gcc bug with namespacing std::hash 2023-03-28 21:53:38 -04:00
trapexit cdceade1ae Merge pull request #1159 from trapexit/wait
More actively report to syslog when waiting for branches to mount
2023-03-28 19:03:50 -04:00
Antonio SJ Musumeci eebd6e9eb4 Actively report to syslog when waiting for mounts 2023-03-28 19:01:21 -04:00
trapexit 9744eab819 Merge pull request #1156 from trapexit/options
Fix loading readonly / write once options from file
2023-03-19 23:41:15 -04:00
Antonio SJ Musumeci 1c5b0f2f5f Fix loading readonly / write once options from file 2023-03-19 23:40:32 -04:00
trapexit d9033b7713 Merge pull request #1155 from trapexit/mover-scripts
Fix mover script link typo
2023-03-19 22:08:31 -04:00
Antonio SJ Musumeci b1d11779f0 Fix mover script link typo 2023-03-19 22:07:03 -04:00
trapexit be19b9ce71 Merge pull request #1154 from trapexit/mover-scripts
Move tiered cache mover scripts to files in tools dir
2023-03-19 22:03:31 -04:00
Antonio SJ Musumeci 9fcaf6a674 Move tiered cache mover scripts to files in tools dir 2023-03-19 01:23:19 -04:00
trapexit 2dd4b788ce Merge pull request #1153 from trapexit/readme
Misc README updates
2023-03-18 21:48:16 -04:00
Antonio SJ Musumeci 5152c63480 Misc README updates 2023-03-18 21:47:37 -04:00
trapexit bd02bfd54c Merge pull request #1151 from kephir4eg/master
Fix config file parsing
2023-03-11 00:45:24 -05:00
Ilya Taranov d04e04e89a Fix config file parsing 2023-03-10 20:55:20 -08:00
trapexit 10a9969a64 Merge pull request #1149 from trapexit/readahead
Add ability to set readahead of mergerfs and branches
2023-03-09 00:13:49 -05:00
Antonio SJ Musumeci 486c5d3734 Add ability to set readahead of mergerfs and branches 2023-03-09 00:12:57 -05:00
trapexit 55bd0ca25a Merge pull request #1147 from trapexit/readme
Update README regarding why epmfs is default
2023-03-06 23:26:00 -05:00
Antonio SJ Musumeci ee2855bb38 Update README regarding why epmfs is default 2023-03-06 23:25:42 -05:00
trapexit 65c004a309 Merge pull request #1146 from jonaswinkler/master
Fix typo in basic setup options
2023-03-06 09:26:21 -05:00
Jonas Winkler a598f63235 Update README.md 2023-03-06 15:17:00 +01:00
trapexit 6e845b337a Merge pull request #1145 from trapexit/readme
Lots of misc README updates
2023-03-05 01:43:08 -05:00
Antonio SJ Musumeci e25fa1954e Lots of misc README updates 2023-03-05 01:42:42 -05:00
trapexit b48d368130 Merge pull request #1143 from trapexit/rework-read
Rework fuse read to use same buffers as messages
2023-02-26 23:37:14 -05:00
Antonio SJ Musumeci 373d331f39 Rework fuse read to use same buffers as messages 2023-02-26 23:31:44 -05:00
trapexit 4a647beec1 Merge pull request #1142 from trapexit/remove-splice
Remove splicing features
2023-02-26 01:45:29 -05:00
Antonio SJ Musumeci 84592a9f13 Remove splicing features
After numerous tests it was found the splice features were at best
the same performance as standard IO and at worse actually slower.
To simplify the code all splice features are removed.
2023-02-26 01:42:58 -05:00
trapexit 09fbb80f8c Merge pull request #1140 from trapexit/pinthreads
Add ability to pin read and processing threads
2023-02-20 22:45:54 -05:00
Antonio SJ Musumeci 34310170ac Add ability to pin read and processing threads 2023-02-19 17:52:29 -05:00
trapexit e39ace0eba Merge pull request #1139 from trapexit/per-process-page-cache
Add "per-process" file caching feature
2023-02-18 01:34:37 -05:00
Antonio SJ Musumeci 9effeb6869 Add "per-process" file caching feature
Allows chosing page caching based on process name.
2023-02-18 01:16:36 -05:00
trapexit b51a5970b2 Merge pull request #1137 from trapexit/btrfs-ioctl
Return NOTTY for all btrfs ioctl calls
2023-02-11 10:25:09 -05:00
Antonio SJ Musumeci 2d9c915641 Return NOTTY for all btrfs ioctl calls
mergerfs tries to pass through ioctl calls but due to the complexity
of btrfs calls their is risk of segfaults. In the future it may be
required to whitelist all supported ioctl calls.
2023-02-11 10:07:55 -05:00
trapexit 737e59d232 Merge pull request #1133 from trapexit/lazy-umount
Add option to lazy umount target mount point
2023-02-02 22:12:17 -05:00
Antonio SJ Musumeci 9adddfc66d Add option to lazy umount target mount point 2023-02-02 21:20:23 -05:00
trapexit 9a6b7835f4 Merge pull request #1131 from trapexit/docs
Add more apps to section on sqlite3 mmap problems
2023-01-29 23:57:46 -05:00
Antonio SJ Musumeci ac4e097511 Add more apps to section on sqlite3 mmap problems 2023-01-29 23:56:50 -05:00
trapexit 3d73c6a596 Merge pull request #1130 from trapexit/docs
Update README regarding requesting support and policy descriptions
2023-01-29 23:24:33 -05:00
Antonio SJ Musumeci 9670fb9704 Update README regarding requesting support and policy descriptions 2023-01-29 23:24:09 -05:00
trapexit e2ece936e6 Merge pull request #1129 from trapexit/fuse-version
Remove FUSE_USE_VERSION, no longer used
2023-01-29 18:27:26 -05:00
Antonio SJ Musumeci a4491169b0 Remove FUSE_USE_VERSION, no longer used 2023-01-29 17:04:08 -05:00
trapexit 0d566befba Merge pull request #1128 from trapexit/checkbranches
Forbid adding mountpoint to branch list
2023-01-29 15:50:25 -05:00
Antonio SJ Musumeci 3e313cd605 Forbid adding mountpoint to branch list 2023-01-29 11:51:56 -05:00
trapexit 5bf2a2be59 Merge pull request #1127 from trapexit/bugfixes
Backport bug fixes from libfuse3
2023-01-28 01:17:50 -05:00
Antonio SJ Musumeci 7ed91c1668 Backport bug fixes from libfuse3 2023-01-28 01:17:07 -05:00
trapexit 041e3f50d5 Merge pull request #1126 from trapexit/removeallowother
Hard code setting of allow_other, ignore when set
2023-01-26 23:40:12 -05:00
Antonio SJ Musumeci 92ccfd3c89 Hard code setting of allow_other, ignore when set 2023-01-26 23:37:37 -05:00
trapexit 24f2d3c94d Merge pull request #1125 from trapexit/scheduling-priority
Allow setting of scheduling priority
2023-01-25 23:42:20 -05:00
Antonio SJ Musumeci a7113bb163 Allow setting of scheduling priority 2023-01-25 23:38:31 -05:00
trapexit ec5ac0c517 Merge pull request #1124 from trapexit/builds
Update CirrusCI setup
2023-01-25 20:24:52 -05:00
Antonio SJ Musumeci fdec3355a1 Update CirrusCI setup 2023-01-25 20:12:53 -05:00
trapexit 16e9ba2f19 Merge pull request #1123 from trapexit/wait
Add option to wait for branches to become new mounts
2023-01-25 19:51:58 -05:00
Antonio SJ Musumeci 939eb3996a Add option to wait for branches to become new mounts
branches-mount-timeout=UINT64 in seconds (default: 0)
2023-01-25 11:59:14 -05:00
trapexit 2d8d0f7ad6 Merge pull request #1120 from trapexit/nonempty
Remove 'nonempty' argument
2023-01-16 23:41:51 -05:00
Antonio SJ Musumeci 3ee93d4c56 Remove 'nonempty' argument
This makes it like all other filesystems and brings it into alignment
with libfuse3's behavior.
2023-01-16 23:33:36 -05:00
trapexit 0b2afda30e Merge pull request #1119 from trapexit/useino
Remove use_ino option and make behavior same as if set
2023-01-16 16:53:30 -05:00
Antonio SJ Musumeci d11807ef7c Remove use_ino option and make behavior same as if set 2023-01-16 16:21:44 -05:00
trapexit 3e725a66e3 Merge pull request #1118 from trapexit/msghandling
Add async message processing
2023-01-16 13:41:00 -05:00
Antonio SJ Musumeci 24423b8d2a Add async message processing 2023-01-16 13:15:53 -05:00
trapexit c89fbde48d Merge pull request #1116 from davidkaufman/patch-1
small grammar correction to README file
2023-01-13 13:47:07 -05:00
David Kaufman b65e52d56b small grammar correction to README file
sorry, i'm a grammar nerd with ocd :-)
2023-01-03 00:58:08 -05:00
trapexit 6c2db76b92 Merge pull request #1109 from trapexit/fixes
Fix regression testing for implemented functions
2022-12-11 14:44:54 -05:00
Antonio SJ Musumeci 094ad862e7 Fix regression testing for implemented functions 2022-12-11 14:44:19 -05:00
trapexit e81b1a6b9d Merge pull request #1107 from trapexit/32bitfixes
Fix printf for 32bit systems
2022-12-08 22:06:15 -05:00
Antonio SJ Musumeci a6ca96fa08 Fix printf for 32bit systems 2022-12-08 22:04:15 -05:00
trapexit a449829d5f Merge pull request #1106 from trapexit/xattrfix
Fix reading of setxattr name
2022-12-08 18:40:57 -05:00
Antonio SJ Musumeci d14427ad9e Fix reading of setxattr name 2022-12-08 18:40:08 -05:00
trapexit ac1f4b4d52 Merge pull request #1105 from trapexit/ll
Misc cleanup
2022-11-27 23:29:53 -05:00
Antonio SJ Musumeci ddf5e53aa4 Misc cleanup 2022-11-27 22:23:38 -06:00
trapexit a2a12afb34 Merge pull request #1104 from trapexit/ll
Remove libfuse abstraction in prep for adding request data
2022-11-27 00:39:05 -05:00
Antonio SJ Musumeci 7606430188 Remove libfuse abstraction in prep for adding request data 2022-11-26 23:30:27 -06:00
trapexit 629806e896 Merge pull request #1093 from lgtm-migrator/codeql
Add CodeQL workflow for GitHub code scanning
2022-11-11 09:53:27 -05:00
LGTM Migrator 50fbf14e1e Add CodeQL workflow for GitHub code scanning 2022-11-11 07:59:54 +00:00
trapexit 4a67bbdc71 Merge pull request #1092 from trapexit/cleanup
Remove write_buf, simplify FUSE msg dispatching
2022-11-10 23:24:25 -05:00
Antonio SJ Musumeci dba9c4451a Remove write_buf, simplify FUSE msg dispatching 2022-11-10 22:43:02 -05:00
trapexit fea499e220 Merge pull request #1091 from trapexit/cleanup
Remove unnecessary libfuse abstractions
2022-11-07 23:35:18 -05:00
Antonio SJ Musumeci 9d056d609f Remove unnecessary libfuse abstractions 2022-11-07 23:09:25 -05:00
trapexit 9a839dd8ba Merge pull request #1089 from trapexit/32bit
Tweaks for 32bit systems
2022-11-05 23:37:19 -04:00
Antonio SJ Musumeci 32e2c9c48e Tweaks for 32bit systems 2022-11-05 23:28:10 -04:00
trapexit 83d7886a0a Merge pull request #1087 from trapexit/kernelh
Update fuse_kernel.h
2022-11-03 23:29:22 -04:00
Antonio SJ Musumeci 316abba0ac Update fuse_kernel.h 2022-11-03 23:28:44 -04:00
trapexit 8001c58c36 Merge pull request #1085 from trapexit/symlinkify
Fix setting of stat vars for symlinkify
2022-10-31 19:47:36 -04:00
Antonio SJ Musumeci 3b0d7fb26e Fix setting of stat vars for symlinkify 2022-10-30 22:27:33 -04:00
trapexit 5d3c5002e0 Merge pull request #1058 from trapexit/docs
Support doc update
2022-08-08 14:09:22 -04:00
Antonio SJ Musumeci 9082285cc8 Support doc update 2022-08-08 13:40:43 -04:00
trapexit d1762b2bac Merge pull request #1057 from trapexit/cfgerrs
Error when given invalid policy names
2022-08-06 23:08:10 -04:00
Antonio SJ Musumeci 46ce28b149 Error when given invalid policy names 2022-08-06 23:01:23 -04:00
trapexit faadeb75e0 Merge pull request #1045 from Gelma/master
Fix typos
2022-06-22 14:27:13 -04:00
Andrea Gelmini 338e559e53 Fix typos 2022-06-22 11:51:23 +02:00
trapexit 3db673410f Merge pull request #1039 from trapexit/docs
Add details about usage of FUSE to docs
2022-05-23 12:49:06 -04:00
Antonio SJ Musumeci 77f098614f Add details about usage of FUSE to docs 2022-05-23 12:40:00 -04:00
trapexit 9589846e9a Merge pull request #1032 from trapexit/support
Rework support section in readme
2022-04-25 17:44:16 -04:00
Antonio SJ Musumeci e2dda3c1b1 Rework support section in readme 2022-04-25 17:42:31 -04:00
trapexit d9ab18282f Merge pull request #1031 from trapexit/root-parent
Return ENOENT when dotdot for root node requested
2022-04-12 23:18:57 -04:00
Antonio SJ Musumeci 14c2ff9ab8 Return ENOENT when dotdot for root node requested 2022-04-12 23:17:39 -04:00
trapexit 77e6f400b5 Merge pull request #1026 from trapexit/loglock
Lock less often during logging
2022-03-20 22:45:07 -04:00
Antonio SJ Musumeci b95ff8ba3a Lock less often during logging 2022-03-20 22:34:55 -04:00
trapexit 4bf8738e5c Merge pull request #1025 from trapexit/estale
Change ENOENT to ESTALE for looking up paths to handle rename race conditions
2022-03-20 12:19:00 -04:00
Antonio SJ Musumeci 3f060f4512 Change ENOENT to ESTALE for looking up paths to handle rename race conditions
As done in https://github.com/libfuse/libfuse/pull/636
2022-03-20 12:09:22 -04:00
trapexit c4c35a9ad0 Merge pull request #1023 from trapexit/follow-symlink-fix
Fix query of attr during symlink
2022-03-19 17:01:11 -04:00
Antonio SJ Musumeci c9a935835f Fix query of attr during symlink
Using getattr when follow-symlink is enabled causes invalid type to the kernel
if symlink pointed to non-symlink.
2022-03-19 16:18:46 -04:00
trapexit 015002ebd9 Merge pull request #1020 from trapexit/slab-maintenance
Rework node slab garbage collection to limit blocking work threads
2022-03-19 15:54:29 -04:00
Antonio SJ Musumeci 9ca10b2413 Rework node slab garbage collection to limit blocking work threads
Also remove debug mode from forcing foreground mode
2022-03-19 13:33:14 -04:00
trapexit 2d5c2c2b6e Merge pull request #1007 from trapexit/trapexit-patch-1
Update bug_report.md
2022-01-18 21:16:22 -05:00
trapexit e3ab739a56 Update bug_report.md 2022-01-18 21:15:59 -05:00
trapexit c784d06029 Merge pull request #1005 from trapexit/readme-readahead
Update README.md regarding readahead
2022-01-15 17:39:31 -05:00
trapexit 58803f4845 Update README.md 2022-01-15 17:33:07 -05:00
trapexit f159fe61f9 Merge pull request #997 from trapexit/link-getattr
Call FUSE getattr rather than syscall for extra logic
2021-12-18 17:21:19 -05:00
Antonio SJ Musumeci c43b464d6c Call FUSE getattr rather than syscall for extra logic
While more efficient calling regular getattr (stat) leads to incorrect
information being returned and would not work correctly when using
symlinkify.
2021-12-18 17:07:23 -05:00
trapexit 34c684a4f5 Merge pull request #991 from trapexit/fix/symlink
Get attrs for link, not target
2021-12-16 19:35:18 -05:00
Antonio SJ Musumeci e256c88e4c Get attrs for link, not target 2021-12-16 19:11:29 -05:00
trapexit 518b4a6b85 Merge pull request #984 from trapexit/disable-locks
Ensure server handling of locks is disabled
2021-11-27 00:02:55 -05:00
Antonio SJ Musumeci ee8532c70d Ensure server handling of locks is disabled 2021-11-27 00:01:12 -05:00
trapexit c58da1ab9c Merge pull request #979 from trapexit/node-size
Remove embedded name in node struct
2021-11-01 22:46:09 -04:00
Antonio SJ Musumeci 68b3026264 Remove embedded name in node struct
The 32 byte array is below the average size so those 32 bytes are wasted a
large portion of the time.
2021-11-01 21:08:58 -04:00
trapexit 810c5a40f7 Merge pull request #978 from trapexit/debug2
Add new debug printing routines, fix ioctl cmd type
2021-10-27 22:31:58 -04:00
Antonio SJ Musumeci 18dead4d86 Add new debug printing routines 2021-10-27 22:12:10 -04:00
trapexit 2082357d3a Merge pull request #977 from trapexit/readme
Readme
2021-10-25 21:58:01 -04:00
Antonio SJ Musumeci 68719da828 Remove ioctl runtime section, use getfattr instead of xattr 2021-10-25 21:57:30 -04:00
trapexit 31fd1ec82e Merge pull request #975 from trapexit/sponsorship
Remove subscribestar from sponsor platforms
2021-10-15 23:30:33 -04:00
trapexit c3845097ee Remove subscribestar from sponsor platforms 2021-10-15 23:30:22 -04:00
trapexit d76934ee9d Merge pull request #972 from trapexit/log-node-info
Add option to log node memory usage metrics
2021-10-11 12:33:11 -04:00
Antonio SJ Musumeci 5f737cb7bf Add option to log node memory usage metrics 2021-10-11 11:57:16 -04:00
trapexit 50ede1ba97 Merge pull request #969 from trapexit/node-size
Reduce struct node size
2021-10-03 22:44:03 -04:00
Antonio SJ Musumeci 930dad31de Reduce struct node size
* Replace the stat values with a crc32b of them instead (for auto-cache)
* Replace char flag with bitfield
* Remove node generation. nodeid is an unsigned 64bit int. Would take 500K+ years
  to rollover at 1M nodes per second.
2021-10-03 22:15:34 -04:00
trapexit 88b91161e0 Merge pull request #968 from trapexit/fix
Fix regression from remember_node refactor
2021-09-30 22:14:51 -04:00
Antonio SJ Musumeci 8150957a01 Fix regression from remember_node refactor 2021-09-30 22:13:29 -04:00
trapexit fee97efafb Merge pull request #967 from trapexit/malloc-trim
Add malloc_trim configure test
2021-09-30 20:25:42 -04:00
trapexit 80856cf7ac Merge pull request #966 from trapexit/libupdates
Update ghc::filesystem and nonstd::optional
2021-09-30 20:05:40 -04:00
Antonio SJ Musumeci c929781d08 Add malloc_trim configure test 2021-09-30 20:00:40 -04:00
Antonio SJ Musumeci 313aa2a1d3 Update ghc::filesystem and nonstd::optional 2021-09-30 19:43:05 -04:00
trapexit 021ce3d97c Merge pull request #964 from trapexit/fmp
Rework of allocation in libfuse
2021-09-19 17:31:39 -04:00
Antonio SJ Musumeci 4ea0de3ef2 Rework dirents buffer management 2021-09-19 16:48:03 -04:00
Antonio SJ Musumeci 6b5c484fbf Major rework of memory allocation using fixed mem pools 2021-09-19 16:48:03 -04:00
trapexit b165332486 Merge pull request #959 from trapexit/readme
Add details on dropping caches before benchmarks
2021-09-03 07:22:21 -04:00
Antonio SJ Musumeci f598d3bc38 Add details on dropping caches before benchmarks 2021-09-03 07:21:16 -04:00
trapexit 4daa9e4eb9 Merge pull request #957 from trapexit/cirrus-ci
Add new cirrus-ci targets
2021-08-29 14:25:17 -04:00
Antonio SJ Musumeci 122f9c1d5d Add new cirrus-ci targets 2021-08-29 13:56:56 -04:00
trapexit 2da5cda4b3 Merge pull request #956 from trapexit/mount-bsd
Remove usage printing regression in mount_bsd
2021-08-29 13:20:07 -04:00
Antonio SJ Musumeci 5263a65dcf Remove usage printing regression in mount_bsd 2021-08-29 13:09:38 -04:00
trapexit 1255d3d1b2 Merge pull request #955 from trapexit/mfs
Fix infinite loop in mfs action policy
2021-08-29 13:07:40 -04:00
Antonio SJ Musumeci 8def16a811 Fix infinite loop in mfs action policy 2021-08-29 12:33:52 -04:00
trapexit 7d1683b607 Merge pull request #954 from trapexit/libfuse-cleanup
Major cleanup of libfuse to remove unneeded features
2021-08-29 12:15:05 -04:00
Antonio SJ Musumeci 43a6d66e3c Major cleanup of libfuse to remove unneeded features
* Remove request interrupt code. Required tracking of all requests unnecesssarily.
* Remove all debugging printing. Have plans to do full replacement.
* Remove deprecated functions.
* Remove unneeded error checking.
* Remove "userdata" which was unused.
* Remove allow_root feature.
2021-08-29 00:05:30 -04:00
trapexit 8b33f9a766 Merge pull request #953 from trapexit/readme-chia
Update docs with Chia wallet address
2021-08-26 12:57:16 -04:00
Antonio SJ Musumeci df721eb253 Update docs with Chia wallet address 2021-08-26 12:56:33 -04:00
trapexit 0547517a99 Merge pull request #951 from trapexit/readme
Add more clarity in what to provide when submitting bug reports
2021-08-22 13:12:03 -04:00
Antonio SJ Musumeci 54e85007a2 Add more clarity in what to provide when submitting bug reports or questions 2021-08-22 13:10:54 -04:00
trapexit 6e53f3b698 Merge pull request #945 from trapexit/readme
Update 'features' section of readme
2021-08-10 21:49:32 -04:00
Antonio SJ Musumeci 1aaf742c13 Update 'features' section of readme 2021-08-10 21:48:51 -04:00
trapexit 3754e20049 Merge pull request #944 from trapexit/trapexit-patch-1
tweak bug report template language
2021-08-09 21:10:16 -04:00
trapexit b4c031d1f0 tweak bug report template language 2021-08-09 21:09:54 -04:00
trapexit 3b8d495c43 Merge pull request #940 from trapexit/ioctl-runtime-removal
Remove config ioctl calls
2021-08-03 17:02:01 -04:00
Antonio SJ Musumeci 61c2187c14 Remove config ioctl calls
While they were going to be the new way of interacting with the runtime config
I've decided to use toml based config for mergerfs v3. In that case all updates
will happen through the config file and ioctl will only be used to load/reload
the config rather than a key:value like API.
2021-08-02 16:56:20 -04:00
trapexit 192e4a4af8 Merge pull request #939 from trapexit/update-nonstd-optional
Update nonstd::optional to v3.4.0
2021-08-02 16:29:40 -04:00
trapexit 749f0290e9 Merge pull request #938 from trapexit/update-ghc-filesystem
Update ghc::filesystem to v1.5.8
2021-08-02 16:24:22 -04:00
Antonio SJ Musumeci 7013ff9aeb Update nonstd::optional to v3.4.0 2021-08-02 16:10:56 -04:00
Antonio SJ Musumeci 3ce0dc56e4 Update ghc::filesystem to v1.5.8 2021-08-02 16:06:43 -04:00
trapexit 8e47bf4946 Merge pull request #926 from trapexit/modzero
pfrd: fix mod by zero error when all branches are filtered
2021-06-25 09:45:01 -04:00
Antonio SJ Musumeci 098f353bf1 pfrd: fix mod by zero error when all branches are filtered 2021-06-25 09:17:16 -04:00
trapexit 859b4da3dc Merge pull request #924 from trapexit/varinit-master
properly initialize fuse_buf in worker loop
2021-06-20 17:40:12 -04:00
Antonio SJ Musumeci 80f30999fa properly initialize fuse_buf in worker loop 2021-06-20 17:38:17 -04:00
trapexit 3fdd322a5c Merge pull request #914 from trapexit/readme
mention bind-propagation and add link to hotio
2021-05-29 13:27:19 -04:00
trapexit c40f42e57e mention bind-propagation and add link to hotio 2021-05-29 13:26:54 -04:00
trapexit 18e87980a4 Merge pull request #913 from trapexit/readme
Update README.md
2021-05-29 13:07:54 -04:00
trapexit 44efbaabe6 Update README.md
Add FAQ entry regarding container runtimes
2021-05-29 13:07:09 -04:00
trapexit a02f3a6856 Merge pull request #891 from trapexit/trapexit-patch-1
Update bug_report.md
2021-03-15 07:58:22 -04:00
trapexit 9573a053d6 Update bug_report.md
update the strace commands and make clear to use a recent release
2021-03-15 07:58:02 -04:00
trapexit 9a5d691619 Merge pull request #889 from trapexit/readme
README: update strace args and add question on snapraid
2021-03-11 15:37:37 -05:00
Antonio SJ Musumeci 495afeffb1 README: update strace args and add question on snapraid 2021-03-11 15:36:50 -05:00
trapexit 4acc1defe2 Merge pull request #888 from Gelma/typo
Fix typo
2021-03-06 17:49:40 -05:00
Andrea Gelmini 58b4eb9089 Fix typo 2021-03-06 23:38:33 +01:00
trapexit ca4b4c6d35 Merge pull request #884 from trapexit/travis
remove travis-ci
2021-02-25 15:40:32 -05:00
Antonio SJ Musumeci 9a90609428 remove travis-ci 2021-02-25 15:40:00 -05:00
trapexit 3e691149f5 Merge pull request #883 from trapexit/link-symlink
new features: follow-symlinks, rename-exdev, link-exdev
2021-02-25 15:33:26 -05:00
Antonio SJ Musumeci 8adebc9489 new features: follow-symlinks, rename-exdev, link-exdev
* follow-symlinks: allows mergerfs to transparently follow symlinks
* link-exdev: in the event a link returns EXDEV create a symlink instead
* rename-exdev: in the event a rename returns EXDEV move the oldpath and
  create a symlink for the newpath
2021-02-11 23:24:08 -05:00
trapexit 50daf84ec0 Merge pull request #880 from trapexit/branch-parse-fix
fix parsing of relative branch paths
2021-02-11 19:37:38 -05:00
Antonio SJ Musumeci d337574665 fix parsing of relative branch paths 2021-02-11 19:22:17 -05:00
trapexit 39d98f1eac Merge pull request #878 from trapexit/readdir_rewind_fix
reset dentry buffer when rewind'ed
2021-02-09 20:21:59 -05:00
trapexit cbea2ba91b Merge branch 'master' into readdir_rewind_fix 2021-02-09 18:13:08 -05:00
trapexit 55bd9a06b1 Merge pull request #876 from trapexit/readme
readme: update support section
2021-02-08 18:15:45 -05:00
Antonio SJ Musumeci 6a9f7e6afc readme: update support section 2021-02-08 17:55:49 -05:00
trapexit f2158d3e66 Merge pull request #871 from trapexit/support
README: update support section
2021-01-23 18:54:42 -05:00
Antonio SJ Musumeci 3bc189cfc8 README: update support section 2021-01-23 18:54:06 -05:00
trapexit d0c5ff7f87 Merge pull request #870 from trapexit/readme
README: add warning/clearity about caching script and hardlinks and cow
2021-01-23 17:19:59 -05:00
Antonio SJ Musumeci dfb544fed8 README: add warning/clearity about caching script and hardlinks and cow 2021-01-23 17:18:07 -05:00
trapexit ae893ca051 Merge pull request #865 from trapexit/config
config: rework global config, remove rwlock, make branches RCU like
2021-01-14 22:10:20 -05:00
Antonio SJ Musumeci 538467b86d config: rework global config, remove rwlock, make branches RCU like
Also added unit tests. Should have done separately but found a number of bugs.
2021-01-14 21:02:10 -05:00
trapexit 46de43d4ad Merge pull request #860 from trapexit/funding
Update FUNDING.yml
2021-01-01 15:52:41 -05:00
trapexit 3808e2683e Update FUNDING.yml 2021-01-01 15:52:15 -05:00
trapexit 52342a76c1 Merge pull request #858 from trapexit/docs
README: misc updates and tweaks
2020-12-29 19:36:30 -05:00
Antonio SJ Musumeci e9e17baf5e README: misc updates and tweaks 2020-12-29 19:34:13 -05:00
1119 changed files with 138305 additions and 38857 deletions
-230
View File
@@ -1,230 +0,0 @@
freebsd_task:
name: "freebsd:12.1"
freebsd_instance:
image_family: freebsd-12-1
env:
ASSUME_ALWAYS_YES: yes
script:
- tools/install-build-pkgs
- gmake -j4
#macos_task:
# osx_instance:
# image: catalina-base
# script:
# - tools/install-build-pkgs
# - gmake -j4
linux_task:
name: "alpine:3.11"
container:
image: alpine:3.11
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make STATIC=1 LTO=1
linux_task:
name: "alpine:3.12"
container:
image: alpine:3.12
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make STATIC=1 LTO=1
linux_task:
name: "centos:7"
container:
image: centos:7
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "centos:8"
container:
image: centos:8
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "fedora:30"
container:
image: fedora:30
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "fedora:31"
container:
image: fedora:31
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- make
- make rpm
linux_task:
name: "fedora:32"
container:
image: fedora:32
cpu: 4
memory: 2G
timeout_in: 10m
script:
- tools/install-build-pkgs
- 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:
image: ubuntu:14.04
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:16.04"
container:
image: ubuntu:16.04
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:18.04"
container:
image: ubuntu:18.04
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:
image: ubuntu:20.04
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: "debian:7"
container:
image: debian:8
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: "debian:8"
container:
image: debian:8
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: "debian:9"
container:
image: debian:9
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: "debian:10"
container:
image: debian: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
+1 -6
View File
@@ -1,7 +1,2 @@
# These are supported funding model platforms
github: [trapexit]
patreon: trapexit
open_collective: trapexit
ko_fi: trapexit
custom: ['https://paypal.me/trapexit','https://www.subscribestar.com/trapexit']
custom: ['https://github.com/trapexit/support']
+55 -12
View File
@@ -7,28 +7,71 @@ assignees: ''
---
See also https://trapexit.github.io/mergerfs/latest/support
**Describe the bug**
A clear and concise description of what the bug is. Please do not file bugs for unreleased versions unless you're a tester or sure it's not a work in progress. The master branch is **not** to be considered in a production state.
A clear and concise description of the unexpected behavior.
**Please be sure to use latest release of mergerfs to ensure the issue
still exists. Not your distro's latest but the latest official
release. Support will NOT be provided for old versions.**
The `master` branch is **not** to be considered production ready. Feel
free to file bug reports but do so indicating clearly that you are
testing unreleased code.
**To Reproduce**
Steps to reproduce the behavior. List **all** steps to reproduce. **All** settings.
Please simplify the reproduction as much as possible.
- Unless it is dependenat on multiple branches, use a single branch
- Use basic tooling if possible (touch,truncate,rm,rmdir,ln,etc.)
Provide steps to reproduce the behavior. List **all** steps to
reproduce. **All** settings. The version of all software involved.
Please simplify the reproduction as much as possible.
* Unless it is dependenat on multiple branches, use a single branch
* Reproduce with standard tooling if possible
(touch,truncate,rm,rmdir,ln,etc.) Having to install 3rd party
software will make debugging more difficult.
**Expected behavior**
A clear and concise description of what you expected to happen.
A clear and concise description of the expected behavior.
**Workarounds already tested**
Please list all workarounds attempted and why they were ruled out as
options.
**System information:**
- OS, kernel version: `uname -a`
- mergerfs version: `mergerfs -V`
- mergerfs settings
- List of drives, filesystems, & sizes: `df -h`
- A strace of the application having a problem: `strace -f -o /tmp/app.strace.txt <cmd>` or `strace -f -p <appPID> -o /tmp/app.strace.txt`
- strace of mergerfs while app tried to do it's thing: `strace -f -p <mergerfsPID> -o /tmp/mergerfs.strace.txt`
* Attach output from
[mergerfs.collect-info](https://trapexit.github.io/mergerfs/latest/tooling/#mergerfscollect-info)
tool.
* Alternatively:
* OS: `lsb_release -a`
* kernel version: `uname -a`
* mergerfs version: `mergerfs --version`
* mergerfs settings / arguments: from fstab, systemd unit, command
line, OMV plugin, etc.
* List of drives, filesystems, & sizes:
* `df -h`
* `lsblk -o NAME,FSTYPE,FSSIZE,SIZE,MOUNTPOINTS,RM,RO,ROTA`
* All information about the relevant paths and files: permissions,
ownership, etc.
* All information about the application making the requests:
version, uid/gid
* Is mergerfs running within a container or used with container
technologies?
* Are the client apps using mergerfs running in a container?
* A strace of the application having a problem:
* `strace -fvTtt -s 256 -o /tmp/app.strace.txt <cmd>`
* `strace -fvTtt -s 256 -o /tmp/app.strace.txt -p <appPID>`
* strace of mergerfs while app tried to do it's thing:
* `strace -fvTtt -s 256 -p <mergerfsPID> -o /tmp/mergerfs.strace.txt`
**Additional context**
Add any other context about the problem here.
+2 -2
View File
@@ -1,10 +1,10 @@
---
name: Question
about: When you're looking for information
about: When you're looking for information or general support
title: ''
labels: investigating, question
assignees: ''
---
You can also ask questions on Discord for realtime help: https://discord.gg/MpAr69V
For general questions and support please use [GitHub Discussions](https://github.com/trapexit/mergerfs/discussions) or [Discord](https://discord.gg/MpAr69V).
+9 -1
View File
@@ -14,12 +14,20 @@
# build artifacts
mergerfs
obj/
build/
src/version.hpp
VERSION
# Debian files
debian/files
debian/changelog
debian/debhelper-build-stamp
debian/mergerfs.debhelper.log
debian/mergerfs.substvars
# RPM files
rpmbuild/
# mkdocs files
mkdocs/venv
__pycache__/
-44
View File
@@ -1,44 +0,0 @@
language: cpp
matrix:
include:
- os: linux
dist: precise
compiler: gcc
sudo: required
- os: linux
dist: precise
compiler: clang
sudo: required
- os: linux
dist: trusty
compiler: gcc
sudo: required
- os: linux
dist: trusty
compiler: clang
sudo: required
- os: linux
dist: xenial
compiler: gcc
sudo: required
- os: linux
dist: xenial
compiler: clang
sudo: required
- os: linux
dist: bionic
compiler: gcc
sudo: required
- os: linux
dist: bionic
compiler: clang
sudo: required
script:
- sudo -E apt-get install fakeroot
- sudo -E make install-build-pkgs
- make -j$(($(nproc) + 1))
- make deb
- sudo -E dpkg -i ../*.deb
- mergerfs -v || true
+17
View File
@@ -0,0 +1,17 @@
## Libraries
### included in repo
* libfuse: https://github.com/libfuse/libfuse (heavily modified fork of v2.x)
* rapidhash: https://github.com/Nicoshev/rapidhash
* fmt: https://github.com/fmtlib/fmt
* concurrentqueue: https://github.com/cameron314/concurrentqueue
* scope_guard: https://github.com/Neargye/scope_guard
* subprocess: https://github.com/arun11299/cpp-subprocess
* CLI11: https://github.com/CLIUtils/CLI11
* string-lite: https://github.com/martinmoene/string-lite
* boost
* download boost
* ./bootstrap.sh
* ./b2 tools/bcp
* ./dist/bin/bcp unordered/concurrent_flat_map.hpp <target_dir>
+1 -1
View File
@@ -1,7 +1,7 @@
/*
ISC License
Copyright (c) 2020, Antonio SJ Musumeci <trapexit@spawn.link>
Copyright (c) 2026, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
+281 -110
View File
@@ -1,4 +1,4 @@
# Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
# Copyright (c) 2025, Antonio SJ Musumeci <trapexit@spawn.link>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
@@ -12,161 +12,279 @@
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
GIT = git
TAR = tar
MKDIR = mkdir
TOUCH = touch
CP = cp
RM = rm
LN = ln
FIND = find
INSTALL = install
MKTEMP = mktemp
STRIP = strip
PANDOC = pandoc
SED = sed
RPMBUILD = rpmbuild
GIT2DEBCL = ./tools/git2debcl
PKGCONFIG = pkg-config
$(info mergerfs MAKEFLAGS: $(MAKEFLAGS))
GIT_REPO = 0
ifeq ($(shell id -u),0)
FAKEROOT ?=
endif
CP ?= cp
FAKEROOT ?= fakeroot
FIND ?= find
GIT ?= git
GIT2DEBCL ?= buildtools/git2debcl
INSTALL ?= install
LN ?= ln
MKDIR ?= mkdir
MKTEMP ?= mktemp
MV ?= mv
RM ?= rm
RPMBUILD ?= rpmbuild
RPMBUILD_FLAGS ?=
SED ?= sed
STRIP ?= strip
TAR ?= tar
TOUCH ?= touch
BUILDDIR := build
GITHUB_REPO ?= "https://github.com/trapexit/mergerfs"
DEFAULT_TARGET := debian:13.amd64
ifndef GIT_REPO
ifneq ($(shell $(GIT) --version 2> /dev/null),)
ifeq ($(shell test -e .git; echo $$?),0)
GIT_REPO = 1
endif
endif
USE_XATTR = 1
UGID_USE_RWLOCK = 0
ifeq ($(DEBUG),1)
OPT_FLAGS := -O0 -g
else
OPT_FLAGS := -O2
endif
ifeq ($(STATIC),1)
USE_XATTR ?= 1
ifdef SANITIZE
ifeq ($(SANITIZE),1)
override SANITIZE := -fsanitize=address,undefined,leak
else ifeq ($(filter -fsanitize=%,$(SANITIZE)),)
override SANITIZE := -fsanitize=$(SANITIZE)
endif
endif
COMMON_OPT_FLAGS += \
-fstack-protector-strong \
-Wextra \
-Wno-unused-parameter
DEBUG_OPT_FLAGS += \
-O0 \
-g3 \
-fno-omit-frame-pointer \
$(SANITIZE)
ifdef RELEASE
OPT_FLAGS := -O3 $(COMMON_OPT_FLAGS)
else
OPT_FLAGS ?= $(DEBUG_OPT_FLAGS) $(COMMON_OPT_FLAGS)
endif
ifdef STATIC
STATIC_FLAGS := -static
else
STATIC_FLAGS :=
endif
ifeq ($(LTO),1)
ifdef LTO
LTO_FLAGS := -flto
else
LTO_FLAGS :=
endif
SRC = $(wildcard src/*.cpp)
OBJS = $(SRC:src/%.cpp=build/%.o)
DEPS = $(SRC:src/%.cpp=build/%.d)
MANPAGE = mergerfs.1
CXXFLAGS ?= ${OPT_FLAGS}
CXXFLAGS := \
${CXXFLAGS} \
-std=c++0x \
$(STATIC_FLAGS) \
$(LTO_FLAGS) \
-Wall \
-Wno-unused-result \
-MMD
FUSE_FLAGS = \
-Ilibfuse/include \
-D_FILE_OFFSET_BITS=64 \
-DFUSE_USE_VERSION=29
MFS_FLAGS = \
-DUSE_XATTR=$(USE_XATTR) \
-DUGID_USE_RWLOCK=$(UGID_USE_RWLOCK)
SRC := $(wildcard src/*.cpp)
OBJS := $(SRC:src/%.cpp=build/.objs/%.cpp.o)
DEPS := $(SRC:src/%.cpp=build/.objs/%.cpp.d)
LDFLAGS := \
${LDFLAGS} \
-pthread \
-lrt
TESTS := $(wildcard tests/*.cpp)
TESTS_OBJS := $(filter-out build/.objs/mergerfs.cpp.o,$(OBJS))
TESTS_OBJS += $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.o)
TESTS_DEPS := $(TESTS:tests/%.cpp=build/.test_objs/%.cpp.d)
TESTS_DEPS += $(DEPS)
DESTDIR =
PREFIX = /usr/local
EXEC_PREFIX = $(PREFIX)
DATAROOTDIR = $(PREFIX)/share
DATADIR = $(DATAROOTDIR)
BINDIR = $(EXEC_PREFIX)/bin
SBINDIR = $(EXEC_PREFIX)/sbin
MANDIR = $(DATAROOTDIR)/man
MAN1DIR = $(MANDIR)/man1
MANPAGE := mergerfs.1
CPPFLAGS ?=
override CPPFLAGS += \
-D_FILE_OFFSET_BITS=64 \
-DBOOST_UNORDERED_DISABLE_PARALLEL_ALGORITHMS
CFLAGS ?= \
$(OPT_FLAGS) \
-Wall \
-Wno-unused-result \
-pipe
override CFLAGS += \
-MMD \
-MP
CXXFLAGS ?= \
$(OPT_FLAGS) \
$(STATIC_FLAGS) \
$(LTO_FLAGS) \
-Wall \
-Wpessimizing-move \
-Werror=pessimizing-move \
-Wredundant-move \
-Werror=redundant-move \
-Wno-unused-result \
-pipe
override CXXFLAGS += \
-std=c++20 \
-MMD \
-MP
override INC_FLAGS := \
-Isrc \
-Ivendored \
-Ivendored/libfuse/include
override MFS_FLAGS := \
-DUSE_XATTR=$(USE_XATTR)
override TESTS_FLAGS := \
-Isrc \
-Ivendored \
-Ivendored/acutest \
-DTESTS
LIBFUSE := vendored/libfuse/$(BUILDDIR)/libfuse.a
LDFLAGS ?=
LDLIBS := \
-lrt \
-pthread
override LDLIBS += \
$(LIBFUSE)
ifeq ($(CXX),g++)
GCC_VERSION := $(shell $(CXX) -dumpversion | cut -f1 -d.)
ifeq ($(shell test $(GCC_VERSION) -lt 9; echo $$?),0)
override LDLIBS += -lstdc++fs
endif
endif
# https://www.gnu.org/prep/standards/html_node/Directory-Variables.html
DESTDIR ?=
PREFIX ?= /usr/local
EXEC_PREFIX ?= $(PREFIX)
DATAROOTDIR ?= $(PREFIX)/share
DATADIR ?= $(DATAROOTDIR)
BINDIR ?= $(EXEC_PREFIX)/bin
SBINDIR ?= $(EXEC_PREFIX)/sbin
LIBDIR ?= $(EXEC_PREFIX)/lib
MANDIR ?= $(DATAROOTDIR)/man
MAN1DIR ?= $(MANDIR)/man1
INSTALLBINDIR ?= $(DESTDIR)$(BINDIR)
INSTALLSBINDIR ?= $(DESTDIR)$(SBINDIR)
INSTALLLIBDIR ?= $(DESTDIR)$(LIBDIR)/mergerfs
INSTALLMAN1DIR ?= $(DESTDIR)$(MAN1DIR)
INSTALLBINDIR = $(DESTDIR)$(BINDIR)
INSTALLSBINDIR = $(DESTDIR)$(SBINDIR)
INSTALLMAN1DIR = $(DESTDIR)$(MAN1DIR)
.PHONY: all
all: mergerfs
all: libfuse $(BUILDDIR)/mergerfs $(BUILDDIR)/fsck.mergerfs $(BUILDDIR)/mergerfs.collect-info
.PHONY: help
help:
@echo "usage: make\n"
@echo "make USE_XATTR=0 - build program without xattrs functionality"
@echo "make STATIC=1 - build static binary"
@echo "make LTO=1 - build with link time optimization"
@echo "usage: make ARG\n"
@echo "USE_XATTR=0 - build program without xattrs functionality"
@echo "STATIC=1 - build static binary"
@echo "LTO=1 - build with link time optimization"
@echo "SANITIZE=1 - build with sanitizers (address,undefined,leak)"
@echo "SANITIZE=list - build with custom sanitizers (comma separated)"
@echo "CLEANUP=1 - cleanup images between release build process"
@echo "PKGDIR=/dir/ - location for release build pkgs"
@echo "GITREF=gitref - gitref to use for release builds"
objects: version build/stamp
$(MAKE) $(OBJS)
build/mergerfs: libfuse objects
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(OBJS) -o $@ libfuse/build/libfuse.a $(LDFLAGS)
$(BUILDDIR)/mergerfs: $(LIBFUSE) src/version.hpp $(OBJS)
$(CXX) $(CXXFLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
mergerfs: build/mergerfs
$(BUILDDIR)/fsck.mergerfs: $(BUILDDIR)/mergerfs
$(LN) -sf "mergerfs" $@
$(BUILDDIR)/mergerfs.collect-info: $(BUILDDIR)/mergerfs
$(LN) -sf "mergerfs" $@
$(BUILDDIR)/tests: $(BUILDDIR)/mergerfs $(TESTS_OBJS)
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) $(TESTS_OBJS) -o $@ $(LDFLAGS) $(LDLIBS)
.PHONY: libfuse
libfuse: $(LIBFUSE)
$(MAKE) -C vendored/libfuse
$(LIBFUSE):
$(MAKE) -C vendored/libfuse $(BUILDDIR)/libfuse.a RELEASE=$(RELEASE)
tests: $(BUILDDIR)/tests
.PHONY:
changelog:
ifeq ($(GIT_REPO),1)
ifdef GIT_REPO
$(GIT2DEBCL) --name mergerfs > ChangeLog
else
@echo "WARNING: need git repo to generate ChangeLog"
endif
.PHONY: version
version:
tools/update-version
version: src/version.hpp
build/stamp:
$(MKDIR) -p build
src/version.hpp:
./buildtools/update-version
$(BUILDDIR)/stamp:
$(MKDIR) -p $(BUILDDIR)/.objs
$(MKDIR) -p $(BUILDDIR)/.test_objs
$(TOUCH) $@
build/%.o: src/%.cpp
$(CXX) $(CXXFLAGS) $(FUSE_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
$(BUILDDIR)/.objs/%.cpp.o: src/%.cpp $(BUILDDIR)/stamp
$(CXX) $(CXXFLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
$(BUILDDIR)/.test_objs/%.cpp.o: tests/%.cpp | $(BUILDDIR)/stamp
$(CXX) $(CXXFLAGS) $(TESTS_FLAGS) $(INC_FLAGS) $(MFS_FLAGS) $(CPPFLAGS) -c $< -o $@
$(BUILDDIR)/preload.so: $(BUILDDIR)/stamp tools/preload.c
$(CC) -shared -fPIC $(CFLAGS) -o $@ tools/preload.c
preload: $(BUILDDIR)/preload.so
.PHONY: clean
clean: rpm-clean
$(RM) -rf build
$(RM) -rf $(BUILDDIR)
$(FIND) . -name "*~" -delete
$(MAKE) -C libfuse clean
$(MAKE) -C vendored/libfuse clean
.PHONY: distclean
distclean: clean
ifeq ($(GIT_REPO),1)
ifdef GIT_REPO
$(GIT) clean -xfd
endif
.PHONY: install
install: install-base install-mount-tools install-man
install: install-base install-mount-tools install-preload install-man
install-base: build/mergerfs
.PHONY: install-base
install-base: all
$(MKDIR) -p "$(INSTALLBINDIR)"
$(INSTALL) -v -m 0755 build/mergerfs "$(INSTALLBINDIR)/mergerfs"
$(INSTALL) -v -m 0755 "$(BUILDDIR)/mergerfs" "$(INSTALLBINDIR)/mergerfs"
$(LN) -fs "mergerfs" "${INSTALLBINDIR}/fsck.mergerfs"
$(LN) -fs "mergerfs" "${INSTALLBINDIR}/mergerfs.collect-info"
.PHONY: install-mount-tools
install-mount-tools: install-base
$(MKDIR) -p "$(INSTALLBINDIR)"
$(MAKE) -C libfuse install
$(MAKE) -C vendored/libfuse install
install-man: $(MANPAGE)
.PHONY: install-man
install-man: man/$(MANPAGE)
$(MKDIR) -p "$(INSTALLMAN1DIR)"
$(INSTALL) -v -m 0644 "man/$(MANPAGE)" "$(INSTALLMAN1DIR)/$(MANPAGE)"
.PHONY: install-preload
install-preload: preload
$(MKDIR) -p "$(INSTALLLIBDIR)"
$(INSTALL) -v -m 444 "$(BUILDDIR)/preload.so" "$(INSTALLLIBDIR)/preload.so"
.PHONY: install-strip
install-strip: install-base
$(STRIP) "$(INSTALLBINDIR)/mergerfs"
.PHONY: uninstall
uninstall: uninstall-base uninstall-mount.mergerfs uninstall-man
uninstall: uninstall-base uninstall-mount.mergerfs uninstall-preload uninstall-man
uninstall-base:
$(RM) -f "$(INSTALLBINDIR)/mergerfs"
$(RM) -f "$(INSTALLBINDIR)/fsck.mergerfs"
$(RM) -f "$(INSTALLBINDIR)/mergerfs.collect-info"
uninstall-mount.mergerfs:
$(RM) -f "$(INSTALLBINDIR)/mount.mergerfs"
@@ -174,17 +292,11 @@ uninstall-mount.mergerfs:
uninstall-man:
$(RM) -f "$(INSTALLMAN1DIR)/$(MANPAGE)"
$(MANPAGE): README.md
ifneq ($(shell $(PANDOC) --version 2> /dev/null),)
$(PANDOC) -s -t man -o "man/$(MANPAGE)" README.md
else
$(warning "pandoc does not appear available: unable to build manpage")
endif
man: $(MANPAGE)
uninstall-preload:
$(RM) -f "$(INSTALLLIBDIR)/preload.so"
.PHONY: tarball
tarball: man changelog version
tarball: changelog version
$(eval VERSION := $(shell cat VERSION))
$(eval VERSION := $(subst -,_,$(VERSION)))
$(eval FILENAME := mergerfs-$(VERSION))
@@ -194,29 +306,38 @@ tarball: man changelog version
$(TAR) --exclude=.git -cz -C $(TMPDIR) -f $(FILENAME).tar.gz $(FILENAME)
$(RM) -rf $(TMPDIR)
.PHONY: debian-changelog
debian-changelog:
ifeq ($(GIT_REPO),1)
ifdef GIT_REPO
$(GIT2DEBCL) --name mergerfs > debian/changelog
else
cp ChangeLog debian/changelog
$(CP) -v ChangeLog debian/changelog
$(eval DISTRO := $(shell lsb_release -i -s | tr '[:upper:]' '[:lower:]'))
$(eval CODENAME := $(shell lsb_release -c -s | tr '[:upper:]' '[:lower:]'))
sed -i 's/~unknown-unknown/~$(DISTRO)-$(CODENAME)/g' debian/changelog
sed -i 's/ unknown; / $(CODENAME); /g' debian/changelog
endif
.PHONY: signed-deb
signed-deb:
$(MAKE) distclean
$(MAKE) debian-changelog
dpkg-source -b .
dpkg-buildpackage -nc
$(FAKEROOT) dpkg-buildpackage -nc
.PHONY: deb
deb:
$(MAKE) distclean
$(MAKE) debian-changelog
dpkg-source -b .
dpkg-buildpackage -nc -uc -us
$(MAKE) version
$(FAKEROOT) dpkg-buildpackage -nc -uc -us
$(MKDIR) -p ./$(BUILDDIR)/pkgs/
$(MV) -v ../mergerfs*deb ./$(BUILDDIR)/pkgs/
.PHONY: rpm-clean
rpm-clean:
$(RM) -rf rpmbuild
.PHONY: rpm
rpm: tarball
$(eval VERSION := $(shell cat VERSION))
$(eval VERSION := $(subst -,_,$(VERSION)))
@@ -224,15 +345,65 @@ rpm: tarball
$(SED) 's/__VERSION__/$(VERSION)/g' mergerfs.spec > \
rpmbuild/SOURCES/mergerfs.spec
cp -ar mergerfs-$(VERSION).tar.gz rpmbuild/SOURCES
$(RPMBUILD) -ba rpmbuild/SOURCES/mergerfs.spec \
$(RPMBUILD) $(RPMBUILD_FLAGS) -ba rpmbuild/SOURCES/mergerfs.spec \
--define "_topdir $(CURDIR)/rpmbuild"
.PHONY: install-build-pkgs
install-build-pkgs:
tools/install-build-pkgs
./buildtools/install-build-pkgs
.PHONY: install-build-tools
install-build-tools:
./buildtools/install-build-tools
define build_release
$(eval GITREF ?= $(shell git describe --exact-match --tags HEAD 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD))
@echo "GITREF=$(GITREF)"
./buildtools/build-release \
--target=$(1) \
$(if $(CLEANUP),--cleanup) \
$(if $(PKGDIR),--pkgdirpath=$(PKGDIR)) \
--git-repo=$(if $(REMOTE_REPO),$(GITHUB_REPO),".") \
--branch=$(GITREF)
endef
.PHONY: release release-all
.PHONY: release-amd64 release-arm64 release-armhf release-riscv64
.PHONY: release-sample release-static release-tarball release-installer
release:
$(MAKE) RELEASE=1 CPPFLAGS="$(CPPFLAGS) -DNDEBUG" all
release-all:
$(call build_release,"all")
release-sample:
$(if $(TARGET),,$(eval TARGET := $(shell ./buildtools/detect-local-target 2>/dev/null)))
$(call build_release,$(if $(TARGET),$(TARGET),$(DEFAULT_TARGET)))
release-amd64:
$(call build_release,"amd64")
release-arm64:
$(call build_release,"arm64")
release-armhf:
$(call build_release,"armhf")
release-riscv64:
$(call build_release,"riscv64")
release-static:
$(call build_release,"static")
release-tarball:
$(call build_release,"tarball")
release-installer:
$(call build_release,"installer")
container:
$(eval GITREF ?= $(shell git describe --exact-match --tags HEAD 2>/dev/null || git symbolic-ref --short HEAD 2>/dev/null || git rev-parse --short HEAD))
@echo "GITREF=$(GITREF)"
./buildtools/build-containerimage "$(GITREF)"
.PHONY: tags
tags:
rm -fv TAGS
find . -name "*.c" -print | etags --append -
find . -name "*.h" -print | etags --append -
find . -name "*.cpp" -print | etags --append -
find . -name "*.hpp" -print | etags --append -
.PHONY: libfuse
libfuse:
$(MAKE) DEBUG=$(DEBUG) -C libfuse
-include $(DEPS)
+93 -1265
View File
File diff suppressed because it is too large Load Diff
+16
View File
@@ -0,0 +1,16 @@
#!/bin/sh
GIT_BRANCH="${1:-master}"
set -x
podman \
build \
--squash \
--no-cache \
--force-rm \
--build-arg="GIT_REPO=file:///mnt" \
--build-arg="BRANCH=${GIT_BRANCH}" \
-v "${PWD}":/mnt:ro \
-f "buildtools/containerimage/Containerfile" \
--tag "ghcr.io/trapexit/mergerfs:${GIT_BRANCH}" \
buildtools/
+76
View File
@@ -0,0 +1,76 @@
#!/bin/sh
set -e
if [ -e /tmp/build-env ]; then
. /tmp/build-env
fi
rpmbuild_flags()
{
case "$(command -v "${CXX:-g++}")" in
/opt/rh/*)
printf '%s' '--undefine _annotated_build'
;;
esac
}
if [ $# -ne 2 ]; then
echo "usage: $0 <branch> <git_repo>"
echo "argv: $@"
echo "argc: $#"
exit 1
fi
GIT_REPO="${1}"
BRANCH="${2}"
BUILDDIR="/tmp/build"
echo "Clone source from ${GIT_REPO} to ${BUILDDIR}"
git \
clone \
--single-branch \
--branch="${BRANCH}" \
"${GIT_REPO}" \
"${BUILDDIR}"
cd "${BUILDDIR}"
git log HEAD^1..
mkdir "/build"
if [ -e /usr/bin/apt-get ]; then
make deb
elif [ -e /usr/bin/dnf ]; then
make RPMBUILD_FLAGS="$(rpmbuild_flags)" rpm
elif [ -e /usr/bin/yum ]; then
make RPMBUILD_FLAGS="$(rpmbuild_flags)" rpm
elif [ -e /sbin/apk ]; then
echo "NOT YET SUPPORTED"
exit 1
elif [ -e /usr/sbin/pkg ]; then
echo "NOT YET SUPPORTED"
exit 1
elif [ -e /usr/bin/pacman ]; then
make tarball
else
echo "NOT YET SUPPORTED"
exit 1
fi
echo "Copy packages to host..."
if [ -e /usr/bin/pacman ]; then
find "${BUILDDIR}" \
-type f \
-name "*.tar.gz" \
-exec cp -v {} /build/ \;
else
find "${BUILDDIR}" \
-type f \
\( -name "*.deb" -or -name "*.rpm" \) \
-not -name "*dbgsym*" \
-not -name "*sym*" \
-not -name "*src.rpm" \
-exec cp -v {} /build/ \;
fi
exit 0
+178
View File
@@ -0,0 +1,178 @@
#!/usr/bin/env python3
import subprocess
import sys
import os
import argparse
import time
def build(git_repo,
branch,
containerfile,
pkgdirpath):
timestamp = time.time_ns()
args = ['podman',
'build',
'--pull=always',
'--force-rm']
if os.path.exists(git_repo):
git_repo = os.path.realpath(git_repo)
args += ['-v',f'{git_repo}:/tmp/mergerfs.git:ro:z']
args += ['--build-arg=GIT_REPO=file:///tmp/mergerfs.git']
else:
args += [f'--build-arg=GIT_REPO={git_repo}']
os.makedirs(pkgdirpath,exist_ok=True)
args += ['-v',f'{os.path.realpath(pkgdirpath)}:/pkgs:ro']
args += ['-o',pkgdirpath,
'-f',containerfile,
f'--build-arg=BRANCH={branch}',
f'--build-arg=BUILD_TIMESTAMP={timestamp}',
'buildtools/']
# TODO: Capture output and write to log
print(args)
rv = subprocess.run(args)
report_filepath = os.path.join(pkgdirpath,"build-report.txt")
with open(report_filepath,"a+") as f:
build = os.path.basename(containerfile)
f.write(build + ": ")
f.write(f"branch={branch}; ")
f.write(f"timestamp={timestamp}; ")
f.write("rv=")
if rv.returncode == 0:
f.write("success;")
else:
f.write("fail;")
f.write("\n")
def setup():
# Detect distribution
if os.path.exists('/usr/bin/apt-get'):
args = ['sudo',
'apt-get',
'install',
'-fy',
'qemu-user-static',
'qemu-user-binfmt']
elif os.path.exists('/usr/bin/pacman'):
args = ['sudo',
'pacman',
'-Sy',
'--noconfirm',
'qemu-user-static']
else:
print("Unsupported distribution for setup")
sys.exit(1)
print(args)
subprocess.run(args)
setup_binfmt()
def setup_binfmt():
"""Register qemu-user-static binfmt handlers (needed on Arch, etc.)."""
binfmt_conf = """\
:qemu-aarch64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-aarch64-static:F
:qemu-arm:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-arm-static:F
:qemu-armeb:M::\\x7fELF\\x01\\x02\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x28:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff:/usr/bin/qemu-armeb-static:F
:qemu-riscv64:M::\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xf3\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-riscv64-static:F
:qemu-i386:M::\\x7fELF\\x01\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\x03\\x00:\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff:/usr/bin/qemu-i386-static:F
"""
conf_path = '/etc/binfmt.d/qemu-static.conf'
print(f"Writing {conf_path}")
try:
with open(conf_path, 'w') as f:
f.write(binfmt_conf)
except PermissionError:
print(f"Permission denied writing {conf_path}; trying with sudo...")
subprocess.run(['sudo', 'tee', conf_path],
input=binfmt_conf.encode(), check=True)
print("Restarting systemd-binfmt...")
subprocess.run(['sudo', 'systemctl', 'restart', 'systemd-binfmt'])
def podman_cleanup():
args = ['podman',
'system',
'prune',
'-af']
print(args)
subprocess.run(args)
def parse_args():
p = argparse.ArgumentParser()
p.add_argument('--target',
default='debian:13.amd64')
p.add_argument('--pkgdirpath',
default='build/pkgs/')
p.add_argument('--branch',
default='master')
p.add_argument('--setup',
required=False,
action='store_true')
p.add_argument('--cleanup',
required=False,
action='store_true')
p.add_argument('--git-repo',
required=False,
type=str)
return p.parse_args()
def should_skip(filename):
if filename.endswith('~'):
return True
return False
def main():
args = parse_args()
print(args)
if args.setup:
setup()
sys.exit(0)
if not args.git_repo:
print("error: the following arguments are required: --git-repo")
sys.exit(1)
containerfiles = []
basepath = 'buildtools/containerfiles'
if os.path.exists(f'{basepath}/{args.target}'):
containerfiles.append(f'{basepath}/{args.target}')
elif args.target == 'all':
for root,dirnames,filenames in os.walk(basepath):
filenames.sort()
for filename in filenames:
if should_skip(filename):
continue
containerfile = f'buildtools/containerfiles/{filename}'
containerfiles.append(containerfile)
else:
for root,dirnames,filenames in os.walk(basepath):
filenames.sort()
for filename in filenames:
if args.target not in filename:
continue
if should_skip(filename):
continue
containerfile = f'buildtools/containerfiles/{filename}'
containerfiles.append(containerfile)
for containerfile in containerfiles:
if args.cleanup:
podman_cleanup()
build(git_repo=args.git_repo,
branch=args.branch,
containerfile=containerfile,
pkgdirpath=args.pkgdirpath)
sys.exit(0)
if __name__ == '__main__':
main()
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 debian:11 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 debian:11 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=armhf debian:11 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=i386 debian:11 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 debian:12 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 debian:12 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=armhf debian:12 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=i386 debian:12 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 debian:13 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 debian:13 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=armhf debian:13 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=i386 debian:13 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=riscv64 debian:13 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 fedora:40 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 fedora:40 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 fedora:41 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 fedora:41 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 fedora:42 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 fedora:42 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 fedora:43 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 fedora:43 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=amd64 fedora:44 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+10
View File
@@ -0,0 +1,10 @@
FROM --platform=arm64 fedora:44 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 quay.io/rockylinux/rockylinux:10 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 quay.io/rockylinux/rockylinux:10 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 quay.io/rockylinux/rockylinux:8 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 quay.io/rockylinux/rockylinux:8 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 quay.io/rockylinux/rockylinux:9 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 quay.io/rockylinux/rockylinux:9 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+15
View File
@@ -0,0 +1,15 @@
FROM --platform=linux/amd64 alpine:latest as build
COPY install-build-pkgs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
WORKDIR /tmp/mergerfs
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
RUN mkdir /build
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_amd64.tar.gz --directory=/tmp usr sbin
FROM scratch
COPY --from=build /build/ /
+15
View File
@@ -0,0 +1,15 @@
FROM --platform=linux/arm64 alpine:latest as build
COPY install-build-pkgs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
WORKDIR /tmp/mergerfs
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
RUN mkdir /build
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_arm64.tar.gz --directory=/tmp usr sbin
FROM scratch
COPY --from=build /build/ /
+15
View File
@@ -0,0 +1,15 @@
FROM --platform=linux/armhf alpine:latest as build
COPY install-build-pkgs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
WORKDIR /tmp/mergerfs
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
RUN mkdir /build
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_armhf.tar.gz --directory=/tmp usr sbin
FROM scratch
COPY --from=build /build/ /
+15
View File
@@ -0,0 +1,15 @@
FROM --platform=linux/i386 alpine:latest as build
COPY install-build-pkgs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
WORKDIR /tmp/mergerfs
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
RUN mkdir /build
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_i386.tar.gz --directory=/tmp usr sbin
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,14 @@
ARG BUILD_TIMESTAMP=0
FROM --platform=linux/amd64 ubuntu:latest as build
COPY install-build-pkgs /tmp/
RUN /tmp/install-build-pkgs && \
DEBIAN_FRONTEND=noninteractive apt-get -qy --no-install-suggests --no-install-recommends install \
makeself
RUN mkdir -p /tmp/mergerfs/
RUN ls -lhd /pkgs
RUN cp -v /pkgs/*static*.gz /tmp/mergerfs/
RUN mkdir -p /build
RUN makeself /tmp/mergerfs/ /build/mergerfs-installer.run "mergerfs" echo "foo"
FROM scratch
COPY --from=build /build/ /
+15
View File
@@ -0,0 +1,15 @@
FROM --platform=linux/riscv64 alpine:latest as build
COPY install-build-pkgs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN git clone --single-branch --branch="${BRANCH}" ${GIT_REPO} /tmp/mergerfs
WORKDIR /tmp/mergerfs
RUN make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp -j$(nproc) install
RUN mkdir /build
RUN /tmp/usr/local/bin/mergerfs --version | head -n1 | cut -c 11- | tee /tmp/version
RUN tar cvfz /build/mergerfs-$(cat /tmp/version)-static-linux_riscv64.tar.gz --directory=/tmp usr sbin
FROM scratch
COPY --from=build /build/ /
+17
View File
@@ -0,0 +1,17 @@
FROM alpine:latest as tarball
COPY install-build-pkgs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG BRANCH=master
ARG GIT_REPO
RUN git clone --single-branch "${GIT_REPO}" /tmp/mergerfs --branch="${BRANCH}"
RUN cd /tmp/mergerfs && make version tarball
RUN mkdir /build
RUN cp -v /tmp/mergerfs/*.tar.gz /build/
FROM scratch
COPY --from=tarball /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 ubuntu:22.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 ubuntu:22.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=armhf ubuntu:22.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=riscv64 ubuntu:22.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 ubuntu:24.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 ubuntu:24.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=armhf ubuntu:24.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=riscv64 ubuntu:24.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 ubuntu:25.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 ubuntu:25.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=armhf ubuntu:25.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=riscv64 ubuntu:25.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 ubuntu:25.10 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 ubuntu:25.10 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=armhf ubuntu:25.10 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=riscv64 ubuntu:25.10 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=amd64 ubuntu:26.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=arm64 ubuntu:26.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=armhf ubuntu:26.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
@@ -0,0 +1,10 @@
FROM --platform=riscv64 ubuntu:26.04 as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs $GIT_REPO $BRANCH
FROM scratch
COPY --from=build /build/ /
+19
View File
@@ -0,0 +1,19 @@
FROM --platform=linux/amd64 alpine:latest as build
ARG GIT_REPO
ARG BRANCH
RUN <<EOF
apk add git gcc g++ make linux-headers
git clone --single-branch --branch="${BRANCH}" "${GIT_REPO}" /tmp/mergerfs
cd /tmp/mergerfs
make NDEBUG=1 LTO=1 STATIC=1 DESTDIR=/tmp/install -j$(nproc) install
tar cvfz /tmp/mergerfs.tgz --directory=/tmp/install usr sbin
EOF
FROM --platform=linux/amd64 alpine:latest
RUN --mount=from=build,source=/tmp/mergerfs.tgz,target=/tmp/mergerfs.tgz <<EOF
tar xvf /tmp/mergerfs.tgz -C /
EOF
ENTRYPOINT ["/usr/local/bin/mergerfs"]
CMD ["--help"]
+14
View File
@@ -0,0 +1,14 @@
#!/bin/sh
set -x
BASEPATH="/tmp"
for x in $(seq -w 2)
do
FILEPATH="${BASEPATH}/mergerfs-${x}.img"
MOUNTPOINT="${BASEPATH}/mergerfs-${x}"
truncate -s 1G "${FILEPATH}"
mkdir -p "${MOUNTPOINT}"
mkfs.ext4 -m0 -L "mergerfs${x}" "${FILEPATH}"
sudo mount "${FILEPATH}" "${MOUNTPOINT}"
done
+119
View File
@@ -0,0 +1,119 @@
#!/bin/bash
# Detects local OS and maps to containerfiles target
# Returns target if found in buildtools/containerfiles/, empty string otherwise
set -euo pipefail
CONTAINERFILES_DIR="buildtools/containerfiles"
# Detect system architecture and map to containerfiles format
detect_arch() {
local arch
arch=$(uname -m)
case "$arch" in
x86_64) echo "amd64" ;;
aarch64) echo "arm64" ;;
armv7l) echo "armhf" ;;
i686|i386) echo "i386" ;;
riscv64) echo "riscv64" ;;
*) echo "" ;;
esac
}
# Detect distro and version from os-release
detect_distro() {
local os_release="${1:-}"
if [[ ! -r "$os_release" ]]; then
return 1
fi
# Source the file safely - ID and VERSION_ID are environment variables
. "$os_release"
local distro="$ID"
local version="$VERSION_ID"
# Map distro ID to containerfiles naming convention
case "$distro" in
ubuntu|debian|fedora) ;;
rocky|rhel|centos|almalinux) distro="rockylinux" ;;
*)
# Fallback to ID_LIKE for derivatives
if [[ -n "${ID_LIKE:-}" ]]; then
case "$ID_LIKE" in
*ubuntu*) distro="ubuntu" ;;
*debian*) distro="debian" ;;
*fedora*) distro="fedora" ;;
esac
fi
;;
esac
# Only return if we have valid distro and version
if [[ -n "$distro" && -n "$version" ]]; then
echo "$distro:$version"
else
return 1
fi
}
# Try to find a matching containerfile target
find_containerfile() {
local target="$1"
local containerfile="${CONTAINERFILES_DIR}/${target}"
# Direct match
if [[ -d "$containerfile" || -f "$containerfile" ]]; then
echo "$target"
return 0
fi
return 1
}
# Main detection logic
main() {
local arch
# Detect architecture
arch=$(detect_arch)
if [[ -z "$arch" ]]; then
echo "WARNING: Could not detect system architecture" >&2
exit 1
fi
# Try to detect distro from multiple locations
local distro_ver
distro_ver=$(detect_distro "/etc/os-release") || \
distro_ver=$(detect_distro "/usr/lib/os-release") || {
echo "WARNING: Could not detect distro from os-release" >&2
exit 1
}
# Build target string
local target="${distro_ver}.${arch}"
# Try to find matching containerfile
if find_containerfile "$target"; then
exit 0
fi
# Try with partial version matching (e.g., 25.10 → 25)
local distro="${distro_ver%%:*}"
local version="${distro_ver##*:}"
# Strip last minor version number and try again
local short_version="${version%.*}"
if [[ -n "$short_version" ]]; then
target="${distro}:${short_version}.${arch}"
if find_containerfile "$target"; then
exit 0
fi
fi
# No match found
echo "WARNING: No containerfile found for target: ${distro_ver}.${arch}" >&2
exit 1
}
main "$@"
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
input_file="${1}"
while IFS= read -r line || [ -n "$line" ]; do
# Skip empty lines
if [ -z "$line" ]; then
continue
fi
image=$(echo "$line" | cut -d' ' -f1)
platform=$(echo "$line" | cut -d' ' -f2-)
echo "${image} ${platform}"
cat <<EOF > "containerfiles/${image##*/}.${platform}"
FROM --platform=${platform} ${image} as build
COPY install-build-pkgs build-mergerfs /tmp/
RUN /tmp/install-build-pkgs
ARG BUILD_TIMESTAMP=0
ARG GIT_REPO
ARG BRANCH
RUN /tmp/build-mergerfs \$GIT_REPO \$BRANCH
FROM scratch
COPY --from=build /build/ /
EOF
done < "$input_file"
+202
View File
@@ -0,0 +1,202 @@
#!/bin/sh
# Copyright (c) 2016, Antonio SJ Musumeci <trapexit@spawn.link>
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
# Default values
NAME=""
VERSION="::guess::"
DISTRO="::guess::"
CODENAME="::guess::"
URGENCY="medium"
# Function to display usage
usage() {
cat << EOF
Usage: $0 --name NAME [OPTIONS]
Generated debian/changelog from git log
Options:
--name NAME Name of package (required)
--version VERSION Place in git history to include upto (default: ::guess::)
--distro DISTRO Distribution name (default: ::guess::)
--codename NAME Distribution codename (default: ::guess::)
--urgency URGENCY Urgency (default: medium)
-h, --help Show this help message
EOF
exit 1
}
# Parse command line arguments
while [ $# -gt 0 ]; do
case "$1" in
--name)
NAME="$2"
shift 2
;;
--version)
VERSION="$2"
shift 2
;;
--distro)
DISTRO="$2"
shift 2
;;
--codename)
CODENAME="$2"
shift 2
;;
--urgency)
URGENCY="$2"
shift 2
;;
-h|--help)
usage
;;
*)
echo "Unknown option: $1" >&2
usage
;;
esac
done
# Check required arguments
if [ -z "$NAME" ]; then
echo "Error: --name is required" >&2
usage
fi
# Function to get git tags sorted in reverse order
git_tags() {
git tag -l | sort -rV
}
# Function to get git log between two tags
git_log() {
local fromtag="$1"
local totag="$2"
git log --no-merges --oneline "${fromtag}...${totag}" 2>/dev/null
}
# Function to get author and time for a tag
git_author_and_time() {
local tag="$1"
git log -1 --format="-- %an <%ae> %cD" "$tag"
}
# Function to get git version
git_version() {
git describe --always --tags --dirty 2>/dev/null || echo "unknown"
}
# Function to guess distribution
guess_distro() {
if command -v lsb_release >/dev/null 2>&1; then
lsb_release -i -s 2>/dev/null | tr '[:upper:]' '[:lower:]'
else
echo "unknown"
fi
}
# Function to guess codename
guess_codename() {
if command -v lsb_release >/dev/null 2>&1; then
lsb_release -c -s 2>/dev/null | tr '[:upper:]' '[:lower:]'
else
echo "unknown"
fi
}
# Handle guessing of values
if [ "$DISTRO" = "::guess::" ]; then
DISTRO=$(guess_distro)
fi
if [ "$CODENAME" = "::guess::" ]; then
CODENAME=$(guess_codename)
fi
if [ "$VERSION" = "::guess::" ]; then
VERSION=$(git_version)
fi
# Version suffix
VERSUFFIX="~${DISTRO}-${CODENAME}"
# Get all tags
TAGS=$(git_tags)
# Create temporary file for tag pairs
TMPFILE=$(mktemp)
trap 'rm -f "$TMPFILE"' EXIT
# Check if version is in tags
if echo "$TAGS" | grep -q "^${VERSION}$"; then
# If version is a tag, start from that tag
echo "$TAGS" | awk -v ver="$VERSION" 'BEGIN{found=0} {if($0==ver)found=1; if(found)print}' > "$TMPFILE"
else
# If version is not a tag, use HEAD as starting point
echo "$VERSION HEAD" > "$TMPFILE"
echo "$TAGS" >> "$TMPFILE"
fi
# Process tags and generate changelog
PREV_TAG=""
PREV_REF=""
FIRST=1
while IFS= read -r line; do
if [ -z "$line" ]; then
continue
fi
# Handle the special case of VERSION HEAD
if [ "$line" = "$VERSION HEAD" ]; then
TAG="$VERSION"
REF="HEAD"
else
TAG="$line"
REF="$line"
fi
if [ -n "$PREV_TAG" ]; then
# Get log entries between current and previous tag
LOG_ENTRIES=$(git_log "$REF" "$PREV_REF")
# Skip if no changes
if [ -z "$LOG_ENTRIES" ] || [ "$LOG_ENTRIES" = "" ]; then
PREV_TAG="$TAG"
PREV_REF="$REF"
continue
fi
# Print package header
printf "%s (%s%s) %s; urgency=%s\n\n" "$NAME" "$PREV_TAG" "$VERSUFFIX" "$CODENAME" "$URGENCY"
# Print each log entry
echo "$LOG_ENTRIES" | while IFS= read -r entry; do
if [ -n "$entry" ]; then
printf " * %s\n" "$entry"
fi
done
# Print author and time
AUTHOR_TIME=$(git_author_and_time "$PREV_REF")
printf "\n %s\n\n" "$AUTHOR_TIME"
fi
PREV_TAG="$TAG"
PREV_REF="$REF"
done < "$TMPFILE"
+162
View File
@@ -0,0 +1,162 @@
#!/bin/sh
set -e
BUILD_ENV=/tmp/build-env
write_gcc_env()
{
{
printf 'export CC=%s\n' "$1"
printf 'export CXX=%s\n' "$2"
} > "$BUILD_ENV"
}
write_toolset_env()
{
{
printf '. %s\n' "$1"
printf 'export CC=gcc\n'
printf 'export CXX=g++\n'
} > "$BUILD_ENV"
}
latest_apt_gxx()
{
apt-cache --names-only search '^g[+][+]-[0-9]' \
| sed -n 's/^\(g++-[0-9][0-9]*\) .*/\1/p' \
| sort -t- -k2,2V \
| tail -n 1
}
latest_dnf_toolset()
{
dnf -q list --showduplicates 'gcc-toolset-*-gcc-c++' 2>/dev/null \
| sed -n 's/^gcc-toolset-\([0-9][0-9]*\)-gcc-c++\..*/\1/p' \
| sort -V \
| tail -n 1
}
latest_yum_toolset()
{
yum -q list available 'devtoolset-*-gcc-c++' 2>/dev/null \
| sed -n 's/^devtoolset-\([0-9][0-9]*\)-gcc-c++\..*/\1/p' \
| sort -V \
| tail -n 1
}
version_gt()
{
highest="$(printf '%s\n%s\n' "$1" "$2" | sort -V | tail -n 1)"
[ "$highest" = "$1" ] && [ "$1" != "$2" ]
}
check_cxx20()
{
cxx="${CXX:-g++}"
test_src=/tmp/mergerfs-cxx20-check.cpp
test_bin=/tmp/mergerfs-cxx20-check
cat > "$test_src" <<'EOF'
template <typename T>
concept Incrementable = requires(T value) { value + 1; };
static_assert(Incrementable<int>);
int main()
{
return 0;
}
EOF
if ! "$cxx" -std=c++20 "$test_src" -o "$test_bin" >/dev/null 2>&1; then
echo "error: $cxx does not support C++20" >&2
exit 1
fi
rm -f "$test_src" "$test_bin"
}
: > "$BUILD_ENV"
if [ -e /usr/bin/apt-get ]; then
export DEBIAN_FRONTEND=noninteractive
apt-get -qy update
cxx_pkg="$(latest_apt_gxx)"
if [ -n "$cxx_pkg" ]; then
gcc_pkg="gcc-${cxx_pkg#g++-}"
compiler_pkgs="$gcc_pkg $cxx_pkg"
write_gcc_env "$gcc_pkg" "$cxx_pkg"
else
compiler_pkgs="g++"
write_gcc_env gcc g++
fi
apt-get -qy --force-yes --no-install-suggests --no-install-recommends \
install \
ca-certificates \
build-essential \
dpkg-dev \
git \
$compiler_pkgs \
debhelper \
lsb-release \
fakeroot
. "$BUILD_ENV"
check_cxx20
elif [ -e /usr/bin/dnf ]; then
dnf -y update
toolset="$(latest_dnf_toolset)"
dnf -y install \
git rpm-build gcc-c++ make which libatomic
default_gxx_major="$(g++ -dumpversion | cut -f1 -d.)"
if [ -n "$toolset" ] && version_gt "$toolset" "$default_gxx_major"; then
dnf -y install \
"gcc-toolset-${toolset}-gcc" \
"gcc-toolset-${toolset}-gcc-c++"
write_toolset_env "/opt/rh/gcc-toolset-${toolset}/enable"
else
write_gcc_env gcc g++
fi
. "$BUILD_ENV"
check_cxx20
elif [ -e /usr/bin/yum ]; then
yum -y update
yum -y install \
git rpm-build gcc-c++ make which
yum -y install centos-release-scl || true
yum -y update
toolset="$(latest_yum_toolset)"
default_gxx_major="$(g++ -dumpversion | cut -f1 -d.)"
if [ -n "$toolset" ] && version_gt "$toolset" "$default_gxx_major"; then
yum -y install \
"devtoolset-${toolset}-gcc" \
"devtoolset-${toolset}-gcc-c++"
write_toolset_env "/opt/rh/devtoolset-${toolset}/enable"
else
write_gcc_env gcc g++
fi
. "$BUILD_ENV"
check_cxx20
elif [ -e /usr/bin/zypper ]; then
zypper update -y
zypper install -y \
git rpm-build gcc-c++ make which
write_gcc_env gcc g++
. "$BUILD_ENV"
check_cxx20
elif [ -e /sbin/apk ]; then
apk add \
abuild git gcc g++ make \
linux-headers
write_gcc_env gcc g++
. "$BUILD_ENV"
check_cxx20
elif [ -e /usr/sbin/pkg ]; then
pkg install \
git gmake gcc
elif [ -e /usr/bin/pacman ]; then
pacman -Sy --noconfirm base-devel git fakeroot
write_gcc_env gcc g++
. "$BUILD_ENV"
check_cxx20
fi
+32
View File
@@ -0,0 +1,32 @@
#!/bin/sh
if [ "$(id -u)" -eq 0 ]; then
SUDO=
elif command -v sudo >/dev/null 2>&1; then
SUDO=sudo
elif command -v doas >/dev/null 2>&1; then
SUDO=doas
else
printf '%s\n' "error: need root privileges; run as root or install sudo/doas" >&2
exit 1
fi
if [ -e /usr/bin/apt-get ]; then
export DEBIAN_FRONTEND=noninteractive
${SUDO} apt-get -qy update
${SUDO} apt-get -qy --no-install-suggests --no-install-recommends install \
qemu-user-static \
podman
elif [ -e /usr/bin/dnf ]; then
${SUDO} dnf -y update
${SUDO} dnf -y install \
qemu-user-static \
podman
elif [ -e /sbin/apk ]; then
${SUDO} apk add \
python3 \
qemu-user-static \
podman
elif [ -e /usr/bin/pacman ]; then
${SUDO} pacman -Sy --noconfirm qemu-user-static podman
fi
+39
View File
@@ -0,0 +1,39 @@
debian:11 amd64
debian:11 arm64
debian:11 armhf
debian:11 i386
debian:12 amd64
debian:12 arm64
debian:12 armhf
debian:12 i386
debian:13 amd64
debian:13 arm64
debian:13 armhf
debian:13 i386
debian:13 riscv64
fedora:40 amd64
fedora:40 arm64
fedora:41 amd64
fedora:41 arm64
fedora:42 amd64
fedora:42 arm64
fedora:43 amd64
fedora:43 arm64
quay.io/rockylinux/rockylinux:10 amd64
quay.io/rockylinux/rockylinux:10 arm64
quay.io/rockylinux/rockylinux:8 amd64
quay.io/rockylinux/rockylinux:8 arm64
quay.io/rockylinux/rockylinux:9 amd64
quay.io/rockylinux/rockylinux:9 arm64
ubuntu:22.04 amd64
ubuntu:22.04 arm64
ubuntu:22.04 armhf
ubuntu:22.04 riscv64
ubuntu:24.04 amd64
ubuntu:24.04 arm64
ubuntu:24.04 armhf
ubuntu:24.04 riscv64
ubuntu:25.04 amd64
ubuntu:25.04 arm64
ubuntu:25.04 armhf
ubuntu:25.04 riscv64
@@ -9,10 +9,12 @@ if [ "${VERSION}" = "" ]; then
VERSION="unknown"
fi
echo "version = ${VERSION}"
echo -n "${VERSION}" > VERSION
grep -q \"${VERSION}\" src/version.hpp
grep -sq \"${VERSION}\" src/version.hpp
RV=$?
if [ $RV -ne 0 ]; then
echo "Writing 'src/version.hpp'"
echo "#pragma once" > src/version.hpp
echo "static const char MERGERFS_VERSION[] = \"${VERSION}\";" >> src/version.hpp
fi
-1
View File
@@ -1 +0,0 @@
9
+1 -1
View File
@@ -2,7 +2,7 @@ Source: mergerfs
Section: utils
Priority: optional
Maintainer: Antonio SJ Musumeci <trapexit@spawn.link>
Build-Depends: debhelper (>= 8.0.0)
Build-Depends: debhelper-compat (= 10)
Standards-Version: 3.9.4
Homepage: http://github.com/trapexit/mergerfs
+8 -3
View File
@@ -1,11 +1,16 @@
#!/usr/bin/make -f
# -*- makefile -*-
# Uncomment this to turn on verbose mode.
export DH_VERBOSE=1
%:
dh $@ --parallel
dh $@
override_dh_auto_build:
$(MAKE) release
override_dh_auto_install:
$(MAKE) DESTDIR=$(CURDIR)/debian/mergerfs PREFIX=/usr install
$(MAKE) \
DESTDIR=$(CURDIR)/debian/mergerfs \
PREFIX=/usr \
install
-3547
View File
File diff suppressed because it is too large Load Diff
-119
View File
@@ -1,119 +0,0 @@
VERSION = 2.9.7-mergerfs_2.30.0
OS := $(shell uname -s)
ifeq ($(OS),Linux)
UTILS := utils
INSTALLUTILS := install-utils
else
UTILS :=
INSTALLUTILS :=
endif
ifeq ($(DEBUG),1)
OPT_FLAGS := -O0 -g
else
OPT_FLAGS := -O2
endif
DESTDIR =
PREFIX = /usr/local
EXEC_PREFIX = $(PREFIX)
DATAROOTDIR = $(PREFIX)/share
DATADIR = $(DATAROOTDIR)
BINDIR = $(EXEC_PREFIX)/bin
SBINDIR = /sbin
MANDIR = $(DATAROOTDIR)/man
MAN1DIR = $(MANDIR)/man1
INSTALLBINDIR = $(DESTDIR)$(BINDIR)
INSTALLSBINDIR = $(DESTDIR)$(SBINDIR)
INSTALLMAN1DIR = $(DESTDIR)$(MAN1DIR)
AR ?= ar
SRC = \
lib/buffer.c \
lib/fuse_dirents.c \
lib/fuse.c \
lib/fuse_kern_chan.c \
lib/fuse_loop_mt.c \
lib/fuse_lowlevel.c \
lib/fuse_mt.c \
lib/fuse_opt.c \
lib/fuse_session.c \
lib/fuse_signals.c \
lib/helper.c \
lib/mount.c
OBJS = $(SRC:lib/%.c=build/%.o)
DEPS = $(SRC:lib/%.c=build/%.d)
CFLAGS ?= \
$(OPT_FLAGS)
CFLAGS := \
${CFLAGS} \
-Wall \
-pipe \
-MMD
FUSERMOUNT_DIR = $(BINDIR)
FUSE_FLAGS = \
-Iinclude \
-Ibuild \
-D_REENTRANT \
-D_FILE_OFFSET_BITS=64 \
-DFUSE_USE_VERSION=29 \
-DPACKAGE_VERSION=\"$(VERSION)\" \
-DFUSERMOUNT_DIR=\"$(FUSERMOUNT_DIR)\"
LDFLAGS := \
${LDFLAGS} \
-lrt \
-pthread
all: build/libfuse.a $(UTILS)
build/config.h: build/stamp
ecfd/build | tee build/config.h
build/stamp:
mkdir -p build
touch $@
objects: build/config.h
$(MAKE) $(OBJS)
build/libfuse.a: objects
${AR} rcs build/libfuse.a $(OBJS)
utils: mergerfs-fusermount mount.mergerfs
build/mergerfs-fusermount: build/config.h util/fusermount.c lib/mount_util.c
$(CC) $(CFLAGS) $(FUSE_FLAGS) -Ilib -o build/mergerfs-fusermount util/fusermount.c lib/mount_util.c
mergerfs-fusermount: build/mergerfs-fusermount
build/mount.mergerfs: build/libfuse.a util/mount.mergerfs.c
$(CC) $(CFLAGS) $(FUSE_FLAGS) -o build/mount.mergerfs util/mount.mergerfs.c build/libfuse.a $(LDFLAGS)
mount.mergerfs: build/mount.mergerfs
build/%.o: lib/%.c
$(CC) $(CFLAGS) $(FUSE_FLAGS) -c $< -o $@
clean:
rm -rf build
distclean: clean
strip:
strip --strip-all build/mount.mergerfs
strip --strip-all build/mergerfs-fusermount
install-utils: mergerfs-fusermount mount.mergerfs strip
install -D build/mergerfs-fusermount "$(INSTALLBINDIR)/mergerfs-fusermount"
install -D build/mount.mergerfs "$(INSTALLSBINDIR)/mount.mergerfs"
chown root "$(INSTALLBINDIR)/mergerfs-fusermount"
chmod u+s "$(INSTALLBINDIR)/mergerfs-fusermount"
install: $(INSTALLUTILS)
.PHONY: objects strip utils install install-utils
-include $(DEPS)
-16
View File
@@ -1,16 +0,0 @@
# ecfd: embeddable C feature discovery
This is a simple script and set of tests to help with what would traditionally be the `configure` step of most C/C++. It is intended to be simple to be embedded into a project and only depends on the C compiler and /bin/sh.
## USAGE
First copy `ecfd` into your project. Next simply call the build script which will run the tests and output a `config.` style file to `stdout`. Compile errors will output to `stderr` which can be used to understand why they aren't working.
```
$ ./ecfd/build > include/config.h
```
## TESTS
Each test is in a single module. The build script will try to compile each module and on success will execute the program. If anything is printed to `stdout` it will be appended to the `#define` printed to the build script's `stdout`. If the compilation fails nothing will be printed. Look at the tests directory for examples.
-32
View File
@@ -1,32 +0,0 @@
#!/bin/sh
PWD=$(pwd)
BASEPATH="${PWD}/${0%/*}"
CC=${CC:-cc}
OUTPUT="/dev/null"
echo "#ifndef CONFIG_H_INCLUDED"
echo "#define CONFIG_H_INCLUDED"
echo
IFS=
for file in "${BASEPATH}/tests/"*.c
do
binary="${file%.c}"
basename=$(basename ${binary})
${CC} -o "${binary}" "${file}" 1>&2
if [ $? -eq 0 ]; then
STDOUT=$(${binary})
if [ "${STDOUT}" != "" ]; then
echo "#define ${basename} ${STDOUT}"
else
echo "#define ${basename}"
fi
rm -f "${binary}"
fi
done
echo
echo "#endif"
-10
View File
@@ -1,10 +0,0 @@
#include <sys/types.h>
#include <unistd.h>
int
main(void)
{
(void)fork;
return 0;
}
-11
View File
@@ -1,11 +0,0 @@
#define _GNU_SOURCE
#include <fcntl.h>
int
main(int argc,
char *argv[])
{
(void)splice;
return 0;
}
@@ -1,14 +0,0 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int
main(int argc,
char *argv[])
{
struct stat st;
(void)st.st_atim;
return 0;
}
-11
View File
@@ -1,11 +0,0 @@
#include <fcntl.h>
#include <sys/stat.h>
int
main(int argc,
char *argv[])
{
(void)utimensat;
return 0;
}
-12
View File
@@ -1,12 +0,0 @@
#define _GNU_SOURCE
#include <fcntl.h>
#include <sys/uio.h>
int
main(int argc,
char *argv[])
{
(void)vmsplice;
return 0;
}
-4
View File
@@ -1,4 +0,0 @@
#pragma once
#define STATIC_ASSERT(condition) \
((void)sizeof(char[1 - 2*!(condition)]))
-932
View File
@@ -1,932 +0,0 @@
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB.
*/
#ifndef _FUSE_H_
#define _FUSE_H_
/** @file
*
* This file defines the library interface of FUSE
*
* IMPORTANT: you should define FUSE_USE_VERSION before including this
* header. To use the newest API define it to 26 (recommended for any
* new application), to use the old API define it to 21 (default) 22
* or 25, to use the even older 1.X API define it to 11.
*/
#ifndef FUSE_USE_VERSION
#define FUSE_USE_VERSION 21
#endif
#include "extern_c.h"
#include "fuse_common.h"
#include "fuse_dirents.h"
#include <fcntl.h>
#include <time.h>
#include <utime.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <sys/uio.h>
EXTERN_C_BEGIN
/* ----------------------------------------------------------- *
* Basic FUSE API *
* ----------------------------------------------------------- */
/** Handle for a FUSE filesystem */
struct fuse;
/** Structure containing a raw command */
struct fuse_cmd;
/**
* The file system operations:
*
* Most of these should work very similarly to the well known UNIX
* file system operations. A major exception is that instead of
* returning an error in 'errno', the operation should return the
* negated error value (-errno) directly.
*
* All methods are optional, but some are essential for a useful
* filesystem (e.g. getattr). Open, flush, release, fsync, opendir,
* releasedir, fsyncdir, access, create, ftruncate, fgetattr, lock,
* init and destroy are special purpose methods, without which a full
* featured filesystem can still be implemented.
*
* Almost all operations take a path which can be of any length.
*
* Changed in fuse 2.8.0 (regardless of API version)
* Previously, paths were limited to a length of PATH_MAX.
*
* See http://fuse.sourceforge.net/wiki/ for more information. There
* is also a snapshot of the relevant wiki pages in the doc/ folder.
*/
struct fuse_operations
{
/** Get file attributes.
*
* Similar to stat(). The 'st_dev' and 'st_blksize' fields are
* ignored. The 'st_ino' field is ignored except if the 'use_ino'
* mount option is given.
*/
int (*getattr) (const char *, struct stat *, fuse_timeouts_t *);
/** Read the target of a symbolic link
*
* The buffer should be filled with a null terminated string. The
* buffer size argument includes the space for the terminating
* null character. If the linkname is too long to fit in the
* buffer, it should be truncated. The return value should be 0
* for success.
*/
int (*readlink) (const char *, char *, size_t);
/** Create a file node
*
* This is called for creation of all non-directory, non-symlink
* nodes. If the filesystem defines a create() method, then for
* regular files that will be called instead.
*/
int (*mknod) (const char *, mode_t, dev_t);
/** Create a directory
*
* Note that the mode argument may not have the type specification
* bits set, i.e. S_ISDIR(mode) can be false. To obtain the
* correct directory type bits use mode|S_IFDIR
* */
int (*mkdir) (const char *, mode_t);
/** Hide files unlinked / renamed over
*
* Allows storing of a file handle when a file is unlinked
* while open. Helps manage the fact the kernel usually does
* not send fh with getattr requests.
*/
int (*prepare_hide)(const char *name_, uint64_t *fh_);
int (*free_hide)(const uint64_t fh_);
/** Remove a file */
int (*unlink) (const char *);
/** Remove a directory */
int (*rmdir) (const char *);
/** Create a symbolic link */
int (*symlink) (const char *, const char *);
/** Rename a file */
int (*rename) (const char *, const char *);
/** Create a hard link to a file */
int (*link) (const char *, const char *);
/** Change the permission bits of a file */
int (*chmod) (const char *, 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 fuse_file_info_t *, const uid_t, const gid_t);
/** Change the size of a file */
int (*truncate) (const char *, off_t);
/** Change the access and/or modification times of a file
*
* Deprecated, use utimens() instead.
*/
int (*utime) (const char *, struct utimbuf *);
/** File open operation
*
* No creation (O_CREAT, O_EXCL) and by default also no
* truncation (O_TRUNC) flags will be passed to open(). If an
* application specifies O_TRUNC, fuse first calls truncate()
* and then open(). Only if 'atomic_o_trunc' has been
* specified and kernel version is 2.6.24 or later, O_TRUNC is
* passed on to open.
*
* Unless the 'default_permissions' mount option is given,
* open should check if the operation is permitted for the
* given flags. Optionally open may also return an arbitrary
* filehandle in the fuse_file_info structure, which will be
* passed to all file operations.
*
* Changed in version 2.2
*/
int (*open) (const char *, fuse_file_info_t *);
/** Read data from an open file
*
* Read should return exactly the number of bytes requested except
* on EOF or error, otherwise the rest of the data will be
* substituted with zeroes. An exception to this is when the
* 'direct_io' mount option is specified, in which case the return
* value of the read system call will reflect the return value of
* this operation.
*
* Changed in version 2.2
*/
int (*read) (const fuse_file_info_t *,
char *,
size_t,
off_t);
/** Write data to an open file
*
* Write should return exactly the number of bytes requested
* except on error. An exception to this is when the 'direct_io'
* mount option is specified (see read operation).
*
* Changed in version 2.2
*/
int (*write) (const fuse_file_info_t *,
const char *,
size_t,
off_t);
/** Get file system statistics
*
* The 'f_frsize', 'f_favail', 'f_fsid' and 'f_flag' fields are ignored
*
* Replaced 'struct statfs' parameter with 'struct statvfs' in
* version 2.5
*/
int (*statfs) (const char *, struct statvfs *);
/** Possibly flush cached data
*
* BIG NOTE: This is not equivalent to fsync(). It's not a
* request to sync dirty data.
*
* Flush is called on each close() of a file descriptor. So if a
* filesystem wants to return write errors in close() and the file
* has cached dirty data, this is a good place to write back data
* and return any errors. Since many applications ignore close()
* errors this is not always useful.
*
* NOTE: The flush() method may be called more than once for each
* open(). This happens if more than one file descriptor refers
* to an opened file due to dup(), dup2() or fork() calls. It is
* not possible to determine if a flush is final, so each flush
* should be treated equally. Multiple write-flush sequences are
* relatively rare, so this shouldn't be a problem.
*
* Filesystems shouldn't assume that flush will always be called
* after some writes, or that if will be called at all.
*
* Changed in version 2.2
*/
int (*flush) (const fuse_file_info_t *);
/** Release an open file
*
* Release is called when there are no more references to an open
* file: all file descriptors are closed and all memory mappings
* are unmapped.
*
* For every open() call there will be exactly one release() call
* with the same flags and file descriptor. It is possible to
* have a file opened more than once, in which case only the last
* release will mean, that no more reads/writes will happen on the
* file. The return value of release is ignored.
*
* Changed in version 2.2
*/
int (*release) (const fuse_file_info_t *);
/** Synchronize file contents
*
* If the datasync parameter is non-zero, then only the user data
* should be flushed, not the meta data.
*
* Changed in version 2.2
*/
int (*fsync) (const fuse_file_info_t *, int);
/** Set extended attributes */
int (*setxattr) (const char *, const char *, const char *, size_t, int);
/** Get extended attributes */
int (*getxattr) (const char *, const char *, char *, size_t);
/** List extended attributes */
int (*listxattr) (const char *, char *, size_t);
/** Remove extended attributes */
int (*removexattr) (const char *, const char *);
/** Open directory
*
* Unless the 'default_permissions' mount option is given,
* this method should check if opendir is permitted for this
* directory. Optionally opendir may also return an arbitrary
* filehandle in the fuse_file_info structure, which will be
* passed to readdir, closedir and fsyncdir.
*
* Introduced in version 2.3
*/
int (*opendir) (const char *,
fuse_file_info_t *);
/** Read directory
*
* This supersedes the old getdir() interface. New applications
* should use this.
*
* The filesystem may choose between two modes of operation:
*
* 1) The readdir implementation ignores the offset parameter, and
* passes zero to the filler function's offset. The filler
* function will not return '1' (unless an error happens), so the
* whole directory is read in a single readdir operation. This
* works just like the old getdir() method.
*
* 2) The readdir implementation keeps track of the offsets of the
* directory entries. It uses the offset parameter and always
* passes non-zero offset to the filler function. When the buffer
* is full (or an error happens) the filler function will return
* '1'.
*
* Introduced in version 2.3
*/
int (*readdir)(const fuse_file_info_t *,
fuse_dirents_t *);
int (*readdir_plus)(const fuse_file_info_t *,
fuse_dirents_t *);
/** Release directory
*
* Introduced in version 2.3
*/
int (*releasedir) (const fuse_file_info_t *);
/** Synchronize directory contents
*
* If the datasync parameter is non-zero, then only the user data
* should be flushed, not the meta data
*
* Introduced in version 2.3
*/
int (*fsyncdir) (const fuse_file_info_t *, int);
/**
* Initialize filesystem
*
* The return value will passed in the private_data field of
* fuse_context to all file operations and as a parameter to the
* destroy() method.
*
* Introduced in version 2.3
* Changed in version 2.6
*/
void *(*init) (struct fuse_conn_info *conn);
/**
* Clean up filesystem
*
* Called on filesystem exit.
*
* Introduced in version 2.3
*/
void (*destroy) (void *);
/**
* Check file access permissions
*
* This will be called for the access() system call. If the
* 'default_permissions' mount option is given, this method is not
* called.
*
* This method is not called under Linux kernel versions 2.4.x
*
* Introduced in version 2.5
*/
int (*access) (const char *, int);
/**
* Create and open a file
*
* If the file does not exist, first create it with the specified
* mode, and then open it.
*
* If this method is not implemented or under Linux kernel
* versions earlier than 2.6.15, the mknod() and open() methods
* will be called instead.
*
* Introduced in version 2.5
*/
int (*create) (const char *, mode_t, fuse_file_info_t *);
/**
* Change the size of an open file
*
* This method is called instead of the truncate() method if the
* truncation was invoked from an ftruncate() system call.
*
* If this method is not implemented or under Linux kernel
* versions earlier than 2.6.15, the truncate() method will be
* called instead.
*
* Introduced in version 2.5
*/
int (*ftruncate) (const fuse_file_info_t *, off_t);
/**
* Get attributes from an open file
*
* This method is called instead of the getattr() method if the
* file information is available.
*
* Currently this is only called after the create() method if that
* is implemented (see above). Later it may be called for
* invocations of fstat() too.
*
* Introduced in version 2.5
*/
int (*fgetattr) (const fuse_file_info_t *, struct stat *, fuse_timeouts_t *);
/**
* Perform POSIX file locking operation
*
* The cmd argument will be either F_GETLK, F_SETLK or F_SETLKW.
*
* For the meaning of fields in 'struct flock' see the man page
* for fcntl(2). The l_whence field will always be set to
* SEEK_SET.
*
* For checking lock ownership, the 'fuse_file_info->owner'
* argument must be used.
*
* For F_GETLK operation, the library will first check currently
* held locks, and if a conflicting lock is found it will return
* information without calling this method. This ensures, that
* for local locks the l_pid field is correctly filled in. The
* results may not be accurate in case of race conditions and in
* the presence of hard links, but it's unlikely that an
* application would rely on accurate GETLK results in these
* cases. If a conflicting lock is not found, this method will be
* called, and the filesystem may fill out l_pid by a meaningful
* value, or it may leave this field zero.
*
* For F_SETLK and F_SETLKW the l_pid field will be set to the pid
* of the process performing the locking operation.
*
* Note: if this method is not implemented, the kernel will still
* allow file locking to work locally. Hence it is only
* interesting for network filesystems and similar.
*
* Introduced in version 2.6
*/
int (*lock) (const fuse_file_info_t *,
int cmd,
struct flock *);
/**
* Change the access and modification times of a file with
* nanosecond resolution
*
* This supersedes the old utime() interface. New applications
* should use this.
*
* See the utimensat(2) man page for details.
*
* Introduced in version 2.6
*/
int (*utimens)(const char *, 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
*
* Note: This makes sense only for block device backed filesystems
* mounted with the 'blkdev' option
*
* Introduced in version 2.6
*/
int (*bmap) (const char *, size_t blocksize, uint64_t *idx);
/**
* Ioctl
*
* flags will have FUSE_IOCTL_COMPAT set for 32bit ioctls in
* 64bit environment. The size and direction of data is
* determined by _IOC_*() decoding of cmd. For _IOC_NONE,
* data will be NULL, for _IOC_WRITE data is out area, for
* _IOC_READ in area and if both are set in/out area. In all
* non-NULL cases, the area is of _IOC_SIZE(cmd) bytes.
*
* If flags has FUSE_IOCTL_DIR then the fuse_file_info refers to a
* directory file handle.
*
* Introduced in version 2.8
*/
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
*
* Note: If ph is non-NULL, the client should notify
* when IO readiness events occur by calling
* fuse_notify_poll() with the specified ph.
*
* Regardless of the number of times poll with a non-NULL ph
* is received, single notification is enough to clear all.
* Notifying more times incurs overhead but doesn't harm
* correctness.
*
* The callee is responsible for destroying ph with
* fuse_pollhandle_destroy() when no longer in use.
*
* Introduced in version 2.8
*/
int (*poll) (const fuse_file_info_t *ffi,
fuse_pollhandle_t *ph,
unsigned *reventsp);
/** Write contents of buffer to an open file
*
* Similar to the write() method, but data is supplied in a
* generic buffer. Use fuse_buf_copy() to transfer data to
* the destination.
*
* Introduced in version 2.9
*/
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
*
* Similar to the read() method, but data is stored and
* returned in a generic buffer.
*
* No actual copying of data has to take place, the source
* file descriptor may simply be stored in the buffer for
* later data transfer.
*
* The buffer must be allocated dynamically and stored at the
* location pointed to by bufp. If the buffer contains memory
* regions, they too must be allocated using malloc(). The
* allocated memory will be freed by the caller.
*
* Introduced in version 2.9
*/
int (*read_buf) (const fuse_file_info_t *ffi,
struct fuse_bufvec **bufp,
size_t size,
off_t off);
/**
* Perform BSD file locking operation
*
* The op argument will be either LOCK_SH, LOCK_EX or LOCK_UN
*
* Nonblocking requests will be indicated by ORing LOCK_NB to
* the above operations
*
* For more information see the flock(2) manual page.
*
* Additionally fi->owner will be set to a value unique to
* this open file. This same value will be supplied to
* ->release() when the file is released.
*
* Note: if this method is not implemented, the kernel will still
* allow file locking to work locally. Hence it is only
* interesting for network filesystems and similar.
*
* Introduced in version 2.9
*/
int (*flock) (const fuse_file_info_t *, int op);
/**
* Allocates space for an open file
*
* This function ensures that required space is allocated for specified
* file. If this function returns success then any subsequent write
* request to specified range is guaranteed not to fail because of lack
* of space on the file system media.
*
* Introduced in version 2.9.1
*/
int (*fallocate) (const fuse_file_info_t *, int, off_t, off_t);
/**
* Copy a range of data from one file to another
*
* Performs an optimized copy between two file descriptors without
* the additional cost of transferring data through the FUSE kernel
* module to user space (glibc) and then back into the FUSE filesystem
* again.
*
* In case this method is not implemented, glibc falls back to
* reading data from the source and writing to the
* destination. Effectively doing an inefficient copy of the
* data.
*/
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
*
* The uid, gid and pid fields are not filled in case of a writepage
* operation.
*/
struct fuse_context
{
/** Pointer to the fuse object */
struct fuse *fuse;
/** User ID of the calling process */
uid_t uid;
/** Group ID of the calling process */
gid_t gid;
/** Thread ID of the calling process */
pid_t pid;
/** Private filesystem data */
void *private_data;
/** Umask of the calling process (introduced in version 2.8) */
mode_t umask;
};
/**
* Main function of FUSE.
*
* This is for the lazy. This is all that has to be called from the
* main() function.
*
* This function does the following:
* - parses command line options (-d -s and -h)
* - passes relevant mount options to the fuse_mount()
* - installs signal handlers for INT, HUP, TERM and PIPE
* - registers an exit handler to unmount the filesystem on program exit
* - creates a fuse handle
* - registers the operations
* - calls either the single-threaded or the multi-threaded event loop
*
* Note: this is currently implemented as a macro.
*
* @param argc the argument counter passed to the main() function
* @param argv the argument vector passed to the main() function
* @param op the file system operation
* @param user_data user data supplied in the context during the init() method
* @return 0 on success, nonzero on failure
*/
/*
int fuse_main(int argc, char *argv[], const struct fuse_operations *op,
void *user_data);
*/
#define fuse_main(argc, argv, op, user_data) \
fuse_main_real(argc, argv, op, sizeof(*(op)), user_data)
/* ----------------------------------------------------------- *
* More detailed API *
* ----------------------------------------------------------- */
/**
* Create a new FUSE filesystem.
*
* @param ch the communication channel
* @param args argument vector
* @param op the filesystem operations
* @param op_size the size of the fuse_operations structure
* @param user_data user data supplied in the context during the init() method
* @return the created FUSE handle
*/
struct fuse *fuse_new(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op, size_t op_size,
void *user_data);
/**
* Destroy the FUSE handle.
*
* The communication channel attached to the handle is also destroyed.
*
* NOTE: This function does not unmount the filesystem. If this is
* needed, call fuse_unmount() before calling this function.
*
* @param f the FUSE handle
*/
void fuse_destroy(struct fuse *f);
/**
* Exit from event loop
*
* @param f the FUSE handle
*/
void fuse_exit(struct fuse *f);
int fuse_config_num_threads(const struct fuse *fuse_);
/**
* FUSE event loop with multiple threads
*
* Requests from the kernel are processed, and the appropriate
* operations are called. Request are processed in parallel by
* distributing them between multiple threads.
*
* Calling this function requires the pthreads library to be linked to
* the application.
*
* @param f the FUSE handle
* @return 0 if no error occurred, -1 otherwise
*/
int fuse_loop_mt(struct fuse *f);
/**
* Get the current context
*
* The context is only valid for the duration of a filesystem
* operation, and thus must not be stored and used later.
*
* @return the context
*/
struct fuse_context *fuse_get_context(void);
/**
* Check if the current request has already been interrupted
*
* @return 1 if the request has been interrupted, 0 otherwise
*/
int fuse_interrupted(void);
/**
* Obsolete, doesn't do anything
*
* @return -EINVAL
*/
int fuse_invalidate(struct fuse *f, const char *path);
/* Deprecated, don't use */
int fuse_is_lib_option(const char *opt);
/**
* The real main function
*
* Do not call this directly, use fuse_main()
*/
int fuse_main_real(int argc, char *argv[], const struct fuse_operations *op,
size_t op_size, void *user_data);
/**
* Start the cleanup thread when using option "remember".
*
* This is done automatically by fuse_loop_mt()
* @param fuse struct fuse pointer for fuse instance
* @return 0 on success and -1 on error
*/
int fuse_start_cleanup_thread(struct fuse *fuse);
/**
* Stop the cleanup thread when using option "remember".
*
* This is done automatically by fuse_loop_mt()
* @param fuse struct fuse pointer for fuse instance
*/
void fuse_stop_cleanup_thread(struct fuse *fuse);
/**
* Iterate over cache removing stale entries
* use in conjunction with "-oremember"
*
* NOTE: This is already done for the standard sessions
*
* @param fuse struct fuse pointer for fuse instance
* @return the number of seconds until the next cleanup
*/
int fuse_clean_cache(struct fuse *fuse);
/*
* Stacking API
*/
/**
* Fuse filesystem object
*
* This is opaque object represents a filesystem layer
*/
struct fuse_fs;
/*
* These functions call the relevant filesystem operation, and return
* the result.
*
* If the operation is not defined, they return -ENOSYS, with the
* exception of fuse_fs_open, fuse_fs_release, fuse_fs_opendir,
* fuse_fs_releasedir and fuse_fs_statfs, which return 0.
*/
int fuse_fs_getattr(struct fuse_fs *fs,
const char *path,
struct stat *buf,
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);
int fuse_fs_unlink(struct fuse_fs *fs, const char *path);
int fuse_fs_rmdir(struct fuse_fs *fs, const char *path);
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,
fuse_file_info_t *fi);
int fuse_fs_open(struct fuse_fs *fs, const char *path,
fuse_file_info_t *fi);
int fuse_fs_read(struct fuse_fs *fs, char *buf, size_t size,
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,
fuse_file_info_t *fi);
int fuse_fs_write(struct fuse_fs *fs, const char *buf,
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,
fuse_file_info_t *fi);
int fuse_fs_fsync(struct fuse_fs *fs, int datasync,
fuse_file_info_t *fi);
int fuse_fs_flush(struct fuse_fs *fs,
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,
fuse_file_info_t *fi);
int fuse_fs_readdir(struct fuse_fs *fs,
fuse_file_info_t *fi,
fuse_dirents_t *buf);
int fuse_fs_fsyncdir(struct fuse_fs *fs, int datasync,
fuse_file_info_t *fi);
int fuse_fs_releasedir(struct fuse_fs *fs,
fuse_file_info_t *fi);
int fuse_fs_create(struct fuse_fs *fs, const char *path, mode_t mode,
fuse_file_info_t *fi);
int fuse_fs_lock(struct fuse_fs *fs,
fuse_file_info_t *fi, int cmd, struct flock *lock);
int fuse_fs_flock(struct fuse_fs *fs,
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,
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);
int fuse_fs_readlink(struct fuse_fs *fs, const char *path, char *buf,
size_t len);
int fuse_fs_mknod(struct fuse_fs *fs, const char *path, mode_t mode,
dev_t rdev);
int fuse_fs_mkdir(struct fuse_fs *fs, const char *path, mode_t mode);
int fuse_fs_setxattr(struct fuse_fs *fs, const char *path, const char *name,
const char *value, size_t size, int flags);
int fuse_fs_getxattr(struct fuse_fs *fs, const char *path, const char *name,
char *value, size_t size);
int fuse_fs_listxattr(struct fuse_fs *fs, const char *path, char *list,
size_t size);
int fuse_fs_removexattr(struct fuse_fs *fs, const char *path,
const char *name);
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,
fuse_file_info_t *fi, unsigned int flags,
void *data, uint32_t *out_bufsz);
int fuse_fs_poll(struct fuse_fs *fs,
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, 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,
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(fuse_pollhandle_t *ph);
/**
* Create a new fuse filesystem object
*
* This is usually called from the factory of a fuse module to create
* a new instance of a filesystem.
*
* @param op the filesystem operations
* @param op_size the size of the fuse_operations structure
* @param user_data user data supplied in the context during the init() method
* @return a new filesystem object
*/
struct fuse_fs *fuse_fs_new(const struct fuse_operations *op, size_t op_size,
void *user_data);
/* ----------------------------------------------------------- *
* Advanced API for event handling, don't worry about this... *
* ----------------------------------------------------------- */
/* NOTE: the following functions are deprecated, and will be removed
from the 3.0 API. Use the lowlevel session functions instead */
/** Function type used to process commands */
typedef void (*fuse_processor_t)(struct fuse *, struct fuse_cmd *, void *);
/** This is the part of fuse_main() before the event loop */
struct fuse *fuse_setup(int argc, char *argv[],
const struct fuse_operations *op, size_t op_size,
char **mountpoint,
void *user_data);
/** This is the part of fuse_main() after the event loop */
void fuse_teardown(struct fuse *fuse, char *mountpoint);
/** Read a single command. If none are read, return NULL */
struct fuse_cmd *fuse_read_cmd(struct fuse *f);
/** Process a single command */
void fuse_process_cmd(struct fuse *f, struct fuse_cmd *cmd);
/** Multi threaded event loop, which calls the custom command
processor function */
int fuse_loop_mt_proc(struct fuse *f, fuse_processor_t proc, void *data);
/** Return the exited flag, which indicates if fuse_exit() has been
called */
int fuse_exited(struct fuse *f);
/** This function is obsolete and implemented as a no-op */
void fuse_set_getcontext_func(struct fuse_context *(*func)(void));
/** Get session from fuse object */
struct fuse_session *fuse_get_session(struct fuse *f);
EXTERN_C_END
#endif /* _FUSE_H_ */
-82
View File
@@ -1,82 +0,0 @@
/*
ISC License
Copyright (c) 2019, Antonio SJ Musumeci <trapexit@spawn.link>
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#pragma once
#include "extern_c.h"
EXTERN_C_BEGIN
#include "kvec.h"
#include "fuse_dirent.h"
#include "fuse_direntplus.h"
#include "fuse_entry.h"
#include "linux_dirent64.h"
#include <dirent.h>
#include <stdint.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
enum fuse_dirents_type_e
{
UNSET = 0,
NORMAL,
PLUS
};
typedef enum fuse_dirents_type_e fuse_dirents_type_t;
typedef struct fuse_dirents_s fuse_dirents_t;
struct fuse_dirents_s
{
char *buf;
uint64_t buf_len;
uint64_t data_len;
kvec_t(uint32_t) offs;
fuse_dirents_type_t type;
};
int fuse_dirents_init(fuse_dirents_t *d);
void fuse_dirents_free(fuse_dirents_t *d);
void fuse_dirents_reset(fuse_dirents_t *d);
int fuse_dirents_add(fuse_dirents_t *d,
const struct dirent *de,
const uint64_t namelen);
int fuse_dirents_add_plus(fuse_dirents_t *d,
const struct dirent *de,
const uint64_t namelen,
const fuse_entry_t *entry,
const struct stat *st);
int fuse_dirents_add_linux(fuse_dirents_t *d,
const struct linux_dirent64 *de,
const uint64_t namelen);
int fuse_dirents_add_linux_plus(fuse_dirents_t *d,
const struct linux_dirent64 *de,
const uint64_t namelen,
const fuse_entry_t *entry,
const struct stat *st);
void *fuse_dirents_find(fuse_dirents_t *d,
const uint64_t ino);
int fuse_dirents_convert_plus2normal(fuse_dirents_t *d);
EXTERN_C_END
File diff suppressed because it is too large Load Diff
-12
View File
@@ -1,12 +0,0 @@
#pragma once
#include <stdint.h>
struct linux_dirent64
{
uint64_t ino;
int64_t off;
uint16_t reclen;
uint8_t type;
char name[];
};
-318
View File
@@ -1,318 +0,0 @@
/*
FUSE: Filesystem in Userspace
Copyright (C) 2010 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB
*/
#define _GNU_SOURCE
#include "config.h"
#include "fuse_i.h"
#include "fuse_lowlevel.h"
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <assert.h>
size_t fuse_buf_size(const struct fuse_bufvec *bufv)
{
size_t i;
size_t size = 0;
for (i = 0; i < bufv->count; i++) {
if (bufv->buf[i].size == SIZE_MAX)
size = SIZE_MAX;
else
size += bufv->buf[i].size;
}
return size;
}
static size_t min_size(size_t s1, size_t s2)
{
return s1 < s2 ? s1 : s2;
}
static ssize_t fuse_buf_write(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off,
size_t len)
{
ssize_t res = 0;
size_t copied = 0;
while (len) {
if (dst->flags & FUSE_BUF_FD_SEEK) {
res = pwrite(dst->fd, src->mem + src_off, len,
dst->pos + dst_off);
} else {
res = write(dst->fd, src->mem + src_off, len);
}
if (res == -1) {
if (!copied)
return -errno;
break;
}
if (res == 0)
break;
copied += res;
if (!(dst->flags & FUSE_BUF_FD_RETRY))
break;
src_off += res;
dst_off += res;
len -= res;
}
return copied;
}
static ssize_t fuse_buf_read(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off,
size_t len)
{
ssize_t res = 0;
size_t copied = 0;
while (len) {
if (src->flags & FUSE_BUF_FD_SEEK) {
res = pread(src->fd, dst->mem + dst_off, len,
src->pos + src_off);
} else {
res = read(src->fd, dst->mem + dst_off, len);
}
if (res == -1) {
if (!copied)
return -errno;
break;
}
if (res == 0)
break;
copied += res;
if (!(src->flags & FUSE_BUF_FD_RETRY))
break;
dst_off += res;
src_off += res;
len -= res;
}
return copied;
}
static ssize_t fuse_buf_fd_to_fd(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off,
size_t len)
{
char buf[4096];
struct fuse_buf tmp = {
.size = sizeof(buf),
.flags = 0,
};
ssize_t res;
size_t copied = 0;
tmp.mem = buf;
while (len) {
size_t this_len = min_size(tmp.size, len);
size_t read_len;
res = fuse_buf_read(&tmp, 0, src, src_off, this_len);
if (res < 0) {
if (!copied)
return res;
break;
}
if (res == 0)
break;
read_len = res;
res = fuse_buf_write(dst, dst_off, &tmp, 0, read_len);
if (res < 0) {
if (!copied)
return res;
break;
}
if (res == 0)
break;
copied += res;
if (res < this_len)
break;
dst_off += res;
src_off += res;
len -= res;
}
return copied;
}
#ifdef HAVE_SPLICE
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off,
size_t len, enum fuse_buf_copy_flags flags)
{
int splice_flags = 0;
off_t *srcpos = NULL;
off_t *dstpos = NULL;
off_t srcpos_val;
off_t dstpos_val;
ssize_t res;
size_t copied = 0;
if (flags & FUSE_BUF_SPLICE_MOVE)
splice_flags |= SPLICE_F_MOVE;
if (flags & FUSE_BUF_SPLICE_NONBLOCK)
splice_flags |= SPLICE_F_NONBLOCK;
if (src->flags & FUSE_BUF_FD_SEEK) {
srcpos_val = src->pos + src_off;
srcpos = &srcpos_val;
}
if (dst->flags & FUSE_BUF_FD_SEEK) {
dstpos_val = dst->pos + dst_off;
dstpos = &dstpos_val;
}
while (len) {
res = splice(src->fd, srcpos, dst->fd, dstpos, len,
splice_flags);
if (res == -1) {
if (copied)
break;
if (errno != EINVAL || (flags & FUSE_BUF_FORCE_SPLICE))
return -errno;
/* Maybe splice is not supported for this combination */
return fuse_buf_fd_to_fd(dst, dst_off, src, src_off,
len);
}
if (res == 0)
break;
copied += res;
if (!(src->flags & FUSE_BUF_FD_RETRY) &&
!(dst->flags & FUSE_BUF_FD_RETRY)) {
break;
}
len -= res;
}
return copied;
}
#else
static ssize_t fuse_buf_splice(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off,
size_t len, enum fuse_buf_copy_flags flags)
{
(void) flags;
return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
}
#endif
static ssize_t fuse_buf_copy_one(const struct fuse_buf *dst, size_t dst_off,
const struct fuse_buf *src, size_t src_off,
size_t len, enum fuse_buf_copy_flags flags)
{
int src_is_fd = src->flags & FUSE_BUF_IS_FD;
int dst_is_fd = dst->flags & FUSE_BUF_IS_FD;
if (!src_is_fd && !dst_is_fd) {
char *dstmem = dst->mem + dst_off;
char *srcmem = src->mem + src_off;
if (dstmem != srcmem) {
if (dstmem + len <= srcmem || srcmem + len <= dstmem)
memcpy(dstmem, srcmem, len);
else
memmove(dstmem, srcmem, len);
}
return len;
} else if (!src_is_fd) {
return fuse_buf_write(dst, dst_off, src, src_off, len);
} else if (!dst_is_fd) {
return fuse_buf_read(dst, dst_off, src, src_off, len);
} else if (flags & FUSE_BUF_NO_SPLICE) {
return fuse_buf_fd_to_fd(dst, dst_off, src, src_off, len);
} else {
return fuse_buf_splice(dst, dst_off, src, src_off, len, flags);
}
}
static const struct fuse_buf *fuse_bufvec_current(struct fuse_bufvec *bufv)
{
if (bufv->idx < bufv->count)
return &bufv->buf[bufv->idx];
else
return NULL;
}
static int fuse_bufvec_advance(struct fuse_bufvec *bufv, size_t len)
{
const struct fuse_buf *buf = fuse_bufvec_current(bufv);
bufv->off += len;
assert(bufv->off <= buf->size);
if (bufv->off == buf->size) {
assert(bufv->idx < bufv->count);
bufv->idx++;
if (bufv->idx == bufv->count)
return 0;
bufv->off = 0;
}
return 1;
}
ssize_t fuse_buf_copy(struct fuse_bufvec *dstv, struct fuse_bufvec *srcv,
enum fuse_buf_copy_flags flags)
{
size_t copied = 0;
if (dstv == srcv)
return fuse_buf_size(dstv);
for (;;) {
const struct fuse_buf *src = fuse_bufvec_current(srcv);
const struct fuse_buf *dst = fuse_bufvec_current(dstv);
size_t src_len;
size_t dst_len;
size_t len;
ssize_t res;
if (src == NULL || dst == NULL)
break;
src_len = src->size - srcv->off;
dst_len = dst->size - dstv->off;
len = min_size(src_len, dst_len);
res = fuse_buf_copy_one(dst, dstv->off, src, srcv->off, len, flags);
if (res < 0) {
if (!copied)
return res;
break;
}
copied += res;
if (!fuse_bufvec_advance(srcv, res) ||
!fuse_bufvec_advance(dstv, res))
break;
if (res < len)
break;
}
return copied;
}
-4919
View File
File diff suppressed because it is too large Load Diff
-410
View File
@@ -1,410 +0,0 @@
#define _FILE_OFFSET_BITS 64
#include "fuse_attr.h"
#include "fuse_dirent.h"
#include "fuse_direntplus.h"
#include "fuse_dirents.h"
#include "fuse_entry.h"
#include "linux_dirent64.h"
#include "stat_utils.h"
#include <dirent.h>
#include <errno.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 32KB - same as glibc getdents buffer size */
#define DEFAULT_SIZE (1024 * 32)
static
uint64_t
align_uint64_t(uint64_t v_)
{
return ((v_ + sizeof(uint64_t) - 1) & ~(sizeof(uint64_t) - 1));
}
static
uint64_t
fuse_dirent_size(const uint64_t namelen_)
{
uint64_t rv;
rv = offsetof(fuse_dirent_t,name);
rv += namelen_;
rv = align_uint64_t(rv);
return rv;
}
static
uint64_t
fuse_direntplus_size(const uint64_t namelen_)
{
uint64_t rv;
rv = offsetof(fuse_direntplus_t,dirent.name);
rv += namelen_;
rv = align_uint64_t(rv);
return rv;
}
static
int
fuse_dirents_buf_resize(fuse_dirents_t *d_,
uint64_t size_)
{
void *p;
if((d_->data_len + size_) >= d_->buf_len)
{
p = realloc(d_->buf,(d_->buf_len * 2));
if(p == NULL)
return -errno;
d_->buf = p;
d_->buf_len *= 2;
}
return 0;
}
static
void*
fuse_dirents_dirent_alloc(fuse_dirents_t *d_,
uint64_t namelen_)
{
int rv;
uint64_t size;
fuse_dirent_t *d;
size = fuse_dirent_size(namelen_);
rv = fuse_dirents_buf_resize(d_,size);
if(rv)
return NULL;
d = (fuse_dirent_t*)&d_->buf[d_->data_len];
d_->data_len += size;
return d;
}
static
void*
fuse_dirents_direntplus_alloc(fuse_dirents_t *d_,
uint64_t namelen_)
{
int rv;
uint64_t size;
fuse_dirent_t *d;
size = fuse_direntplus_size(namelen_);
rv = fuse_dirents_buf_resize(d_,size);
if(rv)
return NULL;
d = (fuse_dirent_t*)&d_->buf[d_->data_len];
d_->data_len += size;
return d;
}
static
void
fuse_dirents_fill_attr(fuse_attr_t *attr_,
const struct stat *st_)
{
attr_->ino = st_->st_ino;
attr_->size = st_->st_size;
attr_->blocks = st_->st_blocks;
attr_->atime = st_->st_atime;
attr_->mtime = st_->st_mtime;
attr_->ctime = st_->st_ctime;
attr_->atimensec = ST_ATIM_NSEC(st_);
attr_->mtimensec = ST_MTIM_NSEC(st_);
attr_->ctimensec = ST_CTIM_NSEC(st_);
attr_->mode = st_->st_mode;
attr_->nlink = st_->st_nlink;
attr_->uid = st_->st_uid;
attr_->gid = st_->st_gid;
attr_->rdev = st_->st_rdev;
attr_->blksize = st_->st_blksize;
}
fuse_dirent_t*
fuse_dirent_next(fuse_dirent_t *cur_)
{
char *buf;
buf = (char*)cur_;
buf += fuse_dirent_size(cur_->namelen);
return (fuse_dirent_t*)buf;
}
fuse_direntplus_t*
fuse_direntplus_next(fuse_direntplus_t *cur_)
{
char *buf;
buf = (char*)cur_;
buf += fuse_direntplus_size(cur_->dirent.namelen);
return (fuse_direntplus_t*)buf;
}
fuse_dirent_t*
fuse_dirent_find(fuse_dirents_t *d_,
const uint64_t ino_)
{
fuse_dirent_t *cur;
fuse_dirent_t *end;
if(d_->type != NORMAL)
return NULL;
cur = (fuse_dirent_t*)&d_->buf[0];
end = (fuse_dirent_t*)&d_->buf[d_->data_len];
while(cur < end)
{
if(cur->ino == ino_)
return cur;
cur = fuse_dirent_next(cur);
}
return NULL;
}
fuse_direntplus_t*
fuse_direntplus_find(fuse_dirents_t *d_,
const uint64_t ino_)
{
fuse_direntplus_t *cur;
fuse_direntplus_t *end;
if(d_->type != PLUS)
return NULL;
cur = (fuse_direntplus_t*)&d_->buf[0];
end = (fuse_direntplus_t*)&d_->buf[d_->data_len];
while(cur < end)
{
if(cur->dirent.ino == ino_)
return cur;
cur = fuse_direntplus_next(cur);
}
return NULL;
}
void*
fuse_dirents_find(fuse_dirents_t *d_,
const uint64_t ino_)
{
switch(d_->type)
{
default:
case UNSET:
return NULL;
case NORMAL:
return fuse_dirent_find(d_,ino_);
case PLUS:
return fuse_direntplus_find(d_,ino_);
}
}
int
fuse_dirents_convert_plus2normal(fuse_dirents_t *d_)
{
return -ENOSYS;
}
int
fuse_dirents_add(fuse_dirents_t *d_,
const struct dirent *dirent_,
const uint64_t namelen_)
{
fuse_dirent_t *d;
switch(d_->type)
{
case UNSET:
d_->type = NORMAL;
break;
case NORMAL:
break;
case PLUS:
return -EINVAL;
}
d = fuse_dirents_dirent_alloc(d_,namelen_);
if(d == NULL)
return -ENOMEM;
d->off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len);
d->ino = dirent_->d_ino;
d->namelen = namelen_;
d->type = dirent_->d_type;
memcpy(d->name,dirent_->d_name,namelen_);
return 0;
}
int
fuse_dirents_add_plus(fuse_dirents_t *d_,
const struct dirent *dirent_,
const uint64_t namelen_,
const fuse_entry_t *entry_,
const struct stat *st_)
{
fuse_direntplus_t *d;
switch(d_->type)
{
case UNSET:
d_->type = PLUS;
break;
case NORMAL:
return -EINVAL;
case PLUS:
break;
}
d = fuse_dirents_direntplus_alloc(d_,namelen_);
if(d == NULL)
return -ENOMEM;
d->dirent.off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len);
d->dirent.ino = dirent_->d_ino;
d->dirent.namelen = namelen_;
d->dirent.type = dirent_->d_type;
memcpy(d->dirent.name,dirent_->d_name,namelen_);
d->entry = *entry_;
fuse_dirents_fill_attr(&d->attr,st_);
return 0;
}
int
fuse_dirents_add_linux(fuse_dirents_t *d_,
const struct linux_dirent64 *dirent_,
const uint64_t namelen_)
{
fuse_dirent_t *d;
switch(d_->type)
{
case UNSET:
d_->type = NORMAL;
break;
case NORMAL:
break;
case PLUS:
return -EINVAL;
}
d = fuse_dirents_dirent_alloc(d_,namelen_);
if(d == NULL)
return -ENOMEM;
d->off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len);
d->ino = dirent_->ino;
d->namelen = namelen_;
d->type = dirent_->type;
memcpy(d->name,dirent_->name,namelen_);
return 0;
}
int
fuse_dirents_add_linux_plus(fuse_dirents_t *d_,
const struct linux_dirent64 *dirent_,
const uint64_t namelen_,
const fuse_entry_t *entry_,
const struct stat *st_)
{
fuse_direntplus_t *d;
switch(d_->type)
{
case UNSET:
d_->type = PLUS;
break;
case NORMAL:
return -EINVAL;
case PLUS:
break;
}
d = fuse_dirents_direntplus_alloc(d_,namelen_);
if(d == NULL)
return -ENOMEM;
d->dirent.off = kv_size(d_->offs);
kv_push(uint32_t,d_->offs,d_->data_len);
d->dirent.ino = dirent_->ino;
d->dirent.namelen = namelen_;
d->dirent.type = dirent_->type;
memcpy(d->dirent.name,dirent_->name,namelen_);
d->entry = *entry_;
fuse_dirents_fill_attr(&d->attr,st_);
return 0;
}
void
fuse_dirents_reset(fuse_dirents_t *d_)
{
d_->data_len = 0;
d_->type = UNSET;
kv_size(d_->offs) = 1;
}
int
fuse_dirents_init(fuse_dirents_t *d_)
{
void *buf;
buf = calloc(DEFAULT_SIZE,1);
if(buf == NULL)
return -ENOMEM;
d_->buf = buf;
d_->buf_len = DEFAULT_SIZE;
d_->data_len = 0;
d_->type = UNSET;
kv_init(d_->offs);
kv_resize(uint32_t,d_->offs,64);
kv_push(uint32_t,d_->offs,0);
return 0;
}
void
fuse_dirents_free(fuse_dirents_t *d_)
{
d_->buf_len = 0;
d_->data_len = 0;
d_->type = UNSET;
kv_destroy(d_->offs);
free(d_->buf);
}
-128
View File
@@ -1,128 +0,0 @@
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB
*/
#pragma once
#include "fuse.h"
#include "fuse_lowlevel.h"
struct fuse_chan;
struct fuse_ll;
struct fuse_session
{
struct fuse_session_ops op;
int (*receive_buf)(struct fuse_session *se, struct fuse_buf *buf,
struct fuse_chan **chp);
void (*process_buf)(void *data, const struct fuse_buf *buf,
struct fuse_chan *ch);
void *data;
volatile int exited;
struct fuse_chan *ch;
};
struct fuse_req
{
struct fuse_ll *f;
uint64_t unique;
int ctr;
pthread_mutex_t lock;
struct fuse_ctx ctx;
struct fuse_chan *ch;
int interrupted;
unsigned int ioctl_64bit : 1;
union {
struct {
uint64_t unique;
} i;
struct {
fuse_interrupt_func_t func;
void *data;
} ni;
} u;
struct fuse_req *next;
struct fuse_req *prev;
};
struct fuse_notify_req
{
uint64_t unique;
void (*reply)(struct fuse_notify_req *, fuse_req_t, fuse_ino_t,
const void *, const struct fuse_buf *);
struct fuse_notify_req *next;
struct fuse_notify_req *prev;
};
struct fuse_ll
{
int debug;
int allow_root;
int no_remote_posix_lock;
int no_remote_flock;
int big_writes;
int splice_write;
int splice_move;
int splice_read;
int no_splice_write;
int no_splice_move;
int no_splice_read;
struct fuse_lowlevel_ops op;
int got_init;
void *userdata;
uid_t owner;
struct fuse_conn_info conn;
struct fuse_req list;
struct fuse_req interrupts;
pthread_mutex_t lock;
int got_destroy;
pthread_key_t pipe_key;
int broken_splice_nonblock;
uint64_t notify_ctr;
struct fuse_notify_req notify_list;
};
struct fuse_cmd
{
char *buf;
size_t buflen;
struct fuse_chan *ch;
};
struct fuse *fuse_new_common(struct fuse_chan *ch, struct fuse_args *args,
const struct fuse_operations *op,
size_t op_size, void *user_data);
struct fuse_chan *fuse_kern_chan_new(int fd);
struct fuse_session *fuse_lowlevel_new_common(struct fuse_args *args,
const struct fuse_lowlevel_ops *op,
size_t op_size, void *userdata);
int fuse_chan_clearfd(struct fuse_chan *ch);
void fuse_kern_unmount(const char *mountpoint, int fd);
int fuse_kern_mount(const char *mountpoint, struct fuse_args *args);
int fuse_send_reply_iov_nofree(fuse_req_t req, int error, struct iovec *iov,
int count);
void fuse_free_req(fuse_req_t req);
struct fuse *fuse_setup_common(int argc, char *argv[],
const struct fuse_operations *op,
size_t op_size,
char **mountpoint,
int *fd,
void *user_data);
int fuse_start_thread(pthread_t *thread_id, void *(*func)(void *), void *arg);
-103
View File
@@ -1,103 +0,0 @@
/*
FUSE: Filesystem in Userspace
Copyright (C) 2001-2007 Miklos Szeredi <miklos@szeredi.hu>
This program can be distributed under the terms of the GNU LGPLv2.
See the file COPYING.LIB
*/
#include "fuse_lowlevel.h"
#include "fuse_kernel.h"
#include "fuse_i.h"
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
static int fuse_kern_chan_receive(struct fuse_chan **chp, char *buf,
size_t size)
{
struct fuse_chan *ch = *chp;
int err;
ssize_t res;
struct fuse_session *se = fuse_chan_session(ch);
assert(se != NULL);
restart:
res = read(fuse_chan_fd(ch), buf, size);
err = errno;
if (fuse_session_exited(se))
return 0;
if (res == -1) {
/* ENOENT means the operation was interrupted, it's safe
to restart */
if (err == ENOENT)
goto restart;
if (err == ENODEV) {
fuse_session_exit(se);
return 0;
}
/* Errors occurring during normal operation: EINTR (read
interrupted), EAGAIN (nonblocking I/O), ENODEV (filesystem
umounted) */
if (err != EINTR && err != EAGAIN)
perror("fuse: reading device");
return -err;
}
if ((size_t) res < sizeof(struct fuse_in_header)) {
fprintf(stderr, "short read on fuse device\n");
return -EIO;
}
return res;
}
static int fuse_kern_chan_send(struct fuse_chan *ch, const struct iovec iov[],
size_t count)
{
if (iov) {
ssize_t res = writev(fuse_chan_fd(ch), iov, count);
int err = errno;
if (res == -1) {
struct fuse_session *se = fuse_chan_session(ch);
assert(se != NULL);
/* ENOENT means the operation was interrupted */
if (!fuse_session_exited(se) && err != ENOENT)
perror("fuse: writing device");
return -err;
}
}
return 0;
}
static void fuse_kern_chan_destroy(struct fuse_chan *ch)
{
int fd = fuse_chan_fd(ch);
if (fd != -1)
close(fd);
}
struct fuse_chan *
fuse_kern_chan_new(int fd_)
{
long pagesize;
size_t bufsize;
struct fuse_chan_ops op =
{
.receive = fuse_kern_chan_receive,
.send = fuse_kern_chan_send,
.destroy = fuse_kern_chan_destroy,
};
pagesize = sysconf(_SC_PAGESIZE);
bufsize = ((FUSE_MAX_MAX_PAGES * pagesize) + 0x1000);
return fuse_chan_new(&op, fd_, bufsize, NULL);
}

Some files were not shown because too many files have changed in this diff Show More