summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2019-06-29 13:28:56 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2019-06-29 13:28:56 +0000
commite9686f2048541f02e63b97976f385b6efa0f4831 (patch)
treea6f0ccfd3f6eba847c5e23e1b9d0f75a90d07a3c
parent9f27b084492b24583dbcc44e59ce9eaacd78ed68 (diff)
parentc7832f2df55c7f8d07e31fd48692e0cb47da34a2 (diff)
downloadillumos-joyent-e9686f2048541f02e63b97976f385b6efa0f4831.tar.gz
[illumos-gate merge]
commit c7832f2df55c7f8d07e31fd48692e0cb47da34a2 11218 loader: load vga text font commit d646956405faf5fdc9460e6b19af1bcb7a5c11ae 11171 pam_modules: NULL pointer errors commit da7753c428994e4e6c715886c93d7b49390c3705 11052 ZFS Reads may result in unneccesary calls to zil_commit commit a1d63828c2e12098f43bb49de5b78a6bafc80979 11212 loader: console c_probe callback must be reusable commit ffca9b6bef40a4b4cb6c2739812326c6234f7984 11090 libconv: NULL pointer errors commit 097aa9ce8122e2a595b37e2c87d970fec0d5fcbb 11217 gfx_private vga font setup should use set_font() to search for vga font commit a60ca23dc52059ace3f92bb9a63e723ac49e649b 11276 Allow unencrypted children of encrypted datasets commit b70e94852cee03960a3aed9ab79cbd643b648628 11216 unix: always load font module commit 45cf6faa16c9889e61cbdb6ee3758cdf856dd994 11215 loader: always pass font module to kernel Conflicts: usr/src/cmd/sgs/libconv/common/corenote.c
-rw-r--r--usr/src/boot/sys/boot/common/multiboot2.c6
-rw-r--r--usr/src/boot/sys/boot/efi/libefi/efi_console.c34
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vidconsole.c233
-rw-r--r--usr/src/cmd/sgs/libconv/common/corenote.c6
-rw-r--r--usr/src/lib/libzfs/common/libzfs_crypto.c42
-rw-r--r--usr/src/lib/libzfs/common/libzfs_dataset.c13
-rw-r--r--usr/src/lib/libzfs/common/libzfs_sendrecv.c74
-rw-r--r--usr/src/lib/pam_modules/dhkeys/dhkeys.c8
-rw-r--r--usr/src/pkg/manifests/system-test-zfstest.mf3
-rw-r--r--usr/src/test/zfs-tests/include/blkdev.shlib449
-rw-r--r--usr/src/test/zfs-tests/include/default.cfg7
-rw-r--r--usr/src/test/zfs-tests/include/libtest.shlib14
-rw-r--r--usr/src/test/zfs-tests/runfiles/delphix.run2
-rw-r--r--usr/src/test/zfs-tests/runfiles/omnios.run2
-rw-r--r--usr/src/test/zfs-tests/runfiles/openindiana.run2
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh20
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh19
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh14
-rwxr-xr-xusr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh103
-rw-r--r--usr/src/uts/common/fs/zfs/arc.c45
-rw-r--r--usr/src/uts/common/fs/zfs/dbuf.c1
-rw-r--r--usr/src/uts/common/fs/zfs/dmu.c9
-rw-r--r--usr/src/uts/common/fs/zfs/dmu_objset.c7
-rw-r--r--usr/src/uts/common/fs/zfs/dmu_recv.c32
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_crypt.c44
-rw-r--r--usr/src/uts/common/fs/zfs/sys/dsl_crypt.h1
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vnops.c13
-rw-r--r--usr/src/uts/i86pc/boot/boot_fb.c3
-rw-r--r--usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h1
-rw-r--r--usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c21
30 files changed, 946 insertions, 282 deletions
diff --git a/usr/src/boot/sys/boot/common/multiboot2.c b/usr/src/boot/sys/boot/common/multiboot2.c
index 4f6098e764..fbd9107214 100644
--- a/usr/src/boot/sys/boot/common/multiboot2.c
+++ b/usr/src/boot/sys/boot/common/multiboot2.c
@@ -893,10 +893,8 @@ multiboot2_exec(struct preloaded_file *fp)
/* mb_kernel_cmdline() updates the environment. */
build_environment_module();
- if (have_framebuffer == true) {
- /* Pass the loaded console font for kernel. */
- build_font_module();
- }
+ /* Pass the loaded console font for kernel. */
+ build_font_module();
size = mbi_size(fp, cmdline); /* Get the size for MBI. */
diff --git a/usr/src/boot/sys/boot/efi/libefi/efi_console.c b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
index 1ad97635f1..a4bc6a27ec 100644
--- a/usr/src/boot/sys/boot/efi/libefi/efi_console.c
+++ b/usr/src/boot/sys/boot/efi/libefi/efi_console.c
@@ -444,10 +444,20 @@ efi_framebuffer_setup(void)
static void
efi_cons_probe(struct console *cp)
{
+ cp->c_flags |= C_PRESENTIN | C_PRESENTOUT;
+}
+
+static int
+efi_cons_init(struct console *cp, int arg __unused)
+{
struct efi_console_data *ecd;
+ void *coninex;
EFI_STATUS status;
UINTN i, max_dim, best_mode, cols, rows;
+ if (cp->c_private != NULL)
+ return (0);
+
ecd = calloc(1, sizeof (*ecd));
/*
* As console probing is called very early, the only reason for
@@ -457,9 +467,12 @@ efi_cons_probe(struct console *cp)
panic("efi_cons_probe: This system has not enough memory\n");
cp->c_private = ecd;
- conout = ST->ConOut;
ecd->ecd_conin = ST->ConIn;
- cp->c_flags |= C_PRESENTIN | C_PRESENTOUT;
+ conout = ST->ConOut;
+
+ conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
+ DEFAULT_BGCOLOR));
+ memset(keybuf, 0, KEYBUFSZ);
status = BS->LocateProtocol(&ccontrol_protocol_guid, NULL,
(VOID **)&console_control);
@@ -509,21 +522,7 @@ efi_cons_probe(struct console *cp)
/* some firmware enables the cursor when switching modes */
conout->EnableCursor(conout, FALSE);
-}
-
-static int
-efi_cons_init(struct console *cp, int arg __unused)
-{
- struct efi_console_data *ecd;
- void *coninex;
- EFI_STATUS status;
- int rc;
- conout->SetAttribute(conout, EFI_TEXT_ATTR(DEFAULT_FGCOLOR,
- DEFAULT_BGCOLOR));
- memset(keybuf, 0, KEYBUFSZ);
-
- ecd = cp->c_private;
coninex = NULL;
/*
* Try to set up for SimpleTextInputEx protocol. If not available,
@@ -535,9 +534,8 @@ efi_cons_init(struct console *cp, int arg __unused)
ecd->ecd_coninex = coninex;
gfx_framework_init(&fb_ops);
- rc = tem_info_init(cp);
- if (rc == 0 && tem == NULL) {
+ if (tem_info_init(cp) == 0 && tem == NULL) {
tem = tem_init();
if (tem != NULL)
tem_activate(tem, B_TRUE);
diff --git a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
index 2927c3cabb..e6a1f62a8e 100644
--- a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
+++ b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c
@@ -79,8 +79,8 @@ static struct vis_modechg_arg *modechg_arg;
static tem_vt_state_t tem;
#define KEYBUFSZ 10
-#define DEFAULT_FGCOLOR 7
-#define DEFAULT_BGCOLOR 0
+#define DEFAULT_FGCOLOR 7
+#define DEFAULT_BGCOLOR 0
static uint8_t keybuf[KEYBUFSZ]; /* keybuf for extended codes */
@@ -132,7 +132,7 @@ plat_stdout_is_framebuffer(void)
if (vbe_available() && VBE_VALID_MODE(vbe_get_mode())) {
return (1);
}
- return (0);
+ return (0);
}
void
@@ -151,8 +151,8 @@ plat_tem_get_prom_pos(uint32_t *row, uint32_t *col)
*col = 0;
} else {
vidc_text_get_cursor(&y, &x);
- *row = (uint32_t) y;
- *col = (uint32_t) x;
+ *row = (uint32_t)y;
+ *col = (uint32_t)x;
}
}
@@ -434,7 +434,7 @@ vga_get_cp437(tem_char_t c)
int min, mid, max;
min = 0;
- max = (sizeof(cp437table) / sizeof(struct unicp437)) - 1;
+ max = (sizeof (cp437table) / sizeof (struct unicp437)) - 1;
if (c < cp437table[0].unicode_base ||
c > cp437table[max].unicode_base + cp437table[max].length)
@@ -447,10 +447,10 @@ vga_get_cp437(tem_char_t c)
else if (c > cp437table[mid].unicode_base +
cp437table[mid].length)
min = mid + 1;
- else
+ else
return (c - cp437table[mid].unicode_base +
cp437table[mid].cp437_base);
- }
+ }
return ('?');
}
@@ -469,7 +469,7 @@ vidc_text_cons_display(struct vis_consdisplay *da)
data = (tem_char_t *)da->data;
attr = (solaris_color_to_pc_color[da->bg_color & 0xf] << 4) |
solaris_color_to_pc_color[da->fg_color & 0xf];
- addr = (struct cgatext *) vgatext + (da->row * TEXT_COLS + da->col);
+ addr = (struct cgatext *)vgatext + (da->row * TEXT_COLS + da->col);
for (i = 0; i < da->width; i++) {
addr[i].ch = vga_get_cp437(data[i]);
@@ -630,8 +630,184 @@ vidc_probe(struct console *cp)
/* XXX for now, always assume we can do BIOS screen output */
cp->c_flags |= C_PRESENTOUT;
- vbe_init();
- tem = NULL;
+}
+
+/*
+ * Binary searchable table for CP437 to Unicode conversion.
+ */
+struct cp437uni {
+ uint8_t cp437_base;
+ uint16_t unicode_base;
+ uint8_t length;
+};
+
+static const struct cp437uni cp437unitable[] = {
+ { 0, 0x0000, 0 }, { 1, 0x263A, 1 }, { 3, 0x2665, 1 },
+ { 5, 0x2663, 0 }, { 6, 0x2660, 0 }, { 7, 0x2022, 0 },
+ { 8, 0x25D8, 0 }, { 9, 0x25CB, 0 }, { 10, 0x25D9, 0 },
+ { 11, 0x2642, 0 }, { 12, 0x2640, 0 }, { 13, 0x266A, 1 },
+ { 15, 0x263C, 0 }, { 16, 0x25BA, 0 }, { 17, 0x25C4, 0 },
+ { 18, 0x2195, 0 }, { 19, 0x203C, 0 }, { 20, 0x00B6, 0 },
+ { 21, 0x00A7, 0 }, { 22, 0x25AC, 0 }, { 23, 0x21A8, 0 },
+ { 24, 0x2191, 0 }, { 25, 0x2193, 0 }, { 26, 0x2192, 0 },
+ { 27, 0x2190, 0 }, { 28, 0x221F, 0 }, { 29, 0x2194, 0 },
+ { 30, 0x25B2, 0 }, { 31, 0x25BC, 0 }, { 32, 0x0020, 0x5e },
+ { 127, 0x2302, 0 }, { 128, 0x00C7, 0 }, { 129, 0x00FC, 0 },
+ { 130, 0x00E9, 0 }, { 131, 0x00E2, 0 }, { 132, 0x00E4, 0 },
+ { 133, 0x00E0, 0 }, { 134, 0x00E5, 0 }, { 135, 0x00E7, 0 },
+ { 136, 0x00EA, 1 }, { 138, 0x00E8, 0 }, { 139, 0x00EF, 0 },
+ { 140, 0x00EE, 0 }, { 141, 0x00EC, 0 }, { 142, 0x00C4, 1 },
+ { 144, 0x00C9, 0 }, { 145, 0x00E6, 0 }, { 146, 0x00C6, 0 },
+ { 147, 0x00F4, 0 }, { 148, 0x00F6, 0 }, { 149, 0x00F2, 0 },
+ { 150, 0x00FB, 0 }, { 151, 0x00F9, 0 }, { 152, 0x00FF, 0 },
+ { 153, 0x00D6, 0 }, { 154, 0x00DC, 0 }, { 155, 0x00A2, 1 },
+ { 157, 0x00A5, 0 }, { 158, 0x20A7, 0 }, { 159, 0x0192, 0 },
+ { 160, 0x00E1, 0 }, { 161, 0x00ED, 0 }, { 162, 0x00F3, 0 },
+ { 163, 0x00FA, 0 }, { 164, 0x00F1, 0 }, { 165, 0x00D1, 0 },
+ { 166, 0x00AA, 0 }, { 167, 0x00BA, 0 }, { 168, 0x00BF, 0 },
+ { 169, 0x2310, 0 }, { 170, 0x00AC, 0 }, { 171, 0x00BD, 0 },
+ { 172, 0x00BC, 0 }, { 173, 0x00A1, 0 }, { 174, 0x00AB, 0 },
+ { 175, 0x00BB, 0 }, { 176, 0x2591, 2 }, { 179, 0x2502, 0 },
+ { 180, 0x2524, 0 }, { 181, 0x2561, 1 }, { 183, 0x2556, 0 },
+ { 184, 0x2555, 0 }, { 185, 0x2563, 0 }, { 186, 0x2551, 0 },
+ { 187, 0x2557, 0 }, { 188, 0x255D, 0 }, { 189, 0x255C, 0 },
+ { 190, 0x255B, 0 }, { 191, 0x2510, 0 }, { 192, 0x2514, 0 },
+ { 193, 0x2534, 0 }, { 194, 0x252C, 0 }, { 195, 0x251C, 0 },
+ { 196, 0x2500, 0 }, { 197, 0x253C, 0 }, { 198, 0x255E, 1 },
+ { 200, 0x255A, 0 }, { 201, 0x2554, 0 }, { 202, 0x2569, 0 },
+ { 203, 0x2566, 0 }, { 204, 0x2560, 0 }, { 205, 0x2550, 0 },
+ { 206, 0x256C, 0 }, { 207, 0x2567, 1 }, { 209, 0x2564, 1 },
+ { 211, 0x2559, 0 }, { 212, 0x2558, 0 }, { 213, 0x2552, 1 },
+ { 215, 0x256B, 0 }, { 216, 0x256A, 0 }, { 217, 0x2518, 0 },
+ { 218, 0x250C, 0 }, { 219, 0x2588, 0 }, { 220, 0x2584, 0 },
+ { 221, 0x258C, 0 }, { 222, 0x2590, 0 }, { 223, 0x2580, 0 },
+ { 224, 0x03B1, 0 }, { 225, 0x00DF, 0 }, { 226, 0x0393, 0 },
+ { 227, 0x03C0, 0 }, { 228, 0x03A3, 0 }, { 229, 0x03C3, 0 },
+ { 230, 0x00B5, 0 }, { 231, 0x03C4, 0 }, { 232, 0x03A6, 0 },
+ { 233, 0x0398, 0 }, { 234, 0x03A9, 0 }, { 235, 0x03B4, 0 },
+ { 236, 0x221E, 0 }, { 237, 0x03C6, 0 }, { 238, 0x03B5, 0 },
+ { 239, 0x2229, 0 }, { 240, 0x2261, 0 }, { 241, 0x00B1, 0 },
+ { 242, 0x2265, 0 }, { 243, 0x2264, 0 }, { 244, 0x2320, 1 },
+ { 246, 0x00F7, 0 }, { 247, 0x2248, 0 }, { 248, 0x00B0, 0 },
+ { 249, 0x2219, 0 }, { 250, 0x00B7, 0 }, { 251, 0x221A, 0 },
+ { 252, 0x207F, 0 }, { 253, 0x00B2, 0 }, { 254, 0x25A0, 0 },
+ { 255, 0x00A0, 0 }
+};
+
+static uint16_t
+vga_cp437_to_uni(uint8_t c)
+{
+ int min, mid, max;
+
+ min = 0;
+ max = (sizeof (cp437unitable) / sizeof (struct cp437uni)) - 1;
+
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (c < cp437unitable[mid].cp437_base)
+ max = mid - 1;
+ else if (c > cp437unitable[mid].cp437_base +
+ cp437unitable[mid].length)
+ min = mid + 1;
+ else
+ return (c - cp437unitable[mid].cp437_base +
+ cp437unitable[mid].unicode_base);
+ }
+
+ return ('?');
+}
+
+/*
+ * install font for text mode, borrowed from gfxp_vgatext.c
+ */
+static void
+vidc_install_font(tem_modechg_cb_arg_t arg __unused)
+{
+ static uchar_t fsreg[8] = {0x0, 0x30, 0x5, 0x35, 0xa, 0x3a, 0xf, 0x3f};
+ const uchar_t *from;
+ uchar_t volatile *to;
+ uint16_t c;
+ int i, j, s;
+ int bpc, f_offset;
+
+ if (plat_stdout_is_framebuffer())
+ return;
+
+ /* Sync-reset the sequencer registers */
+ vga_set_seq(VGA_REG_ADDR, 0x00, 0x01);
+ /*
+ * enable write to plane2, since fonts
+ * could only be loaded into plane2
+ */
+ vga_set_seq(VGA_REG_ADDR, 0x02, 0x04);
+ /*
+ * sequentially access data in the bit map being
+ * selected by MapMask register (index 0x02)
+ */
+ vga_set_seq(VGA_REG_ADDR, 0x04, 0x07);
+ /* Sync-reset ended, and allow the sequencer to operate */
+ vga_set_seq(VGA_REG_ADDR, 0x00, 0x03);
+
+ /*
+ * select plane 2 on Read Mode 0
+ */
+ vga_set_grc(VGA_REG_ADDR, 0x04, 0x02);
+ /*
+ * system addresses sequentially access data, follow
+ * Memory Mode register bit 2 in the sequencer
+ */
+ vga_set_grc(VGA_REG_ADDR, 0x05, 0x00);
+ /*
+ * set range of host memory addresses decoded by VGA
+ * hardware -- A0000h-BFFFFh (128K region)
+ */
+ vga_set_grc(VGA_REG_ADDR, 0x06, 0x00);
+
+ /*
+ * This assumes 8x16 characters, which yield the traditional 80x25
+ * screen. It really should support other character heights.
+ */
+ bpc = 16;
+ s = 0; /* font slot, maybe should use tunable there. */
+ f_offset = s * 8 * 1024;
+ for (i = 0; i < 256; i++) {
+ c = vga_cp437_to_uni(i);
+ from = font_lookup(&tems.ts_font, c);
+ to = (unsigned char *)PTOV(VGA_MEM_ADDR) + f_offset +
+ i * 0x20;
+ for (j = 0; j < bpc; j++)
+ *to++ = *from++;
+ }
+
+ /* Sync-reset the sequencer registers */
+ vga_set_seq(VGA_REG_ADDR, 0x00, 0x01);
+ /* enable write to plane 0 and 1 */
+ vga_set_seq(VGA_REG_ADDR, 0x02, 0x03);
+ /*
+ * enable character map selection
+ * and odd/even addressing
+ */
+ vga_set_seq(VGA_REG_ADDR, 0x04, 0x03);
+ /*
+ * select font map
+ */
+ vga_set_seq(VGA_REG_ADDR, 0x03, fsreg[s]);
+ /* Sync-reset ended, and allow the sequencer to operate */
+ vga_set_seq(VGA_REG_ADDR, 0x00, 0x03);
+
+ /* restore graphic registers */
+
+ /* select plane 0 */
+ vga_set_grc(VGA_REG_ADDR, 0x04, 0x00);
+ /* enable odd/even addressing mode */
+ vga_set_grc(VGA_REG_ADDR, 0x05, 0x10);
+ /*
+ * range of host memory addresses decoded by VGA
+ * hardware -- B8000h-BFFFFh (32K region)
+ */
+ vga_set_grc(VGA_REG_ADDR, 0x06, 0x0e);
+ /* enable all color plane */
+ vga_set_atr(VGA_REG_ADDR, 0x12, 0x0f);
}
static int
@@ -643,6 +819,7 @@ vidc_init(struct console *cp, int arg)
return (0);
vidc_started = 1;
+ vbe_init();
/*
* Check Miscellaneous Output Register (Read at 3CCh, Write at 3C2h)
@@ -650,9 +827,9 @@ vidc_init(struct console *cp, int arg)
* color/graphics adapter.
*/
if (vga_get_reg(VGA_REG_ADDR, VGA_MISC_R) & VGA_MISC_IOA_SEL)
- vgatext = (uint16_t *) PTOV(VGA_MEM_ADDR + VGA_COLOR_BASE);
+ vgatext = (uint16_t *)PTOV(VGA_MEM_ADDR + VGA_COLOR_BASE);
else
- vgatext = (uint16_t *) PTOV(VGA_MEM_ADDR + VGA_MONO_BASE);
+ vgatext = (uint16_t *)PTOV(VGA_MEM_ADDR + VGA_MONO_BASE);
/* set 16bit colors */
i = vga_get_atr(VGA_REG_ADDR, VGA_ATR_MODE);
@@ -679,6 +856,8 @@ vidc_init(struct console *cp, int arg)
}
gfx_framework_init(&fb_ops);
+ /* set up callback before calling tem_info_init(). */
+ tem_register_modechg_cb(vidc_install_font, (tem_modechg_cb_arg_t)cp);
rc = tem_info_init(cp);
if (rc != 0) {
@@ -693,9 +872,9 @@ vidc_init(struct console *cp, int arg)
}
for (i = 0; i < 10 && vidc_ischar(cp); i++)
- (void)vidc_getchar(cp);
+ (void) vidc_getchar(cp);
- return (0); /* XXX reinit? */
+ return (0);
}
static void
@@ -802,21 +981,19 @@ vidc_devinfo(struct console *cp __unused)
#if KEYBOARD_PROBE
-#define PROBE_MAXRETRY 5
-#define PROBE_MAXWAIT 400
-#define IO_DUMMY 0x84
-#define IO_KBD 0x060 /* 8042 Keyboard */
+#define PROBE_MAXRETRY 5
+#define PROBE_MAXWAIT 400
+#define IO_DUMMY 0x84
+#define IO_KBD 0x060 /* 8042 Keyboard */
/* selected defines from kbdio.h */
#define KBD_STATUS_PORT 4 /* status port, read */
-#define KBD_DATA_PORT 0 /* data port, read/write
- * also used as keyboard command
- * and mouse command port
- */
-#define KBDC_ECHO 0x00ee
-#define KBDS_ANY_BUFFER_FULL 0x0001
-#define KBDS_INPUT_BUFFER_FULL 0x0002
-#define KBD_ECHO 0x00ee
+/* data port, read/write also used as keyboard command and mouse command port */
+#define KBD_DATA_PORT 0
+#define KBDC_ECHO 0x00ee
+#define KBDS_ANY_BUFFER_FULL 0x0001
+#define KBDS_INPUT_BUFFER_FULL 0x0002
+#define KBD_ECHO 0x00ee
/* 7 microsec delay necessary for some keyboard controllers */
static void
@@ -845,7 +1022,7 @@ delay1ms(void)
{
int i = 800;
while (--i >= 0)
- (void)inb(0x84);
+ (void) inb(0x84);
}
/*
diff --git a/usr/src/cmd/sgs/libconv/common/corenote.c b/usr/src/cmd/sgs/libconv/common/corenote.c
index ce923bb039..f86d534450 100644
--- a/usr/src/cmd/sgs/libconv/common/corenote.c
+++ b/usr/src/cmd/sgs/libconv/common/corenote.c
@@ -2479,7 +2479,7 @@ conv_cnote_fileflags(uint32_t fileflags, Conv_fmt_flags_t fmt_flags,
{ 0x2000, MSG_PR_O_LARGEFILE },
{ 0x20000, MSG_PR_O_NOFOLLOW },
{ 0x40000, MSG_PR_O_NOLINKS },
- { 0, NULL },
+ { 0, 0 },
};
arg.oflags = arg.rflags = fileflags;
@@ -2531,7 +2531,7 @@ conv_cnote_filemode(uint32_t mode, Conv_fmt_flags_t fmt_flags,
{ 0004, MSG_S_IROTH },
{ 0002, MSG_S_IWOTH },
{ 0001, MSG_S_IXOTH },
- { 0, NULL },
+ { 0, 0 },
};
arg.oflags = arg.rflags = mode & ~(0xf000);
@@ -2570,7 +2570,7 @@ conv_cnote_filemode(uint32_t mode, Conv_fmt_flags_t fmt_flags,
s = MSG_S_IFPORT;
break;
default:
- s = NULL;
+ s = 0;
break;
}
diff --git a/usr/src/lib/libzfs/common/libzfs_crypto.c b/usr/src/lib/libzfs/common/libzfs_crypto.c
index 4533ed8111..7c16207a58 100644
--- a/usr/src/lib/libzfs/common/libzfs_crypto.c
+++ b/usr/src/lib/libzfs/common/libzfs_crypto.c
@@ -787,14 +787,6 @@ zfs_crypto_create(libzfs_handle_t *hdl, char *parent_name, nvlist_t *props,
pcrypt = ZIO_CRYPT_OFF;
}
- /* Check for encryption being explicitly truned off */
- if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Invalid encryption value. Dataset must be encrypted."));
- goto out;
- }
-
/* Get the inherited encryption property if we don't have it locally */
if (!local_crypt)
crypt = pcrypt;
@@ -885,10 +877,6 @@ int
zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp,
char *parent_name, nvlist_t *props)
{
- int ret;
- zfs_handle_t *pzhp = NULL;
- uint64_t pcrypt, ocrypt;
-
/*
* No encryption properties should be specified. They will all be
* inherited from the origin dataset.
@@ -897,40 +885,12 @@ zfs_crypto_clone_check(libzfs_handle_t *hdl, zfs_handle_t *origin_zhp,
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_KEYLOCATION)) ||
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_ENCRYPTION)) ||
nvlist_exists(props, zfs_prop_to_name(ZFS_PROP_PBKDF2_ITERS))) {
- ret = EINVAL;
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
"Encryption properties must inherit from origin dataset."));
- goto out;
- }
-
- /* get a reference to parent dataset, should never be NULL */
- pzhp = make_dataset_handle(hdl, parent_name);
- if (pzhp == NULL) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Failed to lookup parent."));
- return (ENOENT);
- }
-
- /* Lookup parent's crypt */
- pcrypt = zfs_prop_get_int(pzhp, ZFS_PROP_ENCRYPTION);
- ocrypt = zfs_prop_get_int(origin_zhp, ZFS_PROP_ENCRYPTION);
-
- /* all children of encrypted parents must be encrypted */
- if (pcrypt != ZIO_CRYPT_OFF && ocrypt == ZIO_CRYPT_OFF) {
- ret = EINVAL;
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "Cannot create unencrypted clone as a child "
- "of encrypted parent."));
- goto out;
+ return (EINVAL);
}
- zfs_close(pzhp);
return (0);
-
-out:
- if (pzhp != NULL)
- zfs_close(pzhp);
- return (ret);
}
typedef struct loadkeys_cbdata {
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c
index dee622b5de..9fd133c00a 100644
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c
@@ -4514,16 +4514,9 @@ zfs_rename(zfs_handle_t *zhp, const char *target, boolean_t recursive,
"with the new name"));
(void) zfs_error(hdl, EZFS_EXISTS, errbuf);
} else if (errno == EACCES) {
- if (zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION) ==
- ZIO_CRYPT_OFF) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot rename an unencrypted dataset to "
- "be a decendent of an encrypted one"));
- } else {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "cannot move encryption child outside of "
- "its encryption root"));
- }
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "cannot move encrypted child outside of "
+ "its encryption root"));
(void) zfs_error(hdl, EZFS_CRYPTOFAILED, errbuf);
} else {
(void) zfs_standard_error(zhp->zfs_hdl, errno, errbuf);
diff --git a/usr/src/lib/libzfs/common/libzfs_sendrecv.c b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
index c933a24e89..a25574cc19 100644
--- a/usr/src/lib/libzfs/common/libzfs_sendrecv.c
+++ b/usr/src/lib/libzfs/common/libzfs_sendrecv.c
@@ -63,7 +63,7 @@ extern void zfs_setprop_error(libzfs_handle_t *, zfs_prop_t, int, char *);
static int zfs_receive_impl(libzfs_handle_t *, const char *, const char *,
recvflags_t *, int, const char *, nvlist_t *, avl_tree_t *, char **, int,
- uint64_t *, const char *);
+ uint64_t *, const char *, nvlist_t *);
static int guid_to_name(libzfs_handle_t *, const char *,
uint64_t, boolean_t, char *);
@@ -2645,7 +2645,7 @@ recv_fix_encryption_hierarchy(libzfs_handle_t *hdl, const char *destname,
is_clone = zhp->zfs_dmustats.dds_origin[0] != '\0';
(void) zfs_crypto_get_encryption_root(zhp, &is_encroot, NULL);
- /* we don't need to do anything for unencrypted filesystems */
+ /* we don't need to do anything for unencrypted datasets */
if (crypt == ZIO_CRYPT_OFF) {
zfs_close(zhp);
continue;
@@ -2997,7 +2997,8 @@ again:
static int
zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
recvflags_t *flags, dmu_replay_record_t *drr, zio_cksum_t *zc,
- char **top_zfs, int cleanup_fd, uint64_t *action_handlep)
+ char **top_zfs, int cleanup_fd, uint64_t *action_handlep,
+ nvlist_t *cmdprops)
{
nvlist_t *stream_nv = NULL;
avl_tree_t *stream_avl = NULL;
@@ -3174,7 +3175,7 @@ zfs_receive_package(libzfs_handle_t *hdl, int fd, const char *destname,
*/
error = zfs_receive_impl(hdl, destname, NULL, flags, fd,
sendfs, stream_nv, stream_avl, top_zfs, cleanup_fd,
- action_handlep, sendsnap);
+ action_handlep, sendsnap, cmdprops);
if (error == ENODATA) {
error = 0;
break;
@@ -3350,7 +3351,7 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
const char *originsnap, recvflags_t *flags, dmu_replay_record_t *drr,
dmu_replay_record_t *drr_noswap, const char *sendfs, nvlist_t *stream_nv,
avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
- uint64_t *action_handlep, const char *finalsnap)
+ uint64_t *action_handlep, const char *finalsnap, nvlist_t *cmdprops)
{
zfs_cmd_t zc = { 0 };
time_t begin_time;
@@ -3371,6 +3372,8 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
char *snapname = NULL;
nvlist_t *props = NULL;
char tmp_keylocation[MAXNAMELEN];
+ nvlist_t *rcvprops = NULL; /* props received from the send stream */
+ nvlist_t *oxprops = NULL; /* override (-o) and exclude (-x) props */
begin_time = time(NULL);
bzero(tmp_keylocation, MAXNAMELEN);
@@ -3721,8 +3724,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
zfs_close(zhp);
} else {
- zfs_handle_t *zhp;
-
/*
* Destination filesystem does not exist. Therefore we better
* be creating a new filesystem (either from a full backup, or
@@ -3752,39 +3753,6 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
goto out;
}
- /*
- * It is invalid to receive a properties stream that was
- * unencrypted on the send side as a child of an encrypted
- * parent. Technically there is nothing preventing this, but
- * it would mean that the encryption=off property which is
- * locally set on the send side would not be received correctly.
- * We can infer encryption=off if the stream is not raw and
- * properties were included since the send side will only ever
- * send the encryption property in a raw nvlist header.
- */
- if (!raw && props != NULL) {
- uint64_t crypt;
-
- zhp = zfs_open(hdl, zc.zc_name, ZFS_TYPE_DATASET);
- if (zhp == NULL) {
- err = zfs_error(hdl, EZFS_BADRESTORE,
- errbuf);
- goto out;
- }
-
- crypt = zfs_prop_get_int(zhp, ZFS_PROP_ENCRYPTION);
- zfs_close(zhp);
-
- if (crypt != ZIO_CRYPT_OFF) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "parent '%s' must not be encrypted to "
- "receive unencrypted property"),
- zc.zc_name);
- err = zfs_error(hdl, EZFS_BADPROP, errbuf);
- goto out;
- }
- }
-
newfs = B_TRUE;
*cp = '/';
}
@@ -3807,6 +3775,24 @@ zfs_receive_one(libzfs_handle_t *hdl, int infd, const char *tosnap,
goto out;
}
+ /*
+ * When sending with properties (zfs send -p), the encryption property
+ * is not included because it is a SETONCE property and therefore
+ * treated as read only. However, we are always able to determine its
+ * value because raw sends will include it in the DRR_BDEGIN payload
+ * and non-raw sends with properties are not allowed for encrypted
+ * datasets. Therefore, if this is a non-raw properties stream, we can
+ * infer that the value should be ZIO_CRYPT_OFF and manually add that
+ * to the received properties.
+ */
+ if (stream_wantsnewfs && !raw && rcvprops != NULL &&
+ !nvlist_exists(cmdprops, zfs_prop_to_name(ZFS_PROP_ENCRYPTION))) {
+ if (oxprops == NULL)
+ oxprops = fnvlist_alloc();
+ fnvlist_add_uint64(oxprops,
+ zfs_prop_to_name(ZFS_PROP_ENCRYPTION), ZIO_CRYPT_OFF);
+ }
+
zc.zc_nvlist_dst = (uint64_t)(uintptr_t)prop_errbuf;
zc.zc_nvlist_dst_size = sizeof (prop_errbuf);
zc.zc_cleanup_fd = cleanup_fd;
@@ -4080,7 +4066,7 @@ static int
zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
const char *originsnap, recvflags_t *flags, int infd, const char *sendfs,
nvlist_t *stream_nv, avl_tree_t *stream_avl, char **top_zfs, int cleanup_fd,
- uint64_t *action_handlep, const char *finalsnap)
+ uint64_t *action_handlep, const char *finalsnap, nvlist_t *cmdprops)
{
int err;
dmu_replay_record_t drr, drr_noswap;
@@ -4182,12 +4168,12 @@ zfs_receive_impl(libzfs_handle_t *hdl, const char *tosnap,
}
return (zfs_receive_one(hdl, infd, tosnap, originsnap, flags,
&drr, &drr_noswap, sendfs, stream_nv, stream_avl, top_zfs,
- cleanup_fd, action_handlep, finalsnap));
+ cleanup_fd, action_handlep, finalsnap, cmdprops));
} else {
assert(DMU_GET_STREAM_HDRTYPE(drrb->drr_versioninfo) ==
DMU_COMPOUNDSTREAM);
return (zfs_receive_package(hdl, infd, tosnap, flags, &drr,
- &zcksum, top_zfs, cleanup_fd, action_handlep));
+ &zcksum, top_zfs, cleanup_fd, action_handlep, cmdprops));
}
}
@@ -4217,7 +4203,7 @@ zfs_receive(libzfs_handle_t *hdl, const char *tosnap, nvlist_t *props,
VERIFY(cleanup_fd >= 0);
err = zfs_receive_impl(hdl, tosnap, originsnap, flags, infd, NULL, NULL,
- stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL);
+ stream_avl, &top_zfs, cleanup_fd, &action_handle, NULL, props);
VERIFY(0 == close(cleanup_fd));
diff --git a/usr/src/lib/pam_modules/dhkeys/dhkeys.c b/usr/src/lib/pam_modules/dhkeys/dhkeys.c
index b37e422296..bcde37a8b3 100644
--- a/usr/src/lib/pam_modules/dhkeys/dhkeys.c
+++ b/usr/src/lib/pam_modules/dhkeys/dhkeys.c
@@ -257,8 +257,9 @@ establish_key(pam_handle_t *pamh, int flags, int debug, char *netname)
if (passwd) {
(void) strlcpy(short_pass, passwd, sizeof (short_pass));
short_passp = short_pass;
- } else
+ } else {
short_passp = NULL;
+ }
if (mechs = __nis_get_mechanisms(FALSE)) {
@@ -408,7 +409,7 @@ remove_key(pam_handle_t *pamh, int flags, int debug)
pthread_t tid;
(void) pam_get_item(pamh, PAM_USER, (void **)&uname);
- if (uname == NULL || *uname == NULL) {
+ if (uname == NULL || *uname == '\0') {
if (debug)
syslog(LOG_DEBUG,
"pam_dhkeys: user NULL or empty in remove_key()");
@@ -442,8 +443,9 @@ remove_key(pam_handle_t *pamh, int flags, int debug)
pwu_rep->type = auth_rep->type;
pwu_rep->scope = auth_rep->scope;
pwu_rep->scope_len = auth_rep->scope_len;
- } else
+ } else {
pwu_rep = PWU_DEFAULT_REP;
+ }
/* Retrieve user's uid/gid from the password repository */
attr_pw[0].type = ATTR_UID; attr_pw[0].next = &attr_pw[1];
diff --git a/usr/src/pkg/manifests/system-test-zfstest.mf b/usr/src/pkg/manifests/system-test-zfstest.mf
index c0a85644aa..e2a3c9fa2f 100644
--- a/usr/src/pkg/manifests/system-test-zfstest.mf
+++ b/usr/src/pkg/manifests/system-test-zfstest.mf
@@ -196,6 +196,7 @@ file path=opt/zfs-tests/bin/rm_lnkcnt_zero_file mode=0555
file path=opt/zfs-tests/bin/zfstest mode=0555
file path=opt/zfs-tests/callbacks/zfs_dbgmsg mode=0555
file path=opt/zfs-tests/callbacks/zfs_mmp mode=0555
+file path=opt/zfs-tests/include/blkdev.shlib mode=0444
file path=opt/zfs-tests/include/commands.cfg mode=0444
file path=opt/zfs-tests/include/default.cfg mode=0444
file path=opt/zfs-tests/include/libtest.shlib mode=0444
@@ -2806,6 +2807,8 @@ file path=opt/zfs-tests/tests/functional/rsend/send-c_volume mode=0555
file path=opt/zfs-tests/tests/functional/rsend/send-c_zstreamdump mode=0555
file path=opt/zfs-tests/tests/functional/rsend/send-cpL_varied_recsize \
mode=0555
+file path=opt/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol \
+ mode=0555
file path=opt/zfs-tests/tests/functional/rsend/send_encrypted_files mode=0555
file path=opt/zfs-tests/tests/functional/rsend/send_encrypted_hierarchy \
mode=0555
diff --git a/usr/src/test/zfs-tests/include/blkdev.shlib b/usr/src/test/zfs-tests/include/blkdev.shlib
new file mode 100644
index 0000000000..bf4bfbbd87
--- /dev/null
+++ b/usr/src/test/zfs-tests/include/blkdev.shlib
@@ -0,0 +1,449 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+# Copyright (c) 2012, 2016 by Delphix. All rights reserved.
+# Copyright 2016 Nexenta Systems, Inc.
+# Copyright (c) 2016, 2017 by Intel Corporation. All rights reserved.
+# Copyright (c) 2017 Lawrence Livermore National Security, LLC.
+# Copyright (c) 2017 Datto Inc.
+# Copyright (c) 2017 Open-E, Inc. All Rights Reserved.
+#
+
+#
+# Returns SCSI host number for the given disk
+#
+function get_scsi_host #disk
+{
+ typeset disk=$1
+ ls /sys/block/${disk}/device/scsi_device | cut -d : -f 1
+}
+
+#
+# Cause a scan of all scsi host adapters by default
+#
+# $1 optional host number
+#
+function scan_scsi_hosts
+{
+ typeset hostnum=${1}
+
+ if is_linux; then
+ if [[ -z $hostnum ]]; then
+ for host in /sys/class/scsi_host/host*; do
+ log_must eval "echo '- - -' > $host/scan"
+ done
+ else
+ log_must eval \
+ "echo /sys/class/scsi_host/host$hostnum/scan" \
+ > /dev/null
+ log_must eval \
+ "echo '- - -' > /sys/class/scsi_host/host$hostnum/scan"
+ fi
+ fi
+}
+
+#
+# Wait for newly created block devices to have their minors created.
+#
+function block_device_wait
+{
+ if is_linux; then
+ udevadm trigger
+ udevadm settle
+ fi
+}
+
+#
+# Check if the given device is physical device
+#
+function is_physical_device #device
+{
+ typeset device=${1#$DEV_DSKDIR}
+ device=${device#$DEV_RDSKDIR}
+
+ if is_linux; then
+ [[ -b "$DEV_DSKDIR/$device" ]] && \
+ [[ -f /sys/module/loop/parameters/max_part ]]
+ return $?
+ else
+ echo $device | egrep "^c[0-F]+([td][0-F]+)+$" > /dev/null 2>&1
+ return $?
+ fi
+}
+
+#
+# Check if the given device is a real device (ie SCSI device)
+#
+function is_real_device #disk
+{
+ typeset disk=$1
+ [[ -z $disk ]] && log_fail "No argument for disk given."
+
+ if is_linux; then
+ lsblk $DEV_RDSKDIR/$disk -o TYPE 2>/dev/null | \
+ egrep disk >/dev/null
+ return $?
+ fi
+}
+
+#
+# Check if the given device is a loop device
+#
+function is_loop_device #disk
+{
+ typeset disk=$1
+ [[ -z $disk ]] && log_fail "No argument for disk given."
+
+ if is_linux; then
+ lsblk $DEV_RDSKDIR/$disk -o TYPE 2>/dev/null | \
+ egrep loop >/dev/null
+ return $?
+ fi
+}
+
+#
+# Check if the given device is a multipath device and if there is a symbolic
+# link to a device mapper and to a disk
+# Currently no support for dm devices alone without multipath
+#
+function is_mpath_device #disk
+{
+ typeset disk=$1
+ [[ -z $disk ]] && log_fail "No argument for disk given."
+
+ if is_linux; then
+ lsblk $DEV_MPATHDIR/$disk -o TYPE 2>/dev/null | \
+ egrep mpath >/dev/null
+ if (($? == 0)); then
+ readlink $DEV_MPATHDIR/$disk > /dev/null 2>&1
+ return $?
+ else
+ return $?
+ fi
+ fi
+}
+
+# Set the slice prefix for disk partitioning depending
+# on whether the device is a real, multipath, or loop device.
+# Currently all disks have to be of the same type, so only
+# checks first disk to determine slice prefix.
+#
+function set_slice_prefix
+{
+ typeset disk
+ typeset -i i=0
+
+ if is_linux; then
+ while (( i < $DISK_ARRAY_NUM )); do
+ disk="$(echo $DISKS | nawk '{print $(i + 1)}')"
+ if ( is_mpath_device $disk ) && [[ -z $(echo $disk | awk 'substr($1,18,1)\
+ ~ /^[[:digit:]]+$/') ]] || ( is_real_device $disk ); then
+ export SLICE_PREFIX=""
+ return 0
+ elif ( is_mpath_device $disk || is_loop_device \
+ $disk ); then
+ export SLICE_PREFIX="p"
+ return 0
+ else
+ log_fail "$disk not supported for partitioning."
+ fi
+ (( i = i + 1))
+ done
+ fi
+}
+
+#
+# Set the directory path of the listed devices in $DISK_ARRAY_NUM
+# Currently all disks have to be of the same type, so only
+# checks first disk to determine device directory
+# default = /dev (linux)
+# real disk = /dev (linux)
+# multipath device = /dev/mapper (linux)
+#
+function set_device_dir
+{
+ typeset disk
+ typeset -i i=0
+
+ if is_linux; then
+ while (( i < $DISK_ARRAY_NUM )); do
+ disk="$(echo $DISKS | nawk '{print $(i + 1)}')"
+ if is_mpath_device $disk; then
+ export DEV_DSKDIR=$DEV_MPATHDIR
+ return 0
+ else
+ export DEV_DSKDIR=$DEV_RDSKDIR
+ return 0
+ fi
+ (( i = i + 1))
+ done
+ else
+ export DEV_DSKDIR=$DEV_RDSKDIR
+ fi
+}
+
+#
+# Get the directory path of given device
+#
+function get_device_dir #device
+{
+ typeset device=$1
+
+ if ! $(is_physical_device $device) ; then
+ if [[ $device != "/" ]]; then
+ device=${device%/*}
+ fi
+ if [[ -b "$DEV_DSKDIR/$device" ]]; then
+ device="$DEV_DSKDIR"
+ fi
+ echo $device
+ else
+ echo "$DEV_DSKDIR"
+ fi
+}
+
+#
+# Get persistent name for given disk
+#
+function get_persistent_disk_name #device
+{
+ typeset device=$1
+ typeset dev_id
+
+ if is_linux; then
+ if is_real_device $device; then
+ dev_id="$(udevadm info -q all -n $DEV_DSKDIR/$device \
+ | egrep disk/by-id | nawk '{print $2; exit}' \
+ | nawk -F / '{print $3}')"
+ echo $dev_id
+ elif is_mpath_device $device; then
+ dev_id="$(udevadm info -q all -n $DEV_DSKDIR/$device \
+ | egrep disk/by-id/dm-uuid \
+ | nawk '{print $2; exit}' \
+ | nawk -F / '{print $3}')"
+ echo $dev_id
+ else
+ echo $device
+ fi
+ else
+ echo $device
+ fi
+}
+
+#
+# Online or offline a disk on the system
+#
+# First checks state of disk. Test will fail if disk is not properly onlined
+# or offlined. Online is a full rescan of SCSI disks by echoing to every
+# host entry.
+#
+function on_off_disk # disk state{online,offline} host
+{
+ typeset disk=$1
+ typeset state=$2
+ typeset host=$3
+
+ [[ -z $disk ]] || [[ -z $state ]] && \
+ log_fail "Arguments invalid or missing"
+
+ if is_linux; then
+ if [[ $state == "offline" ]] && ( is_mpath_device $disk ); then
+ dm_name="$(readlink $DEV_DSKDIR/$disk \
+ | nawk -F / '{print $2}')"
+ slave="$(ls /sys/block/${dm_name}/slaves \
+ | nawk '{print $1}')"
+ while [[ -n $slave ]]; do
+ #check if disk is online
+ lsscsi | egrep $slave > /dev/null
+ if (($? == 0)); then
+ slave_dir="/sys/block/${dm_name}"
+ slave_dir+="/slaves/${slave}/device"
+ ss="${slave_dir}/state"
+ sd="${slave_dir}/delete"
+ log_must eval "echo 'offline' > ${ss}"
+ log_must eval "echo '1' > ${sd}"
+ lsscsi | egrep $slave > /dev/null
+ if (($? == 0)); then
+ log_fail "Offlining" \
+ "$disk failed"
+ fi
+ fi
+ slave="$(ls /sys/block/$dm_name/slaves \
+ 2>/dev/null | nawk '{print $1}')"
+ done
+ elif [[ $state == "offline" ]] && ( is_real_device $disk ); then
+ #check if disk is online
+ lsscsi | egrep $disk > /dev/null
+ if (($? == 0)); then
+ dev_state="/sys/block/$disk/device/state"
+ dev_delete="/sys/block/$disk/device/delete"
+ log_must eval "echo 'offline' > ${dev_state}"
+ log_must eval "echo '1' > ${dev_delete}"
+ lsscsi | egrep $disk > /dev/null
+ if (($? == 0)); then
+ log_fail "Offlining $disk" \
+ "failed"
+ fi
+ else
+ log_note "$disk is already offline"
+ fi
+ elif [[ $state == "online" ]]; then
+ #force a full rescan
+ scan_scsi_hosts $host
+ block_device_wait
+ if is_mpath_device $disk; then
+ dm_name="$(readlink $DEV_DSKDIR/$disk \
+ | nawk -F / '{print $2}')"
+ slave="$(ls /sys/block/$dm_name/slaves \
+ | nawk '{print $1}')"
+ lsscsi | egrep $slave > /dev/null
+ if (($? != 0)); then
+ log_fail "Onlining $disk failed"
+ fi
+ elif is_real_device $disk; then
+ block_device_wait
+ typeset -i retries=0
+ while ! lsscsi | egrep -q $disk; do
+ if (( $retries > 2 )); then
+ log_fail "Onlining $disk failed"
+ break
+ fi
+ (( ++retries ))
+ sleep 1
+ done
+ else
+ log_fail "$disk is not a real dev"
+ fi
+ else
+ log_fail "$disk failed to $state"
+ fi
+ fi
+}
+
+#
+# Simulate disk removal
+#
+function remove_disk #disk
+{
+ typeset disk=$1
+ on_off_disk $disk "offline"
+ block_device_wait
+}
+
+#
+# Simulate disk insertion for the given SCSI host
+#
+function insert_disk #disk scsi_host
+{
+ typeset disk=$1
+ typeset scsi_host=$2
+ on_off_disk $disk "online" $scsi_host
+ block_device_wait
+}
+
+#
+# Load scsi_debug module with specified parameters
+# $blksz can be either one of: < 512b | 512e | 4Kn >
+#
+function load_scsi_debug # dev_size_mb add_host num_tgts max_luns blksz
+{
+ typeset devsize=$1
+ typeset hosts=$2
+ typeset tgts=$3
+ typeset luns=$4
+ typeset blksz=$5
+
+ [[ -z $devsize ]] || [[ -z $hosts ]] || [[ -z $tgts ]] || \
+ [[ -z $luns ]] || [[ -z $blksz ]] && \
+ log_fail "Arguments invalid or missing"
+
+ case "$5" in
+ '512b')
+ typeset sector=512
+ typeset blkexp=0
+ ;;
+ '512e')
+ typeset sector=512
+ typeset blkexp=3
+ ;;
+ '4Kn')
+ typeset sector=4096
+ typeset blkexp=0
+ ;;
+ *) log_fail "Unsupported blksz value: $5" ;;
+ esac
+
+ if is_linux; then
+ modprobe -n scsi_debug
+ if (($? != 0)); then
+ log_unsupported "Platform does not have scsi_debug"
+ "module"
+ fi
+ lsmod | egrep scsi_debug > /dev/null
+ if (($? == 0)); then
+ log_fail "scsi_debug module already installed"
+ else
+ log_must modprobe scsi_debug dev_size_mb=$devsize \
+ add_host=$hosts num_tgts=$tgts max_luns=$luns \
+ sector_size=$sector physblk_exp=$blkexp
+ block_device_wait
+ lsscsi | egrep scsi_debug > /dev/null
+ if (($? == 1)); then
+ log_fail "scsi_debug module install failed"
+ fi
+ fi
+ fi
+}
+
+#
+# Unload scsi_debug module, if needed.
+#
+function unload_scsi_debug
+{
+ log_must_retry "in use" 5 modprobe -r scsi_debug
+}
+
+#
+# Get scsi_debug device name.
+# Returns basename of scsi_debug device (for example "sdb").
+#
+function get_debug_device
+{
+ for i in {1..10} ; do
+ val=$(lsscsi | nawk '/scsi_debug/ {print $6; exit}' | cut -d / -f3)
+
+ # lsscsi can take time to settle
+ if [ "$val" != "-" ] ; then
+ break
+ fi
+ sleep 1
+ done
+ echo "$val"
+}
+
+#
+# Get actual devices used by the pool (i.e. linux sdb1 not sdb).
+#
+function get_pool_devices #testpool #devdir
+{
+ typeset testpool=$1
+ typeset devdir=$2
+ typeset out=""
+
+ if is_linux; then
+ out=$(zpool status -P $testpool |grep ${devdir} | awk '{print $1}')
+ out=$(echo $out | sed -e "s|${devdir}/||g" | tr '\n' ' ')
+ fi
+ echo $out
+}
diff --git a/usr/src/test/zfs-tests/include/default.cfg b/usr/src/test/zfs-tests/include/default.cfg
index cf61660b76..a4e0e28bee 100644
--- a/usr/src/test/zfs-tests/include/default.cfg
+++ b/usr/src/test/zfs-tests/include/default.cfg
@@ -141,3 +141,10 @@ export ZFS_ALL_VERSIONS="1 2 3 4 5"
for i in $ZFS_ALL_VERSIONS; do
eval 'export ZFS_VERSION_$i="v${i}-fs"'
done
+
+export ZVOL_DEVDIR="/dev/zvol/dsk"
+export ZVOL_RDEVDIR="/dev/zvol/rdsk"
+export DEV_DSKDIR="/dev/dsk"
+export DEV_RDSKDIR="/dev/rdsk"
+
+export NEWFS_DEFAULT_FS="ufs"
diff --git a/usr/src/test/zfs-tests/include/libtest.shlib b/usr/src/test/zfs-tests/include/libtest.shlib
index bf21e9da33..fbdcc85d1c 100644
--- a/usr/src/test/zfs-tests/include/libtest.shlib
+++ b/usr/src/test/zfs-tests/include/libtest.shlib
@@ -29,6 +29,20 @@
#
. ${STF_TOOLS}/contrib/include/logapi.shlib
+. ${STF_SUITE}/include/blkdev.shlib
+
+# Determine if this is a Linux test system
+#
+# Return 0 if platform Linux, 1 if otherwise
+
+function is_linux
+{
+ if [[ $(uname -o) == "GNU/Linux" ]]; then
+ return 0
+ else
+ return 1
+ fi
+}
# Determine whether a dataset is mounted
#
diff --git a/usr/src/test/zfs-tests/runfiles/delphix.run b/usr/src/test/zfs-tests/runfiles/delphix.run
index fb5c8e7bbe..c1563223ec 100644
--- a/usr/src/test/zfs-tests/runfiles/delphix.run
+++ b/usr/src/test/zfs-tests/runfiles/delphix.run
@@ -606,7 +606,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy',
'send_encrypted_truncated_files',
'send_realloc_encrypted_files',
- 'send_mixed_raw']
+ 'send_mixed_raw', 'send-wDR_encrypted_zvol']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/omnios.run b/usr/src/test/zfs-tests/runfiles/omnios.run
index 5d3571307e..8c26d6dfbd 100644
--- a/usr/src/test/zfs-tests/runfiles/omnios.run
+++ b/usr/src/test/zfs-tests/runfiles/omnios.run
@@ -605,7 +605,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy',
'send_encrypted_truncated_files',
'send_realloc_encrypted_files',
- 'send_mixed_raw']
+ 'send_mixed_raw', 'send-wDR_encrypted_zvol']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/runfiles/openindiana.run b/usr/src/test/zfs-tests/runfiles/openindiana.run
index 451852e863..5ee4230f66 100644
--- a/usr/src/test/zfs-tests/runfiles/openindiana.run
+++ b/usr/src/test/zfs-tests/runfiles/openindiana.run
@@ -605,7 +605,7 @@ tests = ['rsend_001_pos', 'rsend_002_pos', 'rsend_003_pos', 'rsend_004_pos',
'send-c_recv_dedup', 'send_encrypted_files', 'send_encrypted_hierarchy',
'send_encrypted_truncated_files',
'send_realloc_encrypted_files',
- 'send_mixed_raw']
+ 'send_mixed_raw', 'send-wDR_encrypted_zvol']
[/opt/zfs-tests/tests/functional/scrub_mirror]
tests = ['scrub_mirror_001_pos', 'scrub_mirror_002_pos',
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh
index 9d5ecab0df..7e5072f0d5 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_create/zfs_create_encrypted.ksh
@@ -51,10 +51,10 @@
# yes unspec 0 1 no no keyformat specified
# yes unspec 1 0 yes new encryption root, crypt inherited
# yes unspec 1 1 yes new encryption root, crypt inherited
-# yes off 0 0 no unencrypted child of encrypted parent
-# yes off 0 1 no unencrypted child of encrypted parent
-# yes off 1 0 no unencrypted child of encrypted parent
-# yes off 1 1 no unencrypted child of encrypted parent
+# yes off 0 0 yes unencrypted child of encrypted parent
+# yes off 0 1 no keylocation given, but crypt off
+# yes off 1 0 no keyformat given, but crypt off
+# yes off 1 1 no keyformat given, but crypt off
# yes on 0 0 yes inherited encryption, local crypt
# yes on 0 1 no no keyformat specified for new key
# yes on 1 0 yes new encryption root
@@ -113,7 +113,9 @@ log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \
log_must eval "echo $PASSPHRASE | zfs create -o keyformat=passphrase" \
"-o keylocation=prompt $TESTPOOL/$TESTFS2/c4"
-log_mustnot zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5
+log_must zfs create -o encryption=off $TESTPOOL/$TESTFS2/c5
+log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS2/c5)" == "off"
+
log_mustnot zfs create -o encryption=off -o keylocation=prompt \
$TESTPOOL/$TESTFS2/c5
log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
@@ -122,13 +124,13 @@ log_mustnot zfs create -o encryption=off -o keyformat=passphrase \
-o keylocation=prompt $TESTPOOL/$TESTFS2/c5
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
- "$TESTPOOL/$TESTFS2/c5"
+ "$TESTPOOL/$TESTFS2/c6"
log_mustnot zfs create -o encryption=on -o keylocation=prompt \
- $TESTPOOL/$TESTFS2/c6
+ $TESTPOOL/$TESTFS2/c7
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
- "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c6"
+ "-o keyformat=passphrase $TESTPOOL/$TESTFS2/c7"
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
- "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c7"
+ "-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2/c8"
log_pass "ZFS creates datasets only if they have a valid combination of" \
"encryption properties set."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
index 57896c6fd3..3ce5ddc36c 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_receive/zfs_receive_to_encrypted.ksh
@@ -46,7 +46,7 @@ function cleanup
log_onexit cleanup
-log_assert "ZFS should receive to an encrypted child dataset"
+log_assert "ZFS should receive encrypted filesystems into child dataset"
typeset passphrase="password"
typeset snap="$TESTPOOL/$TESTFS@snap"
@@ -57,14 +57,21 @@ log_must zfs snapshot $snap
log_must eval "echo $passphrase | zfs create -o encryption=on" \
"-o keyformat=passphrase $TESTPOOL/$TESTFS1"
+# XXX - on illumos we're currently conflicting on mount prop
+log_must zfs set mountpoint=none $TESTPOOL/$TESTFS
+
log_note "Verifying ZFS will receive to an encrypted child"
log_must eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c1"
-log_note "Verifying 'send -p' will not receive to an encrypted child"
-log_mustnot eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2"
+log_note "Verifying 'send -p' will receive to an encrypted child"
+log_must eval "zfs send -p $snap | zfs receive $TESTPOOL/$TESTFS1/c2"
+# XXX - on illumos, not sending encryption prop yet
+# log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c2)" == "off"
-log_note "Verifying 'send -R' will not receive to an encrypted child"
-log_mustnot eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3"
+log_note "Verifying 'send -R' will receive to an encrypted child"
+log_must eval "zfs send -R $snap | zfs receive $TESTPOOL/$TESTFS1/c3"
+# XXX - on illumos, not sending encryption prop yet
+# log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS1/c3)" == "off"
log_note "Verifying ZFS will not receive to an encrypted child when the" \
"parent key is unloaded"
@@ -72,4 +79,4 @@ log_must zfs unmount $TESTPOOL/$TESTFS1
log_must zfs unload-key $TESTPOOL/$TESTFS1
log_mustnot eval "zfs send $snap | zfs receive $TESTPOOL/$TESTFS1/c4"
-log_pass "ZFS can receive to an encrypted child dataset"
+log_pass "ZFS can receive encrypted filesystems into child dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh
index 400592aaca..1b9c6e3c70 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_rename/zfs_rename_to_encrypted.ksh
@@ -23,12 +23,13 @@
#
# DESCRIPTION:
-# 'zfs rename' should not rename an unencrypted dataset to a child
+# 'zfs rename' should be able to move an unencrypted dataset to a child
# of an encrypted dataset
#
# STRATEGY:
# 1. Create an encrypted dataset
-# 2. Attempt to rename the default dataset to a child of the encrypted dataset
+# 2. Rename the default dataset to a child of the encrypted dataset
+# 3. Confirm the child dataset doesn't have any encryption properties
#
verify_runnable "both"
@@ -36,16 +37,17 @@ verify_runnable "both"
function cleanup
{
datasetexists $TESTPOOL/$TESTFS2 && \
- log_must zfs destroy $TESTPOOL/$TESTFS2
+ log_must zfs destroy -r $TESTPOOL/$TESTFS2
}
log_onexit cleanup
-log_assert "'zfs rename' should not rename an unencrypted dataset to a" \
+log_assert "'zfs rename' should allow renaming an unencrypted dataset to a" \
"child of an encrypted dataset"
log_must eval "echo $PASSPHRASE | zfs create -o encryption=on" \
"-o keyformat=passphrase -o keylocation=prompt $TESTPOOL/$TESTFS2"
-log_mustnot zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS
+log_must zfs rename $TESTPOOL/$TESTFS $TESTPOOL/$TESTFS2/$TESTFS
+log_must test "$(get_prop 'encryption' $TESTPOOL/$TESTFS2/$TESTFS)" == "off"
-log_pass "'zfs rename' does not rename an unencrypted dataset to a child" \
+log_pass "'zfs rename' allows renaming an unencrypted dataset to a child" \
"of an encrypted dataset"
diff --git a/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh b/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh
new file mode 100755
index 0000000000..83fe3556d4
--- /dev/null
+++ b/usr/src/test/zfs-tests/tests/functional/rsend/send-wDR_encrypted_zvol.ksh
@@ -0,0 +1,103 @@
+#!/bin/ksh -p
+#
+# CDDL HEADER START
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright (c) 2018 by Datto Inc. All rights reserved.
+# Copyright 2019 Joyent, Inc.
+#
+
+. $STF_SUITE/tests/functional/rsend/rsend.kshlib
+
+#
+# DESCRIPTION:
+# Verify that zvols with dedup=on and encryption=on can be sent and received
+# with a deduplicated raw send stream.
+#
+# STRATEGY:
+# 1. Create a zvol with dedup and encryption on and put a filesystem on it
+# 2. Copy a file into the zvol a few times and take a snapshot
+# 3. Repeat step 2 a few times to create more snapshots
+# 4. Send all snapshots in a recursive, raw, deduplicated send stream
+# 5. Mount the received zvol and verify that all of the data there is correct
+#
+
+verify_runnable "both"
+
+function cleanup
+{
+ if is_linux; then
+ ismounted $recvmnt ext4 && log_must umount $recvmnt
+ ismounted $mntpnt ext4 && log_must umount $mntpnt
+ else
+ ismounted $recvmnt ufs && log_must umount $recvmnt
+ ismounted $mntpnt ufs && log_must umount $mntpnt
+ fi
+ [[ -d $recvmnt ]] && log_must rm -rf $keyfile
+ [[ -d $mntpnt ]] && log_must rm -rf $keyfile
+ destroy_dataset $TESTPOOL/recv "-r"
+ destroy_dataset $TESTPOOL/$TESTVOL "-r"
+ [[ -f $keyfile ]] && log_must rm $keyfile
+ [[ -f $sendfile ]] && log_must rm $sendfile
+}
+log_onexit cleanup
+
+log_assert "Verify zfs can receive raw, recursive, and deduplicated send streams"
+
+typeset keyfile=/$TESTPOOL/pkey
+typeset snap_count=5
+typeset zdev=$ZVOL_DEVDIR/$TESTPOOL/$TESTVOL
+typeset mntpnt=$TESTDIR/$TESTVOL
+typeset recvdev=$ZVOL_DEVDIR/$TESTPOOL/recv
+typeset recvmnt=$TESTDIR/recvmnt
+typeset sendfile=$TESTDIR/sendfile
+
+log_must eval "echo 'password' > $keyfile"
+
+log_must zfs create -o dedup=on -o encryption=on -o keyformat=passphrase \
+ -o keylocation=file://$keyfile -V 128M $TESTPOOL/$TESTVOL
+log_must block_device_wait
+
+if is_linux; then
+ log_must eval "echo 'y' | newfs -t ext4 -v $zdev"
+else
+ log_must eval "echo 'y' | newfs $zdev"
+fi
+log_must mkdir -p $mntpnt
+log_must mkdir -p $recvmnt
+log_must mount $zdev $mntpnt
+
+for ((i = 1; i <= $snap_count; i++)); do
+ log_must dd if=/dev/urandom of=$mntpnt/file bs=1M count=1
+ for ((j = 0; j < 10; j++)); do
+ log_must cp $mntpnt/file $mntpnt/file$j
+ done
+
+ log_must sync
+ log_must zfs snap $TESTPOOL/$TESTVOL@snap$i
+done
+
+log_must eval "zfs send -wDR $TESTPOOL/$TESTVOL@snap$snap_count > $sendfile"
+log_must eval "zfs recv $TESTPOOL/recv < $sendfile"
+log_must zfs load-key $TESTPOOL/recv
+log_must block_device_wait
+
+log_must mount $recvdev $recvmnt
+
+md5_1=$(cat $mntpnt/* | md5sum | awk '{print $1}')
+md5_2=$(cat $recvmnt/* | md5sum | awk '{print $1}')
+[[ "$md5_1" == "$md5_2" ]] || log_fail "md5 mismatch: $md5_1 != $md5_2"
+
+log_pass "zfs can receive raw, recursive, and deduplicated send streams"
diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c
index 56eca3baa8..eb574105a7 100644
--- a/usr/src/uts/common/fs/zfs/arc.c
+++ b/usr/src/uts/common/fs/zfs/arc.c
@@ -1711,6 +1711,9 @@ arc_cksum_free(arc_buf_hdr_t *hdr)
static boolean_t
arc_hdr_has_uncompressed_buf(arc_buf_hdr_t *hdr)
{
+ ASSERT(hdr->b_l1hdr.b_state == arc_anon ||
+ MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr));
+
for (arc_buf_t *b = hdr->b_l1hdr.b_buf; b != NULL; b = b->b_next) {
if (!ARC_BUF_COMPRESSED(b)) {
return (B_TRUE);
@@ -1733,15 +1736,13 @@ arc_cksum_verify(arc_buf_t *buf)
if (!(zfs_flags & ZFS_DEBUG_MODIFY))
return;
- if (ARC_BUF_COMPRESSED(buf)) {
- ASSERT(hdr->b_l1hdr.b_freeze_cksum == NULL ||
- arc_hdr_has_uncompressed_buf(hdr));
+ if (ARC_BUF_COMPRESSED(buf))
return;
- }
ASSERT(HDR_HAS_L1HDR(hdr));
mutex_enter(&hdr->b_l1hdr.b_freeze_lock);
+
if (hdr->b_l1hdr.b_freeze_cksum == NULL || HDR_IO_ERROR(hdr)) {
mutex_exit(&hdr->b_l1hdr.b_freeze_lock);
return;
@@ -1845,11 +1846,7 @@ arc_cksum_compute(arc_buf_t *buf)
ASSERT(HDR_HAS_L1HDR(hdr));
mutex_enter(&buf->b_hdr->b_l1hdr.b_freeze_lock);
- if (hdr->b_l1hdr.b_freeze_cksum != NULL) {
- ASSERT(arc_hdr_has_uncompressed_buf(hdr));
- mutex_exit(&hdr->b_l1hdr.b_freeze_lock);
- return;
- } else if (ARC_BUF_COMPRESSED(buf)) {
+ if (hdr->b_l1hdr.b_freeze_cksum != NULL || ARC_BUF_COMPRESSED(buf)) {
mutex_exit(&hdr->b_l1hdr.b_freeze_lock);
return;
}
@@ -1953,14 +1950,10 @@ arc_buf_thaw(arc_buf_t *buf)
arc_cksum_verify(buf);
/*
- * Compressed buffers do not manipulate the b_freeze_cksum or
- * allocate b_thawed.
+ * Compressed buffers do not manipulate the b_freeze_cksum.
*/
- if (ARC_BUF_COMPRESSED(buf)) {
- ASSERT(hdr->b_l1hdr.b_freeze_cksum == NULL ||
- arc_hdr_has_uncompressed_buf(hdr));
+ if (ARC_BUF_COMPRESSED(buf))
return;
- }
ASSERT(HDR_HAS_L1HDR(hdr));
arc_cksum_free(hdr);
@@ -1982,26 +1975,14 @@ arc_buf_thaw(arc_buf_t *buf)
void
arc_buf_freeze(arc_buf_t *buf)
{
- arc_buf_hdr_t *hdr = buf->b_hdr;
- kmutex_t *hash_lock;
-
if (!(zfs_flags & ZFS_DEBUG_MODIFY))
return;
- if (ARC_BUF_COMPRESSED(buf)) {
- ASSERT(hdr->b_l1hdr.b_freeze_cksum == NULL ||
- arc_hdr_has_uncompressed_buf(hdr));
+ if (ARC_BUF_COMPRESSED(buf))
return;
- }
-
- hash_lock = HDR_LOCK(hdr);
- mutex_enter(hash_lock);
- ASSERT(HDR_HAS_L1HDR(hdr));
- ASSERT(hdr->b_l1hdr.b_freeze_cksum != NULL ||
- hdr->b_l1hdr.b_state == arc_anon);
+ ASSERT(HDR_HAS_L1HDR(buf->b_hdr));
arc_cksum_compute(buf);
- mutex_exit(hash_lock);
}
/*
@@ -2129,7 +2110,7 @@ arc_hdr_authenticate(arc_buf_hdr_t *hdr, spa_t *spa, uint64_t dsobj)
void *tmpbuf = NULL;
abd_t *abd = hdr->b_l1hdr.b_pabd;
- ASSERT(HDR_LOCK(hdr) == NULL || MUTEX_HELD(HDR_LOCK(hdr)));
+ ASSERT(MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr));
ASSERT(HDR_AUTHENTICATED(hdr));
ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL);
@@ -2199,7 +2180,7 @@ arc_hdr_decrypt(arc_buf_hdr_t *hdr, spa_t *spa, const zbookmark_phys_t *zb)
boolean_t no_crypt = B_FALSE;
boolean_t bswap = (hdr->b_l1hdr.b_byteswap != DMU_BSWAP_NUMFUNCS);
- ASSERT(HDR_LOCK(hdr) == NULL || MUTEX_HELD(HDR_LOCK(hdr)));
+ ASSERT(MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr));
ASSERT(HDR_ENCRYPTED(hdr));
arc_hdr_alloc_pabd(hdr, B_FALSE);
@@ -2319,7 +2300,7 @@ arc_buf_untransform_in_place(arc_buf_t *buf, kmutex_t *hash_lock)
ASSERT(HDR_ENCRYPTED(hdr));
ASSERT3U(hdr->b_crypt_hdr.b_ot, ==, DMU_OT_DNODE);
- ASSERT(HDR_LOCK(hdr) == NULL || MUTEX_HELD(HDR_LOCK(hdr)));
+ ASSERT(MUTEX_HELD(HDR_LOCK(hdr)) || HDR_EMPTY(hdr));
ASSERT3P(hdr->b_l1hdr.b_pabd, !=, NULL);
zio_crypt_copy_dnode_bonus(hdr->b_l1hdr.b_pabd, buf->b_data,
diff --git a/usr/src/uts/common/fs/zfs/dbuf.c b/usr/src/uts/common/fs/zfs/dbuf.c
index 824624a3d9..e96cd84928 100644
--- a/usr/src/uts/common/fs/zfs/dbuf.c
+++ b/usr/src/uts/common/fs/zfs/dbuf.c
@@ -1037,7 +1037,6 @@ dbuf_read_verify_dnode_crypt(dmu_buf_impl_t *db, uint32_t flags)
!DMU_OT_IS_ENCRYPTED(dn->dn_bonustype))))
err = 0;
-
DB_DNODE_EXIT(db);
return (err);
diff --git a/usr/src/uts/common/fs/zfs/dmu.c b/usr/src/uts/common/fs/zfs/dmu.c
index 528b82141f..beecf4c43f 100644
--- a/usr/src/uts/common/fs/zfs/dmu.c
+++ b/usr/src/uts/common/fs/zfs/dmu.c
@@ -1711,6 +1711,7 @@ dmu_copy_from_buf(objset_t *os, uint64_t object, uint64_t offset,
dmu_buf_t *dst_handle;
dmu_buf_impl_t *dstdb;
dmu_buf_impl_t *srcdb = (dmu_buf_impl_t *)handle;
+ dmu_object_type_t type;
arc_buf_t *abuf;
uint64_t datalen;
boolean_t byteorder;
@@ -1726,11 +1727,15 @@ dmu_copy_from_buf(objset_t *os, uint64_t object, uint64_t offset,
dstdb = (dmu_buf_impl_t *)dst_handle;
datalen = arc_buf_size(srcdb->db_buf);
+ DB_DNODE_ENTER(dstdb);
+ type = DB_DNODE(dstdb)->dn_type;
+ DB_DNODE_EXIT(dstdb);
+
/* allocated an arc buffer that matches the type of srcdb->db_buf */
if (arc_is_encrypted(srcdb->db_buf)) {
arc_get_raw_params(srcdb->db_buf, &byteorder, salt, iv, mac);
abuf = arc_loan_raw_buf(os->os_spa, dmu_objset_id(os),
- byteorder, salt, iv, mac, DB_DNODE(dstdb)->dn_type,
+ byteorder, salt, iv, mac, type,
datalen, arc_buf_lsize(srcdb->db_buf),
arc_get_compression(srcdb->db_buf));
} else {
@@ -1738,7 +1743,7 @@ dmu_copy_from_buf(objset_t *os, uint64_t object, uint64_t offset,
ASSERT3U(arc_get_compression(srcdb->db_buf),
==, ZIO_COMPRESS_OFF);
abuf = arc_loan_buf(os->os_spa,
- DMU_OT_IS_METADATA(DB_DNODE(dstdb)->dn_type), datalen);
+ DMU_OT_IS_METADATA(type), datalen);
}
ASSERT3U(datalen, ==, arc_buf_size(abuf));
diff --git a/usr/src/uts/common/fs/zfs/dmu_objset.c b/usr/src/uts/common/fs/zfs/dmu_objset.c
index 4d0a5d2fd5..8174222826 100644
--- a/usr/src/uts/common/fs/zfs/dmu_objset.c
+++ b/usr/src/uts/common/fs/zfs/dmu_objset.c
@@ -1259,13 +1259,6 @@ dmu_objset_clone_check(void *arg, dmu_tx_t *tx)
return (SET_ERROR(EINVAL));
}
- error = dmu_objset_clone_crypt_check(pdd, origin->ds_dir);
- if (error != 0) {
- dsl_dataset_rele(origin, FTAG);
- dsl_dir_rele(pdd, FTAG);
- return (error);
- }
-
dsl_dataset_rele(origin, FTAG);
dsl_dir_rele(pdd, FTAG);
diff --git a/usr/src/uts/common/fs/zfs/dmu_recv.c b/usr/src/uts/common/fs/zfs/dmu_recv.c
index b6f63e7e22..b72aa21922 100644
--- a/usr/src/uts/common/fs/zfs/dmu_recv.c
+++ b/usr/src/uts/common/fs/zfs/dmu_recv.c
@@ -306,7 +306,7 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
/* Open the parent of tofs */
ASSERT3U(strlen(tofs), <, sizeof (buf));
(void) strlcpy(buf, tofs, strrchr(tofs, '/') - tofs + 1);
- error = dsl_dataset_hold_flags(dp, buf, dsflags, FTAG, &ds);
+ error = dsl_dataset_hold(dp, buf, FTAG, &ds);
if (error != 0)
return (error);
@@ -324,13 +324,13 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
error = dmu_objset_create_crypt_check(ds->ds_dir,
drba->drba_dcp, &will_encrypt);
if (error != 0) {
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (error);
}
if (will_encrypt &&
(featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) {
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (SET_ERROR(EINVAL));
}
}
@@ -343,46 +343,46 @@ dmu_recv_begin_check(void *arg, dmu_tx_t *tx)
error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
ZFS_PROP_FILESYSTEM_LIMIT, NULL, drba->drba_cred);
if (error != 0) {
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (error);
}
error = dsl_fs_ss_limit_check(ds->ds_dir, 1,
ZFS_PROP_SNAPSHOT_LIMIT, NULL, drba->drba_cred);
if (error != 0) {
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (error);
}
if (drba->drba_origin != NULL) {
dsl_dataset_t *origin;
- error = dsl_dataset_hold_flags(dp, drba->drba_origin,
- dsflags, FTAG, &origin);
+ error = dsl_dataset_hold(dp, drba->drba_origin,
+ FTAG, &origin);
if (error != 0) {
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (error);
}
if (!origin->ds_is_snapshot) {
- dsl_dataset_rele_flags(origin, dsflags, FTAG);
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(origin, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (SET_ERROR(EINVAL));
}
if (dsl_dataset_phys(origin)->ds_guid != fromguid &&
fromguid != 0) {
- dsl_dataset_rele_flags(origin, dsflags, FTAG);
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(origin, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (SET_ERROR(ENODEV));
}
if (origin->ds_dir->dd_crypto_obj != 0 &&
(featureflags & DMU_BACKUP_FEATURE_EMBED_DATA)) {
- dsl_dataset_rele_flags(origin, dsflags, FTAG);
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(origin, FTAG);
+ dsl_dataset_rele(ds, FTAG);
return (SET_ERROR(EINVAL));
}
- dsl_dataset_rele_flags(origin, dsflags, FTAG);
+ dsl_dataset_rele(origin, FTAG);
}
- dsl_dataset_rele_flags(ds, dsflags, FTAG);
+ dsl_dataset_rele(ds, FTAG);
error = 0;
}
return (error);
diff --git a/usr/src/uts/common/fs/zfs/dsl_crypt.c b/usr/src/uts/common/fs/zfs/dsl_crypt.c
index 3937d3cb51..3896efbc76 100644
--- a/usr/src/uts/common/fs/zfs/dsl_crypt.c
+++ b/usr/src/uts/common/fs/zfs/dsl_crypt.c
@@ -1588,15 +1588,8 @@ dsl_dir_rename_crypt_check(dsl_dir_t *dd, dsl_dir_t *newparent)
int ret;
uint64_t curr_rddobj, parent_rddobj;
- if (dd->dd_crypto_obj == 0) {
- /* children of encrypted parents must be encrypted */
- if (newparent->dd_crypto_obj != 0) {
- ret = SET_ERROR(EACCES);
- goto error;
- }
-
+ if (dd->dd_crypto_obj == 0)
return (0);
- }
ret = dsl_dir_get_encryption_root_ddobj(dd, &curr_rddobj);
if (ret != 0)
@@ -1726,34 +1719,6 @@ dsl_dataset_promote_crypt_sync(dsl_dir_t *target, dsl_dir_t *origin,
}
int
-dmu_objset_clone_crypt_check(dsl_dir_t *parentdd, dsl_dir_t *origindd)
-{
- int ret;
- uint64_t pcrypt, crypt;
-
- /*
- * Check that we are not making an unencrypted child of an
- * encrypted parent.
- */
- ret = dsl_dir_get_crypt(parentdd, &pcrypt);
- if (ret != 0)
- return (ret);
-
- ret = dsl_dir_get_crypt(origindd, &crypt);
- if (ret != 0)
- return (ret);
-
- ASSERT3U(pcrypt, !=, ZIO_CRYPT_INHERIT);
- ASSERT3U(crypt, !=, ZIO_CRYPT_INHERIT);
-
- if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF)
- return (SET_ERROR(EINVAL));
-
- return (0);
-}
-
-
-int
dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp,
boolean_t *will_encrypt)
{
@@ -1783,13 +1748,6 @@ dmu_objset_create_crypt_check(dsl_dir_t *parentdd, dsl_crypto_params_t *dcp,
ASSERT3U(pcrypt, !=, ZIO_CRYPT_INHERIT);
ASSERT3U(crypt, !=, ZIO_CRYPT_INHERIT);
- /*
- * We can't create an unencrypted child of an encrypted parent
- * under any circumstances.
- */
- if (crypt == ZIO_CRYPT_OFF && pcrypt != ZIO_CRYPT_OFF)
- return (SET_ERROR(EINVAL));
-
/* check for valid dcp with no encryption (inherited or local) */
if (crypt == ZIO_CRYPT_OFF) {
/* Must not specify encryption params */
diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h
index 360a69b329..cf19665aae 100644
--- a/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h
+++ b/usr/src/uts/common/fs/zfs/sys/dsl_crypt.h
@@ -209,7 +209,6 @@ void dsl_dataset_create_crypt_sync(uint64_t dsobj, dsl_dir_t *dd,
struct dsl_dataset *origin, dsl_crypto_params_t *dcp, dmu_tx_t *tx);
uint64_t dsl_crypto_key_create_sync(uint64_t crypt, dsl_wrapping_key_t *wkey,
dmu_tx_t *tx);
-int dmu_objset_clone_crypt_check(dsl_dir_t *parentdd, dsl_dir_t *origindd);
uint64_t dsl_crypto_key_clone_sync(dsl_dir_t *origindd, dmu_tx_t *tx);
void dsl_crypto_key_destroy_sync(uint64_t dckobj, dmu_tx_t *tx);
diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c
index 2ff37afb8a..2940769eb4 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vnops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c
@@ -513,6 +513,7 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
ssize_t n, nbytes;
int error = 0;
+ boolean_t frsync = B_FALSE;
xuio_t *xuio = NULL;
ZFS_ENTER(zfsvfs);
@@ -550,10 +551,20 @@ zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, caller_context_t *ct)
}
}
+#ifdef FRSYNC
/*
* If we're in FRSYNC mode, sync out this znode before reading it.
+ * Only do this for non-snapshots.
+ *
+ * Some platforms do not support FRSYNC and instead map it
+ * to FSYNC, which results in unnecessary calls to zil_commit. We
+ * only honor FRSYNC requests on platforms which support it.
*/
- if (ioflag & FRSYNC || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
+ frsync = !!(ioflag & FRSYNC);
+#endif
+
+ if (zfsvfs->z_log &&
+ (frsync || zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS))
zil_commit(zfsvfs->z_log, zp->z_id);
/*
diff --git a/usr/src/uts/i86pc/boot/boot_fb.c b/usr/src/uts/i86pc/boot/boot_fb.c
index 72198f5845..1ac4789af7 100644
--- a/usr/src/uts/i86pc/boot/boot_fb.c
+++ b/usr/src/uts/i86pc/boot/boot_fb.c
@@ -158,13 +158,12 @@ xbi_fb_init(struct xboot_info *xbi, bcons_dev_t *bcons_dev)
fb_info.cursor.visible = xbi_fb->cursor.visible;
#endif
+ xbi_init_font(xbi);
tag = (multiboot_tag_framebuffer_t *)(uintptr_t)xbi_fb->framebuffer;
if (tag == NULL) {
return (B_FALSE);
}
- xbi_init_font(xbi);
-
fb_info.paddr = tag->framebuffer_common.framebuffer_addr;
fb_info.pitch = tag->framebuffer_common.framebuffer_pitch;
fb_info.depth = tag->framebuffer_common.framebuffer_bpp;
diff --git a/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h b/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h
index dc49a628b0..6c6cc5e8bf 100644
--- a/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h
+++ b/usr/src/uts/i86pc/io/gfx_private/gfxp_fb.h
@@ -77,6 +77,7 @@ struct gfx_vga {
unsigned char blue;
} colormap[VGA8_CMAP_ENTRIES];
unsigned char attrib_palette[VGA_ATR_NUM_PLT];
+ struct font font;
};
union gfx_console {
diff --git a/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c b/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c
index ee0db4ef92..de48a9fe00 100644
--- a/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c
+++ b/usr/src/uts/i86pc/io/gfx_private/gfxp_vgatext.c
@@ -945,7 +945,10 @@ static void
vgatext_init(struct gfxp_fb_softc *softc)
{
union gfx_console *console = softc->console;
+ bitmap_data_t *font_data;
unsigned char atr_mode;
+ short width, height;
+ int i;
atr_mode = vga_get_atr(&console->vga.regs, VGA_ATR_MODE);
if (atr_mode & VGA_ATR_MODE_GRAPH)
@@ -961,7 +964,21 @@ vgatext_init(struct gfxp_fb_softc *softc)
vga_set_atr(&console->vga.regs, VGA_ATR_BDR_CLR,
vga_get_atr(&console->vga.regs, pc_black));
#endif
- vgatext_setfont(softc); /* need selectable font? */
+
+ width = VGA_TEXT_COLS;
+ height = VGA_TEXT_ROWS;
+ font_data = set_font(&height, &width,
+ 16 * height + BORDER_PIXELS,
+ 8 * width + BORDER_PIXELS);
+ for (i = 0; i < VFNT_MAPS; i++) {
+ console->vga.font.vf_map[i] = font_data->font->vf_map[i];
+ console->vga.font.vf_map_count[i] =
+ font_data->font->vf_map_count[i];
+ }
+ console->vga.font.vf_bytes = font_data->font->vf_bytes;
+ console->vga.font.vf_width = font_data->font->vf_width;
+ console->vga.font.vf_height = font_data->font->vf_height;
+ vgatext_setfont(softc);
}
#if defined(USE_BORDERS)
@@ -1109,7 +1126,7 @@ vgatext_setfont(struct gfxp_fb_softc *softc)
f_offset = s * 8 * 1024;
for (i = 0; i < 256; i++) {
c = vga_cp437_to_uni(i);
- from = font_lookup(font_data_8x16.font, c);
+ from = font_lookup(&console->vga.font, c);
to = (unsigned char *)console->vga.fb.addr + f_offset +
i * 0x20;
for (j = 0; j < bpc; j++)