Skip to content

[2.2.8] various Linux kernel updates #17325

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: zfs-2.2.8-staging
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
41 changes: 39 additions & 2 deletions config/kernel-automount.m4
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ dnl # solution to handling automounts. Prior to this cifs/nfs clients
dnl # which required automount support would abuse the follow_link()
dnl # operation on directories for this purpose.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
AC_DEFUN([ZFS_AC_KERNEL_SRC_D_AUTOMOUNT], [
ZFS_LINUX_TEST_SRC([dentry_operations_d_automount], [
#include <linux/dcache.h>
static struct vfsmount *d_automount(struct path *p) { return NULL; }
Expand All @@ -15,11 +15,48 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
])
])

AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
AC_DEFUN([ZFS_AC_KERNEL_D_AUTOMOUNT], [
AC_MSG_CHECKING([whether dops->d_automount() exists])
ZFS_LINUX_TEST_RESULT([dentry_operations_d_automount], [
AC_MSG_RESULT(yes)
],[
ZFS_LINUX_TEST_ERROR([dops->d_automount()])
])
])

dnl #
dnl # 6.14 API change
dnl # dops->d_revalidate now has four args.
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_D_REVALIDATE_4ARGS], [
ZFS_LINUX_TEST_SRC([dentry_operations_d_revalidate_4args], [
#include <linux/dcache.h>
static int d_revalidate(struct inode *dir,
const struct qstr *name, struct dentry *dentry,
unsigned int fl) { return 0; }
struct dentry_operations dops __attribute__ ((unused)) = {
.d_revalidate = d_revalidate,
};
])
])

AC_DEFUN([ZFS_AC_KERNEL_D_REVALIDATE_4ARGS], [
AC_MSG_CHECKING([whether dops->d_revalidate() takes 4 args])
ZFS_LINUX_TEST_RESULT([dentry_operations_d_revalidate_4args], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_D_REVALIDATE_4ARGS, 1,
[dops->d_revalidate() takes 4 args])
],[
AC_MSG_RESULT(no)
])
])

AC_DEFUN([ZFS_AC_KERNEL_SRC_AUTOMOUNT], [
ZFS_AC_KERNEL_SRC_D_AUTOMOUNT
ZFS_AC_KERNEL_SRC_D_REVALIDATE_4ARGS
])

AC_DEFUN([ZFS_AC_KERNEL_AUTOMOUNT], [
ZFS_AC_KERNEL_D_AUTOMOUNT
ZFS_AC_KERNEL_D_REVALIDATE_4ARGS
])
19 changes: 19 additions & 0 deletions config/kernel-sb-dying.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
dnl #
dnl # SB_DYING exists since Linux 6.6
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_SB_DYING], [
ZFS_LINUX_TEST_SRC([sb_dying], [
#include <linux/fs.h>
],[
(void) SB_DYING;
])
])

AC_DEFUN([ZFS_AC_KERNEL_SB_DYING], [
AC_MSG_CHECKING([whether SB_DYING is defined])
ZFS_LINUX_TEST_RESULT([sb_dying], [
AC_MSG_RESULT(yes)
],[
AC_MSG_RESULT(no)
])
])
27 changes: 27 additions & 0 deletions config/kernel-vfs-migrate_folio.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
dnl #
dnl # Linux 6.0 uses migrate_folio in lieu of migrate_page
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_MIGRATE_FOLIO], [
ZFS_LINUX_TEST_SRC([vfs_has_migrate_folio], [
#include <linux/fs.h>
#include <linux/migrate.h>

static const struct address_space_operations
aops __attribute__ ((unused)) = {
.migrate_folio = migrate_folio,
};
],[])
])

AC_DEFUN([ZFS_AC_KERNEL_VFS_MIGRATE_FOLIO], [
dnl #
dnl # Linux 6.0 uses migrate_folio in lieu of migrate_page
dnl #
AC_MSG_CHECKING([whether migrate_folio exists])
ZFS_LINUX_TEST_RESULT([vfs_has_migrate_folio], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_VFS_MIGRATE_FOLIO, 1, [migrate_folio exists])
],[
AC_MSG_RESULT([no])
])
])
27 changes: 27 additions & 0 deletions config/kernel-vfs-migratepage.m4
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
dnl #
dnl # Linux 6.0 gets rid of address_space_operations.migratepage
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_VFS_MIGRATEPAGE], [
ZFS_LINUX_TEST_SRC([vfs_has_migratepage], [
#include <linux/fs.h>
#include <linux/migrate.h>

static const struct address_space_operations
aops __attribute__ ((unused)) = {
.migratepage = migrate_page,
};
],[])
])

