diff options
author | Martin Matuska <mm@FreeBSD.org> | 2021-03-14 01:23:51 +0000 |
---|---|---|
committer | Martin Matuska <mm@FreeBSD.org> | 2021-03-14 01:32:14 +0000 |
commit | 9db44a8e5da9bf1ce6dd1c0f1468ddafed6d6c91 (patch) | |
tree | 773094eb34c30390e902748ef1ca381665a2ae73 /sys/contrib/openzfs/module | |
parent | a9275d996c229a30879baa42a6d02d24663ac43b (diff) | |
parent | 9162a1ce3ae9158ae75ab1835e30ac14d3b6899c (diff) | |
download | src-9db44a8e5da9bf1ce6dd1c0f1468ddafed6d6c91.tar.gz src-9db44a8e5da9bf1ce6dd1c0f1468ddafed6d6c91.zip |
zfs: merge OpenZFS master-9305ff2ed
Notable upstream pull request merges:
#11153 Scalable teardown lock for FreeBSD
#11651 Don't bomb out when using keylocation=file://
#11667 zvol: call zil_replaying() during replay
#11683 abd_get_offset_struct() may allocate new abd
#11693 Intentionally allow ZFS_READONLY in zfs_write
#11716 zpool import cachefile improvements
#11720 FreeBSD: Clean up zfsdev_close to match Linux
#11730 FreeBSD: bring back possibility to rewind the
checkpoint from bootloader
Obtained from: OpenZFS
MFC after: 2 weeks
Diffstat (limited to 'sys/contrib/openzfs/module')
-rw-r--r-- | sys/contrib/openzfs/module/Makefile.in | 5 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c | 18 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c | 2 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c | 9 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c | 26 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c | 1 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c | 102 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/zcommon/zfs_prop.c | 2 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/zfs/abd.c | 6 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/zfs/spa_misc.c | 4 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/zfs/zfs_vnops.c | 6 | ||||
-rw-r--r-- | sys/contrib/openzfs/module/zfs/zvol.c | 15 |
12 files changed, 141 insertions, 55 deletions
diff --git a/sys/contrib/openzfs/module/Makefile.in b/sys/contrib/openzfs/module/Makefile.in index 69caf48570e9..089b3ff88490 100644 --- a/sys/contrib/openzfs/module/Makefile.in +++ b/sys/contrib/openzfs/module/Makefile.in @@ -17,6 +17,10 @@ check: modules_uninstall modules_uninstall-Linux modules_uninstall-FreeBSD \ cppcheck cppcheck-Linux cppcheck-FreeBSD +# For FreeBSD, use debug options from ./configure if not overridden. +export WITH_DEBUG ?= @WITH_DEBUG@ +export WITH_INVARIANTS ?= @WITH_INVARIANTS@ + # Filter out options that FreeBSD make doesn't understand getflags = ( \ set -- \ @@ -42,6 +46,7 @@ FMAKEFLAGS = -C @abs_srcdir@ -f Makefile.bsd $(shell $(getflags)) ifneq (@abs_srcdir@,@abs_builddir@) FMAKEFLAGS += MAKEOBJDIR=@abs_builddir@ endif + FMAKE = env -u MAKEFLAGS make $(FMAKEFLAGS) modules-Linux: diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c b/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c index c11d4dbcf660..d5ba0d93a569 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/kmod_core.c @@ -182,23 +182,21 @@ out: static void zfsdev_close(void *data) { - zfsdev_state_t *zs, *zsp = data; + zfsdev_state_t *zs = data; + + ASSERT(zs != NULL); mutex_enter(&zfsdev_state_lock); - for (zs = zfsdev_state_list; zs != NULL; zs = zs->zs_next) { - if (zs == zsp) - break; - } - if (zs == NULL || zs->zs_minor <= 0) { - mutex_exit(&zfsdev_state_lock); - return; - } + + ASSERT(zs->zs_minor != 0); + zs->zs_minor = -1; zfs_onexit_destroy(zs->zs_onexit); zfs_zevent_destroy(zs->zs_zevent); - mutex_exit(&zfsdev_state_lock); zs->zs_onexit = NULL; zs->zs_zevent = NULL; + + mutex_exit(&zfsdev_state_lock); } static int diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c index fb01012dd6e7..de145a677600 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zfs_dir.c @@ -209,7 +209,6 @@ zfs_dd_lookup(znode_t *dzp, znode_t **zpp) #ifdef ZFS_DEBUG if (zfsvfs->z_replay == B_FALSE) ASSERT_VOP_LOCKED(ZTOV(dzp), __func__); - ASSERT(ZFS_TEARDOWN_READ_HELD(zfsvfs)); #endif if (dzp->z_unlinked) return (ENOENT); @@ -234,7 +233,6 @@ zfs_dirlook(znode_t *dzp, const char *name, znode_t **zpp) #ifdef ZFS_DEBUG if (zfsvfs->z_replay == B_FALSE) ASSERT_VOP_LOCKED(ZTOV(dzp), __func__); - ASSERT(ZFS_TEARDOWN_READ_HELD(zfsvfs)); #endif if (dzp->z_unlinked) return (SET_ERROR(ENOENT)); diff --git a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c index 2389b1a06355..ba315f104738 100644 --- a/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c +++ b/sys/contrib/openzfs/module/os/freebsd/zfs/zvol_os.c @@ -1163,6 +1163,9 @@ zvol_ensure_zilog(zvol_state_t *zv) zv->zv_zilog = zil_open(zv->zv_objset, zvol_get_data); zv->zv_flags |= ZVOL_WRITTEN_TO; + /* replay / destroy done in zvol_create_minor_impl() */ + VERIFY0((zv->zv_zilog->zl_header->zh_flags & + ZIL_REPLAY_NEEDED)); } rw_downgrade(&zv->zv_suspend_lock); } @@ -1387,12 +1390,16 @@ zvol_create_minor_impl(const char *name) zv->zv_volsize = volsize; zv->zv_objset = os; + ASSERT3P(zv->zv_zilog, ==, NULL); + zv->zv_zilog = zil_open(os, zvol_get_data); if (spa_writeable(dmu_objset_spa(os))) { if (zil_replay_disable) - zil_destroy(dmu_objset_zil(os), B_FALSE); + zil_destroy(zv->zv_zilog, B_FALSE); else zil_replay(os, zv, zvol_replay_vector); } + zil_close(zv->zv_zilog); + zv->zv_zilog = NULL; ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL); dataset_kstats_create(&zv->zv_kstat, zv->zv_objset); diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c index 2628325c0ba9..f8bf55f75e97 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zfs_acl.c @@ -2214,13 +2214,11 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode) } /* - * Only check for READONLY on non-directories. + * Intentionally allow ZFS_READONLY through here. + * See zfs_zaccess_common(). */ if ((v4_mode & WRITE_MASK_DATA) && - ((!S_ISDIR(ZTOI(zp)->i_mode) && - (zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) || - (S_ISDIR(ZTOI(zp)->i_mode) && - (zp->z_pflags & ZFS_IMMUTABLE)))) { + (zp->z_pflags & ZFS_IMMUTABLE)) { return (SET_ERROR(EPERM)); } @@ -2434,6 +2432,24 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, return (0); } + /* + * Note: ZFS_READONLY represents the "DOS R/O" attribute. + * When that flag is set, we should behave as if write access + * were not granted by anything in the ACL. In particular: + * We _must_ allow writes after opening the file r/w, then + * setting the DOS R/O attribute, and writing some more. + * (Similar to how you can write after fchmod(fd, 0444).) + * + * Therefore ZFS_READONLY is ignored in the dataset check + * above, and checked here as if part of the ACL check. + * Also note: DOS R/O is ignored for directories. + */ + if ((v4_mode & WRITE_MASK_DATA) && + S_ISDIR(ZTOI(zp)->i_mode) && + (zp->z_pflags & ZFS_READONLY)) { + return (SET_ERROR(EPERM)); + } + return (zfs_zaccess_aces_check(zp, working_mode, B_FALSE, cr)); } diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c b/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c index 284ca706ede5..2c58fecb2066 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zio_crypt.c @@ -1412,6 +1412,7 @@ zio_crypt_init_uios_zil(boolean_t encrypt, uint8_t *plainbuf, nr_src = 1; nr_dst = 0; } + bzero(dst, datalen); /* find the start and end record of the log block */ zilc = (zil_chain_t *)src; diff --git a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c index 0d62b1490702..7756d819fdeb 100644 --- a/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c +++ b/sys/contrib/openzfs/module/os/linux/zfs/zvol_os.c @@ -56,12 +56,32 @@ struct zvol_state_os { taskq_t *zvol_taskq; static struct ida zvol_ida; -typedef struct zv_request { +typedef struct zv_request_stack { zvol_state_t *zv; struct bio *bio; - taskq_ent_t ent; } zv_request_t; +typedef struct zv_request_task { + zv_request_t zvr; + taskq_ent_t ent; +} zv_request_task_t; + +static zv_request_task_t * +zv_request_task_create(zv_request_t zvr) +{ + zv_request_task_t *task; + task = kmem_alloc(sizeof (zv_request_task_t), KM_SLEEP); + taskq_init_ent(&task->ent); + task->zvr = zvr; + return (task); +} + +static void +zv_request_task_free(zv_request_task_t *task) +{ + kmem_free(task, sizeof (*task)); +} + /* * Given a path, return TRUE if path is a ZVOL. */ @@ -80,9 +100,8 @@ zvol_is_zvol_impl(const char *path) } static void -zvol_write(void *arg) +zvol_write(zv_request_t *zvr) { - zv_request_t *zvr = arg; struct bio *bio = zvr->bio; int error = 0; zfs_uio_t uio; @@ -102,7 +121,6 @@ zvol_write(void *arg) if (uio.uio_resid == 0) { rw_exit(&zv->zv_suspend_lock); BIO_END_IO(bio, 0); - kmem_free(zvr, sizeof (zv_request_t)); return; } @@ -162,13 +180,19 @@ zvol_write(void *arg) blk_generic_end_io_acct(q, disk, WRITE, bio, start_time); BIO_END_IO(bio, -error); - kmem_free(zvr, sizeof (zv_request_t)); } static void -zvol_discard(void *arg) +zvol_write_task(void *arg) +{ + zv_request_task_t *task = arg; + zvol_write(&task->zvr); + zv_request_task_free(task); +} + +static void +zvol_discard(zv_request_t *zvr) { - zv_request_t *zvr = arg; struct bio *bio = zvr->bio; zvol_state_t *zv = zvr->zv; uint64_t start = BIO_BI_SECTOR(bio) << 9; @@ -238,13 +262,19 @@ unlock: blk_generic_end_io_acct(q, disk, WRITE, bio, start_time); BIO_END_IO(bio, -error); - kmem_free(zvr, sizeof (zv_request_t)); } static void -zvol_read(void *arg) +zvol_discard_task(void *arg) +{ + zv_request_task_t *task = arg; + zvol_discard(&task->zvr); + zv_request_task_free(task); +} + +static void +zvol_read(zv_request_t *zvr) { - zv_request_t *zvr = arg; struct bio *bio = zvr->bio; int error = 0; zfs_uio_t uio; @@ -295,7 +325,14 @@ zvol_read(void *arg) blk_generic_end_io_acct(q, disk, READ, bio, start_time); BIO_END_IO(bio, -error); - kmem_free(zvr, sizeof (zv_request_t)); +} + +static void +zvol_read_task(void *arg) +{ + zv_request_task_t *task = arg; + zvol_read(&task->zvr); + zv_request_task_free(task); } #ifdef HAVE_SUBMIT_BIO_IN_BLOCK_DEVICE_OPERATIONS @@ -318,7 +355,6 @@ zvol_request(struct request_queue *q, struct bio *bio) uint64_t offset = BIO_BI_SECTOR(bio) << 9; uint64_t size = BIO_BI_SIZE(bio); int rw = bio_data_dir(bio); - zv_request_t *zvr; if (bio_has_data(bio) && offset + size > zv->zv_volsize) { printk(KERN_INFO @@ -331,6 +367,12 @@ zvol_request(struct request_queue *q, struct bio *bio) goto out; } + zv_request_t zvr = { + .zv = zv, + .bio = bio, + }; + zv_request_task_t *task; + if (rw == WRITE) { if (unlikely(zv->zv_flags & ZVOL_RDONLY)) { BIO_END_IO(bio, -SET_ERROR(EROFS)); @@ -357,15 +399,13 @@ zvol_request(struct request_queue *q, struct bio *bio) zv->zv_zilog = zil_open(zv->zv_objset, zvol_get_data); zv->zv_flags |= ZVOL_WRITTEN_TO; + /* replay / destroy done in zvol_create_minor */ + VERIFY0((zv->zv_zilog->zl_header->zh_flags & + ZIL_REPLAY_NEEDED)); } rw_downgrade(&zv->zv_suspend_lock); } - zvr = kmem_alloc(sizeof (zv_request_t), KM_SLEEP); - zvr->zv = zv; - zvr->bio = bio; - taskq_init_ent(&zvr->ent); - /* * We don't want this thread to be blocked waiting for i/o to * complete, so we instead wait from a taskq callback. The @@ -398,17 +438,19 @@ zvol_request(struct request_queue *q, struct bio *bio) */ if (bio_is_discard(bio) || bio_is_secure_erase(bio)) { if (zvol_request_sync) { - zvol_discard(zvr); + zvol_discard(&zvr); } else { + task = zv_request_task_create(zvr); taskq_dispatch_ent(zvol_taskq, - zvol_discard, zvr, 0, &zvr->ent); + zvol_discard_task, task, 0, &task->ent); } } else { if (zvol_request_sync) { - zvol_write(zvr); + zvol_write(&zvr); } else { + task = zv_request_task_create(zvr); taskq_dispatch_ent(zvol_taskq, - zvol_write, zvr, 0, &zvr->ent); + zvol_write_task, task, 0, &task->ent); } } } else { @@ -422,19 +464,15 @@ zvol_request(struct request_queue *q, struct bio *bio) goto out; } - zvr = kmem_alloc(sizeof (zv_request_t), KM_SLEEP); - zvr->zv = zv; - zvr->bio = bio; - taskq_init_ent(&zvr->ent); - rw_enter(&zv->zv_suspend_lock, RW_READER); /* See comment in WRITE case above. */ if (zvol_request_sync) { - zvol_read(zvr); + zvol_read(&zvr); } else { + task = zv_request_task_create(zvr); taskq_dispatch_ent(zvol_taskq, - zvol_read, zvr, 0, &zvr->ent); + zvol_read_task, task, 0, &task->ent); } } @@ -947,12 +985,16 @@ zvol_os_create_minor(const char *name) blk_queue_flag_set(QUEUE_FLAG_SCSI_PASSTHROUGH, zv->zv_zso->zvo_queue); #endif + ASSERT3P(zv->zv_zilog, ==, NULL); + zv->zv_zilog = zil_open(os, zvol_get_data); if (spa_writeable(dmu_objset_spa(os))) { if (zil_replay_disable) - zil_destroy(dmu_objset_zil(os), B_FALSE); + zil_destroy(zv->zv_zilog, B_FALSE); else zil_replay(os, zv, zvol_replay_vector); } + zil_close(zv->zv_zilog); + zv->zv_zilog = NULL; ASSERT3P(zv->zv_kstat.dk_kstats, ==, NULL); dataset_kstats_create(&zv->zv_kstat, zv->zv_objset); diff --git a/sys/contrib/openzfs/module/zcommon/zfs_prop.c b/sys/contrib/openzfs/module/zcommon/zfs_prop.c index b78331187e13..402d749c1aeb 100644 --- a/sys/contrib/openzfs/module/zcommon/zfs_prop.c +++ b/sys/contrib/openzfs/module/zcommon/zfs_prop.c @@ -417,7 +417,7 @@ zfs_prop_init(void) ZFS_TYPE_FILESYSTEM | ZFS_TYPE_VOLUME, "on | off | lzjb | gzip | gzip-[1-9] | zle | lz4 | " "zstd | zstd-[1-19] | " - "zstd-fast-[1-10,20,30,40,50,60,70,80,90,100,500,1000]", + "zstd-fast | zstd-fast-[1-10,20,30,40,50,60,70,80,90,100,500,1000]", "COMPRESS", compress_table); zprop_register_index(ZFS_PROP_SNAPDIR, "snapdir", ZFS_SNAPDIR_HIDDEN, PROP_INHERIT, ZFS_TYPE_FILESYSTEM, diff --git a/sys/contrib/openzfs/module/zfs/abd.c b/sys/contrib/openzfs/module/zfs/abd.c index 7d3a2f6d69e2..1e6645c90c95 100644 --- a/sys/contrib/openzfs/module/zfs/abd.c +++ b/sys/contrib/openzfs/module/zfs/abd.c @@ -555,8 +555,12 @@ abd_get_offset_impl(abd_t *abd, abd_t *sabd, size_t off, size_t size) abd_t * abd_get_offset_struct(abd_t *abd, abd_t *sabd, size_t off, size_t size) { + abd_t *result; abd_init_struct(abd); - return (abd_get_offset_impl(abd, sabd, off, size)); + result = abd_get_offset_impl(abd, sabd, off, size); + if (result != abd) + abd_fini_struct(abd); + return (result); } abd_t * diff --git a/sys/contrib/openzfs/module/zfs/spa_misc.c b/sys/contrib/openzfs/module/zfs/spa_misc.c index 0dacf9027b27..1a2e5abc5335 100644 --- a/sys/contrib/openzfs/module/zfs/spa_misc.c +++ b/sys/contrib/openzfs/module/zfs/spa_misc.c @@ -2923,10 +2923,10 @@ ZFS_MODULE_PARAM(zfs, zfs_, recover, INT, ZMOD_RW, ZFS_MODULE_PARAM(zfs, zfs_, free_leak_on_eio, INT, ZMOD_RW, "Set to ignore IO errors during free and permanently leak the space"); -ZFS_MODULE_PARAM(zfs, zfs_, deadman_checktime_ms, ULONG, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, checktime_ms, ULONG, ZMOD_RW, "Dead I/O check interval in milliseconds"); -ZFS_MODULE_PARAM(zfs, zfs_, deadman_enabled, INT, ZMOD_RW, +ZFS_MODULE_PARAM(zfs_deadman, zfs_deadman_, enabled, INT, ZMOD_RW, "Enable deadman timer"); ZFS_MODULE_PARAM(zfs_spa, spa_, asize_inflation, INT, ZMOD_RW, diff --git a/sys/contrib/openzfs/module/zfs/zfs_vnops.c b/sys/contrib/openzfs/module/zfs/zfs_vnops.c index a35c17f86f93..0af03e9233b3 100644 --- a/sys/contrib/openzfs/module/zfs/zfs_vnops.c +++ b/sys/contrib/openzfs/module/zfs/zfs_vnops.c @@ -350,9 +350,11 @@ zfs_write(znode_t *zp, zfs_uio_t *uio, int ioflag, cred_t *cr) } /* - * If immutable or not appending then return EPERM + * If immutable or not appending then return EPERM. + * Intentionally allow ZFS_READONLY through here. + * See zfs_zaccess_common() */ - if ((zp->z_pflags & (ZFS_IMMUTABLE | ZFS_READONLY)) || + if ((zp->z_pflags & ZFS_IMMUTABLE) || ((zp->z_pflags & ZFS_APPENDONLY) && !(ioflag & O_APPEND) && (zfs_uio_offset(uio) < zp->z_size))) { ZFS_EXIT(zfsvfs); diff --git a/sys/contrib/openzfs/module/zfs/zvol.c b/sys/contrib/openzfs/module/zfs/zvol.c index 7c6dae8650c7..44f9832ce857 100644 --- a/sys/contrib/openzfs/module/zfs/zvol.c +++ b/sys/contrib/openzfs/module/zfs/zvol.c @@ -473,7 +473,19 @@ zvol_replay_truncate(void *arg1, void *arg2, boolean_t byteswap) offset = lr->lr_offset; length = lr->lr_length; - return (dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, offset, length)); + dmu_tx_t *tx = dmu_tx_create(zv->zv_objset); + dmu_tx_mark_netfree(tx); + int error = dmu_tx_assign(tx, TXG_WAIT); + if (error != 0) { + dmu_tx_abort(tx); + } else { + zil_replaying(zv->zv_zilog, tx); + dmu_tx_commit(tx); + error = dmu_free_long_range(zv->zv_objset, ZVOL_OBJ, offset, + length); + } + + return (error); } /* @@ -513,6 +525,7 @@ zvol_replay_write(void *arg1, void *arg2, boolean_t byteswap) dmu_tx_abort(tx); } else { dmu_write(os, ZVOL_OBJ, offset, length, data, tx); + zil_replaying(zv->zv_zilog, tx); dmu_tx_commit(tx); } |