From 5aac1dd741a0e5a9e48dd4ff60652b8311c3b3fe Mon Sep 17 00:00:00 2001 From: Auke Kok Date: Thu, 30 Apr 2026 16:14:37 -0700 Subject: [PATCH] Add SCOUTFS_IOC_INJECT_TOTL_DELTA ioctl. Inject a signed (total, count) delta at a totl key. No validity checking. Requires CAP_SYS_ADMIN. Signed-off-by: Auke Kok --- kmod/src/ioctl.c | 39 +++++++++++++++++++++++++++++++++++++++ kmod/src/ioctl.h | 13 +++++++++++++ 2 files changed, 52 insertions(+) diff --git a/kmod/src/ioctl.c b/kmod/src/ioctl.c index 0a5fc4c7..25b8ff33 100644 --- a/kmod/src/ioctl.c +++ b/kmod/src/ioctl.c @@ -1739,6 +1739,43 @@ out: return ret; } +static long scoutfs_ioc_inject_totl_delta(struct file *file, unsigned long arg) +{ + struct super_block *sb = file_inode(file)->i_sb; + struct scoutfs_ioctl_inject_totl_delta __user *uitd = (void __user *)arg; + struct scoutfs_ioctl_inject_totl_delta itd; + struct scoutfs_xattr_totl_val tval; + struct scoutfs_lock *lock = NULL; + struct scoutfs_key key; + int ret; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + if (copy_from_user(&itd, uitd, sizeof(itd))) + return -EFAULT; + + scoutfs_xattr_init_totl_key(&key, itd.name); + tval.total = cpu_to_le64((u64)itd.total); + tval.count = cpu_to_le64((u64)itd.count); + + ret = scoutfs_lock_xattr_totl(sb, SCOUTFS_LOCK_WRITE_ONLY, 0, &lock); + if (ret < 0) + goto out; + + ret = scoutfs_hold_trans(sb, false); + if (ret < 0) + goto unlock; + + ret = scoutfs_item_delta(sb, &key, &tval, sizeof(tval), lock); + + scoutfs_release_trans(sb); +unlock: + scoutfs_unlock(sb, lock, SCOUTFS_LOCK_WRITE_ONLY); +out: + return ret; +} + long scoutfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { switch (cmd) { @@ -1790,6 +1827,8 @@ long scoutfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return scoutfs_ioc_read_xattr_index(file, arg); case SCOUTFS_IOC_PUNCH_OFFLINE: return scoutfs_ioc_punch_offline(file, arg); + case SCOUTFS_IOC_INJECT_TOTL_DELTA: + return scoutfs_ioc_inject_totl_delta(file, arg); } return -ENOTTY; diff --git a/kmod/src/ioctl.h b/kmod/src/ioctl.h index c0d22859..1bb466ce 100644 --- a/kmod/src/ioctl.h +++ b/kmod/src/ioctl.h @@ -876,4 +876,17 @@ struct scoutfs_ioctl_punch_offline { #define SCOUTFS_IOC_PUNCH_OFFLINE \ _IOW(SCOUTFS_IOCTL_MAGIC, 24, struct scoutfs_ioctl_punch_offline) +/* + * Inject a signed (total, count) delta at the totl key @name (a, b, c + * match the trailing dotted u64s of a totl xattr name). + */ +struct scoutfs_ioctl_inject_totl_delta { + __u64 name[SCOUTFS_IOCTL_XATTR_TOTAL_NAME_NR]; + __s64 total; + __s64 count; +}; + +#define SCOUTFS_IOC_INJECT_TOTL_DELTA \ + _IOW(SCOUTFS_IOCTL_MAGIC, 25, struct scoutfs_ioctl_inject_totl_delta) + #endif