Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
40df1e0
prandom_bytes and family removed, switch to get_random_bytes variants.
aversecat Apr 21, 2025
8a953c9
Stop using egrep.
aversecat Apr 18, 2025
85e3424
Use a/m/c_time accessor functions.
aversecat Apr 21, 2025
a455d08
Fix el10 not skipping the format-version-forward-back test.
aversecat Apr 22, 2025
c63b318
Account for difference in `stat` output format for device nodes.
aversecat Apr 22, 2025
34a78ae
unaligned.h moved from asm/ to linux/
aversecat Apr 22, 2025
b1bef1b
Fix compiler warnings for flex array definitions.
aversecat Apr 22, 2025
4c4a9c1
RIP bd_inode.
aversecat Apr 22, 2025
5f2f8f1
Adjust for __assign_str() losing second argument.
aversecat Apr 22, 2025
80926cf
bio_add_page is now __must_check
aversecat Apr 22, 2025
4ef1f56
Shrinker API v4.
aversecat Apr 22, 2025
38906a5
generic_fillattr() now wants the request_mask arg from caller.
aversecat Apr 23, 2025
f08a338
set_blocksize() takes struct file argument.
aversecat Apr 23, 2025
e42705d
Add sysfs default_groups usage.
aversecat Apr 29, 2025
92e3c72
mv overwrite error format changes in el10
aversecat Apr 29, 2025
bcde8b2
Fix unlocked pt_excl in scoutfs_readahead.
aversecat May 1, 2025
8ceedbd
Obsolete scoutfs_writepage.
aversecat May 1, 2025
f29a411
generic_file_splice_read is removed.
aversecat May 1, 2025
bcdd6e8
Hook up buffer_migrate_folio.
aversecat May 5, 2025
90a29ae
Switch to .iterate_shared
aversecat May 5, 2025
5407e2d
Avoid \Z negative pattern in test exclude list
aversecat Dec 8, 2025
d51cb20
Fix compat for list_lru_walk in el10
aversecat Dec 9, 2025
161477b
block_write_{begin,end} take a folio as well as page_mkwrite.
aversecat Nov 21, 2025
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
4 changes: 2 additions & 2 deletions kmod/src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,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
128 changes: 128 additions & 0 deletions kmod/src/Makefile.kernelcompat
Original file line number Diff line number Diff line change
Expand Up @@ -496,3 +496,131 @@ endif
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

#
# 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

#
# 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

#
# 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
2 changes: 1 addition & 1 deletion kmod/src/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,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 @@ -308,14 +308,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 @@ -884,7 +884,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 @@ -1229,7 +1229,12 @@ static int sm_block_io(struct super_block *sb, struct block_device *bdev, blk_op
kc_bio_set_sector(bio, 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 @@ -1285,9 +1290,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 @@ -1309,7 +1317,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 @@ -2208,7 +2208,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