AC_DEFUN([ZFS_AC_KERNEL_VFS_MIGRATEPAGE], [
dnl #
dnl # Linux 6.0 gets rid of address_space_operations.migratepage
dnl #
AC_MSG_CHECKING([whether migratepage exists])
ZFS_LINUX_TEST_RESULT([vfs_has_migratepage], [
AC_MSG_RESULT([yes])
AC_DEFINE(HAVE_VFS_MIGRATEPAGE, 1, [migratepage exists])
],[
AC_MSG_RESULT([no])
])
])
6 changes: 6 additions & 0 deletions config/kernel.m4
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,13 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
ZFS_AC_KERNEL_SRC_TRUNCATE_SETSIZE
ZFS_AC_KERNEL_SRC_SECURITY_INODE
ZFS_AC_KERNEL_SRC_FST_MOUNT
ZFS_AC_KERNEL_SRC_SB_DYING
ZFS_AC_KERNEL_SRC_SET_NLINK
ZFS_AC_KERNEL_SRC_SGET
ZFS_AC_KERNEL_SRC_VFS_FILEMAP_DIRTY_FOLIO
ZFS_AC_KERNEL_SRC_VFS_READ_FOLIO
ZFS_AC_KERNEL_SRC_VFS_MIGRATE_FOLIO
ZFS_AC_KERNEL_SRC_VFS_MIGRATEPAGE
ZFS_AC_KERNEL_SRC_VFS_FSYNC_2ARGS
ZFS_AC_KERNEL_SRC_VFS_DIRECT_IO
ZFS_AC_KERNEL_SRC_VFS_READPAGES
Expand Down Expand Up @@ -183,10 +186,13 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
ZFS_AC_KERNEL_TRUNCATE_SETSIZE
ZFS_AC_KERNEL_SECURITY_INODE
ZFS_AC_KERNEL_FST_MOUNT
ZFS_AC_KERNEL_SB_DYING
ZFS_AC_KERNEL_SET_NLINK
ZFS_AC_KERNEL_SGET
ZFS_AC_KERNEL_VFS_FILEMAP_DIRTY_FOLIO
ZFS_AC_KERNEL_VFS_READ_FOLIO
ZFS_AC_KERNEL_VFS_MIGRATE_FOLIO
ZFS_AC_KERNEL_VFS_MIGRATEPAGE
ZFS_AC_KERNEL_VFS_FSYNC_2ARGS
ZFS_AC_KERNEL_VFS_DIRECT_IO
ZFS_AC_KERNEL_VFS_READPAGES
Expand Down
2 changes: 1 addition & 1 deletion include/os/linux/kernel/linux/blkdev_compat.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ bio_set_flush(struct bio *bio)
static inline boolean_t
bio_is_flush(struct bio *bio)
{
return (bio_op(bio) == REQ_OP_FLUSH);
return (bio_op(bio) == REQ_OP_FLUSH || op_is_flush(bio->bi_opf));
}

/*
Expand Down
4 changes: 2 additions & 2 deletions include/os/linux/spl/sys/uio.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ zfs_uio_bvec_init(zfs_uio_t *uio, struct bio *bio, struct request *rq)
#if defined(HAVE_VFS_IOV_ITER)
static inline void
zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
ssize_t resid, size_t skip)
ssize_t resid)
{
uio->uio_iter = iter;
uio->uio_iovcnt = iter->nr_segs;
Expand All @@ -161,7 +161,7 @@ zfs_uio_iov_iter_init(zfs_uio_t *uio, struct iov_iter *iter, offset_t offset,
uio->uio_fmode = 0;
uio->uio_extflg = 0;
uio->uio_resid = resid;
uio->uio_skip = skip;
uio->uio_skip = 0;
}
#endif

Expand Down
3 changes: 0 additions & 3 deletions module/os/linux/zfs/zfs_uio.c
Original file line number Diff line number Diff line change
Expand Up @@ -268,9 +268,6 @@ zfs_uiomove_iter(void *p, size_t n, zfs_uio_rw_t rw, zfs_uio_t *uio,
{
size_t cnt = MIN(n, uio->uio_resid);

if (uio->uio_skip)
iov_iter_advance(uio->uio_iter, uio->uio_skip);

if (rw == UIO_READ)
cnt = copy_to_iter(p, cnt, uio->uio_iter);
else
Expand Down
6 changes: 6 additions & 0 deletions module/os/linux/zfs/zpl_ctldir.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,14 @@ zpl_snapdir_automount(struct path *path)
* as of the 3.18 kernel revaliding the mountpoint dentry will result in
* the snapshot being immediately unmounted.
*/
#ifdef HAVE_D_REVALIDATE_4ARGS
static int
zpl_snapdir_revalidate(struct inode *dir, const struct qstr *name,
struct dentry *dentry, unsigned int flags)
#else
static int
zpl_snapdir_revalidate(struct dentry *dentry, unsigned int flags)
#endif
{
return (!!dentry->d_inode);
}
Expand Down
9 changes: 8 additions & 1 deletion module/os/linux/zfs/zpl_file.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <linux/compat.h>
#endif
#include <linux/fs.h>
#include <linux/migrate.h>
#include <sys/file.h>
#include <sys/dmu_objset.h>
#include <sys/zfs_znode.h>
Expand Down Expand Up @@ -227,7 +228,8 @@ zpl_uio_init(zfs_uio_t *uio, struct kiocb *kiocb, struct iov_iter *to,
loff_t pos, ssize_t count, size_t skip)
{
#if defined(HAVE_VFS_IOV_ITER)
zfs_uio_iov_iter_init(uio, to, pos, count, skip);
(void) skip;
zfs_uio_iov_iter_init(uio, to, pos, count);
#else
zfs_uio_iovec_init(uio, zfs_uio_iter_iov(to), to->nr_segs, pos,
zfs_uio_iov_iter_type(to) & ITER_KVEC ?
Expand Down Expand Up @@ -1090,6 +1092,11 @@ const struct address_space_operations zpl_address_space_operations = {
#ifdef HAVE_VFS_FILEMAP_DIRTY_FOLIO
.dirty_folio = filemap_dirty_folio,
#endif
#ifdef HAVE_VFS_MIGRATE_FOLIO
.migrate_folio = migrate_folio,
#elif defined(HAVE_VFS_MIGRATEPAGE)
.migratepage = migrate_page,
#endif
};

const struct file_operations zpl_file_operations = {
Expand Down
26 changes: 17 additions & 9 deletions module/os/linux/zfs/zpl_super.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,17 +370,25 @@ zpl_prune_sb(uint64_t nr_to_scan, void *arg)
int objects = 0;

/*
* deactivate_locked_super calls shrinker_free and only then
* sops->kill_sb cb, resulting in UAF on umount when trying to reach
* for the shrinker functions in zpl_prune_sb of in-umount dataset.
* Increment if s_active is not zero, but don't prune if it is -
* umount could be underway.
* Ensure the superblock is not in the process of being torn down.
*/
if (atomic_inc_not_zero(&sb->s_active)) {
(void) -zfs_prune(sb, nr_to_scan, &objects);
atomic_dec(&sb->s_active);
#ifdef HAVE_SB_DYING
if (down_read_trylock(&sb->s_umount)) {
if (!(sb->s_flags & SB_DYING) && sb->s_root &&
(sb->s_flags & SB_BORN)) {
(void) zfs_prune(sb, nr_to_scan, &objects);
}
up_read(&sb->s_umount);
}

#else
if (down_read_trylock(&sb->s_umount)) {
if (!hlist_unhashed(&sb->s_instances) &&
sb->s_root && (sb->s_flags & SB_BORN)) {
(void) zfs_prune(sb, nr_to_scan, &objects);
}
up_read(&sb->s_umount);
}
#endif
}

const struct super_operations zpl_super_operations = {
Expand Down
11 changes: 10 additions & 1 deletion module/os/linux/zfs/zvol_os.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,16 @@ static int zvol_blk_mq_alloc_tag_set(zvol_state_t *zv)
* We need BLK_MQ_F_BLOCKING here since we do blocking calls in
* zvol_request_impl()
*/
zso->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_BLOCKING;
zso->tag_set.flags = BLK_MQ_F_BLOCKING;

#ifdef BLK_MQ_F_SHOULD_MERGE
/*
* Linux 6.14 removed BLK_MQ_F_SHOULD_MERGE and made it implicit.
* For older kernels, we set it.
*/
zso->tag_set.flags |= BLK_MQ_F_SHOULD_MERGE;
#endif

zso->tag_set.driver_data = zv;

return (blk_mq_alloc_tag_set(&zso->tag_set));
Expand Down
Loading