Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
456068f
Stop using egrep
aversecat Apr 18, 2025
393bd9e
Account for difference in `stat` output format for device nodes
aversecat Apr 22, 2025
f920290
mv overwrite error format changes in el10
aversecat Apr 29, 2025
c8cf76f
Avoid \Z negative pattern in test exclude list
aversecat Dec 8, 2025
454aa80
prandom_bytes and family removed, switch to get_random_bytes variants
aversecat Jun 24, 2026
ac7b3db
Use a/m/c_time accessor functions
aversecat Jun 24, 2026
023b672
unaligned.h moved from asm/ to linux/
aversecat Apr 22, 2025
f84bfcf
Fix compiler warnings for flex array definitions
aversecat Apr 22, 2025
ae7ae90
RIP bd_inode
aversecat Apr 22, 2025
e6735e1
Adjust for __assign_str() losing second argument
aversecat Apr 22, 2025
1f84ac1
bio_add_page is now __must_check
aversecat Apr 22, 2025
804895b
Shrinker API v4
aversecat Apr 22, 2025
302e72b
generic_fillattr() now wants the request_mask arg from caller
aversecat Apr 23, 2025
faac3cb
set_blocksize() takes struct file argument
aversecat Apr 23, 2025
1c15f6e
Add sysfs default_groups usage
aversecat Apr 29, 2025
8afa8f0
Hook up buffer_migrate_folio
aversecat May 5, 2025
f6e6003
Obsolete scoutfs_writepage
aversecat May 1, 2025
c11cc15
generic_file_splice_read is removed
aversecat May 1, 2025
efb3842
Switch to .iterate_shared
aversecat May 5, 2025
c1873aa
Fix compat for list_lru_walk in el10
aversecat Dec 9, 2025
24c25de
block_write_{begin,end} take a folio as well as page_mkwrite
aversecat Nov 21, 2025
eb128ca
Fix xfstests on el10
aversecat Jun 11, 2026
4661181
Compat for iomap private and write_ops arguments
aversecat Aug 6, 2026
836f987
Drop el7 from our spec
aversecat Aug 6, 2026
0de3195
Also filter out netfs: messages when nfs tests run.
aversecat Aug 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions kmod/scoutfs-kmod.spec.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,31 +8,19 @@
%{!?kversion: %global kversion %(uname -r)}
%global kernel_version %{kversion}

%if 0%{?el7}
%global kernel_source() /usr/src/kernels/%{kernel_version}.$(arch)
%else
%global kernel_source() /usr/src/kernels/%{kernel_version}
%endif

%{!?_release: %global _release 0.%{pkg_date}git%{kmod_git_hash}}

%if 0%{?el7}
Name: %{kmod_name}
%else
Name: kmod-%{kmod_name}
%endif
Summary: %{kmod_name} kernel module
Version: %{kmod_version}
Release: %{_release}%{?dist}
License: GPLv2
Group: System/Kernel
URL: http://scoutfs.org/

%if 0%{?el7}
BuildRequires: %{kernel_module_package_buildreqs}
%else
BuildRequires: elfutils-libelf-devel
%endif
BuildRequires: kernel-devel-uname-r = %{kernel_version}
BuildRequires: git
BuildRequires: module-init-tools
Expand All @@ -41,17 +29,9 @@ ExclusiveArch: x86_64

Source: %{kmod_name}-kmod-%{kmod_version}.tar

%if 0%{?el7}
# Build only for standard kernel variant(s); for debug packages, append "debug"
# after "default" (separated by space)
%kernel_module_package default
%endif

%global install_mod_dir extra/%{kmod_name}

%if ! 0%{?el7}
%global flavors_to_build x86_64
%endif

