diff --git a/kmod/scoutfs-kmod.spec.in b/kmod/scoutfs-kmod.spec.in index 836159be..d8e97929 100644 --- a/kmod/scoutfs-kmod.spec.in +++ b/kmod/scoutfs-kmod.spec.in @@ -8,19 +8,11 @@ %{!?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} @@ -28,11 +20,7 @@ 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 @@ -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: @@ -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} diff --git a/kmod/src/Makefile b/kmod/src/Makefile index 7fd73191..c6741f6d 100644 --- a/kmod/src/Makefile +++ b/kmod/src/Makefile @@ -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 diff --git a/kmod/src/Makefile.kernelcompat b/kmod/src/Makefile.kernelcompat index 88b97f89..f12ac54e 100644 --- a/kmod/src/Makefile.kernelcompat +++ b/kmod/src/Makefile.kernelcompat @@ -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 # @@ -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 diff --git a/kmod/src/acl.c b/kmod/src/acl.c index fa3066ed..50201fc2 100644 --- a/kmod/src/acl.c +++ b/kmod/src/acl.c @@ -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); } } diff --git a/kmod/src/alloc.c b/kmod/src/alloc.c index 78191e4b..aeb6b048 100644 --- a/kmod/src/alloc.c +++ b/kmod/src/alloc.c @@ -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); } diff --git a/kmod/src/attr_x.c b/kmod/src/attr_x.c index 39e84a36..409c9c79 100644 --- a/kmod/src/attr_x.c +++ b/kmod/src/attr_x.c @@ -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)); @@ -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; diff --git a/kmod/src/block.c b/kmod/src/block.c index 7d28758e..115acc97 100644 --- a/kmod/src/block.c +++ b/kmod/src/block.c @@ -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)); @@ -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; @@ -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); @@ -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); diff --git a/kmod/src/btree.c b/kmod/src/btree.c index d8a25f0f..86ce8fd7 100644 --- a/kmod/src/btree.c +++ b/kmod/src/btree.c @@ -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) @@ -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); diff --git a/kmod/src/btree.h b/kmod/src/btree.h index 8656dd65..065c190e 100644 --- a/kmod/src/btree.h +++ b/kmod/src/btree.h @@ -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, diff --git a/kmod/src/counters.c b/kmod/src/counters.c index 5578ae26..9ba5b1a7 100644 --- a/kmod/src/counters.c +++ b/kmod/src/counters.c @@ -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) { @@ -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)); } @@ -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, }; diff --git a/kmod/src/data.c b/kmod/src/data.c index 44ca4c9d..f1d9bb66 100644 --- a/kmod/src/data.c +++ b/kmod/src/data.c @@ -811,10 +811,12 @@ static void scoutfs_readahead(struct readahead_control *rac) } } +#ifdef KC_HAVE_BLOCK_WRITE_FULL_PAGE static int scoutfs_writepage(struct page *page, struct writeback_control *wbc) { return block_write_full_page(page, scoutfs_get_block_write, wbc); } +#endif static int scoutfs_writepages(struct address_space *mapping, struct writeback_control *wbc) @@ -834,7 +836,7 @@ static int scoutfs_write_begin(struct file *file, #ifdef KC_BLOCK_WRITE_BEGIN_AOP_FLAGS unsigned flags, #endif - struct page **pagep, void **fsdata) + KC_PAGE_OR_FOLIO(struct page **pagep, struct folio **folio), void **fsdata) { struct inode *inode = mapping->host; struct scoutfs_inode_info *si = SCOUTFS_I(inode); @@ -879,7 +881,7 @@ static int scoutfs_write_begin(struct file *file, #ifdef KC_BLOCK_WRITE_BEGIN_AOP_FLAGS flags, #endif - pagep, scoutfs_get_block_write); + KC_PAGE_OR_FOLIO(pagep, folio), scoutfs_get_block_write); if (ret < 0) { scoutfs_release_trans(sb); scoutfs_inode_index_unlock(sb, &wbd->ind_locks); @@ -927,17 +929,20 @@ void scoutfs_do_write_end(struct inode *inode, struct scoutfs_lock *data_lock, static int scoutfs_write_end(struct file *file, struct address_space *mapping, loff_t pos, unsigned len, unsigned copied, - struct page *page, void *fsdata) + KC_PAGE_OR_FOLIO(struct page *pagep, struct folio *folio), + void *fsdata) { struct inode *inode = mapping->host; struct super_block *sb = inode->i_sb; struct write_begin_data *wbd = fsdata; int ret; - trace_scoutfs_write_end(sb, scoutfs_ino(inode), page->index, (u64)pos, - len, copied); + trace_scoutfs_write_end(sb, scoutfs_ino(inode), + KC_PAGE_OR_FOLIO(pagep->index, folio_index(folio)), + (u64)pos, len, copied); - ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata); + ret = generic_write_end(file, mapping, pos, len, copied, + KC_PAGE_OR_FOLIO(pagep, folio), fsdata); if (ret > 0) scoutfs_do_write_end(inode, wbd->lock, &wbd->ind_locks); @@ -1529,12 +1534,14 @@ int scoutfs_data_move_blocks(struct inode *from, u64 from_off, cur_time = current_time(from); if (!is_stage) { - to->i_ctime = to->i_mtime = cur_time; + inode_set_ctime_to_ts(to, cur_time); + inode_set_mtime_to_ts(to, cur_time); inode_inc_iversion(to); scoutfs_inode_inc_data_version(to); scoutfs_inode_set_data_seq(to); } - from->i_ctime = from->i_mtime = cur_time; + inode_set_ctime_to_ts(from, cur_time); + inode_set_mtime_to_ts(from, cur_time); inode_inc_iversion(from); scoutfs_inode_inc_data_version(from); scoutfs_inode_set_data_seq(from); @@ -1990,7 +1997,11 @@ int scoutfs_data_waiting(struct super_block *sb, u64 ino, u64 iblock, static vm_fault_t scoutfs_data_page_mkwrite(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; +#ifdef KC_MPAGE_READ_FOLIO + struct folio *folio = page_folio(vmf->page); +#else struct page *page = vmf->page; +#endif struct file *file = vma->vm_file; struct inode *inode = file_inode(file); struct scoutfs_inode_info *si = SCOUTFS_I(inode); @@ -2058,27 +2069,50 @@ static vm_fault_t scoutfs_data_page_mkwrite(struct vm_fault *vmf) down_write(&si->extent_sem); +#ifdef KC_MPAGE_READ_FOLIO + if (!folio_trylock(folio)) { +#else if (!trylock_page(page)) { +#endif ret = VM_FAULT_NOPAGE; goto out_sem; } ret = VM_FAULT_LOCKED; +#ifdef KC_MPAGE_READ_FOLIO + if ((folio->mapping != inode->i_mapping) || + (!folio_test_uptodate(folio)) || + (folio_pos(folio) > size)) { + folio_unlock(folio); +#else if ((page->mapping != inode->i_mapping) || (!PageUptodate(page)) || - (page_offset(page) > size)) { + (page_offset(page) > size)) { unlock_page(page); +#endif ret = VM_FAULT_NOPAGE; goto out_sem; } +#ifdef KC_MPAGE_READ_FOLIO + if (folio_index(folio) == (size - 1) >> PAGE_SHIFT) +#else if (page->index == (size - 1) >> PAGE_SHIFT) +#endif len = ((size - 1) & ~PAGE_MASK) + 1; +#ifdef KC_MPAGE_READ_FOLIO + err = __block_write_begin(KC_PAGE_OR_FOLIO(folio_page(folio, 0), folio), pos, PAGE_SIZE, scoutfs_get_block); +#else err = __block_write_begin(page, pos, PAGE_SIZE, scoutfs_get_block); +#endif if (err) { ret = vmf_error(err); +#ifdef KC_MPAGE_READ_FOLIO + folio_unlock(folio); +#else unlock_page(page); +#endif goto out_sem; } /* end scoutfs_write_begin */ @@ -2088,8 +2122,13 @@ static vm_fault_t scoutfs_data_page_mkwrite(struct vm_fault *vmf) * progress, we are guaranteed that writeback during freezing will * see the dirty page and writeprotect it again. */ +#ifdef KC_MPAGE_READ_FOLIO + folio_mark_dirty(folio); + folio_wait_stable(folio); +#else set_page_dirty(page); wait_for_stable_page(page); +#endif /* scoutfs_write_end */ scoutfs_inode_set_data_seq(inode); @@ -2244,11 +2283,16 @@ const struct address_space_operations scoutfs_file_aops = { .dirty_folio = block_dirty_folio, .invalidate_folio = block_invalidate_folio, .read_folio = scoutfs_read_folio, +#ifdef KC_HAVE_BUFFER_MIGRATE_FOLIO + .migrate_folio = buffer_migrate_folio, +#endif #else .readpage = scoutfs_readpage, #endif .readahead = scoutfs_readahead, +#ifdef KC_HAVE_BLOCK_WRITE_FULL_PAGE .writepage = scoutfs_writepage, +#endif .writepages = scoutfs_writepages, .write_begin = scoutfs_write_begin, .write_end = scoutfs_write_end, @@ -2257,8 +2301,12 @@ const struct address_space_operations scoutfs_file_aops = { const struct file_operations scoutfs_file_fops = { .read_iter = scoutfs_file_read_iter, .write_iter = scoutfs_file_write_iter, - .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, +#ifdef KC_HAVE_GENERIC_FILE_SPLICE_READ + .splice_read = generic_file_splice_read, +#else + .splice_read = copy_splice_read, +#endif .mmap = scoutfs_file_mmap, .unlocked_ioctl = scoutfs_ioctl, .fsync = scoutfs_file_fsync, diff --git a/kmod/src/dir.c b/kmod/src/dir.c index 622320c5..61130c69 100644 --- a/kmod/src/dir.c +++ b/kmod/src/dir.c @@ -751,6 +751,7 @@ static int scoutfs_mknod(KC_VFS_NS_DEF struct scoutfs_lock *dir_lock = NULL; struct scoutfs_lock *inode_lock = NULL; struct scoutfs_inode_info *si; + struct timespec64 cur_time; LIST_HEAD(ind_locks); u64 hash; u64 pos; @@ -782,9 +783,13 @@ static int scoutfs_mknod(KC_VFS_NS_DEF set_dentry_fsdata(dentry, dir_lock); i_size_write(dir, i_size_read(dir) + dentry->d_name.len); - dir->i_mtime = dir->i_ctime = current_time(inode); - inode->i_mtime = inode->i_atime = inode->i_ctime = dir->i_mtime; - si->crtime = inode->i_mtime; + cur_time = current_time(inode); + inode_set_mtime_to_ts(dir, cur_time); + inode_set_ctime_to_ts(dir, cur_time); + inode_set_mtime_to_ts(inode, cur_time); + inode_set_atime_to_ts(inode, cur_time); + inode_set_ctime_to_ts(inode, cur_time); + si->crtime = inode_get_mtime(inode); inode_inc_iversion(dir); inode_inc_iversion(inode); scoutfs_forest_inc_inode_count(sb); @@ -837,6 +842,7 @@ static int scoutfs_link(struct dentry *old_dentry, struct scoutfs_lock *dir_lock; struct scoutfs_lock *inode_lock = NULL; struct scoutfs_lock *orph_lock = NULL; + struct timespec64 cur_time; LIST_HEAD(ind_locks); bool del_orphan = false; u64 dir_size; @@ -911,8 +917,10 @@ static int scoutfs_link(struct dentry *old_dentry, set_dentry_fsdata(dentry, dir_lock); i_size_write(dir, dir_size); - dir->i_mtime = dir->i_ctime = current_time(inode); - inode->i_ctime = dir->i_mtime; + cur_time = current_time(inode); + inode_set_mtime_to_ts(dir, cur_time); + inode_set_ctime_to_ts(dir, cur_time); + inode_set_ctime_to_ts(inode, inode_get_mtime(dir)); inc_nlink(inode); inode_inc_iversion(dir); inode_inc_iversion(inode); @@ -1022,13 +1030,13 @@ static int scoutfs_unlink(struct inode *dir, struct dentry *dentry) set_dentry_fsdata(dentry, dir_lock); - dir->i_ctime = ts; - dir->i_mtime = ts; + inode_set_ctime_to_ts(dir, ts); + inode_set_mtime_to_ts(dir, ts); i_size_write(dir, i_size_read(dir) - dentry->d_name.len); inode_inc_iversion(dir); inode_inc_iversion(inode); - inode->i_ctime = ts; + inode_set_ctime_to_ts(inode, ts); drop_nlink(inode); if (S_ISDIR(inode->i_mode)) { drop_nlink(dir); @@ -1212,6 +1220,7 @@ static int scoutfs_symlink(KC_VFS_NS_DEF struct scoutfs_lock *dir_lock = NULL; struct scoutfs_lock *inode_lock = NULL; struct scoutfs_inode_info *si; + struct timespec64 cur_time; LIST_HEAD(ind_locks); u64 hash; u64 pos; @@ -1251,11 +1260,13 @@ static int scoutfs_symlink(KC_VFS_NS_DEF set_dentry_fsdata(dentry, dir_lock); i_size_write(dir, i_size_read(dir) + dentry->d_name.len); - dir->i_mtime = dir->i_ctime = current_time(inode); + cur_time = current_time(inode); + inode_set_mtime_to_ts(dir, cur_time); + inode_set_ctime_to_ts(dir, cur_time); inode_inc_iversion(dir); - inode->i_ctime = dir->i_mtime; - si->crtime = inode->i_ctime; + inode_set_ctime_to_ts(inode, inode_get_mtime(dir)); + si->crtime = inode_get_ctime(inode); i_size_write(inode, name_len); inode_inc_iversion(inode); scoutfs_forest_inc_inode_count(sb); @@ -1780,15 +1791,15 @@ static int scoutfs_rename_common(KC_VFS_NS_DEF } now = current_time(old_inode); - old_dir->i_ctime = now; - old_dir->i_mtime = now; + inode_set_ctime_to_ts(old_dir, now); + inode_set_mtime_to_ts(old_dir, now); if (new_dir != old_dir) { - new_dir->i_ctime = now; - new_dir->i_mtime = now; + inode_set_ctime_to_ts(new_dir, now); + inode_set_mtime_to_ts(new_dir, now); } - old_inode->i_ctime = now; + inode_set_ctime_to_ts(old_inode, now); if (new_inode) - new_inode->i_ctime = now; + inode_set_ctime_to_ts(new_inode, now); inode_inc_iversion(old_dir); inode_inc_iversion(old_inode); @@ -1886,6 +1897,7 @@ static int scoutfs_tmpfile(KC_VFS_NS_DEF struct scoutfs_lock *inode_lock = NULL; struct scoutfs_lock *orph_lock = NULL; struct scoutfs_inode_info *si; + struct timespec64 cur_time; LIST_HEAD(ind_locks); int ret; @@ -1902,8 +1914,11 @@ static int scoutfs_tmpfile(KC_VFS_NS_DEF if (ret < 0) goto out; /* XXX returning error but items created */ - inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); - si->crtime = inode->i_mtime; + cur_time = current_time(inode); + inode_set_mtime_to_ts(inode, cur_time); + inode_set_ctime_to_ts(inode, cur_time); + inode_set_atime_to_ts(inode, cur_time); + si->crtime = inode_get_mtime(inode); insert_inode_hash(inode); ihold(inode); /* need to update inode modifications in d_tmpfile */ #ifdef KC_D_TMPFILE_DENTRY @@ -1956,7 +1971,11 @@ const struct inode_operations scoutfs_symlink_iops = { }; const struct file_operations scoutfs_dir_fops = { +#ifdef KC_HAVE_ITERATE_SHARED + .iterate_shared = scoutfs_readdir, +#else .iterate = scoutfs_readdir, +#endif .unlocked_ioctl = scoutfs_ioctl, .fsync = scoutfs_file_fsync, .llseek = generic_file_llseek, diff --git a/kmod/src/fence.c b/kmod/src/fence.c index a3579228..db19fa61 100644 --- a/kmod/src/fence.c +++ b/kmod/src/fence.c @@ -219,6 +219,9 @@ static struct attribute *fence_attrs[] = { SCOUTFS_ATTR_PTR(rid), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(fence); +#endif #define FENCE_TIMEOUT_MS (MSEC_PER_SEC * 30) @@ -274,7 +277,8 @@ int scoutfs_fence_start(struct super_block *sb, u64 rid, __be32 ipv4_addr, int r goto unlock; ret = scoutfs_sysfs_create_attrs_parent(sb, &fi->kset->kobj, - &fence->ssa, fence_attrs, + &fence->ssa, + KC_KOBJ_DEFAULT(fence), "%016llx", rid); if (ret < 0) goto unlock; diff --git a/kmod/src/file.c b/kmod/src/file.c index 730a6625..1968a044 100644 --- a/kmod/src/file.c +++ b/kmod/src/file.c @@ -154,7 +154,7 @@ static ssize_t scoutfs_file_direct_read(struct kiocb *iocb, struct iov_iter *to, retry: pagefault_disable(); to->nofault = true; - ret = iomap_dio_rw(iocb, to, &scoutfs_iomap_ops, NULL, IOMAP_DIO_PARTIAL, read); + ret = KC_IOMAP_DIO_RW(iocb, to, &scoutfs_iomap_ops, NULL, IOMAP_DIO_PARTIAL, read); to->nofault = false; pagefault_enable(); @@ -336,9 +336,9 @@ static ssize_t scoutfs_file_direct_write(struct kiocb *iocb, struct iov_iter *fr * any needed pages later on. */ from->nofault = true; - ret = iomap_dio_rw(iocb, from, &scoutfs_iomap_ops, NULL, - IOMAP_DIO_PARTIAL | IOMAP_DIO_FORCE_WAIT, - written); + ret = KC_IOMAP_DIO_RW(iocb, from, &scoutfs_iomap_ops, NULL, + IOMAP_DIO_PARTIAL | IOMAP_DIO_FORCE_WAIT, + written); from->nofault = false; if (ret <= 0) { @@ -410,7 +410,7 @@ static ssize_t scoutfs_file_buffered_write(struct kiocb *iocb, struct iov_iter * locked = true; pagefault_disable(); - ret = iomap_file_buffered_write(iocb, from, &scoutfs_iomap_ops); + ret = KC_IOMAP_FILE_BUFFERED_WRITE(iocb, from, &scoutfs_iomap_ops); pagefault_enable(); /* Accumulate the count of what's been written so far */ diff --git a/kmod/src/inode.c b/kmod/src/inode.c index 6db15554..8a846529 100644 --- a/kmod/src/inode.c +++ b/kmod/src/inode.c @@ -258,12 +258,9 @@ static void load_inode(struct inode *inode, struct scoutfs_inode *cinode, int in i_gid_write(inode, le32_to_cpu(cinode->gid)); inode->i_mode = le32_to_cpu(cinode->mode); inode->i_rdev = le32_to_cpu(cinode->rdev); - inode->i_atime.tv_sec = le64_to_cpu(cinode->atime.sec); - inode->i_atime.tv_nsec = le32_to_cpu(cinode->atime.nsec); - inode->i_mtime.tv_sec = le64_to_cpu(cinode->mtime.sec); - inode->i_mtime.tv_nsec = le32_to_cpu(cinode->mtime.nsec); - inode->i_ctime.tv_sec = le64_to_cpu(cinode->ctime.sec); - inode->i_ctime.tv_nsec = le32_to_cpu(cinode->ctime.nsec); + inode_set_atime(inode, le64_to_cpu(cinode->atime.sec), le32_to_cpu(cinode->atime.nsec)); + inode_set_mtime(inode, le64_to_cpu(cinode->mtime.sec), le32_to_cpu(cinode->mtime.nsec)); + inode_set_ctime(inode, le64_to_cpu(cinode->ctime.sec), le32_to_cpu(cinode->ctime.nsec)); si->meta_seq = le64_to_cpu(cinode->meta_seq); si->data_seq = le64_to_cpu(cinode->data_seq); @@ -377,6 +374,7 @@ int scoutfs_getattr(KC_VFS_NS_DEF SCOUTFS_LKF_REFRESH_INODE, inode, &lock); if (ret == 0) { generic_fillattr(KC_VFS_INIT_NS + KC_FILLATTR_REQUEST_MASK inode, stat); scoutfs_unlock(sb, lock, SCOUTFS_LOCK_READ); } @@ -388,6 +386,7 @@ static int set_inode_size(struct inode *inode, struct scoutfs_lock *lock, { struct scoutfs_inode_info *si = SCOUTFS_I(inode); struct super_block *sb = inode->i_sb; + struct timespec64 cur_time; SCOUTFS_DECLARE_PER_TASK_ENTRY(pt_ent); LIST_HEAD(ind_locks); int ret; @@ -412,7 +411,9 @@ static int set_inode_size(struct inode *inode, struct scoutfs_lock *lock, scoutfs_inode_inc_data_version(inode); truncate_setsize(inode, new_size); - inode->i_ctime = inode->i_mtime = current_time(inode); + cur_time = current_time(inode); + inode_set_ctime_to_ts(inode, cur_time); + inode_set_mtime_to_ts(inode, cur_time); if (truncate) si->flags |= SCOUTFS_INO_FLAG_TRUNCATE; scoutfs_inode_set_data_seq(inode); @@ -880,14 +881,14 @@ static void store_inode(struct scoutfs_inode *cinode, struct inode *inode, int i cinode->gid = cpu_to_le32(i_gid_read(inode)); cinode->mode = cpu_to_le32(inode->i_mode); cinode->rdev = cpu_to_le32(inode->i_rdev); - cinode->atime.sec = cpu_to_le64(inode->i_atime.tv_sec); - cinode->atime.nsec = cpu_to_le32(inode->i_atime.tv_nsec); + cinode->atime.sec = cpu_to_le64(inode_get_atime_sec(inode)); + cinode->atime.nsec = cpu_to_le32(inode_get_atime_nsec(inode)); memset(cinode->atime.__pad, 0, sizeof(cinode->atime.__pad)); - cinode->ctime.sec = cpu_to_le64(inode->i_ctime.tv_sec); - cinode->ctime.nsec = cpu_to_le32(inode->i_ctime.tv_nsec); + cinode->ctime.sec = cpu_to_le64(inode_get_ctime_sec(inode)); + cinode->ctime.nsec = cpu_to_le32(inode_get_ctime_nsec(inode)); memset(cinode->ctime.__pad, 0, sizeof(cinode->ctime.__pad)); - cinode->mtime.sec = cpu_to_le64(inode->i_mtime.tv_sec); - cinode->mtime.nsec = cpu_to_le32(inode->i_mtime.tv_nsec); + cinode->mtime.sec = cpu_to_le64(inode_get_mtime_sec(inode)); + cinode->mtime.nsec = cpu_to_le32(inode_get_mtime_nsec(inode)); memset(cinode->mtime.__pad, 0, sizeof(cinode->mtime.__pad)); cinode->meta_seq = cpu_to_le64(scoutfs_inode_meta_seq(inode)); @@ -1545,6 +1546,7 @@ int scoutfs_new_inode(struct super_block *sb, struct inode *dir, umode_t mode, d struct scoutfs_inode sinode; struct scoutfs_key key; struct inode *inode; + struct timespec64 cur_time; int inode_bytes; int ret; @@ -1574,7 +1576,10 @@ int scoutfs_new_inode(struct super_block *sb, struct inode *dir, umode_t mode, d inode_init_owner(KC_VFS_INIT_NS inode, dir, mode); inode_set_bytes(inode, 0); - inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode); + cur_time = current_time(inode); + inode_set_mtime_to_ts(inode, cur_time); + inode_set_atime_to_ts(inode, cur_time); + inode_set_ctime_to_ts(inode, cur_time); inode->i_rdev = rdev; set_inode_ops(inode); @@ -2047,7 +2052,7 @@ void scoutfs_inode_schedule_orphan_dwork(struct super_block *sb) low = (opts.orphan_scan_delay_ms * 80) / 100; high = (opts.orphan_scan_delay_ms * 120) / 100; - delay = msecs_to_jiffies(low + prandom_u32_max(high - low)) ?: 1; + delay = msecs_to_jiffies(low + get_random_u32_below(high - low)) ?: 1; mod_delayed_work(system_wq, &inf->orphan_scan_dwork, delay); } diff --git a/kmod/src/iomap.h b/kmod/src/iomap.h index 3d4c8547..27c2a971 100644 --- a/kmod/src/iomap.h +++ b/kmod/src/iomap.h @@ -3,6 +3,5 @@ extern const struct iomap_ops scoutfs_iomap_report_ops; extern const struct iomap_ops scoutfs_iomap_ops; -extern const struct iomap_page_ops scoutfs_iomap_page_ops; #endif diff --git a/kmod/src/item.c b/kmod/src/item.c index fdeb7c9e..650e261c 100644 --- a/kmod/src/item.c +++ b/kmod/src/item.c @@ -143,7 +143,7 @@ struct cached_item { unsigned int val_len; struct scoutfs_key key; u64 seq; - char val[0]; + char val[]; }; #define CACHED_ITEM_ALIGN 8 @@ -421,7 +421,7 @@ static struct cached_item *alloc_item(struct cached_page *pg, item->seq = seq; if (val_len) - memcpy(item->val, val, val_len); + memcpy(&item->val[0], val, val_len); update_pg_max_seq(pg, item); @@ -1996,7 +1996,7 @@ int scoutfs_item_update(struct super_block *sb, struct scoutfs_key *key, if (val_len <= found->val_len) { if (val_len) - memcpy(found->val, val, val_len); + memcpy(&found->val[0], val, val_len); if (val_len < found->val_len) pg->erased_bytes += item_val_bytes(found->val_len) - item_val_bytes(val_len); @@ -2313,7 +2313,7 @@ int scoutfs_item_write_dirty(struct super_block *sb) lst->seq = item->seq; lst->flags = item->deletion ? SCOUTFS_ITEM_FLAG_DELETION : 0; lst->val_len = item->val_len; - memcpy(lst->val, item->val, item->val_len); + memcpy(&lst->val[0], item->val, item->val_len); } spin_lock(&cinf->dirty_lock); @@ -2607,10 +2607,10 @@ int scoutfs_item_setup(struct super_block *sb) for_each_possible_cpu(cpu) init_pcpu_pages(cinf, cpu); - - KC_INIT_SHRINKER_FUNCS(&cinf->shrinker, item_cache_count_objects, - item_cache_scan_objects); - KC_REGISTER_SHRINKER(&cinf->shrinker, "scoutfs-item:" SCSBF, SCSB_ARGS(sb)); + KC_SETUP_SHRINKER(cinf->shrinker, cinf, 0, item_cache_count_objects, + item_cache_scan_objects, "scoutfs-item:" SCSBF, SCSB_ARGS(sb)); + if (KC_SHRINKER_IS_NULL(cinf->shrinker)) + return -ENOMEM; sbi->item_cache_info = cinf; return 0; @@ -2628,7 +2628,7 @@ void scoutfs_item_destroy(struct super_block *sb) int cpu; if (cinf) { - KC_UNREGISTER_SHRINKER(&cinf->shrinker); + KC_UNREGISTER_SHRINKER(cinf->shrinker); for_each_possible_cpu(cpu) drop_pcpu_pages(sb, cinf, cpu); diff --git a/kmod/src/kernelcompat.c b/kmod/src/kernelcompat.c index 6457728f..74c8a851 100644 --- a/kmod/src/kernelcompat.c +++ b/kmod/src/kernelcompat.c @@ -36,3 +36,13 @@ unsigned long kc_list_lru_shrink_walk(struct list_lru *lru, struct shrink_contro } #endif + +#ifndef KC_FS_INODE_C_TIME_ACCESSOR +struct timespec64 inode_set_ctime_current(struct inode *inode) +{ + struct timespec64 now = current_time(inode); + + inode_set_ctime(inode, now.tv_sec, now.tv_nsec); + return now; +} +#endif diff --git a/kmod/src/kernelcompat.h b/kmod/src/kernelcompat.h index cfa78214..86dec4b7 100644 --- a/kmod/src/kernelcompat.h +++ b/kmod/src/kernelcompat.h @@ -4,22 +4,53 @@ #include #include -#define KC_DEFINE_SHRINKER(name) struct shrinker name -#define KC_INIT_SHRINKER_FUNCS(name, countfn, scanfn) do { \ - __typeof__(name) _shrink = (name); \ - _shrink->count_objects = (countfn); \ - _shrink->scan_objects = (scanfn); \ - _shrink->seeks = DEFAULT_SEEKS; \ +#ifdef KC_SHRINKER_ALLOC +// el10+ + +#define KC_DEFINE_SHRINKER(name) struct shrinker *(name) +#define KC_SHRINKER_CONTAINER_OF(ptr, type) ptr->private_data +#define KC_SETUP_SHRINKER(ptr, priv, flags, countfn, scanfn, fmt, args) \ +do { \ + ptr = shrinker_alloc(flags, fmt, args); \ + if (ptr) { \ + ptr->private_data = (priv); \ + ptr->seeks = DEFAULT_SEEKS; \ + ptr->count_objects = countfn; \ + ptr->scan_objects = scanfn; \ + shrinker_register(ptr); \ + } \ } while (0) +#define KC_UNREGISTER_SHRINKER(ptr) shrinker_free(ptr) +#define KC_SHRINKER_FN(ptr) (ptr) +#define KC_SHRINKER_IS_NULL(ptr) (!(ptr)) + +#else /* KC_SHRINKER_ALLOC */ +// el9, el8 +#define KC_DEFINE_SHRINKER(name) struct shrinker (name) #define KC_SHRINKER_CONTAINER_OF(ptr, type) container_of(ptr, type, shrinker) #ifdef KC_SHRINKER_NAME -#define KC_REGISTER_SHRINKER register_shrinker +#define KC_SETUP_SHRINKER(ptr, priv, flags, countfn, scanfn, fmt, args) \ +do { \ + (ptr).count_objects = (countfn); \ + (ptr).scan_objects = (scanfn); \ + (ptr).seeks = DEFAULT_SEEKS; \ + register_shrinker(&(ptr), fmt, args); \ +} while (0) #else -#define KC_REGISTER_SHRINKER(ptr, fmt, ...) (register_shrinker(ptr)) +#define KC_SETUP_SHRINKER(ptr, priv, flags, countfn, scanfn, fmt, args) \ +do { \ + (ptr).count_objects = (countfn); \ + (ptr).scan_objects = (scanfn); \ + (ptr).seeks = DEFAULT_SEEKS; \ + register_shrinker(&(ptr)); \ +} while (0) #endif /* KC_SHRINKER_NAME */ -#define KC_UNREGISTER_SHRINKER(ptr) (unregister_shrinker(ptr)) -#define KC_SHRINKER_FN(ptr) (ptr) +#define KC_UNREGISTER_SHRINKER(ptr) (unregister_shrinker(&(ptr))) +#define KC_SHRINKER_FN(ptr) (&ptr) +#define KC_SHRINKER_IS_NULL(ptr) (0) + +#endif /* KC_SHRINKER_ALLOC */ #ifdef KC_GENERIC_PERFORM_WRITE_KIOCB_IOV_ITER static inline int kc_generic_perform_write(struct kiocb *iocb, struct iov_iter *iter, loff_t pos) @@ -68,6 +99,12 @@ typedef unsigned int blk_opf_t; #endif #endif /* KC_VFS_METHOD_MNT_IDMAP_ARG */ +#ifdef KC_GENERIC_FILLATTR_REQUEST_MASK +#define KC_FILLATTR_REQUEST_MASK request_mask, +#else +#define KC_FILLATTR_REQUEST_MASK +#endif + #ifdef KC_BIO_ALLOC_DEV_OPF_ARGS #define kc_bio_alloc bio_alloc #else @@ -205,6 +242,156 @@ unsigned long kc_list_lru_shrink_walk(struct list_lru *lru, struct shrink_contro kc_list_lru_walk_cb_t isolate, void *cb_arg); #else #define kc_list_lru_shrink_walk list_lru_shrink_walk +#define kc_list_lru_walk list_lru_walk +#endif + +#ifndef KC_HAVE_GET_RANDOM_U32_BELOW +#define get_random_u32_below prandom_u32_max +#endif + +#ifndef KC_FS_INODE_C_TIME_ACCESSOR +struct timespec64 inode_set_ctime_current(struct inode *inode); +static inline struct timespec64 inode_set_ctime_to_ts(struct inode *inode, + struct timespec64 ts) +{ + inode->i_ctime.tv_sec = ts.tv_sec; + inode->i_ctime.tv_nsec = ts.tv_nsec; + return ts; +} + +static inline struct timespec64 inode_set_ctime(struct inode *inode, + time64_t sec, long nsec) +{ + struct timespec64 ts = { .tv_sec = sec, + .tv_nsec = nsec }; + + return inode_set_ctime_to_ts(inode, ts); +} + +static inline struct timespec64 inode_get_ctime(const struct inode *inode) +{ + struct timespec64 ts = { .tv_sec = inode->i_ctime.tv_sec, + .tv_nsec = inode->i_ctime.tv_nsec }; + return ts; +} +#endif + +#ifndef KC_FS_INODE_AM_TIME_ACCESSOR +static inline struct timespec64 inode_get_mtime(const struct inode *inode) +{ + struct timespec64 ts = { .tv_sec = inode->i_mtime.tv_sec, + .tv_nsec = inode->i_mtime.tv_nsec }; + return ts; +} + +static inline struct timespec64 inode_set_mtime_to_ts(struct inode *inode, + struct timespec64 ts) +{ + inode->i_mtime.tv_sec = ts.tv_sec; + inode->i_mtime.tv_nsec = ts.tv_nsec; + return ts; +} + +static inline struct timespec64 inode_set_mtime(struct inode *inode, + time64_t sec, long nsec) +{ + struct timespec64 ts = { .tv_sec = sec, + .tv_nsec = nsec }; + + return inode_set_mtime_to_ts(inode, ts); +} + +static inline struct timespec64 inode_set_atime_to_ts(struct inode *inode, + struct timespec64 ts) +{ + inode->i_atime.tv_sec = ts.tv_sec; + inode->i_atime.tv_nsec = ts.tv_nsec; + return ts; +} + +static inline struct timespec64 inode_set_atime(struct inode *inode, + time64_t sec, long nsec) +{ + struct timespec64 ts = { .tv_sec = sec, + .tv_nsec = nsec }; + + return inode_set_atime_to_ts(inode, ts); +} + +static inline time64_t inode_get_ctime_sec(const struct inode *inode) +{ + return inode->i_ctime.tv_sec; +} +static inline long inode_get_ctime_nsec(const struct inode *inode) +{ + return inode->i_ctime.tv_nsec; +} +static inline time64_t inode_get_mtime_sec(const struct inode *inode) +{ + return inode->i_mtime.tv_sec; +} +static inline long inode_get_mtime_nsec(const struct inode *inode) +{ + return inode->i_mtime.tv_nsec; +} +static inline time64_t inode_get_atime_sec(const struct inode *inode) +{ + return inode->i_atime.tv_sec; +} +static inline long inode_get_atime_nsec(const struct inode *inode) +{ + return inode->i_atime.tv_nsec; +} +#endif + +#ifdef KC_HAVE_BD_INODE +#define KC_BDEV_INODE(b) (b)->bd_inode +#define KC_BDEV_MAPPING(b) (b)->bd_inode->i_mapping +#else +#define KC_BDEV_INODE(b) (b)->bd_mapping->host +#define KC_BDEV_MAPPING(b) (b)->bd_mapping +#endif + +#ifdef KC_HAVE_ASSIGN_STR_PARMS +#define kc__assign_str(a, b) __assign_str(a, b) +#else +#define kc__assign_str(a, b) __assign_str(a) +#endif + +#ifdef KC_KOBJECT_DEFAULT_GROUPS +#define KC_KOBJ_DEFAULT_OP default_groups +#define KC_KOBJ_DEFAULT(name) (name##_groups) +#define KC_KOBJ_DEFAULT_PICK(group, attrs) (group) +#else +#define KC_KOBJ_DEFAULT_OP default_attrs +#define KC_KOBJ_DEFAULT(name) (name##_attrs) +#define KC_KOBJ_DEFAULT_PICK(group, attrs) (attrs) +#endif + +#ifdef KC_BLOCK_WRITE_BEGIN_FOLIO +#define KC_PAGE_OR_FOLIO(p, f) f +#else +#define KC_PAGE_OR_FOLIO(p, f) p +#endif + +/* + * We don't have any per-iter state or write ops of our own, so we just + * pass in nulls for the newer arguments. + */ +#ifdef KC_IOMAP_DIO_RW_PRIVATE +#define KC_IOMAP_DIO_RW(iocb, iter, ops, dops, dio_flags, done_before) \ + iomap_dio_rw(iocb, iter, ops, dops, dio_flags, NULL, done_before) +#else +#define KC_IOMAP_DIO_RW(iocb, iter, ops, dops, dio_flags, done_before) \ + iomap_dio_rw(iocb, iter, ops, dops, dio_flags, done_before) +#endif + +#ifdef KC_IOMAP_WRITE_OPS +#define KC_IOMAP_FILE_BUFFERED_WRITE(iocb, iter, ops) \ + iomap_file_buffered_write(iocb, iter, ops, NULL, NULL) +#else +#define KC_IOMAP_FILE_BUFFERED_WRITE(iocb, iter, ops) \ + iomap_file_buffered_write(iocb, iter, ops) #endif #ifndef KC_TIMER_CONTAINER_OF diff --git a/kmod/src/options.c b/kmod/src/options.c index 1ff6e55f..14642c94 100644 --- a/kmod/src/options.c +++ b/kmod/src/options.c @@ -752,13 +752,18 @@ static struct attribute *options_attrs[] = { SCOUTFS_ATTR_PTR(quorum_slot_nr), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(options); +#endif int scoutfs_options_setup(struct super_block *sb) { DECLARE_OPTIONS_INFO(sb, optinf); int ret; - ret = scoutfs_sysfs_create_attrs(sb, &optinf->sysfs_attrs, options_attrs, "mount_options"); + ret = scoutfs_sysfs_create_attrs(sb, &optinf->sysfs_attrs, + KC_KOBJ_DEFAULT_PICK(options_groups, options_attrs), + "mount_options"); if (ret < 0) scoutfs_options_destroy(sb); return ret; diff --git a/kmod/src/quorum.c b/kmod/src/quorum.c index d87033c5..c45f0fd9 100644 --- a/kmod/src/quorum.c +++ b/kmod/src/quorum.c @@ -162,7 +162,7 @@ static void quorum_slot_sin(struct scoutfs_quorum_config *qconf, int i, struct s static ktime_t election_timeout(void) { return ktime_add_ms(ktime_get(), SCOUTFS_QUORUM_ELECT_MIN_MS + - prandom_u32_max(SCOUTFS_QUORUM_ELECT_VAR_MS)); + get_random_u32_below(SCOUTFS_QUORUM_ELECT_VAR_MS)); } static ktime_t heartbeat_interval(void) @@ -1192,6 +1192,9 @@ static struct attribute *quorum_attrs[] = { SCOUTFS_ATTR_PTR(is_leader), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(quorum); +#endif static inline bool valid_ipv4_unicast(__be32 addr) { @@ -1351,7 +1354,7 @@ int scoutfs_quorum_setup(struct super_block *sb) if (ret < 0) goto out; - ret = scoutfs_sysfs_create_attrs(sb, &qinf->ssa, quorum_attrs, + ret = scoutfs_sysfs_create_attrs(sb, &qinf->ssa, KC_KOBJ_DEFAULT(quorum), "quorum"); if (ret < 0) goto out; diff --git a/kmod/src/quota.c b/kmod/src/quota.c index cb2b0b4f..ac6752f2 100644 --- a/kmod/src/quota.c +++ b/kmod/src/quota.c @@ -205,7 +205,7 @@ static struct squota_check *lookup_random_check(struct rhashtable *rht) tbl = rht_dereference_rcu(rht->tbl, rht); do { - for (s = 0, i = prandom_u32_max(tbl->size); + for (s = 0, i = get_random_u32_below(tbl->size); s < tbl->size; s++, i = (i + 1) % tbl->size) { rht_for_each_entry_rcu(chk, pos, tbl, i, head) { @@ -270,7 +270,7 @@ static void shrink_all_cached_checks(struct squota_info *qtinf) { struct shrink_control sc = { .nr_to_scan = LONG_MAX, }; - scan_cached_checks(KC_SHRINKER_FN(&qtinf->shrinker), &sc); + scan_cached_checks(KC_SHRINKER_FN(qtinf->shrinker), &sc); } static u8 ns_is_attr(u8 ns) @@ -1235,8 +1235,12 @@ int scoutfs_quota_setup(struct super_block *sb) spin_lock_init(&qtinf->lock); init_waitqueue_head(&qtinf->waitq); - KC_INIT_SHRINKER_FUNCS(&qtinf->shrinker, count_cached_checks, scan_cached_checks); - KC_REGISTER_SHRINKER(&qtinf->shrinker, "scoutfs-quota:" SCSBF, SCSB_ARGS(sb)); + KC_SETUP_SHRINKER(qtinf->shrinker, qtinf, 0, count_cached_checks, + scan_cached_checks, "scoutfs-quota:" SCSBF, SCSB_ARGS(sb)); + if (KC_SHRINKER_IS_NULL(qtinf->shrinker)) { + ret = -ENOMEM; + goto out; + } sbi->squota_info = qtinf; @@ -1260,7 +1264,7 @@ void scoutfs_quota_destroy(struct super_block *sb) if (qtinf) { debugfs_remove(qtinf->drop_dentry); - KC_UNREGISTER_SHRINKER(&qtinf->shrinker); + KC_UNREGISTER_SHRINKER(qtinf->shrinker); spin_lock(&qtinf->lock); rs = rcu_dereference_protected(qtinf->ruleset, lockdep_is_held(&qtinf->lock)); diff --git a/kmod/src/scoutfs_trace.h b/kmod/src/scoutfs_trace.h index 90fbc0aa..29f8c065 100644 --- a/kmod/src/scoutfs_trace.h +++ b/kmod/src/scoutfs_trace.h @@ -102,7 +102,7 @@ TRACE_EVENT(scoutfs_setattr, SCSB_TRACE_ASSIGN(dentry->d_inode->i_sb); __entry->ino = scoutfs_ino(dentry->d_inode); __entry->d_len = dentry->d_name.len; - __assign_str(d_name, dentry->d_name.name); + kc__assign_str(d_name, dentry->d_name.name); __entry->ia_valid = attr->ia_valid; __entry->size_change = !!(attr->ia_valid & ATTR_SIZE); __entry->ia_size = attr->ia_size; @@ -1638,9 +1638,9 @@ TRACE_EVENT(scoutfs_rename, TP_fast_assign( SCSB_TRACE_ASSIGN(sb); __entry->old_dir_ino = scoutfs_ino(old_dir); - __assign_str(old_name, old_dentry->d_name.name) + kc__assign_str(old_name, old_dentry->d_name.name); __entry->new_dir_ino = scoutfs_ino(new_dir); - __assign_str(new_name, new_dentry->d_name.name) + kc__assign_str(new_name, new_dentry->d_name.name); __entry->new_inode_ino = new_dentry->d_inode ? scoutfs_ino(new_dentry->d_inode) : 0; ), @@ -1670,7 +1670,7 @@ TRACE_EVENT(scoutfs_d_revalidate, TP_fast_assign( SCSB_TRACE_ASSIGN(sb); __entry->dentry = dentry; - __assign_str(name, dentry->d_name.name) + kc__assign_str(name, dentry->d_name.name); __entry->ino = dentry->d_inode ? scoutfs_ino(dentry->d_inode) : 0; __entry->dir_ino = dir_ino; __entry->flags = flags; @@ -1705,7 +1705,7 @@ TRACE_EVENT(scoutfs_validate_dentry, SCSB_TRACE_ASSIGN(sb); __entry->dentry = dentry; __entry->dir_ino = dir_ino; - __assign_str(name, dentry->d_name.name) + kc__assign_str(name, dentry->d_name.name); __entry->dentry_ino = dentry_ino; __entry->dent_ino = dent_ino; __entry->fsdata_gen = (unsigned long long)dentry->d_fsdata; @@ -1827,7 +1827,7 @@ TRACE_EVENT(scoutfs_get_name, SCSB_TRACE_ASSIGN(sb); __entry->parent_ino = scoutfs_ino(parent); __entry->child_ino = scoutfs_ino(child); - __assign_str(name, name); + kc__assign_str(name, name); ), TP_printk(SCSBF" parent %llu child %llu name: %s", diff --git a/kmod/src/server.c b/kmod/src/server.c index 73a8bfa7..6ef7437c 100644 --- a/kmod/src/server.c +++ b/kmod/src/server.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "format.h" #include "counters.h" @@ -3476,7 +3475,7 @@ static int server_clear_volopt(struct super_block *sb, struct scoutfs_net_connec static u64 device_blocks(struct block_device *bdev, int shift) { - return i_size_read(bdev->bd_inode) >> shift; + return i_size_read(KC_BDEV_INODE(bdev)) >> shift; } static int server_resize_devices(struct super_block *sb, struct scoutfs_net_connection *conn, diff --git a/kmod/src/srch.c b/kmod/src/srch.c index c4ce1b79..01018e28 100644 --- a/kmod/src/srch.c +++ b/kmod/src/srch.c @@ -18,7 +18,11 @@ #include #include #include +#ifdef KC_HAVE__LINUX_UNALIGNED_H +#include +#else #include +#endif #include "super.h" #include "format.h" @@ -2346,6 +2350,9 @@ static struct attribute *srch_attrs[] = { SCOUTFS_ATTR_PTR(compact_delay_ms), NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(srch); +#endif void scoutfs_srch_destroy(struct super_block *sb) { @@ -2387,7 +2394,8 @@ int scoutfs_srch_setup(struct super_block *sb) sbi->srch_info = srinf; - ret = scoutfs_sysfs_create_attrs(sb, &srinf->ssa, srch_attrs, "srch"); + ret = scoutfs_sysfs_create_attrs(sb, &srinf->ssa, KC_KOBJ_DEFAULT(srch), + "srch"); if (ret < 0) goto out; diff --git a/kmod/src/super.c b/kmod/src/super.c index f2e1420f..978af1c3 100644 --- a/kmod/src/super.c +++ b/kmod/src/super.c @@ -283,7 +283,7 @@ int scoutfs_write_super(struct super_block *sb, static bool small_bdev(struct super_block *sb, char *which, u64 blocks, struct block_device *bdev, int shift) { - u64 size = (u64)i_size_read(bdev->bd_inode); + u64 size = (u64)i_size_read(KC_BDEV_INODE(bdev)); u64 count = size >> shift; if (blocks > count) { @@ -508,7 +508,7 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent) sb->s_time_gran = 1; /* btree blocks use long lived bh->b_data refs */ - mapping_set_gfp_mask(sb->s_bdev->bd_inode->i_mapping, GFP_NOFS); + mapping_set_gfp_mask(KC_BDEV_MAPPING(sb->s_bdev), GFP_NOFS); sbi = kzalloc(sizeof(struct scoutfs_sb_info), GFP_KERNEL); sb->s_fs_info = sbi; @@ -552,6 +552,7 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent) } sbi->meta_bdev_file = meta_bdev_file; sbi->meta_bdev = file_bdev(meta_bdev_file); + #else #ifdef KC_BLKDEV_PUT_HOLDER_ARG meta_bdev = blkdev_get_by_path(opts.metadev_path, SCOUTFS_META_BDEV_MODE, sb, NULL); @@ -567,7 +568,11 @@ static int scoutfs_fill_super(struct super_block *sb, void *data, int silent) sbi->meta_bdev = meta_bdev; #endif +#ifdef KC_BLKDEV_SET_BLOCKSIZE_FILE + ret = set_blocksize(sbi->meta_bdev_file, SCOUTFS_BLOCK_SM_SIZE); +#else ret = set_blocksize(sbi->meta_bdev, SCOUTFS_BLOCK_SM_SIZE); +#endif if (ret != 0) { scoutfs_err(sb, "failed to set metadev blocksize, returned %d", ret); diff --git a/kmod/src/sysfs.c b/kmod/src/sysfs.c index b3c7ddbf..3b7e176f 100644 --- a/kmod/src/sysfs.c +++ b/kmod/src/sysfs.c @@ -103,12 +103,11 @@ static ssize_t attr_funcs_show(struct kobject *kobj, struct attribute *attr, }; \ \ static struct kobj_type _name##_ktype = { \ - .default_attrs = _name##_attrs, \ + .KC_KOBJ_DEFAULT_OP = KC_KOBJ_DEFAULT(_name), \ .sysfs_ops = &_name##_sysfs_ops, \ .release = _name##_release, \ }; - static struct attribute *sb_id_attrs[] = { &data_device_maj_min_attr_funcs.attr, &format_version_attr_funcs.attr, @@ -116,6 +115,9 @@ static struct attribute *sb_id_attrs[] = { &rid_attr_funcs.attr, NULL, }; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +ATTRIBUTE_GROUPS(sb_id); +#endif KTYPE(sb_id); struct kobject *scoutfs_sysfs_sb_dir(struct super_block *sb) @@ -155,7 +157,12 @@ void scoutfs_sysfs_init_attrs(struct super_block *sb, int scoutfs_sysfs_create_attrs_parent(struct super_block *sb, struct kobject *parent, struct scoutfs_sysfs_attrs *ssa, - struct attribute **attrs, char *fmt, ...) +#ifdef KC_KOBJECT_DEFAULT_GROUPS + const struct attribute_group **groups, +#else + struct attribute **attrs, +#endif + char *fmt, ...) { va_list args; size_t name_len; @@ -168,7 +175,11 @@ int scoutfs_sysfs_create_attrs_parent(struct super_block *sb, ssa->sb = sb; init_completion(&ssa->comp); +#ifdef KC_KOBJECT_DEFAULT_GROUPS + ssa->ktype.default_groups = groups; +#else ssa->ktype.default_attrs = attrs; +#endif ssa->ktype.sysfs_ops = &kobj_sysfs_ops; ssa->ktype.release = scoutfs_sysfs_release; diff --git a/kmod/src/sysfs.h b/kmod/src/sysfs.h index 70b85af8..177e98f7 100644 --- a/kmod/src/sysfs.h +++ b/kmod/src/sysfs.h @@ -39,10 +39,15 @@ void scoutfs_sysfs_init_attrs(struct super_block *sb, int scoutfs_sysfs_create_attrs_parent(struct super_block *sb, struct kobject *parent, struct scoutfs_sysfs_attrs *ssa, - struct attribute **attrs, char *fmt, ...); -#define scoutfs_sysfs_create_attrs(sb, ssa, attrs, fmt, args...) \ +#ifdef KC_KOBJECT_DEFAULT_GROUPS + const struct attribute_group **groups, +#else + struct attribute **attrs, +#endif + char *fmt, ...); +#define scoutfs_sysfs_create_attrs(sb, ssa, group_or_attrs, fmt, args...) \ scoutfs_sysfs_create_attrs_parent(sb, scoutfs_sysfs_sb_dir(sb), \ - ssa, attrs, fmt, ##args) + ssa, group_or_attrs, fmt, ##args) void scoutfs_sysfs_destroy_attrs(struct super_block *sb, struct scoutfs_sysfs_attrs *ssa); diff --git a/kmod/src/volopt.c b/kmod/src/volopt.c index 303d94b0..b87e4ac5 100644 --- a/kmod/src/volopt.c +++ b/kmod/src/volopt.c @@ -52,6 +52,15 @@ static struct volopt_nr_name { /* initialized by setup, pointer array is null terminated */ static struct kobj_attribute volopt_attrs[ARRAY_SIZE(volopt_table)]; static struct attribute *volopt_attr_ptrs[ARRAY_SIZE(volopt_table) + 1]; +#ifdef KC_KOBJECT_DEFAULT_GROUPS +static const struct attribute_group volopt_group = { + .attrs = volopt_attr_ptrs, +}; +static const struct attribute_group *volopt_groups[] = { + &volopt_group, + NULL, +}; +#endif static void get_opt_data(struct kobj_attribute *attr, struct scoutfs_volume_options *volopt, u64 *bit, __le64 **opt) @@ -164,7 +173,9 @@ int scoutfs_volopt_setup(struct super_block *sb) BUILD_BUG_ON(ARRAY_SIZE(volopt_table) != ARRAY_SIZE(volopt_attr_ptrs) - 1); volopt_attr_ptrs[i] = NULL; - ret = scoutfs_sysfs_create_attrs(sb, &vinf->ssa, volopt_attr_ptrs, "volume_options"); + ret = scoutfs_sysfs_create_attrs(sb, &vinf->ssa, + KC_KOBJ_DEFAULT_PICK(volopt_groups, volopt_attr_ptrs), + "volume_options"); if (ret < 0) goto out; diff --git a/kmod/src/wkic.c b/kmod/src/wkic.c index b8b011c3..9129f16e 100644 --- a/kmod/src/wkic.c +++ b/kmod/src/wkic.c @@ -172,7 +172,7 @@ struct wkic_item { u64 seq; unsigned int val_len; u8 flags; - u8 val[0] __aligned(ARCH_KMALLOC_MINALIGN); /* totls have native structs */ + u8 val[] __aligned(ARCH_KMALLOC_MINALIGN); /* totls have native structs */ }; static struct wkic_item *witem_container(struct rb_node *node) @@ -764,7 +764,7 @@ static void fill_page_items(struct super_block *sb, struct wkic_page *wpage, str pg_item->val_len = witem->val_len; pg_item->flags = witem->flags; if (witem->val_len) - memcpy(pg_item->val, witem->val, witem->val_len); + memcpy(&pg_item->val[0], witem->val, witem->val_len); /* always inserting greatest item into page */ rb_link_node(&pg_item->node, parent, node); @@ -1169,8 +1169,13 @@ int scoutfs_wkic_setup(struct super_block *sb) } winf->sb = sb; - KC_INIT_SHRINKER_FUNCS(&winf->shrinker, wkic_shrink_count, wkic_shrink_scan); - KC_REGISTER_SHRINKER(&winf->shrinker, "scoutfs-weak_item:" SCSBF, SCSB_ARGS(sb)); + KC_SETUP_SHRINKER(winf->shrinker, winf, 0, wkic_shrink_count, + wkic_shrink_scan, "scoutfs-weak_item:" SCSBF, SCSB_ARGS(sb)); + if (KC_SHRINKER_IS_NULL(winf->shrinker)) { + debugfs_remove(winf->drop_dentry); + kfree(winf); + return -ENOMEM; + } sbi->wkic_info = winf; return 0; @@ -1198,7 +1203,7 @@ void scoutfs_wkic_destroy(struct super_block *sb) if (winf) { debugfs_remove(winf->drop_dentry); - KC_UNREGISTER_SHRINKER(&winf->shrinker); + KC_UNREGISTER_SHRINKER(winf->shrinker); /* trees are in sync so tearing down one frees all pages */ rbtree_postorder_for_each_entry_safe(wpage, tmp, &winf->wpage_roots[0], nodes[0]) { diff --git a/kmod/src/xattr.c b/kmod/src/xattr.c index 4ac83cad..34402f5a 100644 --- a/kmod/src/xattr.c +++ b/kmod/src/xattr.c @@ -908,7 +908,7 @@ int scoutfs_xattr_set_locked(struct inode *inode, const char *name, size_t name_ /* XXX do these want i_mutex or anything? */ inode_inc_iversion(inode); - inode->i_ctime = current_time(inode); + inode_set_ctime_to_ts(inode, current_time(inode)); ret = 0; out: diff --git a/tests/.xfstests-branch b/tests/.xfstests-branch index 31a466f6..d4c0599c 100644 --- a/tests/.xfstests-branch +++ b/tests/.xfstests-branch @@ -1 +1 @@ -v2022.05.01-2-g787cd20 +v2022.05.01-5-g0108afcd diff --git a/tests/funcs/filter.sh b/tests/funcs/filter.sh index 831702e3..75d90007 100644 --- a/tests/funcs/filter.sh +++ b/tests/funcs/filter.sh @@ -3,7 +3,8 @@ t_filter_fs() { sed -e 's@mnt/test\.[0-9]*@mnt/test@g' \ - -e 's@Device: [a-fA-F0-9]*h/[0-9]*d@Device: 0h/0d@g' + -e 's@Device: [a-fA-F0-9]*h/[0-9]*d@Device: 0h/0d@g' \ + -e 's@Device: [0-9]*,[0-9]*@Device: 0h/0d@g' } # @@ -177,6 +178,7 @@ t_filter_dmesg() re="$re|NFSD: .*" re="$re|RPC: .*" re="$re|FS-Cache: .*" + re="$re|netfs: .*" # fencing tests force unmounts and trigger timeouts re="$re|scoutfs .* forcing unmount" @@ -236,7 +238,12 @@ t_filter_dmesg() re="$re|File: /mnt/test.* PID:.* Comm: dd" re="$re|dio_warn_stale_pagecache*" - egrep -v "($re)" | \ + # xfstests probing our devices + re="$re|ISOFS" + re="$re|FAT-fs" + re="$re|XFS" + + grep -v -E "($re)" | \ ignore_harmless_unwind_kasan_stack_oob | \ ignore_harmless_xfs_lockdep_warning } diff --git a/tests/golden/basic-posix-consistency b/tests/golden/basic-posix-consistency index e96251bc..7fd126a1 100644 --- a/tests/golden/basic-posix-consistency +++ b/tests/golden/basic-posix-consistency @@ -47,7 +47,7 @@ four --- dir within dir --- overwrite file --- can't overwrite non-empty dir -mv: cannot move '/mnt/test/test/basic-posix-consistency/dir/c/clobber' to '/mnt/test/test/basic-posix-consistency/dir/a/dir': Directory not empty +mv: cannot overwrite '/mnt/test/test/basic-posix-consistency/dir/a/dir': Directory not empty --- can overwrite empty dir --- can rename into root == path resoluion diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 005ce924..3101bbc6 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -304,7 +304,7 @@ fi # include everything by default test -z "$T_INCLUDE" && T_INCLUDE="-e '.*'" # (quickly) exclude nothing by default -test -z "$T_EXCLUDE" && T_EXCLUDE="-e '\Zx'" +test -z "$T_EXCLUDE" && T_EXCLUDE="-e '^$'" # eval to strip re ticks but not expand tests=$(grep -v "^#" $T_SEQUENCE | diff --git a/tests/tests/basic-posix-consistency.sh b/tests/tests/basic-posix-consistency.sh index 6abe4e46..bb9d9e66 100644 --- a/tests/tests/basic-posix-consistency.sh +++ b/tests/tests/basic-posix-consistency.sh @@ -138,7 +138,9 @@ echo "--- can't overwrite non-empty dir" mkdir "$T_D0/dir/a/dir" touch "$T_D0/dir/a/dir/nope" mkdir "$T_D1/dir/c/clobber" -mv -T "$T_D1/dir/c/clobber" "$T_D1/dir/a/dir" 2>&1 | t_filter_fs +mv -T "$T_D1/dir/c/clobber" "$T_D1/dir/a/dir" 2>&1 | \ + sed "s@mv: cannot move '.*' to '\(.*\)': Directory not empty@mv: cannot overwrite '\1': Directory not empty@g" | \ + t_filter_fs find "$T_D0/dir" -ls 2>&1 | t_filter_fs > "$T_TMP.0" find "$T_D1/dir" -ls 2>&1 | t_filter_fs > "$T_TMP.1" diff -u "$T_TMP.0" "$T_TMP.1" diff --git a/utils/sparse.sh b/utils/sparse.sh index adef573b..a31b3630 100755 --- a/utils/sparse.sh +++ b/utils/sparse.sh @@ -71,7 +71,7 @@ else m64="" fi -sparse $m64 $include $search/include "$@" 2>&1 | egrep -v "($RE)" | tee .sparse.output +sparse $m64 $include $search/include "$@" 2>&1 | grep -v -E "($RE)" | tee .sparse.output rm -f $defines