Skip to content
Merged
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
16 changes: 16 additions & 0 deletions .github/workflows/zfs-tests-functional.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,22 @@ jobs:
./configure --enable-debug --enable-debuginfo
- name: Make
run: |
# Hack for zfs-2.1.16+
#
# When Alien converts the RPMs to DEB packages, it calls this line:
#
# $this->do("rpm2cpio '".$this->filename."' | (cd $workdir; $decomp cpio
# --extract --make-directories --no-absolute-filenames
# --preserve-modification-time) 2>&1")
#
# This seems to fail with zfs-2.1.16 with:
#
# cpio: ./usr/src/spl-2.1.16/6.5.0-1025-azure: Cannot open: No such file or directory
#
# The workaround is just to always return true from the 'cpio' command.
# This does not seem to affect anything.
sudo sed -i 's/preserve-modification-time/preserve-modification-time | true/g' /usr/share/perl5/Alien/Package/Rpm.pm

make --no-print-directory -s pkg-utils pkg-kmod
- name: Install
run: |
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/zfs-tests-sanity.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ jobs:
./configure --enable-debug --enable-debuginfo
- name: Make
run: |
# Hack for zfs-2.1.16+
#
# When Alien converts the RPMs to DEB packages, it calls this line:
#
# $this->do("rpm2cpio '".$this->filename."' | (cd $workdir; $decomp cpio
# --extract --make-directories --no-absolute-filenames
# --preserve-modification-time) 2>&1")
#
# This seems to fail with zfs-2.1.16 with:
#
# cpio: ./usr/src/spl-2.1.16/6.5.0-1025-azure: Cannot open: No such file or directory
#
# The workaround is just to always return true from the 'cpio' command.
# This does not seem to affect anything.
sudo sed -i 's/preserve-modification-time/preserve-modification-time | true/g' /usr/share/perl5/Alien/Package/Rpm.pm

make --no-print-directory -s pkg-utils pkg-kmod
- name: Install
run: |
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/zloop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,22 @@ jobs:
./configure --enable-debug --enable-debuginfo
- name: Make
run: |
# Hack for zfs-2.1.16+
#
# When Alien converts the RPMs to DEB packages, it calls this line:
#
# $this->do("rpm2cpio '".$this->filename."' | (cd $workdir; $decomp cpio
# --extract --make-directories --no-absolute-filenames
# --preserve-modification-time) 2>&1")
#
# This seems to fail with zfs-2.1.16 with:
#
# cpio: ./usr/src/spl-2.1.16/6.5.0-1025-azure: Cannot open: No such file or directory
#
# The workaround is just to always return true from the 'cpio' command.
# This does not seem to affect anything.
sudo sed -i 's/preserve-modification-time/preserve-modification-time | true/g' /usr/share/perl5/Alien/Package/Rpm.pm

make --no-print-directory -s pkg-utils pkg-kmod
- name: Install
run: |
Expand Down
2 changes: 1 addition & 1 deletion META
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Meta: 1
Name: zfs
Branch: 1.0
Version: 2.1.15
Version: 2.1.16
Release: 1
Release-Tags: relext
License: CDDL
Expand Down
43 changes: 41 additions & 2 deletions config/kernel-blkdev.m4
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH], [
])
])

dnl #
dnl # 6.9.x API change
dnl # bdev_file_open_by_path() replaced bdev_open_by_path(),
dnl # and returns struct file*
dnl #
AC_DEFUN([ZFS_AC_KERNEL_SRC_BDEV_FILE_OPEN_BY_PATH], [
ZFS_LINUX_TEST_SRC([bdev_file_open_by_path], [
#include <linux/fs.h>
#include <linux/blkdev.h>
], [
struct file *file __attribute__ ((unused)) = NULL;
const char *path = "path";
fmode_t mode = 0;
void *holder = NULL;
struct blk_holder_ops h;

file = bdev_file_open_by_path(path, mode, holder, &h);
])
])

AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
AC_MSG_CHECKING([whether blkdev_get_by_path() exists and takes 3 args])
ZFS_LINUX_TEST_RESULT([blkdev_get_by_path], [
Expand All @@ -73,7 +93,16 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_GET_BY_PATH], [
[bdev_open_by_path() exists])
AC_MSG_RESULT(yes)
], [
ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether bdev_file_open_by_path() exists])
ZFS_LINUX_TEST_RESULT([bdev_file_open_by_path], [
AC_DEFINE(HAVE_BDEV_FILE_OPEN_BY_PATH, 1,
[bdev_file_open_by_path() exists])
AC_MSG_RESULT(yes)
], [
AC_MSG_RESULT(no)
ZFS_LINUX_TEST_ERROR([blkdev_get_by_path()])
])
])
])
])
Expand Down Expand Up @@ -149,10 +178,19 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE], [
])
])

dnl #
dnl # 6.9.x API change
dnl #
dnl # bdev_release() now private, but because bdev_file_open_by_path() returns
dnl # struct file*, we can just use fput(). So the blkdev_put test no longer
dnl # fails if not found.
dnl #

AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
AC_MSG_CHECKING([whether blkdev_put() exists])
ZFS_LINUX_TEST_RESULT([blkdev_put], [
AC_MSG_RESULT(yes)
AC_DEFINE(HAVE_BLKDEV_PUT, 1, [blkdev_put() exists])
], [
AC_MSG_RESULT(no)
AC_MSG_CHECKING([whether blkdev_put() accepts void* as arg 2])
Expand All @@ -168,7 +206,7 @@ AC_DEFUN([ZFS_AC_KERNEL_BLKDEV_PUT], [
AC_DEFINE(HAVE_BDEV_RELEASE, 1,
[bdev_release() exists])
], [
ZFS_LINUX_TEST_ERROR([blkdev_put()])
AC_MSG_RESULT(no)
])
])
])
Expand Down Expand Up @@ -621,6 +659,7 @@ AC_DEFUN([ZFS_AC_KERNEL_SRC_BLKDEV], [
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_GET_BY_PATH_4ARG
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_OPEN_BY_PATH
ZFS_AC_KERNEL_SRC_BDEV_FILE_OPEN_BY_PATH
ZFS_AC_KERNEL_SRC_BLKDEV_PUT
ZFS_AC_KERNEL_SRC_BLKDEV_PUT_HOLDER
ZFS_AC_KERNEL_SRC_BLKDEV_BDEV_RELEASE
Expand Down
103 changes: 57 additions & 46 deletions module/os/linux/zfs/vdev_disk.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,25 @@
/*
* Linux 6.8.x uses a bdev_handle as an instance/refcount for an underlying
* block_device. Since it carries the block_device inside, its convenient to
* just use the handle as a proxy. For pre-6.8, we just emulate this with
* a cast, since we don't need any of the other fields inside the handle.
* just use the handle as a proxy.
*
* Linux 6.9.x uses a file for the same purpose.
*
* For pre-6.8, we just emulate this with a cast, since we don't need any of
* the other fields inside the handle.
*/
#ifdef HAVE_BDEV_OPEN_BY_PATH
#if defined(HAVE_BDEV_OPEN_BY_PATH)
typedef struct bdev_handle zfs_bdev_handle_t;
#define BDH_BDEV(bdh) ((bdh)->bdev)
#define BDH_IS_ERR(bdh) (IS_ERR(bdh))
#define BDH_PTR_ERR(bdh) (PTR_ERR(bdh))
#define BDH_ERR_PTR(err) (ERR_PTR(err))
#elif defined(HAVE_BDEV_FILE_OPEN_BY_PATH)
typedef struct file zfs_bdev_handle_t;
#define BDH_BDEV(bdh) (file_bdev(bdh))
#define BDH_IS_ERR(bdh) (IS_ERR(bdh))
#define BDH_PTR_ERR(bdh) (PTR_ERR(bdh))
#define BDH_ERR_PTR(err) (ERR_PTR(err))
#else
typedef void zfs_bdev_handle_t;
#define BDH_BDEV(bdh) ((struct block_device *)bdh)
Expand Down Expand Up @@ -94,38 +104,41 @@ typedef struct dio_request {
struct bio *dr_bio[0]; /* Attached bio's */
} dio_request_t;

/*
* Convert SPA mode flags into bdev open mode flags.
*/
#ifdef HAVE_BLK_MODE_T
static blk_mode_t
typedef blk_mode_t vdev_bdev_mode_t;
#define VDEV_BDEV_MODE_READ BLK_OPEN_READ
#define VDEV_BDEV_MODE_WRITE BLK_OPEN_WRITE
#define VDEV_BDEV_MODE_EXCL BLK_OPEN_EXCL
#define VDEV_BDEV_MODE_MASK (BLK_OPEN_READ|BLK_OPEN_WRITE|BLK_OPEN_EXCL)
#else
static fmode_t
typedef fmode_t vdev_bdev_mode_t;
#define VDEV_BDEV_MODE_READ FMODE_READ
#define VDEV_BDEV_MODE_WRITE FMODE_WRITE
#define VDEV_BDEV_MODE_EXCL FMODE_EXCL
#define VDEV_BDEV_MODE_MASK (FMODE_READ|FMODE_WRITE|FMODE_EXCL)
#endif
vdev_bdev_mode(spa_mode_t spa_mode, boolean_t exclusive)
{
#ifdef HAVE_BLK_MODE_T
blk_mode_t mode = 0;

if (spa_mode & SPA_MODE_READ)
mode |= BLK_OPEN_READ;
static vdev_bdev_mode_t
vdev_bdev_mode(spa_mode_t smode)
{
ASSERT3U(smode, !=, SPA_MODE_UNINIT);
ASSERT0(smode & ~(SPA_MODE_READ|SPA_MODE_WRITE));

if (spa_mode & SPA_MODE_WRITE)
mode |= BLK_OPEN_WRITE;
vdev_bdev_mode_t bmode = VDEV_BDEV_MODE_EXCL;

if (exclusive)
mode |= BLK_OPEN_EXCL;
#else
fmode_t mode = 0;
if (smode & SPA_MODE_READ)
bmode |= VDEV_BDEV_MODE_READ;

if (spa_mode & SPA_MODE_READ)
mode |= FMODE_READ;
if (smode & SPA_MODE_WRITE)
bmode |= VDEV_BDEV_MODE_WRITE;

if (spa_mode & SPA_MODE_WRITE)
mode |= FMODE_WRITE;
ASSERT(bmode & VDEV_BDEV_MODE_MASK);
ASSERT0(bmode & ~VDEV_BDEV_MODE_MASK);

if (exclusive)
mode |= FMODE_EXCL;
#endif

return (mode);
return (bmode);
}

/*
Expand Down Expand Up @@ -232,30 +245,32 @@ vdev_disk_kobj_evt_post(vdev_t *v)
}

static zfs_bdev_handle_t *
vdev_blkdev_get_by_path(const char *path, spa_mode_t mode, void *holder)
vdev_blkdev_get_by_path(const char *path, spa_mode_t smode, void *holder)
{
#if defined(HAVE_BDEV_OPEN_BY_PATH)
return (bdev_open_by_path(path,
vdev_bdev_mode(mode, B_TRUE), holder, NULL));
vdev_bdev_mode_t bmode = vdev_bdev_mode(smode);

#if defined(HAVE_BDEV_FILE_OPEN_BY_PATH)
return (bdev_file_open_by_path(path, bmode, holder, NULL));
#elif defined(HAVE_BDEV_OPEN_BY_PATH)
return (bdev_open_by_path(path, bmode, holder, NULL));
#elif defined(HAVE_BLKDEV_GET_BY_PATH_4ARG)
return (blkdev_get_by_path(path,
vdev_bdev_mode(mode, B_TRUE), holder, NULL));
return (blkdev_get_by_path(path, bmode, holder, NULL));
#else
return (blkdev_get_by_path(path,
vdev_bdev_mode(mode, B_TRUE), holder));
return (blkdev_get_by_path(path, bmode, holder));
#endif
}

static void
vdev_blkdev_put(zfs_bdev_handle_t *bdh, spa_mode_t mode, void *holder)
vdev_blkdev_put(zfs_bdev_handle_t *bdh, spa_mode_t smode, void *holder)
{
#if defined(HAVE_BDEV_RELEASE)
return (bdev_release(bdh));
#elif defined(HAVE_BLKDEV_PUT_HOLDER)
return (blkdev_put(BDH_BDEV(bdh), holder));
#elif defined(HAVE_BLKDEV_PUT)
return (blkdev_put(BDH_BDEV(bdh), vdev_bdev_mode(smode)));
#else
return (blkdev_put(BDH_BDEV(bdh),
vdev_bdev_mode(mode, B_TRUE)));
fput(bdh);
#endif
}

Expand All @@ -264,11 +279,7 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
uint64_t *logical_ashift, uint64_t *physical_ashift)
{
zfs_bdev_handle_t *bdh;
#ifdef HAVE_BLK_MODE_T
blk_mode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa), B_FALSE);
#else
fmode_t mode = vdev_bdev_mode(spa_mode(v->vdev_spa), B_FALSE);
#endif
spa_mode_t smode = spa_mode(v->vdev_spa);
hrtime_t timeout = MSEC2NSEC(zfs_vdev_open_timeout_ms);
vdev_disk_t *vd;

Expand Down Expand Up @@ -319,16 +330,16 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
reread_part = B_TRUE;
}

vdev_blkdev_put(bdh, mode, zfs_vdev_holder);
vdev_blkdev_put(bdh, smode, zfs_vdev_holder);
}

if (reread_part) {
bdh = vdev_blkdev_get_by_path(disk_name, mode,
bdh = vdev_blkdev_get_by_path(disk_name, smode,
zfs_vdev_holder);
if (!BDH_IS_ERR(bdh)) {
int error =
vdev_bdev_reread_part(BDH_BDEV(bdh));
vdev_blkdev_put(bdh, mode, zfs_vdev_holder);
vdev_blkdev_put(bdh, smode, zfs_vdev_holder);
if (error == 0) {
timeout = MSEC2NSEC(
zfs_vdev_open_timeout_ms * 2);
Expand Down Expand Up @@ -373,7 +384,7 @@ vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *max_psize,
hrtime_t start = gethrtime();
bdh = BDH_ERR_PTR(-ENXIO);
while (BDH_IS_ERR(bdh) && ((gethrtime() - start) < timeout)) {
bdh = vdev_blkdev_get_by_path(v->vdev_path, mode,
bdh = vdev_blkdev_get_by_path(v->vdev_path, smode,
zfs_vdev_holder);
if (unlikely(BDH_PTR_ERR(bdh) == -ENOENT)) {
/*
Expand Down
Loading