# el9 sanity: make sure we lock to the minor release we built for and block upgrades
%{lua:
Expand Down Expand Up @@ -100,14 +80,12 @@ done
# mark modules executable so that strip-to-file can strip them
find %{buildroot} -type f -name \*.ko -exec %{__chmod} u+x \{\} \;

%if ! 0%{?el7}
%files
/lib/modules

%post
echo /lib/modules/%{kversion}/%{install_mod_dir}/scoutfs.ko | weak-modules --add-modules --no-initramfs
depmod -a
%endif

%clean
rm -rf %{buildroot}
Expand Down
4 changes: 2 additions & 2 deletions kmod/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ scoutfs-y += \
#
.PHONY: $(src)/check_exported_types
$(src)/check_exported_types:
@if egrep '\<[us](8|16|32|64\>)' $(src)/format.h $(src)/ioctl.h; then \
@if grep -E '\<[us](8|16|32|64\>)' $(src)/format.h $(src)/ioctl.h; then \
echo "no raw types in exported headers, preface with __"; \
exit 1; \
fi
@if egrep '\<__packed\>' $(src)/format.h $(src)/ioctl.h; then \
@if grep -E '\<__packed\>' $(src)/format.h $(src)/ioctl.h; then \
echo "no __packed allowed in exported headers"; \
exit 1; \
fi
Expand Down
150 changes: 150 additions & 0 deletions kmod/src/Makefile.kernelcompat
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,135 @@ ifneq (,$(shell grep 'struct posix_acl.*get_inode_acl' include/linux/fs.h))
ccflags-y += -DKC_GET_INODE_ACL
endif

#
# v6.1-rc5-2-ge9a688bcb193
#
# get_random_u32_below() implementation
ifneq (,$(shell grep 'u32 get_random_u32_below' include/linux/random.h))
ccflags-y += -DKC_HAVE_GET_RANDOM_U32_BELOW
endif

#
# v6.5-rc1-7-g9b6304c1d537
#
# ctime accessor methods
ifneq (,$(shell grep 'timespec64 inode_set_ctime_current' include/linux/fs.h))
ccflags-y += -DKC_FS_INODE_C_TIME_ACCESSOR
endif

#
# v6.6-rc5-1-g077c212f0344
#
# Must use access methods from fs.h to get to inode ctime/mtime/atime
ifneq (,$(shell grep 'inline time64_t inode_get_atime_sec' include/linux/fs.h))
ccflags-y += -DKC_FS_INODE_AM_TIME_ACCESSOR
endif

#
# v6.12-rc1-3-g5f60d5f6bbc1
#
# asm/unaligned.h replaced with linux/unaligned.h
ifneq (,$(shell grep -s 'define __LINUX_UNALIGNED_H' include/linux/unaligned.h))
ccflags-y += -DKC_HAVE__LINUX_UNALIGNED_H
endif

#
# v6.9-rc4-29-g203c1ce0bb06
#
# RIP bd_inode. (note, struct moved between headers!)
ifneq (,$(shell grep -s 'struct inode.*bd_inode' include/linux/blk_types.h include/linux/fs.h))
ccflags-y += -DKC_HAVE_BD_INODE
endif

#
# v6.8-9146-gc759e609030c
#
# Removes __assign_str_len() and removes the 2nd param of __assign_str().
ifneq (,$(shell grep -s 'define __assign_str.dst, src' \
include/trace/trace_events.h \
include/trace/ftrace.h \
include/trace/stages/stage6_event_callback.h))
ccflags-y += -DKC_HAVE_ASSIGN_STR_PARMS
endif

#
# v6.5-113-g615e95831ec3
#
ifneq (,$(shell grep 'generic_fillattr..*,.u32,' include/linux/fs.h))
ccflags-y += -DKC_GENERIC_FILLATTR_REQUEST_MASK
endif

#
# v6.6-rc4-53-gc42d50aefd17
#
# el10 yet again modifies the shrinker API significantly, breaking our current
# implementation.
ifneq (,$(shell grep 'struct shrinker .shrinker_alloc' include/linux/shrinker.h))
ccflags-y += -DKC_SHRINKER_ALLOC
endif

#
# v6.9-rc4-8-gead083aeeed9
#
# set_blocksize() now has a struct file arg.
ifneq (,$(shell grep -s 'int set_blocksize.struct file' include/linux/blkdev.h))
ccflags-y += -DKC_BLKDEV_SET_BLOCKSIZE_FILE
endif

#
# v5.1-rc3-29-gaa30f47cf666
#
# struct kobj_type now has member `default_groups`
ifneq (,$(shell grep 'const struct attribute_group ..default_groups;' include/linux/kobject.h))
ccflags-y += -DKC_KOBJECT_DEFAULT_GROUPS
endif

#
# v5.19-rc3-395-g67235182a41c
#
# Adds buffer_migrate_folio(), similar to other fss. Quote willy: "If the filesystem
# implements migrate_folio and writepages, there is no need for a writepage implementation."
ifneq (,$(shell grep 'int buffer_migrate_folio.struct address_space' include/linux/buffer_head.h))
ccflags-y += -DKC_HAVE_BUFFER_MIGRATE_FOLIO
endif

#
# v6.7-rc4-307-g17bf23a981be
#
# block_write_full_page() is replaced with block_write_full_folio(),
# but that isn't exported as it used to be (and the only users now
# are builtin). However, the kernel will fall back to using the
# .writepages method instead, so we can drop this method.
ifneq (,$(shell grep 'int block_write_full_page.struct page' include/linux/buffer_head.h))
ccflags-y += -DKC_HAVE_BLOCK_WRITE_FULL_PAGE
endif

#
# v6.4-rc2-29-gc6585011bc1d
#
# generic_file_splice_read is removed. It can be replaced with filemap_splice_read
# or copy_splice_read.
ifneq (,$(shell grep 'ssize_t generic_file_splice_read.struct file' include/linux/fs.h))
ccflags-y += -DKC_HAVE_GENERIC_FILE_SPLICE_READ
endif

#
# v4.6-rc3-29-g6192269444eb
#
# Adds .iterate_shared readdir() iterator vfs method.
ifneq (,$(shell grep 'iterate_shared...struct file.., struct dir_context' include/linux/fs.h))
ccflags-y += -DKC_HAVE_ITERATE_SHARED
endif

#
# v6.11-rc1-54-g9f04609f74ec
#
# Last of a series of changes that make block_write_begin/end take a folio instead of
# a struct pagep.
ifneq (,$(shell grep 'int __block_write_begin.struct.folio' include/linux/buffer_head.h))
ccflags-y += -DKC_BLOCK_WRITE_BEGIN_FOLIO
endif

#
# v6.15-13744-g41cb08555c41
#
Expand All @@ -232,3 +361,24 @@ endif
ifneq (,$(shell grep 'copy_page_to_iter_nofault' include/linux/uio.h))
ccflags-y += -DKC_USE_IOMAP_FOR_IO
endif

#
# v5.18-rc7-162-g786f847f43a5
#
# iomap_dio_rw() takes a private pointer that it stores in the iomap_iter
# for the filesystem's use.
#
ifneq (,$(shell grep 'unsigned int dio_flags, void .private' include/linux/iomap.h))
ccflags-y += -DKC_IOMAP_DIO_RW_PRIVATE
endif

#
# v6.16-rc1-11-g2a5574fc57d1
#
# The iomap_folio_ops that used to hang off the iomap are replaced by
# iomap_write_ops which are passed to iomap_file_buffered_write() along
# with a private pointer.
#
ifneq (,$(shell grep 'const struct iomap_write_ops .write_ops, void .private' include/linux/iomap.h))
ccflags-y += -DKC_IOMAP_WRITE_OPS
endif
2 changes: 1 addition & 1 deletion kmod/src/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ int scoutfs_set_acl_locked(struct inode *inode, struct posix_acl *acl, int type,
if (!value) {
/* can be setting an acl that only affects mode, didn't need xattr */
inode_inc_iversion(inode);
inode->i_ctime = current_time(inode);
inode_set_ctime_current(inode);
}
}

Expand Down
4 changes: 2 additions & 2 deletions kmod/src/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,14 +309,14 @@ static bool invalid_extent(u64 start, u64 end, u64 first, u64 last)
static bool invalid_meta_blkno(struct super_block *sb, u64 blkno)
{
struct scoutfs_sb_info *sbi = SCOUTFS_SB(sb);
u64 last_meta = (i_size_read(sbi->meta_bdev->bd_inode) >> SCOUTFS_BLOCK_LG_SHIFT) - 1;
u64 last_meta = (i_size_read(KC_BDEV_INODE(sbi->meta_bdev)) >> SCOUTFS_BLOCK_LG_SHIFT) - 1;

return invalid_extent(blkno, blkno, SCOUTFS_META_DEV_START_BLKNO, last_meta);
}

static bool invalid_data_extent(struct super_block *sb, u64 start, u64 len)
{
u64 last_data = (i_size_read(sb->s_bdev->bd_inode) >> SCOUTFS_BLOCK_SM_SHIFT) - 1;
u64 last_data = (i_size_read(KC_BDEV_INODE(sb->s_bdev)) >> SCOUTFS_BLOCK_SM_SHIFT) - 1;

return invalid_extent(start, start + len - 1, SCOUTFS_DATA_DEV_START_BLKNO, last_data);
}
Expand Down
10 changes: 4 additions & 6 deletions kmod/src/attr_x.c
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ int scoutfs_get_attr_x(struct inode *inode, struct scoutfs_ioctl_inode_attr_x *i
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_OFFLINE_BLOCKS,
offline_blocks, offline);
}
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_CTIME, ctime_sec, inode->i_ctime.tv_sec);
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_CTIME, ctime_nsec, inode->i_ctime.tv_nsec);
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_CTIME, ctime_sec, inode_get_ctime_sec(inode));
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_CTIME, ctime_nsec, inode_get_ctime_nsec(inode));
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_CRTIME, crtime_sec, si->crtime.tv_sec);
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_CRTIME, crtime_nsec, si->crtime.tv_nsec);
size = fill_attr(size, iax, SCOUTFS_IOC_IAX_SIZE, size, i_size_read(inode));
Expand Down Expand Up @@ -223,10 +223,8 @@ int scoutfs_set_attr_x(struct inode *inode, struct scoutfs_ioctl_inode_attr_x *i
scoutfs_inode_set_data_version(inode, iax->data_version);
if (iax->x_mask & SCOUTFS_IOC_IAX_SIZE)
i_size_write(inode, iax->size);
if (iax->x_mask & SCOUTFS_IOC_IAX_CTIME) {
inode->i_ctime.tv_sec = iax->ctime_sec;
inode->i_ctime.tv_nsec = iax->ctime_nsec;
}
if (iax->x_mask & SCOUTFS_IOC_IAX_CTIME)
inode_set_ctime(inode, iax->ctime_sec, iax->ctime_nsec);
if (iax->x_mask & SCOUTFS_IOC_IAX_CRTIME) {
si->crtime.tv_sec = iax->crtime_sec;
si->crtime.tv_nsec = iax->crtime_nsec;
Expand Down
20 changes: 14 additions & 6 deletions kmod/src/block.c
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ int scoutfs_block_dirty_ref(struct super_block *sb, struct scoutfs_alloc *alloc,
hdr->magic = cpu_to_le32(magic);
hdr->fsid = cpu_to_le64(sbi->fsid);
hdr->blkno = cpu_to_le64(bl->blkno);
prandom_bytes(&hdr->seq, sizeof(hdr->seq));
get_random_bytes(&hdr->seq, sizeof(hdr->seq));

trace_scoutfs_block_dirty_ref(sb, le64_to_cpu(ref->blkno), le64_to_cpu(ref->seq),
le64_to_cpu(hdr->blkno), le64_to_cpu(hdr->seq));
Expand Down Expand Up @@ -1239,7 +1239,12 @@ static int sm_block_io(struct super_block *sb, struct block_device *bdev, blk_op
bio->bi_iter.bi_sector = blkno << (SCOUTFS_BLOCK_SM_SHIFT - 9);
bio->bi_end_io = sm_block_bio_end_io;
bio->bi_private = &sbc;
bio_add_page(bio, page, SCOUTFS_BLOCK_SM_SIZE, 0);
ret = bio_add_page(bio, page, SCOUTFS_BLOCK_SM_SIZE, 0);
if (ret != SCOUTFS_BLOCK_SM_SIZE) {
bio_put(bio);
ret = -EFAULT;
goto out;
}

init_completion(&sbc.comp);
sbc.err = 0;
Expand Down Expand Up @@ -1295,9 +1300,12 @@ int scoutfs_block_setup(struct super_block *sb)

binf->sb = sb;
init_waitqueue_head(&binf->waitq);
KC_INIT_SHRINKER_FUNCS(&binf->shrinker, block_count_objects,
block_scan_objects);
KC_REGISTER_SHRINKER(&binf->shrinker, "scoutfs-block:" SCSBF, SCSB_ARGS(sb));
KC_SETUP_SHRINKER(binf->shrinker, binf, 0, block_count_objects,
block_scan_objects, "scoutfs-block:" SCSBF, SCSB_ARGS(sb));
if (KC_SHRINKER_IS_NULL(binf->shrinker)) {
ret = -ENOMEM;
goto out;
}
INIT_WORK(&binf->free_work, block_free_work);
init_llist_head(&binf->free_llist);

Expand All @@ -1319,7 +1327,7 @@ void scoutfs_block_destroy(struct super_block *sb)
struct block_info *binf = SCOUTFS_SB(sb)->block_info;

if (binf) {
KC_UNREGISTER_SHRINKER(&binf->shrinker);
KC_UNREGISTER_SHRINKER(binf->shrinker);
block_shrink_all(sb);
flush_work(&binf->free_work);
rhashtable_destroy(&binf->ht);
Expand Down
4 changes: 2 additions & 2 deletions kmod/src/btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2042,7 +2042,7 @@ struct merged_item {
u64 seq;
u8 flags;
unsigned int val_len;
u8 val[0];
u8 val[];
};

static inline struct merged_item *mitem_container(struct rb_node *node)
Expand Down Expand Up @@ -2210,7 +2210,7 @@ static int merge_read_item(struct super_block *sb, struct scoutfs_key *key, u64
mitem->flags = flags;
mitem->val_len = val_len;
if (val_len)
memcpy(mitem->val, val, val_len);
memcpy(&mitem->val[0], val, val_len);

if (found) {
replace_mitem(rng, found, mitem);
Expand Down
2 changes: 1 addition & 1 deletion kmod/src/btree.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct scoutfs_btree_item_list {
u64 seq;
u8 flags;
int val_len;
u8 val[0];
u8 val[];
};

int scoutfs_btree_lookup(struct super_block *sb,
Expand Down
14 changes: 12 additions & 2 deletions kmod/src/counters.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,17 @@ static struct attribute scoutfs_counter_attrs[] = {
#define NR_ATTRS ARRAY_SIZE(scoutfs_counter_attrs)
static struct attribute *scoutfs_counter_attr_ptrs[NR_ATTRS + 1];

#ifdef KC_KOBJECT_DEFAULT_GROUPS
static struct attribute_group scoutfs_counter_attr_group = {
.attrs = scoutfs_counter_attr_ptrs,
};

static const struct attribute_group *scoutfs_counter_attr_groups[] = {
&scoutfs_counter_attr_group,
NULL,
};
#endif

static ssize_t scoutfs_counter_attr_show(struct kobject *kobj,
struct attribute *attr, char *buf)
{
Expand All @@ -45,7 +56,6 @@ static ssize_t scoutfs_counter_attr_show(struct kobject *kobj,
counters = container_of(kobj, struct scoutfs_counters, kobj);
index = attr - scoutfs_counter_attrs;
pcpu = &counters->FIRST_COUNTER + index;

return snprintf(buf, PAGE_SIZE, "%lld\n", percpu_counter_sum(pcpu));
}

Expand All @@ -63,7 +73,7 @@ static const struct sysfs_ops scoutfs_counter_attr_ops = {
};

static struct kobj_type scoutfs_counters_ktype = {
.default_attrs = scoutfs_counter_attr_ptrs,
.KC_KOBJ_DEFAULT_OP = KC_KOBJ_DEFAULT_PICK(scoutfs_counter_attr_groups, scoutfs_counter_attr_ptrs),
.sysfs_ops = &scoutfs_counter_attr_ops,
.release = scoutfs_counters_kobj_release,
};
Expand Down
Loading