# scoutfs-notify Observer-only file access notifications for [ScoutFS](https://github.com/versity/scoutfs), distributed as a rebasable `git format-patch` series plus a small Go userspace relay daemon. Maintained as one long-lived branch per currently-supported upstream scoutfs version. ## What the series adds Three patches against each supported scoutfs release: 1. **Kmod core** — a per-mount 64 KiB ring of 64-byte notification records and a single-reader drain ioctl (`SCOUTFS_IOC_READ_NOTIFY`, nr 25). Emit is non-blocking, drop-on-full; the monotonic `seq` field exposes drops to consumers. Three percpu counters (`notify_emitted`, `notify_dropped_ring_full`, `notify_reader_attached`). No mount option, no sysfs toggle. 2. **Kmod hooks** — `->open` wrapper and READ emit in `scoutfs_file_aio_read` / `scoutfs_file_read_iter`. Every hook is a single predicted-false branch when no reader is attached. Nothing in the data-waiter state machine is touched. 3. **scoutfs-notifyd (Go)** — userspace daemon that binds `/run/scoutfs//notify.sock` (AF_UNIX SOCK_SEQPACKET, mode 0600, root-only), drains the ring, and broadcasts each record to connected clients. Pure-stdlib Go; no external module dependencies. Shipped with a systemd template unit `scoutfs-notifyd@.service`. The notify ABI (`SCOUTFS_IOC_READ_NOTIFY` nr 25, 64-byte event record) is identical across all three supported scoutfs versions, so consumers and the daemon do not need per-version branching in their own code. ## Repository layout Each supported scoutfs version lives on its own long-lived branch. The patches in each branch are tuned for that specific scoutfs tree; they do NOT apply cross-version without rebasing. | Branch | Targets scoutfs | Tag | |----------------|-----------------|------------------| | `v1.28` | `v1.28` | `v1.28-notify-1` | | `v1.29` | `v1.29` | `v1.29-notify-1` | | `main` / `v1.30` | `v1.30` | `v1.30-notify-1` | `main` tracks the newest supported scoutfs version. When a new scoutfs release ships, a new branch is created and the patches are rebased onto it; when a scoutfs version ages out of support, its branch stays in the repo for historical builds but is no longer maintained. ## Applying Against a scoutfs git working tree at the matching upstream tag: ```sh git clone -b v1.29 https://git.anomalous.dev/alphacentri/scoutfs-notify.git /tmp/notify /tmp/notify/apply.sh /path/to/scoutfs-v1.29-checkout ``` The script runs `git am --3way` on each patch in order. ## Rebasing onto a new upstream release ```sh # In a fresh scoutfs checkout: git checkout v1.31 git checkout -b notify-v1.31 # Apply the previous branch's patches (usually clean; resolve any # conflicts, git am --continue). git am --3way /path/to/scoutfs-notify-v1.30/patches/*.patch git format-patch v1.31..notify-v1.31 -o /tmp/new-patches/ # Push a new branch + tag in this repo: cd /path/to/scoutfs-notify git checkout -b v1.31 main rm patches/*.patch cp /tmp/new-patches/*.patch patches/ echo v1.31 > base.txt git commit -am 'v1.31-notify-1: rebase onto scoutfs v1.31' git push -u origin v1.31 git tag v1.31-notify-1 && git push origin v1.31-notify-1 # Fast-forward main to the new tip once you're ready to promote it. ``` ## Quick smoke test after installation ```sh systemctl enable --now scoutfs-notifyd@mnt-scoutfs.service FSID=$(scoutfs stat /mnt/scoutfs | awk '/fsid/ { print $2 }') socat - UNIX-CONNECT:/run/scoutfs/${FSID}/notify.sock | xxd | head # touch some files in /mnt/scoutfs in another terminal ```