summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2016-11-22 12:56:16 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2016-11-22 12:56:16 +0000
commitdec418ad77ca1ad8b6560e627d4f4d4cee27ab5c (patch)
tree8b010779fbe156ed1462f203170b948386ec6023
parent0e094404f4a199a440ac665b3442f89891352798 (diff)
parent90f2c094b3822f4825f21cef2c2faf7d03b55139 (diff)
downloadillumos-joyent-dec418ad77ca1ad8b6560e627d4f4d4cee27ab5c.tar.gz
[illumos-gate merge]
commit 90f2c094b3822f4825f21cef2c2faf7d03b55139 7181 race between zfs_mount and zfs_ioc_rollback commit 3faa67c4f6f8f33a78fe84ef48445aeb0ce858d3 7566 Add kernel environment variables under smbios.system. commit c079fa4d202eff15e318131c52755d214ffa2da7 6428 set canmount=off on unmounted filesystem tries to unmount children commit bfaed0b91e57062c38bc16b4f89db3c8f0052a9b 7199 dsl_dataset_rollback_sync may try to free already free blocks 7200 no blocks must be born in a txg after a snaphot is created commit edb901aab9c738b5eb15aa55933e82b0f2f9d9a2 7386 zfs get does not work properly with bookmarks commit 690041b9caf801816f2d0bac90bc7cecefb73523 7180 potential race between zfs_suspend_fs+zfs_resume_fs and zfs_ioc_rename commit e5b103bba9ae456b34ffc1e123d7e81d4584a945 7596 iwn: Firmware update for 6205 (Taylor Peak)
-rw-r--r--manifest2
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/smbios.c7
-rw-r--r--usr/src/cmd/zfs/zfs_main.c4
-rw-r--r--usr/src/common/zfs/zfs_namecheck.c93
-rw-r--r--usr/src/common/zfs/zfs_namecheck.h3
-rw-r--r--usr/src/lib/libzfs/common/libzfs_dataset.c123
-rw-r--r--usr/src/lib/libzfs/common/libzfs_pool.c5
-rw-r--r--usr/src/lib/libzfs/common/libzfs_util.c2
-rw-r--r--usr/src/man/man1m/zfs.1m6
-rw-r--r--usr/src/pkg/manifests/driver-network-iwn.mf2
-rw-r--r--usr/src/test/zfs-tests/include/default.cfg1
-rw-r--r--usr/src/test/zfs-tests/include/libtest.shlib57
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh25
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_005_neg.ksh35
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_008_pos.ksh19
-rw-r--r--usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib9
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_dataset.c62
-rw-r--r--usr/src/uts/common/fs/zfs/dsl_pool.c14
-rw-r--r--usr/src/uts/common/fs/zfs/sys/dsl_dataset.h1
-rw-r--r--usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h2
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_ioctl.c14
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c27
-rw-r--r--usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucodebin444128 -> 0 bytes
-rw-r--r--usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucodebin0 -> 677296 bytes
-rw-r--r--usr/src/uts/common/io/iwn/if_iwn.c2
-rw-r--r--usr/src/uts/intel/iwn/Makefile2
26 files changed, 405 insertions, 112 deletions
diff --git a/manifest b/manifest
index ac4d24124d..6d2762f9b1 100644
--- a/manifest
+++ b/manifest
@@ -871,7 +871,7 @@ f kernel/firmware/iwn/iwlwifi-4965-2.ucode 0666 root sys
f kernel/firmware/iwn/iwlwifi-5000-2.ucode 0666 root sys
f kernel/firmware/iwn/iwlwifi-5150-2.ucode 0666 root sys
f kernel/firmware/iwn/iwlwifi-6000-4.ucode 0666 root sys
-f kernel/firmware/iwn/iwlwifi-6000g2a-5.ucode 0666 root sys
+f kernel/firmware/iwn/iwlwifi-6000g2a-6.ucode 0666 root sys
f kernel/firmware/iwn/iwlwifi-6000g2b-6.ucode 0666 root sys
f kernel/firmware/iwn/iwlwifi-6050-5.ucode 0666 root sys
d kernel/fs 0755 root sys
diff --git a/usr/src/boot/sys/boot/i386/libi386/smbios.c b/usr/src/boot/sys/boot/i386/libi386/smbios.c
index 7a7ce4ba4f..2aa62fa85d 100644
--- a/usr/src/boot/sys/boot/i386/libi386/smbios.c
+++ b/usr/src/boot/sys/boot/i386/libi386/smbios.c
@@ -238,6 +238,11 @@ smbios_parse_table(const caddr_t addr)
smbios_setenv("smbios.system.serial", addr, 0x07);
smbios_setuuid("smbios.system.uuid", addr + 0x08, smbios.ver);
#endif
+ if (smbios.major > 2 ||
+ (smbios.major == 2 && smbios.minor >= 4)) {
+ smbios_setenv("smbios.system.sku", addr, 0x19);
+ smbios_setenv("smbios.system.family", addr, 0x1a);
+ }
break;
case 2: /* 3.3.3 Base Board (or Module) Information (Type 2) */
@@ -246,7 +251,9 @@ smbios_parse_table(const caddr_t addr)
smbios_setenv("smbios.planar.version", addr, 0x06);
#ifdef SMBIOS_SERIAL_NUMBERS
smbios_setenv("smbios.planar.serial", addr, 0x07);
+ smbios_setenv("smbios.planar.tag", addr, 0x08);
#endif
+ smbios_setenv("smbios.planar.location", addr, 0x0a);
break;
case 3: /* 3.3.4 System Enclosure or Chassis (Type 3) */
diff --git a/usr/src/cmd/zfs/zfs_main.c b/usr/src/cmd/zfs/zfs_main.c
index f9318db544..7d9153f9fe 100644
--- a/usr/src/cmd/zfs/zfs_main.c
+++ b/usr/src/cmd/zfs/zfs_main.c
@@ -232,7 +232,7 @@ get_usage(zfs_help_t idx)
"[-o \"all\" | field[,...]]\n"
"\t [-t type[,...]] [-s source[,...]]\n"
"\t <\"all\" | property[,...]> "
- "[filesystem|volume|snapshot] ...\n"));
+ "[filesystem|volume|snapshot|bookmark] ...\n"));
case HELP_INHERIT:
return (gettext("\tinherit [-rS] <property> "
"<filesystem|volume|snapshot> ...\n"));
@@ -1658,7 +1658,7 @@ zfs_do_get(int argc, char **argv)
{
zprop_get_cbdata_t cb = { 0 };
int i, c, flags = ZFS_ITER_ARGS_CAN_BE_PATHS;
- int types = ZFS_TYPE_DATASET;
+ int types = ZFS_TYPE_DATASET | ZFS_TYPE_BOOKMARK;
char *value, *fields;
int ret = 0;
int limit = 0;
diff --git a/usr/src/common/zfs/zfs_namecheck.c b/usr/src/common/zfs/zfs_namecheck.c
index 439d4491a0..950d41f353 100644
--- a/usr/src/common/zfs/zfs_namecheck.c
+++ b/usr/src/common/zfs/zfs_namecheck.c
@@ -120,9 +120,9 @@ permset_namecheck(const char *path, namecheck_err_t *why, char *what)
}
/*
- * Dataset names must be of the following form:
+ * Entity names must be of the following form:
*
- * [component][/]*[component][@component]
+ * [component/]*[component][(@|#)component]?
*
* Where each component is made up of alphanumeric characters plus the following
* characters:
@@ -133,10 +133,10 @@ permset_namecheck(const char *path, namecheck_err_t *why, char *what)
* names for temporary clones (for online recv).
*/
int
-dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
+entity_namecheck(const char *path, namecheck_err_t *why, char *what)
{
- const char *loc, *end;
- int found_snapshot;
+ const char *start, *end;
+ int found_delim;
/*
* Make sure the name is not too long.
@@ -161,12 +161,13 @@ dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
return (-1);
}
- loc = path;
- found_snapshot = 0;
+ start = path;
+ found_delim = 0;
for (;;) {
/* Find the end of this component */
- end = loc;
- while (*end != '/' && *end != '@' && *end != '\0')
+ end = start;
+ while (*end != '/' && *end != '@' && *end != '#' &&
+ *end != '\0')
end++;
if (*end == '\0' && end[-1] == '/') {
@@ -176,25 +177,8 @@ dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
return (-1);
}
- /* Zero-length components are not allowed */
- if (loc == end) {
- if (why) {
- /*
- * Make sure this is really a zero-length
- * component and not a '@@'.
- */
- if (*end == '@' && found_snapshot) {
- *why = NAME_ERR_MULTIPLE_AT;
- } else {
- *why = NAME_ERR_EMPTY_COMPONENT;
- }
- }
-
- return (-1);
- }
-
/* Validate the contents of this component */
- while (loc != end) {
+ for (const char *loc = start; loc != end; loc++) {
if (!valid_char(*loc) && *loc != '%') {
if (why) {
*why = NAME_ERR_INVALCHAR;
@@ -202,43 +186,64 @@ dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
}
return (-1);
}
- loc++;
}
- /* If we've reached the end of the string, we're OK */
- if (*end == '\0')
- return (0);
-
- if (*end == '@') {
- /*
- * If we've found an @ symbol, indicate that we're in
- * the snapshot component, and report a second '@'
- * character as an error.
- */
- if (found_snapshot) {
+ /* Snapshot or bookmark delimiter found */
+ if (*end == '@' || *end == '#') {
+ /* Multiple delimiters are not allowed */
+ if (found_delim != 0) {
if (why)
- *why = NAME_ERR_MULTIPLE_AT;
+ *why = NAME_ERR_MULTIPLE_DELIMITERS;
return (-1);
}
- found_snapshot = 1;
+ found_delim = 1;
+ }
+
+ /* Zero-length components are not allowed */
+ if (start == end) {
+ if (why)
+ *why = NAME_ERR_EMPTY_COMPONENT;
+ return (-1);
}
+ /* If we've reached the end of the string, we're OK */
+ if (*end == '\0')
+ return (0);
+
/*
- * If there is a '/' in a snapshot name
+ * If there is a '/' in a snapshot or bookmark name
* then report an error
*/
- if (*end == '/' && found_snapshot) {
+ if (*end == '/' && found_delim != 0) {
if (why)
*why = NAME_ERR_TRAILING_SLASH;
return (-1);
}
/* Update to the next component */
- loc = end + 1;
+ start = end + 1;
}
}
+/*
+ * Dataset is any entity, except bookmark
+ */
+int
+dataset_namecheck(const char *path, namecheck_err_t *why, char *what)
+{
+ int ret = entity_namecheck(path, why, what);
+
+ if (ret == 0 && strchr(path, '#') != NULL) {
+ if (why != NULL) {
+ *why = NAME_ERR_INVALCHAR;
+ *what = '#';
+ }
+ return (-1);
+ }
+
+ return (ret);
+}
/*
* mountpoint names must be of the following form:
diff --git a/usr/src/common/zfs/zfs_namecheck.h b/usr/src/common/zfs/zfs_namecheck.h
index cbefbaa0d5..db70641dba 100644
--- a/usr/src/common/zfs/zfs_namecheck.h
+++ b/usr/src/common/zfs/zfs_namecheck.h
@@ -38,7 +38,7 @@ typedef enum {
NAME_ERR_EMPTY_COMPONENT, /* name contains an empty component */
NAME_ERR_TRAILING_SLASH, /* name ends with a slash */
NAME_ERR_INVALCHAR, /* invalid character found */
- NAME_ERR_MULTIPLE_AT, /* multiple '@' characters found */
+ NAME_ERR_MULTIPLE_DELIMITERS, /* multiple '@'/'#' delimiters found */
NAME_ERR_NOLETTER, /* pool doesn't begin with a letter */
NAME_ERR_RESERVED, /* entire name is reserved */
NAME_ERR_DISKLIKE, /* reserved disk name (c[0-9].*) */
@@ -49,6 +49,7 @@ typedef enum {
#define ZFS_PERMSET_MAXLEN 64
int pool_namecheck(const char *, namecheck_err_t *, char *);
+int entity_namecheck(const char *, namecheck_err_t *, char *);
int dataset_namecheck(const char *, namecheck_err_t *, char *);
int mountpoint_namecheck(const char *, namecheck_err_t *);
int zfs_component_namecheck(const char *, namecheck_err_t *, char *);
diff --git a/usr/src/lib/libzfs/common/libzfs_dataset.c b/usr/src/lib/libzfs/common/libzfs_dataset.c
index da80c41623..bbb0acaa3d 100644
--- a/usr/src/lib/libzfs/common/libzfs_dataset.c
+++ b/usr/src/lib/libzfs/common/libzfs_dataset.c
@@ -105,7 +105,7 @@ zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
char what;
(void) zfs_prop_get_table();
- if (dataset_namecheck(path, &why, &what) != 0) {
+ if (entity_namecheck(path, &why, &what) != 0) {
if (hdl != NULL) {
switch (why) {
case NAME_ERR_TOOLONG:
@@ -134,9 +134,10 @@ zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
"'%c' in name"), what);
break;
- case NAME_ERR_MULTIPLE_AT:
+ case NAME_ERR_MULTIPLE_DELIMITERS:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "multiple '@' delimiters in name"));
+ "multiple '@' and/or '#' delimiters in "
+ "name"));
break;
case NAME_ERR_NOLETTER:
@@ -167,7 +168,7 @@ zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
if (!(type & ZFS_TYPE_SNAPSHOT) && strchr(path, '@') != NULL) {
if (hdl != NULL)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "snapshot delimiter '@' in filesystem name"));
+ "snapshot delimiter '@' is not expected here"));
return (0);
}
@@ -178,6 +179,20 @@ zfs_validate_name(libzfs_handle_t *hdl, const char *path, int type,
return (0);
}
+ if (!(type & ZFS_TYPE_BOOKMARK) && strchr(path, '#') != NULL) {
+ if (hdl != NULL)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "bookmark delimiter '#' is not expected here"));
+ return (0);
+ }
+
+ if (type == ZFS_TYPE_BOOKMARK && strchr(path, '#') == NULL) {
+ if (hdl != NULL)
+ zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
+ "missing '#' delimiter in bookmark name"));
+ return (0);
+ }
+
if (modifying && strchr(path, '%') != NULL) {
if (hdl != NULL)
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
@@ -619,8 +634,36 @@ make_bookmark_handle(zfs_handle_t *parent, const char *path,
return (zhp);
}
+struct zfs_open_bookmarks_cb_data {
+ const char *path;
+ zfs_handle_t *zhp;
+};
+
+static int
+zfs_open_bookmarks_cb(zfs_handle_t *zhp, void *data)
+{
+ struct zfs_open_bookmarks_cb_data *dp = data;
+
+ /*
+ * Is it the one we are looking for?
+ */
+ if (strcmp(dp->path, zfs_get_name(zhp)) == 0) {
+ /*
+ * We found it. Save it and let the caller know we are done.
+ */
+ dp->zhp = zhp;
+ return (EEXIST);
+ }
+
+ /*
+ * Not found. Close the handle and ask for another one.
+ */
+ zfs_close(zhp);
+ return (0);
+}
+
/*
- * Opens the given snapshot, filesystem, or volume. The 'types'
+ * Opens the given snapshot, bookmark, filesystem, or volume. The 'types'
* argument is a mask of acceptable types. The function will print an
* appropriate error message and return NULL if it can't be opened.
*/
@@ -629,6 +672,7 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
{
zfs_handle_t *zhp;
char errbuf[1024];
+ char *bookp;
(void) snprintf(errbuf, sizeof (errbuf),
dgettext(TEXT_DOMAIN, "cannot open '%s'"), path);
@@ -636,20 +680,68 @@ zfs_open(libzfs_handle_t *hdl, const char *path, int types)
/*
* Validate the name before we even try to open it.
*/
- if (!zfs_validate_name(hdl, path, ZFS_TYPE_DATASET, B_FALSE)) {
- zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "invalid dataset name"));
+ if (!zfs_validate_name(hdl, path, types, B_FALSE)) {
(void) zfs_error(hdl, EZFS_INVALIDNAME, errbuf);
return (NULL);
}
/*
- * Try to get stats for the dataset, which will tell us if it exists.
+ * Bookmarks needs to be handled separately.
*/
- errno = 0;
- if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
- (void) zfs_standard_error(hdl, errno, errbuf);
- return (NULL);
+ bookp = strchr(path, '#');
+ if (bookp == NULL) {
+ /*
+ * Try to get stats for the dataset, which will tell us if it
+ * exists.
+ */
+ errno = 0;
+ if ((zhp = make_dataset_handle(hdl, path)) == NULL) {
+ (void) zfs_standard_error(hdl, errno, errbuf);
+ return (NULL);
+ }
+ } else {
+ char dsname[ZFS_MAX_DATASET_NAME_LEN];
+ zfs_handle_t *pzhp;
+ struct zfs_open_bookmarks_cb_data cb_data = {path, NULL};
+
+ /*
+ * We need to cut out '#' and everything after '#'
+ * to get the parent dataset name only.
+ */
+ assert(bookp - path < sizeof (dsname));
+ (void) strncpy(dsname, path, bookp - path);
+ dsname[bookp - path] = '\0';
+
+ /*
+ * Create handle for the parent dataset.
+ */
+ errno = 0;
+ if ((pzhp = make_dataset_handle(hdl, dsname)) == NULL) {
+ (void) zfs_standard_error(hdl, errno, errbuf);
+ return (NULL);
+ }
+
+ /*
+ * Iterate bookmarks to find the right one.
+ */
+ errno = 0;
+ if ((zfs_iter_bookmarks(pzhp, zfs_open_bookmarks_cb,
+ &cb_data) == 0) && (cb_data.zhp == NULL)) {
+ (void) zfs_error(hdl, EZFS_NOENT, errbuf);
+ zfs_close(pzhp);
+ return (NULL);
+ }
+ if (cb_data.zhp == NULL) {
+ (void) zfs_standard_error(hdl, errno, errbuf);
+ zfs_close(pzhp);
+ return (NULL);
+ }
+ zhp = cb_data.zhp;
+
+ /*
+ * Cleanup.
+ */
+ zfs_close(pzhp);
}
if (!(types & zhp->zfs_type)) {
@@ -1601,8 +1693,9 @@ zfs_prop_set_list(zfs_handle_t *zhp, nvlist_t *props)
* its canmount property to 'on' or 'noauto'. We only use
* the changelist logic to unmount when setting canmount=off.
*/
- if (!(prop == ZFS_PROP_CANMOUNT &&
- fnvpair_value_uint64(elem) != ZFS_CANMOUNT_OFF)) {
+ if (prop != ZFS_PROP_CANMOUNT ||
+ (fnvpair_value_uint64(elem) == ZFS_CANMOUNT_OFF &&
+ zfs_is_mounted(zhp, NULL))) {
cls[cl_idx] = changelist_gather(zhp, prop, 0, 0);
if (cls[cl_idx] == NULL)
goto error;
diff --git a/usr/src/lib/libzfs/common/libzfs_pool.c b/usr/src/lib/libzfs/common/libzfs_pool.c
index c6f7d5d88c..325adb2c4f 100644
--- a/usr/src/lib/libzfs/common/libzfs_pool.c
+++ b/usr/src/lib/libzfs/common/libzfs_pool.c
@@ -947,9 +947,10 @@ zpool_name_valid(libzfs_handle_t *hdl, boolean_t isopen, const char *pool)
"trailing slash in name"));
break;
- case NAME_ERR_MULTIPLE_AT:
+ case NAME_ERR_MULTIPLE_DELIMITERS:
zfs_error_aux(hdl, dgettext(TEXT_DOMAIN,
- "multiple '@' delimiters in name"));
+ "multiple '@' and/or '#' delimiters in "
+ "name"));
break;
default:
diff --git a/usr/src/lib/libzfs/common/libzfs_util.c b/usr/src/lib/libzfs/common/libzfs_util.c
index 848663e1f8..c79da78024 100644
--- a/usr/src/lib/libzfs/common/libzfs_util.c
+++ b/usr/src/lib/libzfs/common/libzfs_util.c
@@ -730,7 +730,7 @@ zfs_get_pool_handle(const zfs_handle_t *zhp)
* Given a name, determine whether or not it's a valid path
* (starts with '/' or "./"). If so, walk the mnttab trying
* to match the device number. If not, treat the path as an
- * fs/vol/snap name.
+ * fs/vol/snap/bkmark name.
*/
zfs_handle_t *
zfs_path_to_zhandle(libzfs_handle_t *hdl, char *path, zfs_type_t argtype)
diff --git a/usr/src/man/man1m/zfs.1m b/usr/src/man/man1m/zfs.1m
index dc09c50458..8c78343cc4 100644
--- a/usr/src/man/man1m/zfs.1m
+++ b/usr/src/man/man1m/zfs.1m
@@ -28,7 +28,7 @@
.\" Copyright (c) 2014 Integros [integros.com]
.\" Copyright 2016 Nexenta Systems, Inc.
.\"
-.Dd September 3, 2016
+.Dd September 16, 2016
.Dt ZFS 1M
.Os
.Sh NAME
@@ -112,7 +112,7 @@
.Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns ... Oc
.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc
.Cm all | Ar property Ns Oo , Ns Ar property Oc Ns ...
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Ns ...
.Nm
.Cm inherit
.Op Fl rS
@@ -2123,7 +2123,7 @@ section.
.Oo Fl s Ar source Ns Oo , Ns Ar source Oc Ns ... Oc
.Oo Fl t Ar type Ns Oo , Ns Ar type Oc Ns ... Oc
.Cm all | Ar property Ns Oo , Ns Ar property Oc Ns ...
-.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns ...
+.Ar filesystem Ns | Ns Ar volume Ns | Ns Ar snapshot Ns | Ns Ar bookmark Ns ...
.Xc
Displays properties for the given datasets. If no datasets are specified, then
the command displays properties for all datasets on the system. For each
diff --git a/usr/src/pkg/manifests/driver-network-iwn.mf b/usr/src/pkg/manifests/driver-network-iwn.mf
index dc8ceac4fd..a7b55d2c7a 100644
--- a/usr/src/pkg/manifests/driver-network-iwn.mf
+++ b/usr/src/pkg/manifests/driver-network-iwn.mf
@@ -77,7 +77,7 @@ file path=kernel/firmware/iwn/iwlwifi-4965-2.ucode
file path=kernel/firmware/iwn/iwlwifi-5000-2.ucode
file path=kernel/firmware/iwn/iwlwifi-5150-2.ucode
file path=kernel/firmware/iwn/iwlwifi-6000-4.ucode
-file path=kernel/firmware/iwn/iwlwifi-6000g2a-5.ucode
+file path=kernel/firmware/iwn/iwlwifi-6000g2a-6.ucode
file path=kernel/firmware/iwn/iwlwifi-6000g2b-6.ucode
file path=kernel/firmware/iwn/iwlwifi-6050-5.ucode
file path=usr/share/man/man7d/iwn.7d
diff --git a/usr/src/test/zfs-tests/include/default.cfg b/usr/src/test/zfs-tests/include/default.cfg
index 8747963bfa..d36b0f3b84 100644
--- a/usr/src/test/zfs-tests/include/default.cfg
+++ b/usr/src/test/zfs-tests/include/default.cfg
@@ -106,6 +106,7 @@ export TESTVOL2=testvol2
export TESTFILE0=testfile0
export TESTFILE1=testfile1
export TESTFILE2=testfile2
+export TESTBKMARK=testbkmark
export LONGPNAME="poolname50charslong_012345678901234567890123456789"
export LONGFSNAME="fsysname50charslong_012345678901234567890123456789"
diff --git a/usr/src/test/zfs-tests/include/libtest.shlib b/usr/src/test/zfs-tests/include/libtest.shlib
index dc4e3ca3d2..2957cf0808 100644
--- a/usr/src/test/zfs-tests/include/libtest.shlib
+++ b/usr/src/test/zfs-tests/include/libtest.shlib
@@ -237,6 +237,35 @@ function create_clone # snapshot clone
log_must zfs clone $snap $clone
}
+#
+# Create a bookmark of the given snapshot. Defaultly create a bookmark on
+# filesystem.
+#
+# $1 Existing filesystem or volume name. Default, $TESTFS
+# $2 Existing snapshot name. Default, $TESTSNAP
+# $3 bookmark name. Default, $TESTBKMARK
+#
+function create_bookmark
+{
+ typeset fs_vol=${1:-$TESTFS}
+ typeset snap=${2:-$TESTSNAP}
+ typeset bkmark=${3:-$TESTBKMARK}
+
+ [[ -z $fs_vol ]] && log_fail "Filesystem or volume's name is undefined."
+ [[ -z $snap ]] && log_fail "Snapshot's name is undefined."
+ [[ -z $bkmark ]] && log_fail "Bookmark's name is undefined."
+
+ if bkmarkexists $fs_vol#$bkmark; then
+ log_fail "$fs_vol#$bkmark already exists."
+ fi
+ datasetexists $fs_vol || \
+ log_fail "$fs_vol must exist."
+ snapexists $fs_vol@$snap || \
+ log_fail "$fs_vol@$snap must exist."
+
+ log_must $ZFS bookmark $fs_vol@$snap $fs_vol#$bkmark
+}
+
function default_mirror_setup
{
default_mirror_setup_noexit $1 $2 $3
@@ -515,6 +544,23 @@ function destroy_clone
log_must rm -rf $mtpt
}
+#
+# Common function used to cleanup bookmark of file system or volume. Default
+# to delete the file system's bookmark.
+#
+# $1 bookmark name
+#
+function destroy_bookmark
+{
+ typeset bkmark=${1:-$TESTPOOL/$TESTFS#$TESTBKMARK}
+
+ if ! bkmarkexists $bkmark; then
+ log_fail "'$bkmarkp' does not existed."
+ fi
+
+ log_must $ZFS destroy $bkmark
+}
+
# Return 0 if a snapshot exists; $? otherwise
#
# $1 - snapshot name
@@ -526,6 +572,17 @@ function snapexists
}
#
+# Return 0 if a bookmark exists; $? otherwise
+#
+# $1 - bookmark name
+#
+function bkmarkexists
+{
+ $ZFS list -H -t bookmark "$1" > /dev/null 2>&1
+ return $?
+}
+
+#
# Set a property to a certain value on a dataset.
# Sets a property of the dataset to the value as passed in.
# @param:
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh
index c7eefbc5d8..d12b1dc9a5 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_001_pos.ksh
@@ -38,7 +38,7 @@
# correct property value.
#
# STRATEGY:
-# 1. Create pool, filesystem, volume and snapshot.
+# 1. Create pool, filesystem, volume, snapshot, and bookmark.
# 2. Setting valid parameter, 'zfs get' should succeed.
# 3. Compare the output property name with the original input property.
#
@@ -69,6 +69,9 @@ typeset all_props=("${zfs_props[@]}" "${userquota_props[@]}")
typeset dataset=($TESTPOOL/$TESTCTR $TESTPOOL/$TESTFS $TESTPOOL/$TESTVOL \
$TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTVOL@$TESTSNAP)
+typeset bookmark_props=(creation)
+typeset bookmark=($TESTPOOL/$TESTFS#$TESTBKMARK $TESTPOOL/$TESTVOL#$TESTBKMARK)
+
#
# According to dataset and option, checking if 'zfs get' return correct
# property information.
@@ -115,6 +118,10 @@ log_onexit cleanup
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP
create_snapshot $TESTPOOL/$TESTVOL $TESTSNAP
+# Create filesystem and volume's bookmark
+create_bookmark $TESTPOOL/$TESTFS $TESTSNAP $TESTBKMARK
+create_bookmark $TESTPOOL/$TESTVOL $TESTSNAP $TESTBKMARK
+
typeset -i i=0
while ((i < ${#dataset[@]})); do
for opt in "${options[@]}"; do
@@ -131,5 +138,21 @@ while ((i < ${#dataset[@]})); do
((i += 1))
done
+i=0
+while ((i < ${#bookmark[@]})); do
+ for opt in "${options[@]}"; do
+ for prop in ${bookmark_props[@]}; do
+ eval "$ZFS get $opt $prop ${bookmark[i]} > \
+ $TESTDIR/$TESTFILE0"
+ ret=$?
+ if [[ $ret != 0 ]]; then
+ log_fail "$ZFS get returned: $ret"
+ fi
+ check_return_value ${bookmark[i]} "$prop" "$opt"
+ done
+ done
+ ((i += 1))
+done
+
log_pass "Setting the valid options to dataset, it should succeed and return " \
"valid value. 'zfs get' pass."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_005_neg.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_005_neg.ksh
index 701989695c..0d70fba54e 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_005_neg.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_005_neg.ksh
@@ -70,6 +70,9 @@ val_props_str=$(gen_option_str "${val_props[*]}" "" "," $prop_numb)
inval_opts_str=$(gen_option_str "${inval_opts[*]}" "-" "" $opt_numb)
inval_props_str=$(gen_option_str "${inval_props[*]}" "" "," $prop_numb)
+typeset val_bookmark_props=(creation)
+typeset bookmark=($TESTPOOL/$TESTFS#$TESTBKMARK $TESTPOOL/$TESTVOL#$TESTBKMARK)
+
#
# Test different options and properties combination.
#
@@ -95,6 +98,31 @@ function test_options
done
}
+#
+# Test different options and properties combination for bookmarks.
+#
+# $1 options
+# $2 properties
+#
+function test_options_bookmarks
+{
+ typeset opts=$1
+ typeset props=$2
+
+ for dst in ${bookmark[@]}; do
+ for opt in $opts; do
+ for prop in $props; do
+ $ZFS get $opt -- $prop $dst > /dev/null 2>&1
+ ret=$?
+ if [[ $ret == 0 ]]; then
+ log_fail "$ZFS get $opt -- $prop " \
+ "$dst unexpectedly succeeded."
+ fi
+ done
+ done
+ done
+}
+
log_assert "Setting the invalid option and properties, 'zfs get' should be \
failed."
log_onexit cleanup
@@ -103,13 +131,20 @@ log_onexit cleanup
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP
create_snapshot $TESTPOOL/$TESTVOL $TESTSNAP
+# Create filesystem and volume's bookmark
+create_bookmark $TESTPOOL/$TESTFS $TESTSNAP $TESTBKMARK
+create_bookmark $TESTPOOL/$TESTVOL $TESTSNAP $TESTBKMARK
+
log_note "Valid options + invalid properties, 'zfs get' should fail."
test_options "$val_opts_str" "$inval_props_str"
+test_options_bookmark "$val_opts_str" "$inval_props_str"
log_note "Invalid options + valid properties, 'zfs get' should fail."
test_options "$inval_opts_str" "$val_props_str"
+test_options_bookmark "$inval_opts_str" "$val_bookmark_props"
log_note "Invalid options + invalid properties, 'zfs get' should fail."
test_options "$inval_opts_str" "$inval_props_str"
+test_options_bookmarks "$inval_opts_str" "$inval_props_str"
log_pass "Setting the invalid options to dataset, 'zfs get' pass."
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_008_pos.ksh b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_008_pos.ksh
index 976beb7ab9..b81a974370 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_008_pos.ksh
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_008_pos.ksh
@@ -37,7 +37,7 @@
# Verify "-d <n>" can work with other options
#
# STRATEGY:
-# 1. Create pool, filesystem, dataset, volume and snapshot.
+# 1. Create pool, filesystem, dataset, volume, snapshot, and bookmark.
# 2. Getting an -d option, other options and properties random combination.
# 3. Using the combination as the parameters of 'zfs get' to check the
# command line return value.
@@ -65,6 +65,9 @@ fi
set -A dataset $TESTPOOL/$TESTCTR $TESTPOOL/$TESTFS $TESTPOOL/$TESTVOL \
$TESTPOOL/$TESTFS@$TESTSNAP $TESTPOOL/$TESTVOL@$TESTSNAP
+set -A bookmark_props creation
+set -A bookmark $TESTPOOL/$TESTFS#$TESTBKMARK $TESTPOOL/$TESTVOL#$TESTBKMARK
+
log_assert "Verify '-d <n>' can work with other options"
log_onexit cleanup
@@ -72,6 +75,10 @@ log_onexit cleanup
create_snapshot $TESTPOOL/$TESTFS $TESTSNAP
create_snapshot $TESTPOOL/$TESTVOL $TESTSNAP
+# Create filesystem and volume's bookmark
+create_bookmark $TESTPOOL/$TESTFS $TESTSNAP $TESTBKMARK
+create_bookmark $TESTPOOL/$TESTVOL $TESTSNAP $TESTBKMARK
+
typeset -i opt_numb=16
typeset -i prop_numb=16
typeset -i i=0
@@ -91,5 +98,15 @@ for dst in ${dataset[@]}; do
done
done
+for dst in ${bookmark[@]}; do
+ (( i=0 ))
+ while (( i < opt_numb )); do
+ (( item = $RANDOM % ${#options[@]} ))
+ (( depth_item = $RANDOM % ${#depth_options[@]} ))
+ log_must eval "$ZFS get -${depth_options[depth_item]} ${options[item]} $bookmark_props $dst > /dev/null 2>&1"
+ (( i += 1 ))
+ done
+done
+
log_pass "Verify '-d <n>' can work with other options"
diff --git a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib
index 6e05175aee..d8cb9af028 100644
--- a/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib
+++ b/usr/src/test/zfs-tests/tests/functional/cli_root/zfs_get/zfs_get_common.kshlib
@@ -87,8 +87,8 @@ function gen_option_str # $elements $prefix $separator $counter
}
#
-# Cleanup the volume snapshot and filesystem snapshot were created for
-# this test case.
+# Cleanup the volume snapshot, filesystem snapshot, volume bookmark, and
+# filesystem bookmark that were created for this test case.
#
function cleanup
{
@@ -97,5 +97,10 @@ function cleanup
datasetexists $TESTPOOL/$TESTFS@$TESTSNAP && \
destroy_snapshot $TESTPOOL/$TESTFS@$TESTSNAP
+ bkmarkexists $TESTPOOL/$TESTVOL#$TESTBKMARK && \
+ destroy_bookmark $TESTPOOL/$TESTVOL#$TESTBKMARK
+ bkmarkexists $TESTPOOL/$TESTFS#$TESTBKMARK && \
+ destroy_bookmark $TESTPOOL/$TESTFS#$TESTBKMARK
+
[[ -e $TESTFILE0 ]] && log_must rm $TESTFILE0
}
diff --git a/usr/src/uts/common/fs/zfs/dsl_dataset.c b/usr/src/uts/common/fs/zfs/dsl_dataset.c
index 74409fecaa..bac325b3a1 100644
--- a/usr/src/uts/common/fs/zfs/dsl_dataset.c
+++ b/usr/src/uts/common/fs/zfs/dsl_dataset.c
@@ -81,6 +81,8 @@ extern inline dsl_dataset_phys_t *dsl_dataset_phys(dsl_dataset_t *ds);
extern int spa_asize_inflation;
+static zil_header_t zero_zil;
+
/*
* Figure out how much of this delta should be propogated to the dsl_dir
* layer. If there's a refreservation, that space has already been
@@ -125,6 +127,7 @@ dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp, dmu_tx_t *tx)
return;
}
+ ASSERT3U(bp->blk_birth, >, dsl_dataset_phys(ds)->ds_prev_snap_txg);
dmu_buf_will_dirty(ds->ds_dbuf, tx);
mutex_enter(&ds->ds_lock);
delta = parent_delta(ds, used);
@@ -914,8 +917,20 @@ dsl_dataset_zero_zil(dsl_dataset_t *ds, dmu_tx_t *tx)
objset_t *os;
VERIFY0(dmu_objset_from_ds(ds, &os));
- bzero(&os->os_zil_header, sizeof (os->os_zil_header));
- dsl_dataset_dirty(ds, tx);
+ if (bcmp(&os->os_zil_header, &zero_zil, sizeof (zero_zil)) != 0) {
+ dsl_pool_t *dp = ds->ds_dir->dd_pool;
+ zio_t *zio;
+
+ bzero(&os->os_zil_header, sizeof (os->os_zil_header));
+
+ zio = zio_root(dp->dp_spa, NULL, NULL, ZIO_FLAG_MUSTSUCCEED);
+ dsl_dataset_sync(ds, zio, tx);
+ VERIFY0(zio_wait(zio));
+
+ /* dsl_dataset_sync_done will drop this reference. */
+ dmu_buf_add_ref(ds->ds_dbuf, ds);
+ dsl_dataset_sync_done(ds, tx);
+ }
}
uint64_t
@@ -1055,8 +1070,10 @@ dsl_dataset_dirty(dsl_dataset_t *ds, dmu_tx_t *tx)
if (dsl_dataset_phys(ds)->ds_next_snap_obj != 0)
panic("dirtying snapshot!");
- dp = ds->ds_dir->dd_pool;
+ /* Must not dirty a dataset in the same txg where it got snapshotted. */
+ ASSERT3U(tx->tx_txg, >, dsl_dataset_phys(ds)->ds_prev_snap_txg);
+ dp = ds->ds_dir->dd_pool;
if (txg_list_add(&dp->dp_dirty_datasets, ds, tx->tx_txg)) {
/* up the hold count until we can be written out */
dmu_buf_add_ref(ds->ds_dbuf, ds);
@@ -1311,8 +1328,6 @@ void
dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,
dmu_tx_t *tx)
{
- static zil_header_t zero_zil;
-
dsl_pool_t *dp = ds->ds_dir->dd_pool;
dmu_buf_t *dbuf;
dsl_dataset_phys_t *dsphys;
@@ -1331,6 +1346,10 @@ dsl_dataset_snapshot_sync_impl(dsl_dataset_t *ds, const char *snapname,
bcmp(&os->os_phys->os_zil_header, &zero_zil,
sizeof (zero_zil)) == 0);
+ /* Should not snapshot a dirty dataset. */
+ ASSERT(!txg_list_member(&ds->ds_dir->dd_pool->dp_dirty_datasets,
+ ds, tx->tx_txg));
+
dsl_fs_ss_count_adjust(ds->ds_dir, 1, DD_FIELD_SNAPSHOT_COUNT, tx);
/*
@@ -1677,6 +1696,27 @@ dsl_dataset_sync(dsl_dataset_t *ds, zio_t *zio, dmu_tx_t *tx)
}
}
+static int
+deadlist_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
+{
+ dsl_deadlist_t *dl = arg;
+ dsl_deadlist_insert(dl, bp, tx);
+ return (0);
+}
+
+void
+dsl_dataset_sync_done(dsl_dataset_t *ds, dmu_tx_t *tx)
+{
+ objset_t *os = ds->ds_objset;
+
+ bplist_iterate(&ds->ds_pending_deadlist,
+ deadlist_enqueue_cb, &ds->ds_deadlist, tx);
+
+ ASSERT(!dmu_objset_is_dirty(os, dmu_tx_get_txg(tx)));
+
+ dmu_buf_rele(ds->ds_dbuf, ds);
+}
+
static void
get_clones_stat(dsl_dataset_t *ds, nvlist_t *nv)
{
@@ -2176,6 +2216,18 @@ dsl_dataset_rollback_check(void *arg, dmu_tx_t *tx)
return (SET_ERROR(EINVAL));
}
+ /*
+ * No rollback to a snapshot created in the current txg, because
+ * the rollback may dirty the dataset and create blocks that are
+ * not reachable from the rootbp while having a birth txg that
+ * falls into the snapshot's range.
+ */
+ if (dmu_tx_is_syncing(tx) &&
+ dsl_dataset_phys(ds)->ds_prev_snap_txg >= tx->tx_txg) {
+ dsl_dataset_rele(ds, FTAG);
+ return (SET_ERROR(EAGAIN));
+ }
+
/* must not have any bookmarks after the most recent snapshot */
nvlist_t *proprequest = fnvlist_alloc();
fnvlist_add_boolean(proprequest, zfs_prop_to_name(ZFS_PROP_CREATETXG));
diff --git a/usr/src/uts/common/fs/zfs/dsl_pool.c b/usr/src/uts/common/fs/zfs/dsl_pool.c
index 995fc6aa48..0d44ba6ac6 100644
--- a/usr/src/uts/common/fs/zfs/dsl_pool.c
+++ b/usr/src/uts/common/fs/zfs/dsl_pool.c
@@ -425,14 +425,6 @@ dsl_pool_mos_diduse_space(dsl_pool_t *dp,
mutex_exit(&dp->dp_lock);
}
-static int
-deadlist_enqueue_cb(void *arg, const blkptr_t *bp, dmu_tx_t *tx)
-{
- dsl_deadlist_t *dl = arg;
- dsl_deadlist_insert(dl, bp, tx);
- return (0);
-}
-
static void
dsl_pool_sync_mos(dsl_pool_t *dp, dmu_tx_t *tx)
{
@@ -533,11 +525,7 @@ dsl_pool_sync(dsl_pool_t *dp, uint64_t txg)
* - release hold from dsl_dataset_dirty()
*/
while ((ds = list_remove_head(&synced_datasets)) != NULL) {
- objset_t *os = ds->ds_objset;
- bplist_iterate(&ds->ds_pending_deadlist,
- deadlist_enqueue_cb, &ds->ds_deadlist, tx);
- ASSERT(!dmu_objset_is_dirty(os, txg));
- dmu_buf_rele(ds->ds_dbuf, ds);
+ dsl_dataset_sync_done(ds, tx);
}
while ((dd = txg_list_remove(&dp->dp_dirty_dirs, txg)) != NULL) {
dsl_dir_sync(dd, tx);
diff --git a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h
index 18466bb405..22c67b48a9 100644
--- a/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h
+++ b/usr/src/uts/common/fs/zfs/sys/dsl_dataset.h
@@ -274,6 +274,7 @@ boolean_t dsl_dataset_modified_since_snap(dsl_dataset_t *ds,
dsl_dataset_t *snap);
void dsl_dataset_sync(dsl_dataset_t *os, zio_t *zio, dmu_tx_t *tx);
+void dsl_dataset_sync_done(dsl_dataset_t *os, dmu_tx_t *tx);
void dsl_dataset_block_born(dsl_dataset_t *ds, const blkptr_t *bp,
dmu_tx_t *tx);
diff --git a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
index b382d27bdf..3278171372 100644
--- a/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
+++ b/usr/src/uts/common/fs/zfs/sys/zfs_vfsops.h
@@ -137,7 +137,7 @@ typedef struct zfid_long {
extern uint_t zfs_fsyncer_key;
extern int zfs_suspend_fs(zfsvfs_t *zfsvfs);
-extern int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname);
+extern int zfs_resume_fs(zfsvfs_t *zfsvfs, struct dsl_dataset *ds);
extern int zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
const char *domain, uint64_t rid, uint64_t *valuep);
extern int zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
diff --git a/usr/src/uts/common/fs/zfs/zfs_ioctl.c b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
index 1948aa443b..823822e44c 100644
--- a/usr/src/uts/common/fs/zfs/zfs_ioctl.c
+++ b/usr/src/uts/common/fs/zfs/zfs_ioctl.c
@@ -3683,12 +3683,15 @@ zfs_ioc_rollback(const char *fsname, nvlist_t *args, nvlist_t *outnvl)
int error;
if (getzfsvfs(fsname, &zfsvfs) == 0) {
+ dsl_dataset_t *ds;
+
+ ds = dmu_objset_ds(zfsvfs->z_os);
error = zfs_suspend_fs(zfsvfs);
if (error == 0) {
int resume_err;
error = dsl_dataset_rollback(fsname, zfsvfs, outnvl);
- resume_err = zfs_resume_fs(zfsvfs, fsname);
+ resume_err = zfs_resume_fs(zfsvfs, ds);
error = error ? error : resume_err;
}
VFS_RELE(zfsvfs->z_vfs);
@@ -4313,8 +4316,10 @@ zfs_ioc_recv(zfs_cmd_t *zc)
if (getzfsvfs(tofs, &zfsvfs) == 0) {
/* online recv */
+ dsl_dataset_t *ds;
int end_err;
+ ds = dmu_objset_ds(zfsvfs->z_os);
error = zfs_suspend_fs(zfsvfs);
/*
* If the suspend fails, then the recv_end will
@@ -4322,7 +4327,7 @@ zfs_ioc_recv(zfs_cmd_t *zc)
*/
end_err = dmu_recv_end(&drc, zfsvfs);
if (error == 0)
- error = zfs_resume_fs(zfsvfs, tofs);
+ error = zfs_resume_fs(zfsvfs, ds);
error = error ? error : end_err;
VFS_RELE(zfsvfs->z_vfs);
} else {
@@ -4846,11 +4851,14 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
* objset needs to be closed & reopened (to grow the
* objset_phys_t). Suspend/resume the fs will do that.
*/
+ dsl_dataset_t *ds;
+
+ ds = dmu_objset_ds(zfsvfs->z_os);
error = zfs_suspend_fs(zfsvfs);
if (error == 0) {
dmu_objset_refresh_ownership(zfsvfs->z_os,
zfsvfs);
- error = zfs_resume_fs(zfsvfs, zc->zc_name);
+ error = zfs_resume_fs(zfsvfs, ds);
}
}
if (error == 0)
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
index f069e3553e..9e0a8c0ed8 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
@@ -1020,13 +1020,6 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
if (error)
return (error);
- /*
- * Set the objset user_ptr to track its zfsvfs.
- */
- mutex_enter(&zfsvfs->z_os->os_user_ptr_lock);
- dmu_objset_set_user(zfsvfs->z_os, zfsvfs);
- mutex_exit(&zfsvfs->z_os->os_user_ptr_lock);
-
zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data);
/*
@@ -1087,6 +1080,13 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */
}
+ /*
+ * Set the objset user_ptr to track its zfsvfs.
+ */
+ mutex_enter(&zfsvfs->z_os->os_user_ptr_lock);
+ dmu_objset_set_user(zfsvfs->z_os, zfsvfs);
+ mutex_exit(&zfsvfs->z_os->os_user_ptr_lock);
+
return (0);
}
@@ -2032,7 +2032,7 @@ zfs_suspend_fs(zfsvfs_t *zfsvfs)
* zfsvfs, held, and long held on entry.
*/
int
-zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname)
+zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
{
int err;
znode_t *zp;
@@ -2041,14 +2041,13 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname)
ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock));
/*
- * We already own this, so just hold and rele it to update the
- * objset_t, as the one we had before may have been evicted.
+ * We already own this, so just update the objset_t, as the one we
+ * had before may have been evicted.
*/
objset_t *os;
- VERIFY0(dmu_objset_hold(osname, zfsvfs, &os));
- VERIFY3P(os->os_dsl_dataset->ds_owner, ==, zfsvfs);
- VERIFY(dsl_dataset_long_held(os->os_dsl_dataset));
- dmu_objset_rele(os, zfsvfs);
+ VERIFY3P(ds->ds_owner, ==, zfsvfs);
+ VERIFY(dsl_dataset_long_held(ds));
+ VERIFY0(dmu_objset_from_ds(ds, &os));
err = zfsvfs_init(zfsvfs, os);
if (err != 0)
diff --git a/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucode b/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucode
deleted file mode 100644
index 24f7d146d0..0000000000
--- a/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-5.ucode
+++ /dev/null
Binary files differ
diff --git a/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucode b/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucode
new file mode 100644
index 0000000000..a1f2454df7
--- /dev/null
+++ b/usr/src/uts/common/io/iwn/fw-iw/iwlwifi-6000g2a-6.ucode
Binary files differ
diff --git a/usr/src/uts/common/io/iwn/if_iwn.c b/usr/src/uts/common/io/iwn/if_iwn.c
index a4334cc19d..fc60627899 100644
--- a/usr/src/uts/common/io/iwn/if_iwn.c
+++ b/usr/src/uts/common/io/iwn/if_iwn.c
@@ -1321,7 +1321,7 @@ iwn5000_attach(struct iwn_softc *sc, uint16_t pid)
ops->config_bt_coex = iwn_config_bt_coex_adv1;
}
else
- sc->fwname = "iwlwifi-6000g2a-5.ucode";
+ sc->fwname = "iwlwifi-6000g2a-6.ucode";
iwn_kstat_create(sc, "temp_offset",
sizeof (struct iwn_ks_toff_6000),
diff --git a/usr/src/uts/intel/iwn/Makefile b/usr/src/uts/intel/iwn/Makefile
index a629462e56..2dcf4b1eae 100644
--- a/usr/src/uts/intel/iwn/Makefile
+++ b/usr/src/uts/intel/iwn/Makefile
@@ -31,7 +31,7 @@ FWDIR = $(UTSBASE)/common/io/iwn/fw-iw
FWFILES = iwlwifi-100-5.ucode iwlwifi-1000-3.ucode iwlwifi-105-6.ucode \
iwlwifi-135-6.ucode iwlwifi-2000-6.ucode iwlwifi-2030-6.ucode \
iwlwifi-4965-2.ucode iwlwifi-5000-2.ucode iwlwifi-5150-2.ucode \
- iwlwifi-6000-4.ucode iwlwifi-6000g2a-5.ucode iwlwifi-6000g2b-6.ucode \
+ iwlwifi-6000-4.ucode iwlwifi-6000g2a-6.ucode iwlwifi-6000g2b-6.ucode \
iwlwifi-6050-5.ucode
#