summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2019-12-04 12:40:25 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2019-12-04 12:40:25 +0000
commitcf92efd859a395f572e8fdb1fada65ac7be45fb0 (patch)
tree08a74365025a332a86b7473aea3acde719ad5998
parent1e3614d0308cc53fe5630084af9ef8719a9c44a8 (diff)
parent99d3b4e271d47a93935645d0c2d348d161f90c80 (diff)
downloadillumos-joyent-release-20191205.tar.gz
[illumos-gate merge]release-20191205
commit 99d3b4e271d47a93935645d0c2d348d161f90c80 11950 diff_cb() does not handle large dnodes commit c4fc965c904c30ee88c7ec42768b39cdbb328de9 11979 libshell: bitwise comparison always evaluates to false commit e63ea1f970505bef26ee06b3cef54076ad25b94e 12043 Streams ioctl for _I_CMD within kernel causes EFAULT
-rw-r--r--usr/src/lib/libshell/common/sh/nvtree.c2
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh13
-rw-r--r--usr/src/uts/common/fs/zfs/dmu_diff.c5
-rw-r--r--usr/src/uts/common/os/streamio.c26
4 files changed, 33 insertions, 13 deletions
diff --git a/usr/src/lib/libshell/common/sh/nvtree.c b/usr/src/lib/libshell/common/sh/nvtree.c
index eaa0dc99d2..8ff1605138 100644
--- a/usr/src/lib/libshell/common/sh/nvtree.c
+++ b/usr/src/lib/libshell/common/sh/nvtree.c
@@ -428,7 +428,7 @@ void nv_attribute(register Namval_t *np,Sfio_t *out,char *prefix,int noname)
if ((attr=nv_isattr(np,~NV_NOFREE)) || fp)
{
- if((attr&NV_NOPRINT|NV_INTEGER)==NV_NOPRINT)
+ if((attr&(NV_NOPRINT|NV_INTEGER))==NV_NOPRINT)
attr &= ~NV_NOPRINT;
if(!attr && !fp)
return;
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh
index 67f65ac4b2..96e6d9b5ae 100755
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_diff/zfs_diff_encrypted.ksh
@@ -31,8 +31,8 @@ verify_runnable "both"
function cleanup
{
- datasetexists $TESTPOOL/$TESTFS1 && \
- log_must zfs destroy -r $TESTPOOL/$TESTFS1
+ destroy_dataset "$TESTPOOL/$TESTFS1" "-r"
+ destroy_dataset "$TESTPOOL/$TESTFS2" "-r"
}
log_assert "'zfs diff' should work with encrypted datasets"
@@ -51,4 +51,13 @@ log_must zfs snapshot $TESTPOOL/$TESTFS1@snap2
# 3. Perform 'zfs diff' and verify no errors occur
log_must zfs diff -Ft $TESTPOOL/$TESTFS1@snap1 $TESTPOOL/$TESTFS1@snap2
+# 4. Perform the same test on a dataset with large dnodes
+log_must eval "echo 'password' | zfs create -o dnodesize=4k \
+ -o encryption=on -o keyformat=passphrase $TESTPOOL/$TESTFS2"
+MNTPOINT="$(get_prop mountpoint $TESTPOOL/$TESTFS2)"
+log_must zfs snapshot $TESTPOOL/$TESTFS2@snap1
+log_must touch "$MNTPOINT/file"
+log_must zfs snapshot $TESTPOOL/$TESTFS2@snap2
+log_must zfs diff -Ft $TESTPOOL/$TESTFS2@snap1 $TESTPOOL/$TESTFS2@snap2
+
log_pass "'zfs diff' works with encrypted datasets"
diff --git a/usr/src/uts/common/fs/zfs/dmu_diff.c b/usr/src/uts/common/fs/zfs/dmu_diff.c
index 76c32b1264..6a7cd844c4 100644
--- a/usr/src/uts/common/fs/zfs/dmu_diff.c
+++ b/usr/src/uts/common/fs/zfs/dmu_diff.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012, 2015 by Delphix. All rights reserved.
+ * Copyright (c) 2019, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
*/
#include <sys/dmu.h>
@@ -130,7 +131,7 @@ diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
dnode_phys_t *blk;
arc_buf_t *abuf;
arc_flags_t aflags = ARC_FLAG_WAIT;
- int blksz = BP_GET_LSIZE(bp);
+ int epb = BP_GET_LSIZE(bp) >> DNODE_SHIFT;
int zio_flags = ZIO_FLAG_CANFAIL;
int i;
@@ -142,7 +143,7 @@ diff_cb(spa_t *spa, zilog_t *zilog, const blkptr_t *bp,
return (SET_ERROR(EIO));
blk = abuf->b_data;
- for (i = 0; i < blksz >> DNODE_SHIFT; i++) {
+ for (i = 0; i < epb; i += blk[i].dn_extra_slots + 1) {
uint64_t dnobj = (zb->zb_blkid <<
(DNODE_BLOCK_SHIFT - DNODE_SHIFT)) + i;
err = report_dnode(da, dnobj, blk+i);
diff --git a/usr/src/uts/common/os/streamio.c b/usr/src/uts/common/os/streamio.c
index 95c0a5e720..15d612078c 100644
--- a/usr/src/uts/common/os/streamio.c
+++ b/usr/src/uts/common/os/streamio.c
@@ -3613,29 +3613,39 @@ strioctl(struct vnode *vp, int cmd, intptr_t arg, int flag, int copyflag,
if (stp->sd_flag & STRHUP)
return (ENXIO);
- if ((scp = kmem_alloc(sizeof (strcmd_t), KM_NOSLEEP)) == NULL)
- return (ENOMEM);
+ if (copyflag == U_TO_K) {
+ if ((scp = kmem_alloc(sizeof (strcmd_t),
+ KM_NOSLEEP)) == NULL) {
+ return (ENOMEM);
+ }
- if (copyin((void *)arg, scp, sizeof (strcmd_t))) {
- kmem_free(scp, sizeof (strcmd_t));
- return (EFAULT);
+ if (copyin((void *)arg, scp, sizeof (strcmd_t))) {
+ kmem_free(scp, sizeof (strcmd_t));
+ return (EFAULT);
+ }
+ } else {
+ scp = (strcmd_t *)arg;
}
access = job_control_type(scp->sc_cmd);
mutex_enter(&stp->sd_lock);
if (access != -1 && (error = i_straccess(stp, access)) != 0) {
mutex_exit(&stp->sd_lock);
- kmem_free(scp, sizeof (strcmd_t));
+ if (copyflag == U_TO_K)
+ kmem_free(scp, sizeof (strcmd_t));
return (error);
}
mutex_exit(&stp->sd_lock);
*rvalp = 0;
if ((error = strdocmd(stp, scp, crp)) == 0) {
- if (copyout(scp, (void *)arg, sizeof (strcmd_t)))
+ if (copyflag == U_TO_K &&
+ copyout(scp, (void *)arg, sizeof (strcmd_t))) {
error = EFAULT;
+ }
}
- kmem_free(scp, sizeof (strcmd_t));
+ if (copyflag == U_TO_K)
+ kmem_free(scp, sizeof (strcmd_t));
return (error);
case I_NREAD: