zfs: merge openzfs/zfs@0455150f1
Notable upstream pull request merges: #17836adacf020cFix return value for setting zvol threading #1783944704616bzpool: fix conflict with -v and -o options #178513a55e76b8FreeBSD: zfs_getpages: Don't zero freshly allocated pages #178630455150f1FreeBSD zio_crypt.c: initialize uio variables before access Obtained from: OpenZFS OpenZFS commit:0455150f11
This commit is contained in:
@@ -53,6 +53,7 @@ Jason Harmening <jason.harmening@gmail.com>
|
||||
Jeremy Faulkner <gldisater@gmail.com>
|
||||
Jinshan Xiong <jinshan.xiong@gmail.com>
|
||||
John Poduska <jpoduska@datto.com>
|
||||
Jo Zzsi <jozzsicsataban@gmail.com>
|
||||
Justin Scholz <git@justinscholz.de>
|
||||
Ka Ho Ng <khng300@gmail.com>
|
||||
Kash Pande <github@tripleback.net>
|
||||
@@ -67,6 +68,7 @@ Michael Gmelin <grembo@FreeBSD.org>
|
||||
Olivier Mazouffre <olivier.mazouffre@ims-bordeaux.fr>
|
||||
Piotr Kubaj <pkubaj@anongoth.pl>
|
||||
Quentin Zdanis <zdanisq@gmail.com>
|
||||
Roberto Ricci <io@r-ricci.it>
|
||||
Roberto Ricci <ricci@disroot.org>
|
||||
Rob Norris <robn@despairlabs.com>
|
||||
Rob Norris <rob.norris@klarasystems.com>
|
||||
@@ -83,7 +85,10 @@ Youzhong Yang <youzhong@gmail.com>
|
||||
# Signed-off-by: overriding Author:
|
||||
Alexander Ziaee <ziaee@FreeBSD.org> <concussious@runbox.com>
|
||||
Felix Schmidt <felixschmidt20@aol.com> <f.sch.prototype@gmail.com>
|
||||
Jean-Sébastien Pédron <dumbbell@FreeBSD.org> <jean-sebastien.pedron@dumbbell.fr>
|
||||
Konstantin Belousov <kib@FreeBSD.org> <kib@kib.kiev.ua>
|
||||
Olivier Certner <olce@FreeBSD.org> <olce.freebsd@certner.fr>
|
||||
Patrick Xia <patrickx@google.com> <octalc0de@aim.com>
|
||||
Phil Sutter <phil@nwl.cc> <p.github@nwl.cc>
|
||||
poscat <poscat@poscat.moe> <poscat0x04@outlook.com>
|
||||
Qiuhao Chen <chenqiuhao1997@gmail.com> <haohao0924@126.com>
|
||||
@@ -125,6 +130,7 @@ buzzingwires <buzzingwires@outlook.com> <131118055+buzzingwires@users.noreply.gi
|
||||
Cedric Maunoury <cedric.maunoury@gmail.com> <38213715+cedricmaunoury@users.noreply.github.com>
|
||||
Charles Suh <charles.suh@gmail.com> <charlessuh@users.noreply.github.com>
|
||||
Chris Peredun <chris.peredun@ixsystems.com> <126915832+chrisperedun@users.noreply.github.com>
|
||||
classabbyamp <dev@placeviolette.net> <5366828+classabbyamp@users.noreply.github.com>
|
||||
Dacian Reece-Stremtan <dacianstremtan@gmail.com> <35844628+dacianstremtan@users.noreply.github.com>
|
||||
Damian Szuberski <szuberskidamian@gmail.com> <30863496+szubersk@users.noreply.github.com>
|
||||
Daniel Hiepler <d-git@coderdu.de> <32984777+heeplr@users.noreply.github.com>
|
||||
@@ -185,6 +191,7 @@ Michael Niewöhner <foss@mniewoehner.de> <c0d3z3r0@users.noreply.github.com>
|
||||
Michael Zhivich <mzhivich@akamai.com> <33133421+mzhivich@users.noreply.github.com>
|
||||
MigeljanImeri <ImeriMigel@gmail.com> <78048439+MigeljanImeri@users.noreply.github.com>
|
||||
Mo Zhou <cdluminate@gmail.com> <5723047+cdluminate@users.noreply.github.com>
|
||||
nav1s <nav1s@proton.me> <42621369+nav1s@users.noreply.github.com>
|
||||
Nick Mattis <nickm970@gmail.com> <nmattis@users.noreply.github.com>
|
||||
omni <omni+vagant@hack.org> <79493359+omnivagant@users.noreply.github.com>
|
||||
Pablo Correa Gómez <ablocorrea@hotmail.com> <32678034+pablofsf@users.noreply.github.com>
|
||||
@@ -206,6 +213,7 @@ Samuel Wycliffe <samuelwycliffe@gmail.com> <50765275+npc203@users.noreply.github
|
||||
Savyasachee Jha <hi@savyasacheejha.com> <savyajha@users.noreply.github.com>
|
||||
Scott Colby <scott@scolby.com> <scolby33@users.noreply.github.com>
|
||||
Sean Eric Fagan <kithrup@mac.com> <kithrup@users.noreply.github.com>
|
||||
Shreshth Srivastava <shreshthsrivastava2@gmail.com> <66148173+Shreshth3@users.noreply.github.com>
|
||||
Spencer Kinny <spencerkinny1995@gmail.com> <30333052+Spencer-Kinny@users.noreply.github.com>
|
||||
Srikanth N S <srikanth.nagasubbaraoseetharaman@hpe.com> <75025422+nssrikanth@users.noreply.github.com>
|
||||
Stefan Lendl <s.lendl@proxmox.com> <1321542+stfl@users.noreply.github.com>
|
||||
|
||||
@@ -154,6 +154,7 @@ CONTRIBUTORS:
|
||||
Chris Zubrzycki <github@mid-earth.net>
|
||||
Chuck Tuffli <ctuffli@gmail.com>
|
||||
Chunwei Chen <david.chen@nutanix.com>
|
||||
classabbyamp <dev@placeviolette.net>
|
||||
Clemens Fruhwirth <clemens@endorphin.org>
|
||||
Clemens Lang <cl@clang.name>
|
||||
Clint Armstrong <clint@clintarmstrong.net>
|
||||
@@ -161,6 +162,7 @@ CONTRIBUTORS:
|
||||
Colin Ian King <colin.king@canonical.com>
|
||||
Colin Percival <cperciva@tarsnap.com>
|
||||
Colm Buckley <colm@tuatha.org>
|
||||
Cong Zhang <congzhangzh@users.noreply.github.com>
|
||||
Crag Wang <crag0715@gmail.com>
|
||||
Craig Loomis <cloomis@astro.princeton.edu>
|
||||
Craig Sanders <github@taz.net.au>
|
||||
@@ -217,6 +219,7 @@ CONTRIBUTORS:
|
||||
Eitan Adler <lists@eitanadler.com>
|
||||
Eli Rosenthal <eli.rosenthal@delphix.com>
|
||||
Eli Schwartz <eschwartz93@gmail.com>
|
||||
Eric A. Borisch <eborisch@gmail.com>
|
||||
Eric Desrochers <eric.desrochers@canonical.com>
|
||||
Eric Dillmann <eric@jave.fr>
|
||||
Eric Schrock <Eric.Schrock@delphix.com>
|
||||
@@ -288,6 +291,7 @@ CONTRIBUTORS:
|
||||
Henrik Riomar <henrik.riomar@gmail.com>
|
||||
Herb Wartens <wartens2@llnl.gov>
|
||||
Hiếu Lê <leorize+oss@disroot.org>
|
||||
hoshinomori <hoshinomorimorimo@gmail.com>
|
||||
Huang Liu <liu.huang@zte.com.cn>
|
||||
Håkan Johansson <f96hajo@chalmers.se>
|
||||
Igor K <igor@dilos.org>
|
||||
@@ -300,6 +304,7 @@ CONTRIBUTORS:
|
||||
ilovezfs <ilovezfs@icloud.com>
|
||||
InsanePrawn <Insane.Prawny@gmail.com>
|
||||
Isaac Huang <he.huang@intel.com>
|
||||
Ivan Shapovalov <intelfx@intelfx.name>
|
||||
Ivan Volosyuk <Ivan.Volosyuk@gmail.com>
|
||||
Jacek Fefliński <feflik@gmail.com>
|
||||
Jacob Adams <tookmund@gmail.com>
|
||||
@@ -322,6 +327,7 @@ CONTRIBUTORS:
|
||||
Javen Wu <wu.javen@gmail.com>
|
||||
Jaydeep Kshirsagar <jkshirsagar@maxlinear.com>
|
||||
Jean-Baptiste Lallement <jean-baptiste@ubuntu.com>
|
||||
Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
|
||||
Jeff Dike <jdike@akamai.com>
|
||||
Jeremy Faulkner <gldisater@gmail.com>
|
||||
Jeremy Gill <jgill@parallax-innovations.com>
|
||||
@@ -355,7 +361,9 @@ CONTRIBUTORS:
|
||||
Josh Soref <jsoref@users.noreply.github.com>
|
||||
Joshua M. Clulow <josh@sysmgr.org>
|
||||
José Luis Salvador Rufo <salvador.joseluis@gmail.com>
|
||||
Jo Zzsi <jozzsicsataban@gmail.com>
|
||||
João Carlos Mendes Luís <jonny@jonny.eng.br>
|
||||
JT Pennington <jt.pennington@klarasystems.com>
|
||||
Julian Brunner <julian.brunner@gmail.com>
|
||||
Julian Heuking <JulianH@beckhoff.com>
|
||||
jumbi77 <jumbi77@users.noreply.github.com>
|
||||
@@ -388,6 +396,7 @@ CONTRIBUTORS:
|
||||
Kleber Tarcísio <klebertarcisio@yahoo.com.br>
|
||||
Kody A Kantor <kody.kantor@gmail.com>
|
||||
Kohsuke Kawaguchi <kk@kohsuke.org>
|
||||
Konstantin Belousov <kib@FreeBSD.org>
|
||||
Konstantin Khorenko <khorenko@virtuozzo.com>
|
||||
KORN Andras <korn@elan.rulez.org>
|
||||
kotauskas <v.toncharov@gmail.com>
|
||||
@@ -416,6 +425,7 @@ CONTRIBUTORS:
|
||||
luozhengzheng <luo.zhengzheng@zte.com.cn>
|
||||
Luís Henriques <henrix@camandro.org>
|
||||
Madhav Suresh <madhav.suresh@delphix.com>
|
||||
Maksym Shkolnyi <maksym.shkolnyi@workato.com>
|
||||
manfromafar <jonsonb10@gmail.com>
|
||||
Manoj Joseph <manoj.joseph@delphix.com>
|
||||
Manuel Amador (Rudd-O) <rudd-o@rudd-o.com>
|
||||
@@ -482,6 +492,7 @@ CONTRIBUTORS:
|
||||
Nathaniel Clark <Nathaniel.Clark@misrule.us>
|
||||
Nathaniel Wesley Filardo <nwf@cs.jhu.edu>
|
||||
Nathan Lewis <linux.robotdude@gmail.com>
|
||||
nav1s <nav1s@proton.me>
|
||||
Nav Ravindranath <nav@delphix.com>
|
||||
Neal Gompa (ニール・ゴンパ) <ngompa13@gmail.com>
|
||||
Ned Bass <bass6@llnl.gov>
|
||||
@@ -506,6 +517,7 @@ CONTRIBUTORS:
|
||||
Palash Gandhi <pbg4930@rit.edu>
|
||||
Patrick Fasano <patrick@patrickfasano.com>
|
||||
Patrick Mooney <pmooney@pfmooney.com>
|
||||
Patrick Xia <patrickx@google.com>
|
||||
Patrik Greco <sikevux@sikevux.se>
|
||||
Paul B. Henson <henson@acm.org>
|
||||
Paul Dagnelie <pcd@delphix.com>
|
||||
@@ -605,6 +617,7 @@ CONTRIBUTORS:
|
||||
Shengqi Chen <harry-chen@outlook.com>
|
||||
SHENGYI HONG <aokblast@FreeBSD.org>
|
||||
Shen Yan <shenyanxxxy@qq.com>
|
||||
Shreshth Srivastava <shreshthsrivastava2@gmail.com>
|
||||
Sietse <sietse@wizdom.nu>
|
||||
Simon Guest <simon.guest@tesujimath.org>
|
||||
Simon Howard <fraggle@soulsphere.org>
|
||||
@@ -665,6 +678,7 @@ CONTRIBUTORS:
|
||||
Toyam Cox <aviator45003@gmail.com>
|
||||
Trevor Bautista <trevrb@trevrb.net>
|
||||
Trey Dockendorf <treydock@gmail.com>
|
||||
trick2011 <trick2011@users.noreply.github.com>
|
||||
Troels Nørgaard <tnn@tradeshift.com>
|
||||
tstabrawa <tstabrawa@users.noreply.github.com>
|
||||
Tulsi Jain <tulsi.jain@delphix.com>
|
||||
|
||||
@@ -9747,6 +9747,9 @@ main(int argc, char **argv)
|
||||
*/
|
||||
spa_mode_readable_spacemaps = B_TRUE;
|
||||
|
||||
libspl_set_assert_ok((dump_opt['A'] == 1) || (dump_opt['A'] > 2));
|
||||
zfs_recover = (dump_opt['A'] > 1);
|
||||
|
||||
if (dump_all)
|
||||
verbose = MAX(verbose, 1);
|
||||
|
||||
@@ -9757,9 +9760,6 @@ main(int argc, char **argv)
|
||||
dump_opt[c] += verbose;
|
||||
}
|
||||
|
||||
libspl_set_assert_ok((dump_opt['A'] == 1) || (dump_opt['A'] > 2));
|
||||
zfs_recover = (dump_opt['A'] > 1);
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
if (argc < 2 && dump_opt['R'])
|
||||
|
||||
@@ -6975,7 +6975,6 @@ collect_vdev_prop(zpool_prop_t prop, uint64_t value, const char *str,
|
||||
|
||||
/*
|
||||
* print static default line per vdev
|
||||
* not compatible with '-o' <proplist> option
|
||||
*/
|
||||
static void
|
||||
collect_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||
@@ -7031,48 +7030,98 @@ collect_list_stats(zpool_handle_t *zhp, const char *name, nvlist_t *nv,
|
||||
* 'toplevel' boolean value is passed to the print_one_column()
|
||||
* to indicate that the value is valid.
|
||||
*/
|
||||
if (VDEV_STAT_VALID(vs_pspace, c) && vs->vs_pspace) {
|
||||
collect_vdev_prop(ZPOOL_PROP_SIZE, vs->vs_pspace, NULL,
|
||||
scripted, B_TRUE, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
} else {
|
||||
collect_vdev_prop(ZPOOL_PROP_SIZE, vs->vs_space, NULL,
|
||||
scripted, toplevel, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
for (zprop_list_t *pl = cb->cb_proplist; pl != NULL;
|
||||
pl = pl->pl_next) {
|
||||
switch (pl->pl_prop) {
|
||||
case ZPOOL_PROP_SIZE:
|
||||
if (VDEV_STAT_VALID(vs_pspace, c) &&
|
||||
vs->vs_pspace) {
|
||||
collect_vdev_prop(
|
||||
ZPOOL_PROP_SIZE, vs->vs_pspace,
|
||||
NULL, scripted, B_TRUE, format,
|
||||
cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
} else {
|
||||
collect_vdev_prop(
|
||||
ZPOOL_PROP_SIZE, vs->vs_space, NULL,
|
||||
scripted, toplevel, format,
|
||||
cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
}
|
||||
break;
|
||||
case ZPOOL_PROP_ALLOCATED:
|
||||
collect_vdev_prop(ZPOOL_PROP_ALLOCATED,
|
||||
vs->vs_alloc, NULL, scripted, toplevel,
|
||||
format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_FREE:
|
||||
collect_vdev_prop(ZPOOL_PROP_FREE,
|
||||
vs->vs_space - vs->vs_alloc, NULL, scripted,
|
||||
toplevel, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_CHECKPOINT:
|
||||
collect_vdev_prop(ZPOOL_PROP_CHECKPOINT,
|
||||
vs->vs_checkpoint_space, NULL, scripted,
|
||||
toplevel, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_EXPANDSZ:
|
||||
collect_vdev_prop(ZPOOL_PROP_EXPANDSZ,
|
||||
vs->vs_esize, NULL, scripted, B_TRUE,
|
||||
format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_FRAGMENTATION:
|
||||
collect_vdev_prop(
|
||||
ZPOOL_PROP_FRAGMENTATION,
|
||||
vs->vs_fragmentation, NULL, scripted,
|
||||
(vs->vs_fragmentation != ZFS_FRAG_INVALID &&
|
||||
toplevel),
|
||||
format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_CAPACITY:
|
||||
cap = (vs->vs_space == 0) ?
|
||||
0 : (vs->vs_alloc * 10000 / vs->vs_space);
|
||||
collect_vdev_prop(ZPOOL_PROP_CAPACITY, cap,
|
||||
NULL, scripted, toplevel, format,
|
||||
cb->cb_json, props, cb->cb_json_as_int);
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_HEALTH:
|
||||
state = zpool_state_to_name(vs->vs_state,
|
||||
vs->vs_aux);
|
||||
if (isspare) {
|
||||
if (vs->vs_aux == VDEV_AUX_SPARED)
|
||||
state = "INUSE";
|
||||
else if (vs->vs_state ==
|
||||
VDEV_STATE_HEALTHY)
|
||||
state = "AVAIL";
|
||||
}
|
||||
collect_vdev_prop(ZPOOL_PROP_HEALTH, 0, state,
|
||||
scripted, B_TRUE, format, cb->cb_json,
|
||||
props, cb->cb_json_as_int);
|
||||
break;
|
||||
|
||||
case ZPOOL_PROP_NAME:
|
||||
break;
|
||||
|
||||
default:
|
||||
collect_vdev_prop(pl->pl_prop, 0,
|
||||
NULL, scripted, B_FALSE, format,
|
||||
cb->cb_json, props, cb->cb_json_as_int);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
collect_vdev_prop(ZPOOL_PROP_ALLOCATED, vs->vs_alloc, NULL,
|
||||
scripted, toplevel, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
collect_vdev_prop(ZPOOL_PROP_FREE, vs->vs_space - vs->vs_alloc,
|
||||
NULL, scripted, toplevel, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
collect_vdev_prop(ZPOOL_PROP_CHECKPOINT,
|
||||
vs->vs_checkpoint_space, NULL, scripted, toplevel, format,
|
||||
cb->cb_json, props, cb->cb_json_as_int);
|
||||
collect_vdev_prop(ZPOOL_PROP_EXPANDSZ, vs->vs_esize, NULL,
|
||||
scripted, B_TRUE, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
collect_vdev_prop(ZPOOL_PROP_FRAGMENTATION,
|
||||
vs->vs_fragmentation, NULL, scripted,
|
||||
(vs->vs_fragmentation != ZFS_FRAG_INVALID && toplevel),
|
||||
format, cb->cb_json, props, cb->cb_json_as_int);
|
||||
cap = (vs->vs_space == 0) ? 0 :
|
||||
(vs->vs_alloc * 10000 / vs->vs_space);
|
||||
collect_vdev_prop(ZPOOL_PROP_CAPACITY, cap, NULL,
|
||||
scripted, toplevel, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
collect_vdev_prop(ZPOOL_PROP_DEDUPRATIO, 0, NULL,
|
||||
scripted, toplevel, format, cb->cb_json, props,
|
||||
cb->cb_json_as_int);
|
||||
state = zpool_state_to_name(vs->vs_state, vs->vs_aux);
|
||||
if (isspare) {
|
||||
if (vs->vs_aux == VDEV_AUX_SPARED)
|
||||
state = "INUSE";
|
||||
else if (vs->vs_state == VDEV_STATE_HEALTHY)
|
||||
state = "AVAIL";
|
||||
}
|
||||
collect_vdev_prop(ZPOOL_PROP_HEALTH, 0, state, scripted,
|
||||
B_TRUE, format, cb->cb_json, props, cb->cb_json_as_int);
|
||||
|
||||
if (cb->cb_json) {
|
||||
fnvlist_add_nvlist(ent, "properties", props);
|
||||
|
||||
@@ -119,15 +119,49 @@ AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK], [
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 6.18 API change
|
||||
dnl # block_device_operation->getgeo takes struct gendisk* as first arg
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_GETGEO_GENDISK], [
|
||||
ZFS_LINUX_TEST_SRC([block_device_operations_getgeo_gendisk], [
|
||||
#include <linux/blkdev.h>
|
||||
|
||||
static int blk_getgeo(struct gendisk *disk, struct hd_geometry *geo)
|
||||
{
|
||||
(void) disk, (void) geo;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const struct block_device_operations
|
||||
bops __attribute__ ((unused)) = {
|
||||
.getgeo = blk_getgeo,
|
||||
};
|
||||
], [], [])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_GETGEO_GENDISK], [
|
||||
AC_MSG_CHECKING([whether bops->getgeo() takes gendisk as first arg])
|
||||
ZFS_LINUX_TEST_RESULT([block_device_operations_getgeo_gendisk], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_BLOCK_DEVICE_OPERATIONS_GETGEO_GENDISK], [1],
|
||||
[Define if getgeo() in block_device_operations takes struct gendisk * as its first arg])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS], [
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||
ZFS_AC_KERNEL_SRC_BLOCK_DEVICE_OPERATIONS_GETGEO_GENDISK
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS], [
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_CHECK_EVENTS
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_RELEASE_VOID
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_REVALIDATE_DISK
|
||||
ZFS_AC_KERNEL_BLOCK_DEVICE_OPERATIONS_GETGEO_GENDISK
|
||||
])
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
dnl #
|
||||
dnl # 6.18 API change
|
||||
dnl # - generic_drop_inode() renamed to inode_generic_drop()
|
||||
dnl # - generic_delete_inode() renamed to inode_just_drop()
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_INODE_GENERIC_DROP], [
|
||||
ZFS_LINUX_TEST_SRC([inode_generic_drop], [
|
||||
#include <linux/fs.h>
|
||||
],[
|
||||
struct inode *ip = NULL;
|
||||
inode_generic_drop(ip);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_INODE_GENERIC_DROP], [
|
||||
AC_MSG_CHECKING([whether inode_generic_drop() exists])
|
||||
ZFS_LINUX_TEST_RESULT([inode_generic_drop], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_INODE_GENERIC_DROP, 1,
|
||||
[inode_generic_drop() exists])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
@@ -0,0 +1,31 @@
|
||||
dnl #
|
||||
dnl # 6.18 API change
|
||||
dnl # ns->ops->type was moved to ns->ns.ns_type (struct ns_common)
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_NS_COMMON_TYPE], [
|
||||
ZFS_LINUX_TEST_SRC([ns_common_type], [
|
||||
#include <linux/user_namespace.h>
|
||||
],[
|
||||
struct user_namespace ns;
|
||||
ns.ns.ns_type = 0;
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_NS_COMMON_TYPE], [
|
||||
AC_MSG_CHECKING([whether ns_type is accessible through ns_common])
|
||||
ZFS_LINUX_TEST_RESULT([ns_common_type], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE([HAVE_NS_COMMON_TYPE], 1,
|
||||
[Define if ns_type is accessible through ns_common])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_NAMESPACE], [
|
||||
ZFS_AC_KERNEL_SRC_NS_COMMON_TYPE
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_NAMESPACE], [
|
||||
ZFS_AC_KERNEL_NS_COMMON_TYPE
|
||||
])
|
||||
@@ -1,79 +0,0 @@
|
||||
dnl #
|
||||
dnl # 2.6.38 API change
|
||||
dnl # ns_capable() was introduced
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_NS_CAPABLE], [
|
||||
ZFS_LINUX_TEST_SRC([ns_capable], [
|
||||
#include <linux/capability.h>
|
||||
],[
|
||||
ns_capable((struct user_namespace *)NULL, CAP_SYS_ADMIN);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_NS_CAPABLE], [
|
||||
AC_MSG_CHECKING([whether ns_capable exists])
|
||||
ZFS_LINUX_TEST_RESULT([ns_capable], [
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([ns_capable()])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 2.6.39 API change
|
||||
dnl # struct user_namespace was added to struct cred_t as cred->user_ns member
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_CRED_USER_NS], [
|
||||
ZFS_LINUX_TEST_SRC([cred_user_ns], [
|
||||
#include <linux/cred.h>
|
||||
],[
|
||||
struct cred cr;
|
||||
cr.user_ns = (struct user_namespace *)NULL;
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_CRED_USER_NS], [
|
||||
AC_MSG_CHECKING([whether cred_t->user_ns exists])
|
||||
ZFS_LINUX_TEST_RESULT([cred_user_ns], [
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([cred_t->user_ns()])
|
||||
])
|
||||
])
|
||||
|
||||
dnl #
|
||||
dnl # 3.4 API change
|
||||
dnl # kuid_has_mapping() and kgid_has_mapping() were added to distinguish
|
||||
dnl # between internal kernel uids/gids and user namespace uids/gids.
|
||||
dnl #
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING], [
|
||||
ZFS_LINUX_TEST_SRC([kuid_has_mapping], [
|
||||
#include <linux/uidgid.h>
|
||||
],[
|
||||
kuid_has_mapping((struct user_namespace *)NULL, KUIDT_INIT(0));
|
||||
kgid_has_mapping((struct user_namespace *)NULL, KGIDT_INIT(0));
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_KUID_HAS_MAPPING], [
|
||||
AC_MSG_CHECKING([whether kuid_has_mapping/kgid_has_mapping exist])
|
||||
ZFS_LINUX_TEST_RESULT([kuid_has_mapping], [
|
||||
AC_MSG_RESULT(yes)
|
||||
],[
|
||||
ZFS_LINUX_TEST_ERROR([kuid_has_mapping()])
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_USERNS_CAPABILITIES], [
|
||||
ZFS_AC_KERNEL_SRC_NS_CAPABLE
|
||||
ZFS_AC_KERNEL_SRC_HAS_CAPABILITY
|
||||
ZFS_AC_KERNEL_SRC_CRED_USER_NS
|
||||
ZFS_AC_KERNEL_SRC_KUID_HAS_MAPPING
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_USERNS_CAPABILITIES], [
|
||||
ZFS_AC_KERNEL_NS_CAPABLE
|
||||
ZFS_AC_KERNEL_HAS_CAPABILITY
|
||||
ZFS_AC_KERNEL_CRED_USER_NS
|
||||
ZFS_AC_KERNEL_KUID_HAS_MAPPING
|
||||
])
|
||||
@@ -0,0 +1,58 @@
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITEPAGE_T], [
|
||||
dnl #
|
||||
dnl # 6.3 API change
|
||||
dnl # The writepage_t function type now has its first argument as
|
||||
dnl # struct folio* instead of struct page*
|
||||
dnl #
|
||||
ZFS_LINUX_TEST_SRC([writepage_t_folio], [
|
||||
#include <linux/writeback.h>
|
||||
static int putpage(struct folio *folio,
|
||||
struct writeback_control *wbc, void *data)
|
||||
{ return 0; }
|
||||
writepage_t func = putpage;
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_WRITEPAGE_T], [
|
||||
AC_MSG_CHECKING([whether int (*writepage_t)() takes struct folio*])
|
||||
ZFS_LINUX_TEST_RESULT([writepage_t_folio], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_WRITEPAGE_T_FOLIO, 1,
|
||||
[int (*writepage_t)() takes struct folio*])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITE_CACHE_PAGES], [
|
||||
dnl #
|
||||
dnl # 6.18 API change
|
||||
dnl # write_cache_pages() has been removed.
|
||||
dnl #
|
||||
ZFS_LINUX_TEST_SRC([write_cache_pages], [
|
||||
#include <linux/writeback.h>
|
||||
], [
|
||||
(void) write_cache_pages(NULL, NULL, NULL, NULL);
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_WRITE_CACHE_PAGES], [
|
||||
AC_MSG_CHECKING([whether write_cache_pages() is available])
|
||||
ZFS_LINUX_TEST_RESULT([write_cache_pages], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_WRITE_CACHE_PAGES, 1,
|
||||
[write_cache_pages() is available])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITEBACK], [
|
||||
ZFS_AC_KERNEL_SRC_WRITEPAGE_T
|
||||
ZFS_AC_KERNEL_SRC_WRITE_CACHE_PAGES
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_WRITEBACK], [
|
||||
ZFS_AC_KERNEL_WRITEPAGE_T
|
||||
ZFS_AC_KERNEL_WRITE_CACHE_PAGES
|
||||
])
|
||||
@@ -1,26 +0,0 @@
|
||||
AC_DEFUN([ZFS_AC_KERNEL_SRC_WRITEPAGE_T], [
|
||||
dnl #
|
||||
dnl # 6.3 API change
|
||||
dnl # The writepage_t function type now has its first argument as
|
||||
dnl # struct folio* instead of struct page*
|
||||
dnl #
|
||||
ZFS_LINUX_TEST_SRC([writepage_t_folio], [
|
||||
#include <linux/writeback.h>
|
||||
static int putpage(struct folio *folio,
|
||||
struct writeback_control *wbc, void *data)
|
||||
{ return 0; }
|
||||
writepage_t func = putpage;
|
||||
],[])
|
||||
])
|
||||
|
||||
AC_DEFUN([ZFS_AC_KERNEL_WRITEPAGE_T], [
|
||||
AC_MSG_CHECKING([whether int (*writepage_t)() takes struct folio*])
|
||||
ZFS_LINUX_TEST_RESULT([writepage_t_folio], [
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_DEFINE(HAVE_WRITEPAGE_T_FOLIO, 1,
|
||||
[int (*writepage_t)() takes struct folio*])
|
||||
],[
|
||||
AC_MSG_RESULT(no)
|
||||
])
|
||||
])
|
||||
|
||||
@@ -121,7 +121,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||
ZFS_AC_KERNEL_SRC_IDMAP_MNT_API
|
||||
ZFS_AC_KERNEL_SRC_IDMAP_NO_USERNS
|
||||
ZFS_AC_KERNEL_SRC_IATTR_VFSID
|
||||
ZFS_AC_KERNEL_SRC_WRITEPAGE_T
|
||||
ZFS_AC_KERNEL_SRC_WRITEBACK
|
||||
ZFS_AC_KERNEL_SRC_RECLAIMED
|
||||
ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_TABLE
|
||||
ZFS_AC_KERNEL_SRC_REGISTER_SYSCTL_SZ
|
||||
@@ -136,6 +136,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_SRC], [
|
||||
ZFS_AC_KERNEL_SRC_TIMER
|
||||
ZFS_AC_KERNEL_SRC_SUPER_BLOCK_S_WB_ERR
|
||||
ZFS_AC_KERNEL_SRC_SOPS_FREE_INODE
|
||||
ZFS_AC_KERNEL_SRC_NAMESPACE
|
||||
ZFS_AC_KERNEL_SRC_INODE_GENERIC_DROP
|
||||
case "$host_cpu" in
|
||||
powerpc*)
|
||||
ZFS_AC_KERNEL_SRC_CPU_HAS_FEATURE
|
||||
@@ -240,7 +242,7 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||
ZFS_AC_KERNEL_IDMAP_MNT_API
|
||||
ZFS_AC_KERNEL_IDMAP_NO_USERNS
|
||||
ZFS_AC_KERNEL_IATTR_VFSID
|
||||
ZFS_AC_KERNEL_WRITEPAGE_T
|
||||
ZFS_AC_KERNEL_WRITEBACK
|
||||
ZFS_AC_KERNEL_RECLAIMED
|
||||
ZFS_AC_KERNEL_REGISTER_SYSCTL_TABLE
|
||||
ZFS_AC_KERNEL_REGISTER_SYSCTL_SZ
|
||||
@@ -256,6 +258,8 @@ AC_DEFUN([ZFS_AC_KERNEL_TEST_RESULT], [
|
||||
ZFS_AC_KERNEL_TIMER
|
||||
ZFS_AC_KERNEL_SUPER_BLOCK_S_WB_ERR
|
||||
ZFS_AC_KERNEL_SOPS_FREE_INODE
|
||||
ZFS_AC_KERNEL_NAMESPACE
|
||||
ZFS_AC_KERNEL_INODE_GENERIC_DROP
|
||||
case "$host_cpu" in
|
||||
powerpc*)
|
||||
ZFS_AC_KERNEL_CPU_HAS_FEATURE
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Lawrence Livermore National Security, LLC.
|
||||
* Copyright (C) 2015 Jörg Thalheim.
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#ifndef _ZFS_VFS_H
|
||||
@@ -262,4 +263,10 @@ zpl_is_32bit_api(void)
|
||||
#define zpl_generic_fillattr(user_ns, ip, sp) generic_fillattr(ip, sp)
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INODE_GENERIC_DROP
|
||||
/* 6.18 API change. These were renamed, alias the old names to the new. */
|
||||
#define generic_delete_inode(ip) inode_just_drop(ip)
|
||||
#define generic_drop_inode(ip) inode_generic_drop(ip)
|
||||
#endif
|
||||
|
||||
#endif /* _ZFS_VFS_H */
|
||||
|
||||
@@ -58,8 +58,8 @@ This command supports removing hot spare, cache, log, and both mirrored and
|
||||
non-redundant primary top-level vdevs, including dedup and special vdevs.
|
||||
.Pp
|
||||
Top-level vdevs can only be removed if the primary pool storage does not contain
|
||||
a top-level raidz vdev, all top-level vdevs have the same sector size, and the
|
||||
keys for all encrypted datasets are loaded.
|
||||
a top-level raidz or draid vdev, all top-level vdevs have the same ashift size,
|
||||
and the keys for all encrypted datasets are loaded.
|
||||
.Pp
|
||||
Removing a top-level vdev reduces the total amount of space in the storage pool.
|
||||
The specified device will be evacuated by copying all allocated space from it to
|
||||
|
||||
@@ -77,7 +77,8 @@ static const uint32_t SHA256_K[64] = {
|
||||
h = g, g = f, f = e, e = d + T1; \
|
||||
d = c, c = b, b = a, a = T1 + T2;
|
||||
|
||||
static void sha256_generic(uint32_t state[8], const void *data, size_t num_blks)
|
||||
static void
|
||||
icp_sha256_generic(uint32_t state[8], const void *data, size_t num_blks)
|
||||
{
|
||||
uint64_t blk;
|
||||
|
||||
@@ -173,7 +174,8 @@ static const uint64_t SHA512_K[80] = {
|
||||
0x5fcb6fab3ad6faec, 0x6c44198c4a475817
|
||||
};
|
||||
|
||||
static void sha512_generic(uint64_t state[8], const void *data, size_t num_blks)
|
||||
static void
|
||||
icp_sha512_generic(uint64_t state[8], const void *data, size_t num_blks)
|
||||
{
|
||||
uint64_t blk;
|
||||
|
||||
@@ -226,7 +228,8 @@ static void sha512_generic(uint64_t state[8], const void *data, size_t num_blks)
|
||||
}
|
||||
}
|
||||
|
||||
static void sha256_update(sha256_ctx *ctx, const uint8_t *data, size_t len)
|
||||
static void
|
||||
icp_sha256_update(sha256_ctx *ctx, const uint8_t *data, size_t len)
|
||||
{
|
||||
uint64_t pos = ctx->count[0];
|
||||
uint64_t total = ctx->count[1];
|
||||
@@ -258,7 +261,8 @@ static void sha256_update(sha256_ctx *ctx, const uint8_t *data, size_t len)
|
||||
ctx->count[1] = total;
|
||||
}
|
||||
|
||||
static void sha512_update(sha512_ctx *ctx, const uint8_t *data, size_t len)
|
||||
static void
|
||||
icp_sha512_update(sha512_ctx *ctx, const uint8_t *data, size_t len)
|
||||
{
|
||||
uint64_t pos = ctx->count[0];
|
||||
uint64_t total = ctx->count[1];
|
||||
@@ -290,7 +294,8 @@ static void sha512_update(sha512_ctx *ctx, const uint8_t *data, size_t len)
|
||||
ctx->count[1] = total;
|
||||
}
|
||||
|
||||
static void sha256_final(sha256_ctx *ctx, uint8_t *result, int bits)
|
||||
static void
|
||||
icp_sha256_final(sha256_ctx *ctx, uint8_t *result, int bits)
|
||||
{
|
||||
uint64_t mlen, pos = ctx->count[0];
|
||||
uint8_t *m = ctx->wbuf;
|
||||
@@ -334,7 +339,8 @@ static void sha256_final(sha256_ctx *ctx, uint8_t *result, int bits)
|
||||
memset(ctx, 0, sizeof (*ctx));
|
||||
}
|
||||
|
||||
static void sha512_final(sha512_ctx *ctx, uint8_t *result, int bits)
|
||||
static void
|
||||
icp_sha512_final(sha512_ctx *ctx, uint8_t *result, int bits)
|
||||
{
|
||||
uint64_t mlen, pos = ctx->count[0];
|
||||
uint8_t *m = ctx->wbuf, *r;
|
||||
@@ -461,14 +467,14 @@ SHA2Update(SHA2_CTX *ctx, const void *data, size_t len)
|
||||
|
||||
switch (ctx->algotype) {
|
||||
case SHA256:
|
||||
sha256_update(&ctx->sha256, data, len);
|
||||
icp_sha256_update(&ctx->sha256, data, len);
|
||||
break;
|
||||
case SHA512:
|
||||
case SHA512_HMAC_MECH_INFO_TYPE:
|
||||
sha512_update(&ctx->sha512, data, len);
|
||||
icp_sha512_update(&ctx->sha512, data, len);
|
||||
break;
|
||||
case SHA512_256:
|
||||
sha512_update(&ctx->sha512, data, len);
|
||||
icp_sha512_update(&ctx->sha512, data, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -479,32 +485,33 @@ SHA2Final(void *digest, SHA2_CTX *ctx)
|
||||
{
|
||||
switch (ctx->algotype) {
|
||||
case SHA256:
|
||||
sha256_final(&ctx->sha256, digest, 256);
|
||||
icp_sha256_final(&ctx->sha256, digest, 256);
|
||||
break;
|
||||
case SHA512:
|
||||
case SHA512_HMAC_MECH_INFO_TYPE:
|
||||
sha512_final(&ctx->sha512, digest, 512);
|
||||
icp_sha512_final(&ctx->sha512, digest, 512);
|
||||
break;
|
||||
case SHA512_256:
|
||||
sha512_final(&ctx->sha512, digest, 256);
|
||||
icp_sha512_final(&ctx->sha512, digest, 256);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* the generic implementation is always okay */
|
||||
static boolean_t sha2_is_supported(void)
|
||||
static boolean_t
|
||||
icp_sha2_is_supported(void)
|
||||
{
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
||||
const sha256_ops_t sha256_generic_impl = {
|
||||
.name = "generic",
|
||||
.transform = sha256_generic,
|
||||
.is_supported = sha2_is_supported
|
||||
.transform = icp_sha256_generic,
|
||||
.is_supported = icp_sha2_is_supported
|
||||
};
|
||||
|
||||
const sha512_ops_t sha512_generic_impl = {
|
||||
.name = "generic",
|
||||
.transform = sha512_generic,
|
||||
.is_supported = sha2_is_supported
|
||||
.transform = icp_sha512_generic,
|
||||
.is_supported = icp_sha2_is_supported
|
||||
};
|
||||
|
||||
@@ -437,6 +437,7 @@ zio_crypt_key_wrap(crypto_key_t *cwkey, zio_crypt_key_t *key, uint8_t *iv,
|
||||
|
||||
ASSERT3U(crypt, <, ZIO_CRYPT_FUNCTIONS);
|
||||
|
||||
memset(&cuio_s, 0, sizeof (cuio_s));
|
||||
zfs_uio_init(&cuio, &cuio_s);
|
||||
|
||||
keydata_len = zio_crypt_table[crypt].ci_keylen;
|
||||
@@ -519,6 +520,7 @@ zio_crypt_key_unwrap(crypto_key_t *cwkey, uint64_t crypt, uint64_t version,
|
||||
keydata_len = zio_crypt_table[crypt].ci_keylen;
|
||||
rw_init(&key->zk_salt_lock, NULL, RW_DEFAULT, NULL);
|
||||
|
||||
memset(&cuio_s, 0, sizeof (cuio_s));
|
||||
zfs_uio_init(&cuio, &cuio_s);
|
||||
|
||||
/*
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysmacros.h>
|
||||
#include <sys/kmem.h>
|
||||
@@ -56,6 +60,19 @@ typedef struct zone_dataset {
|
||||
} zone_dataset_t;
|
||||
|
||||
#ifdef CONFIG_USER_NS
|
||||
|
||||
/*
|
||||
* Linux 6.18 moved the generic namespace type away from ns->ops->type onto
|
||||
* ns_common itself.
|
||||
*/
|
||||
#ifdef HAVE_NS_COMMON_TYPE
|
||||
#define ns_is_newuser(ns) \
|
||||
((ns)->ns_type == CLONE_NEWUSER)
|
||||
#else
|
||||
#define ns_is_newuser(ns) \
|
||||
((ns)->ops != NULL && (ns)->ops->type == CLONE_NEWUSER)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Returns:
|
||||
* - 0 on success
|
||||
@@ -84,7 +101,7 @@ user_ns_get(int fd, struct user_namespace **userns)
|
||||
goto done;
|
||||
}
|
||||
ns = get_proc_ns(file_inode(nsfile));
|
||||
if (ns->ops->type != CLONE_NEWUSER) {
|
||||
if (!ns_is_newuser(ns)) {
|
||||
error = ENOTTY;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* Copyright (c) 2014 by Chunwei Chen. All rights reserved.
|
||||
* Copyright (c) 2019 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2023, 2024, Klara Inc.
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -1109,6 +1110,14 @@ abd_return_buf_copy(abd_t *abd, void *buf, size_t n)
|
||||
#define ABD_ITER_PAGE_SIZE(page) (PAGESIZE)
|
||||
#endif
|
||||
|
||||
#ifndef nth_page
|
||||
/*
|
||||
* Since 6.18 nth_page() no longer exists, and is no longer required to iterate
|
||||
* within a single SG entry, so we replace it with a simple addition.
|
||||
*/
|
||||
#define nth_page(p, n) ((p)+(n))
|
||||
#endif
|
||||
|
||||
void
|
||||
abd_iter_page(struct abd_iter *aiter)
|
||||
{
|
||||
|
||||
@@ -2524,7 +2524,7 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
|
||||
* Also note: DOS R/O is ignored for directories.
|
||||
*/
|
||||
if ((v4_mode & WRITE_MASK_DATA) &&
|
||||
S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
!S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & ZFS_READONLY)) {
|
||||
return (SET_ERROR(EPERM));
|
||||
}
|
||||
|
||||
@@ -2033,10 +2033,7 @@ zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr, zidmap_t *mnt_ns)
|
||||
goto out3;
|
||||
}
|
||||
|
||||
if ((mask & ATTR_SIZE) && (zp->z_pflags & ZFS_READONLY)) {
|
||||
err = SET_ERROR(EPERM);
|
||||
goto out3;
|
||||
}
|
||||
/* ZFS_READONLY will be handled in zfs_zaccess() */
|
||||
|
||||
/*
|
||||
* Verify timestamps doesn't overflow 32 bits.
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* Copyright (c) 2011, Lawrence Livermore National Security, LLC.
|
||||
* Copyright (c) 2015 by Chunwei Chen. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
|
||||
@@ -478,6 +479,7 @@ zpl_putpage(struct page *pp, struct writeback_control *wbc, void *data)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifdef HAVE_WRITE_CACHE_PAGES
|
||||
#ifdef HAVE_WRITEPAGE_T_FOLIO
|
||||
static int
|
||||
zpl_putfolio(struct folio *pp, struct writeback_control *wbc, void *data)
|
||||
@@ -499,6 +501,78 @@ zpl_write_cache_pages(struct address_space *mapping,
|
||||
#endif
|
||||
return (result);
|
||||
}
|
||||
#else
|
||||
static inline int
|
||||
zpl_write_cache_pages(struct address_space *mapping,
|
||||
struct writeback_control *wbc, void *data)
|
||||
{
|
||||
pgoff_t start = wbc->range_start >> PAGE_SHIFT;
|
||||
pgoff_t end = wbc->range_end >> PAGE_SHIFT;
|
||||
|
||||
struct folio_batch fbatch;
|
||||
folio_batch_init(&fbatch);
|
||||
|
||||
/*
|
||||
* This atomically (-ish) tags all DIRTY pages in the range with
|
||||
* TOWRITE, allowing users to continue dirtying or undirtying pages
|
||||
* while we get on with writeback, without us treading on each other.
|
||||
*/
|
||||
tag_pages_for_writeback(mapping, start, end);
|
||||
|
||||
int err = 0;
|
||||
unsigned int npages;
|
||||
|
||||
/*
|
||||
* Grab references to the TOWRITE pages just flagged. This may not get
|
||||
* all of them, so we do it in a loop until there are none left.
|
||||
*/
|
||||
while ((npages = filemap_get_folios_tag(mapping, &start, end,
|
||||
PAGECACHE_TAG_TOWRITE, &fbatch)) != 0) {
|
||||
|
||||
/* Loop over each page and write it out. */
|
||||
struct folio *folio;
|
||||
while ((folio = folio_batch_next(&fbatch)) != NULL) {
|
||||
folio_lock(folio);
|
||||
|
||||
/*
|
||||
* If the folio has been remapped, or is no longer
|
||||
* dirty, then there's nothing to do.
|
||||
*/
|
||||
if (folio->mapping != mapping ||
|
||||
!folio_test_dirty(folio)) {
|
||||
folio_unlock(folio);
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* If writeback is already in progress, wait for it to
|
||||
* finish. We continue after this even if the page
|
||||
* ends up clean; zfs_putpage() will skip it if no
|
||||
* further work is required.
|
||||
*/
|
||||
while (folio_test_writeback(folio))
|
||||
folio_wait_bit(folio, PG_writeback);
|
||||
|
||||
/*
|
||||
* Write it out and collect any error. zfs_putpage()
|
||||
* will clear the TOWRITE and DIRTY flags, and return
|
||||
* with the page unlocked.
|
||||
*/
|
||||
int ferr = zpl_putpage(&folio->page, wbc, data);
|
||||
if (err == 0 && ferr != 0)
|
||||
err = ferr;
|
||||
|
||||
/* Housekeeping for the caller. */
|
||||
wbc->nr_to_write -= folio_nr_pages(folio);
|
||||
}
|
||||
|
||||
/* Release any remaining references on the batch. */
|
||||
folio_batch_release(&fbatch);
|
||||
}
|
||||
|
||||
return (err);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
zpl_writepages(struct address_space *mapping, struct writeback_control *wbc)
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
* Copyright (c) 2011, Lawrence Livermore National Security, LLC.
|
||||
* Copyright (c) 2023, Datto Inc. All rights reserved.
|
||||
* Copyright (c) 2025, Klara, Inc.
|
||||
* Copyright (c) 2025, Rob Norris <robn@despairlabs.com>
|
||||
*/
|
||||
|
||||
|
||||
@@ -33,6 +34,7 @@
|
||||
#include <sys/zpl.h>
|
||||
#include <linux/iversion.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/vfs_compat.h>
|
||||
|
||||
/*
|
||||
* What to do when the last reference to an inode is released. If 0, the kernel
|
||||
@@ -104,7 +106,7 @@ zpl_dirty_inode(struct inode *ip, int flags)
|
||||
* reporting memory pressure and requests OpenZFS release some memory (see
|
||||
* zfs_prune()).
|
||||
*
|
||||
* When set to 1, we call generic_delete_node(), which always returns "destroy
|
||||
* When set to 1, we call generic_delete_inode(), which always returns "destroy
|
||||
* immediately", resulting in inodes being destroyed immediately, releasing
|
||||
* their associated dnodes and dbufs to the dbuf cached and the ARC to be
|
||||
* evicted as normal.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2012, 2020 by Delphix. All rights reserved.
|
||||
* Copyright (c) 2024, Rob Norris <robn@despairlabs.com>
|
||||
* Copyright (c) 2024, 2025, Rob Norris <robn@despairlabs.com>
|
||||
* Copyright (c) 2024, 2025, Klara, Inc.
|
||||
*/
|
||||
|
||||
@@ -1032,12 +1032,12 @@ zvol_os_update_volsize(zvol_state_t *zv, uint64_t volsize)
|
||||
* tiny devices. For devices over 1 Mib a standard head and sector count
|
||||
* is used to keep the cylinders count reasonable.
|
||||
*/
|
||||
static int
|
||||
zvol_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
||||
static inline int
|
||||
zvol_getgeo_impl(struct gendisk *disk, struct hd_geometry *geo)
|
||||
{
|
||||
zvol_state_t *zv = atomic_load_ptr(&disk->private_data);
|
||||
sector_t sectors;
|
||||
|
||||
zvol_state_t *zv = atomic_load_ptr(&bdev->bd_disk->private_data);
|
||||
ASSERT3P(zv, !=, NULL);
|
||||
ASSERT3U(zv->zv_open_count, >, 0);
|
||||
|
||||
@@ -1057,6 +1057,20 @@ zvol_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef HAVE_BLOCK_DEVICE_OPERATIONS_GETGEO_GENDISK
|
||||
static int
|
||||
zvol_getgeo(struct gendisk *disk, struct hd_geometry *geo)
|
||||
{
|
||||
return (zvol_getgeo_impl(disk, geo));
|
||||
}
|
||||
#else
|
||||
static int
|
||||
zvol_getgeo(struct block_device *bdev, struct hd_geometry *geo)
|
||||
{
|
||||
return (zvol_getgeo_impl(bdev->bd_disk, geo));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Why have two separate block_device_operations structs?
|
||||
*
|
||||
@@ -1500,7 +1514,7 @@ zvol_os_remove_minor(zvol_state_t *zv)
|
||||
if (zso->use_blk_mq)
|
||||
blk_mq_free_tag_set(&zso->tag_set);
|
||||
|
||||
ida_simple_remove(&zvol_ida, MINOR(zso->zvo_dev) >> ZVOL_MINOR_BITS);
|
||||
ida_free(&zvol_ida, MINOR(zso->zvo_dev) >> ZVOL_MINOR_BITS);
|
||||
|
||||
kmem_free(zso, sizeof (struct zvol_state_os));
|
||||
|
||||
@@ -1655,7 +1669,7 @@ zvol_os_create_minor(const char *name)
|
||||
if (zvol_inhibit_dev)
|
||||
return (0);
|
||||
|
||||
idx = ida_simple_get(&zvol_ida, 0, 0, kmem_flags_convert(KM_SLEEP));
|
||||
idx = ida_alloc(&zvol_ida, kmem_flags_convert(KM_SLEEP));
|
||||
if (idx < 0)
|
||||
return (SET_ERROR(-idx));
|
||||
minor = idx << ZVOL_MINOR_BITS;
|
||||
@@ -1663,7 +1677,7 @@ zvol_os_create_minor(const char *name)
|
||||
/* too many partitions can cause an overflow */
|
||||
zfs_dbgmsg("zvol: create minor overflow: %s, minor %u/%u",
|
||||
name, minor, MINOR(minor));
|
||||
ida_simple_remove(&zvol_ida, idx);
|
||||
ida_free(&zvol_ida, idx);
|
||||
return (SET_ERROR(EINVAL));
|
||||
}
|
||||
|
||||
@@ -1671,7 +1685,7 @@ zvol_os_create_minor(const char *name)
|
||||
if (zv) {
|
||||
ASSERT(MUTEX_HELD(&zv->zv_state_lock));
|
||||
mutex_exit(&zv->zv_state_lock);
|
||||
ida_simple_remove(&zvol_ida, idx);
|
||||
ida_free(&zvol_ida, idx);
|
||||
return (SET_ERROR(EEXIST));
|
||||
}
|
||||
|
||||
@@ -1771,7 +1785,7 @@ zvol_os_create_minor(const char *name)
|
||||
rw_exit(&zvol_state_lock);
|
||||
error = zvol_os_add_disk(zv->zv_zso->zvo_disk);
|
||||
} else {
|
||||
ida_simple_remove(&zvol_ida, idx);
|
||||
ida_free(&zvol_ida, idx);
|
||||
}
|
||||
|
||||
return (error);
|
||||
|
||||
@@ -51,34 +51,70 @@
|
||||
#include <sys/trace_zfs.h>
|
||||
|
||||
/*
|
||||
* This file contains the necessary logic to remove vdevs from a
|
||||
* storage pool. Currently, the only devices that can be removed
|
||||
* are log, cache, and spare devices; and top level vdevs from a pool
|
||||
* w/o raidz or mirrors. (Note that members of a mirror can be removed
|
||||
* by the detach operation.)
|
||||
* This file contains the necessary logic to remove vdevs from a storage
|
||||
* pool. Note that members of a mirror can be removed by the detach
|
||||
* operation. Currently, the only devices that can be removed are:
|
||||
*
|
||||
* Log vdevs are removed by evacuating them and then turning the vdev
|
||||
* into a hole vdev while holding spa config locks.
|
||||
* 1) Traditional hot spare and cache vdevs. Note that draid distributed
|
||||
* spares are fixed at creation time and cannot be removed.
|
||||
*
|
||||
* Top level vdevs are removed and converted into an indirect vdev via
|
||||
* a multi-step process:
|
||||
* 2) Log vdevs are removed by evacuating them and then turning the vdev
|
||||
* into a hole vdev while holding spa config locks.
|
||||
*
|
||||
* - Disable allocations from this device (spa_vdev_remove_top).
|
||||
* 3) Top-level singleton and mirror vdevs, including dedup and special
|
||||
* vdevs, are removed and converted into an indirect vdev via a
|
||||
* multi-step process:
|
||||
*
|
||||
* - From a new thread (spa_vdev_remove_thread), copy data from
|
||||
* the removing vdev to a different vdev. The copy happens in open
|
||||
* context (spa_vdev_copy_impl) and issues a sync task
|
||||
* (vdev_mapping_sync) so the sync thread can update the partial
|
||||
* indirect mappings in core and on disk.
|
||||
* - Disable allocations from this device (spa_vdev_remove_top).
|
||||
*
|
||||
* - If a free happens during a removal, it is freed from the
|
||||
* removing vdev, and if it has already been copied, from the new
|
||||
* location as well (free_from_removing_vdev).
|
||||
* - From a new thread (spa_vdev_remove_thread), copy data from the
|
||||
* removing vdev to a different vdev. The copy happens in open context
|
||||
* (spa_vdev_copy_impl) and issues a sync task (vdev_mapping_sync) so
|
||||
* the sync thread can update the partial indirect mappings in core
|
||||
* and on disk.
|
||||
*
|
||||
* - After the removal is completed, the copy thread converts the vdev
|
||||
* into an indirect vdev (vdev_remove_complete) before instructing
|
||||
* the sync thread to destroy the space maps and finish the removal
|
||||
* (spa_finish_removal).
|
||||
* - If a free happens during a removal, it is freed from the removing
|
||||
* vdev, and if it has already been copied, from the new location as
|
||||
* well (free_from_removing_vdev).
|
||||
*
|
||||
* - After the removal is completed, the copy thread converts the vdev
|
||||
* into an indirect vdev (vdev_remove_complete) before instructing
|
||||
* the sync thread to destroy the space maps and finish the removal
|
||||
* (spa_finish_removal).
|
||||
*
|
||||
* The following constraints currently apply primary device removal:
|
||||
*
|
||||
* - All vdevs must be online, healthy, and not be missing any data
|
||||
* according to the DTLs.
|
||||
*
|
||||
* - When removing a singleton or mirror vdev, regardless of it's a
|
||||
* special, dedup, or primary device, it must have the same ashift
|
||||
* as the devices in the normal allocation class. Furthermore, all
|
||||
* vdevs in the normal allocation class must have the same ashift to
|
||||
* ensure the new allocations never includes additional padding.
|
||||
*
|
||||
* - The normal allocation class cannot contain any raidz or draid
|
||||
* top-level vdevs since segments are copied without regard for block
|
||||
* boundaries. This makes it impossible to calculate the required
|
||||
* parity columns when using these vdev types as the destination.
|
||||
*
|
||||
* - The encryption keys must be loaded so the ZIL logs can be reset
|
||||
* in order to prevent writing to the device being removed.
|
||||
*
|
||||
* N.B. ashift and raidz/draid constraints for primary top-level device
|
||||
* removal could be slightly relaxed if it were possible to request that
|
||||
* DVAs from a mirror or singleton in the specified allocation class be
|
||||
* used (metaslab_alloc_dva).
|
||||
*
|
||||
* This flexibility would be particularly useful for raidz/draid pools which
|
||||
* often include a mirrored special device. If a mistakenly added top-level
|
||||
* singleton were added it could then still be removed at the cost of some
|
||||
* special device capacity. This may be a worthwhile tradeoff depending on
|
||||
* the pool capacity and expense (cost, complexity, time) of creating a new
|
||||
* pool and copying all of the data to correct the configuration.
|
||||
*
|
||||
* Furthermore, while not currently supported it should be possible to allow
|
||||
* vdevs of any type to be removed as long as they've never been written to.
|
||||
*/
|
||||
|
||||
typedef struct vdev_copy_arg {
|
||||
|
||||
@@ -410,7 +410,7 @@ zvol_set_volthreading(const char *name, boolean_t value)
|
||||
{
|
||||
zvol_state_t *zv = zvol_find_by_name(name, RW_NONE);
|
||||
if (zv == NULL)
|
||||
return (SET_ERROR(ENOENT));
|
||||
return (-1);
|
||||
zv->zv_threading = value;
|
||||
mutex_exit(&zv->zv_state_lock);
|
||||
return (0);
|
||||
|
||||
@@ -797,6 +797,10 @@ msg "${TEST_RUNNER}" \
|
||||
2>&1; echo $? >"$REPORT_FILE"; } | tee "$RESULTS_FILE"
|
||||
read -r RUNRESULT <"$REPORT_FILE"
|
||||
|
||||
if [[ "$RUNRESULT" -eq "255" ]] ; then
|
||||
fail "$TEST_RUNNER failed, test aborted."
|
||||
fi
|
||||
|
||||
#
|
||||
# Analyze the results.
|
||||
#
|
||||
|
||||
@@ -25,6 +25,7 @@ import sys
|
||||
import ctypes
|
||||
import re
|
||||
import configparser
|
||||
import traceback
|
||||
|
||||
from datetime import datetime
|
||||
from optparse import OptionParser
|
||||
@@ -1138,7 +1139,7 @@ def filter_tests(testrun, options):
|
||||
testrun.filter(failed)
|
||||
|
||||
|
||||
def fail(retstr, ret=1):
|
||||
def fail(retstr, ret=255):
|
||||
print('%s: %s' % (sys.argv[0], retstr))
|
||||
exit(ret)
|
||||
|
||||
@@ -1247,23 +1248,27 @@ def parse_args():
|
||||
def main():
|
||||
options = parse_args()
|
||||
|
||||
testrun = TestRun(options)
|
||||
try:
|
||||
testrun = TestRun(options)
|
||||
|
||||
if options.runfiles:
|
||||
testrun.read(options)
|
||||
else:
|
||||
find_tests(testrun, options)
|
||||
if options.runfiles:
|
||||
testrun.read(options)
|
||||
else:
|
||||
find_tests(testrun, options)
|
||||
|
||||
if options.logfile:
|
||||
filter_tests(testrun, options)
|
||||
if options.logfile:
|
||||
filter_tests(testrun, options)
|
||||
|
||||
if options.template:
|
||||
testrun.write(options)
|
||||
exit(0)
|
||||
if options.template:
|
||||
testrun.write(options)
|
||||
exit(0)
|
||||
|
||||
testrun.complete_outputdirs()
|
||||
testrun.run(options)
|
||||
exit(testrun.summary())
|
||||
testrun.complete_outputdirs()
|
||||
testrun.run(options)
|
||||
exit(testrun.summary())
|
||||
|
||||
except Exception:
|
||||
fail("Uncaught exception in test runner:\n" + traceback.format_exc())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -204,6 +204,10 @@
|
||||
/* BLK_STS_RESV_CONFLICT is defined */
|
||||
/* #undef HAVE_BLK_STS_RESV_CONFLICT */
|
||||
|
||||
/* Define if getgeo() in block_device_operations takes struct gendisk * as its
|
||||
first arg */
|
||||
/* #undef HAVE_BLOCK_DEVICE_OPERATIONS_GETGEO_GENDISK */
|
||||
|
||||
/* Define if release() in block_device_operations takes 1 arg */
|
||||
/* #undef HAVE_BLOCK_DEVICE_OPERATIONS_RELEASE_1ARG */
|
||||
|
||||
@@ -339,6 +343,9 @@
|
||||
/* Define if compiler supports -Winfinite-recursion */
|
||||
/* #undef HAVE_INFINITE_RECURSION */
|
||||
|
||||
/* inode_generic_drop() exists */
|
||||
/* #undef HAVE_INODE_GENERIC_DROP */
|
||||
|
||||
/* inode_get_atime() exists in linux/fs.h */
|
||||
/* #undef HAVE_INODE_GET_ATIME */
|
||||
|
||||
@@ -510,6 +517,9 @@
|
||||
/* Define if host toolchain supports MOVBE */
|
||||
#define HAVE_MOVBE 1
|
||||
|
||||
/* Define if ns_type is accessible through ns_common */
|
||||
/* #undef HAVE_NS_COMMON_TYPE */
|
||||
|
||||
/* folio_wait_bit() exists */
|
||||
/* #undef HAVE_PAGEMAP_FOLIO_WAIT_BIT */
|
||||
|
||||
@@ -759,6 +769,9 @@
|
||||
/* int (*writepage_t)() takes struct folio* */
|
||||
/* #undef HAVE_WRITEPAGE_T_FOLIO */
|
||||
|
||||
/* write_cache_pages() is available */
|
||||
/* #undef HAVE_WRITE_CACHE_PAGES */
|
||||
|
||||
/* xattr_handler->get() wants dentry and inode and flags */
|
||||
/* #undef HAVE_XATTR_GET_DENTRY_INODE_FLAGS */
|
||||
|
||||
@@ -843,7 +856,7 @@
|
||||
/* #undef ZFS_DEVICE_MINOR */
|
||||
|
||||
/* Define the project alias string. */
|
||||
#define ZFS_META_ALIAS "zfs-2.4.99-113-FreeBSD_g6ae99d269"
|
||||
#define ZFS_META_ALIAS "zfs-2.4.99-129-FreeBSD_g0455150f1"
|
||||
|
||||
/* Define the project author. */
|
||||
#define ZFS_META_AUTHOR "OpenZFS"
|
||||
@@ -873,7 +886,7 @@
|
||||
#define ZFS_META_NAME "zfs"
|
||||
|
||||
/* Define the project release. */
|
||||
#define ZFS_META_RELEASE "113-FreeBSD_g6ae99d269"
|
||||
#define ZFS_META_RELEASE "129-FreeBSD_g0455150f1"
|
||||
|
||||
/* Define the project version. */
|
||||
#define ZFS_META_VERSION "2.4.99"
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define ZFS_META_GITREV "zfs-2.4.99-113-g6ae99d269"
|
||||
#define ZFS_META_GITREV "zfs-2.4.99-129-g0455150f1"
|
||||
|
||||
Reference in New Issue
Block a user