summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
authorMatthew Ahrens <mahrens@delphix.com>2016-05-10 20:49:32 -0700
committerMatthew Ahrens <mahrens@delphix.com>2016-05-11 16:30:33 -0700
commit1fdcbd00c9cbac286b5f92e08877e8cb3c448420 (patch)
tree669bdbb4d391ade1c4d4ba58b9d5ef249e844379 /usr/src/uts
parent7ea027865de56bac0c639f5fe006cc752ce41413 (diff)
downloadillumos-joyent-1fdcbd00c9cbac286b5f92e08877e8cb3c448420.tar.gz
6874 rollback and receive need to reset ZPL state to what's on disk
Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Paul Dagnelie <pcd@delphix.com> Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_vfsops.c189
1 files changed, 92 insertions, 97 deletions
diff --git a/usr/src/uts/common/fs/zfs/zfs_vfsops.c b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
index ebacf850ec..0d02fd5bec 100644
--- a/usr/src/uts/common/fs/zfs/zfs_vfsops.c
+++ b/usr/src/uts/common/fs/zfs/zfs_vfsops.c
@@ -20,7 +20,7 @@
*/
/*
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
+ * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
*/
@@ -852,61 +852,46 @@ zfs_owner_overquota(zfsvfs_t *zfsvfs, znode_t *zp, boolean_t isgroup)
return (zfs_fuid_overquota(zfsvfs, isgroup, fuid));
}
-int
-zfsvfs_create(const char *osname, zfsvfs_t **zfvp)
+/*
+ * Associate this zfsvfs with the given objset, which must be owned.
+ * This will cache a bunch of on-disk state from the objset in the
+ * zfsvfs.
+ */
+static int
+zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os)
{
- objset_t *os;
- zfsvfs_t *zfsvfs;
- uint64_t zval;
- int i, error;
- uint64_t sa_obj;
-
- zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
-
- /*
- * We claim to always be readonly so we can open snapshots;
- * other ZPL code will prevent us from writing to snapshots.
- */
- error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zfsvfs, &os);
- if (error) {
- kmem_free(zfsvfs, sizeof (zfsvfs_t));
- return (error);
- }
+ int error;
+ uint64_t val;
- /*
- * Initialize the zfs-specific filesystem structure.
- * Should probably make this a kmem cache, shuffle fields,
- * and just bzero up to z_hold_mtx[].
- */
- zfsvfs->z_vfs = NULL;
- zfsvfs->z_parent = zfsvfs;
zfsvfs->z_max_blksz = SPA_OLD_MAXBLOCKSIZE;
zfsvfs->z_show_ctldir = ZFS_SNAPDIR_VISIBLE;
zfsvfs->z_os = os;
error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zfsvfs->z_version);
- if (error) {
- goto out;
- } else if (zfsvfs->z_version >
+ if (error != 0)
+ return (error);
+ if (zfsvfs->z_version >
zfs_zpl_version_map(spa_version(dmu_objset_spa(os)))) {
(void) printf("Can't mount a version %lld file system "
"on a version %lld pool\n. Pool must be upgraded to mount "
"this file system.", (u_longlong_t)zfsvfs->z_version,
(u_longlong_t)spa_version(dmu_objset_spa(os)));
- error = SET_ERROR(ENOTSUP);
- goto out;
+ return (SET_ERROR(ENOTSUP));
}
- if ((error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &zval)) != 0)
- goto out;
- zfsvfs->z_norm = (int)zval;
+ error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &val);
+ if (error != 0)
+ return (error);
+ zfsvfs->z_norm = (int)val;
- if ((error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &zval)) != 0)
- goto out;
- zfsvfs->z_utf8 = (zval != 0);
+ error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &val);
+ if (error != 0)
+ return (error);
+ zfsvfs->z_utf8 = (val != 0);
- if ((error = zfs_get_zplprop(os, ZFS_PROP_CASE, &zval)) != 0)
- goto out;
- zfsvfs->z_case = (uint_t)zval;
+ error = zfs_get_zplprop(os, ZFS_PROP_CASE, &val);
+ if (error != 0)
+ return (error);
+ zfsvfs->z_case = (uint_t)val;
/*
* Fold case on file systems that are always or sometimes case
@@ -919,60 +904,88 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp)
zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os);
zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os);
+ uint64_t sa_obj = 0;
if (zfsvfs->z_use_sa) {
/* should either have both of these objects or none */
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1,
&sa_obj);
- if (error)
- goto out;
- } else {
- /*
- * Pre SA versions file systems should never touch
- * either the attribute registration or layout objects.
- */
- sa_obj = 0;
+ if (error != 0)
+ return (error);
}
error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
&zfsvfs->z_attr_table);
- if (error)
- goto out;
+ if (error != 0)
+ return (error);
if (zfsvfs->z_version >= ZPL_VERSION_SA)
sa_register_update_callback(os, zfs_sa_upgrade);
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1,
&zfsvfs->z_root);
- if (error)
- goto out;
+ if (error != 0)
+ return (error);
ASSERT(zfsvfs->z_root != 0);
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
&zfsvfs->z_unlinkedobj);
- if (error)
- goto out;
+ if (error != 0)
+ return (error);
error = zap_lookup(os, MASTER_NODE_OBJ,
zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA],
8, 1, &zfsvfs->z_userquota_obj);
- if (error && error != ENOENT)
- goto out;
+ if (error == ENOENT)
+ zfsvfs->z_userquota_obj = 0;
+ else if (error != 0)
+ return (error);
error = zap_lookup(os, MASTER_NODE_OBJ,
zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA],
8, 1, &zfsvfs->z_groupquota_obj);
- if (error && error != ENOENT)
- goto out;
+ if (error == ENOENT)
+ zfsvfs->z_groupquota_obj = 0;
+ else if (error != 0)
+ return (error);
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, 8, 1,
&zfsvfs->z_fuid_obj);
- if (error && error != ENOENT)
- goto out;
+ if (error == ENOENT)
+ zfsvfs->z_fuid_obj = 0;
+ else if (error != 0)
+ return (error);
error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SHARES_DIR, 8, 1,
&zfsvfs->z_shares_dir);
- if (error && error != ENOENT)
- goto out;
+ if (error == ENOENT)
+ zfsvfs->z_shares_dir = 0;
+ else if (error != 0)
+ return (error);
+
+ return (0);
+}
+
+int
+zfsvfs_create(const char *osname, zfsvfs_t **zfvp)
+{
+ objset_t *os;
+ zfsvfs_t *zfsvfs;
+ int error;
+
+ zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
+
+ /*
+ * We claim to always be readonly so we can open snapshots;
+ * other ZPL code will prevent us from writing to snapshots.
+ */
+ error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zfsvfs, &os);
+ if (error) {
+ kmem_free(zfsvfs, sizeof (zfsvfs_t));
+ return (error);
+ }
+
+ zfsvfs->z_vfs = NULL;
+ zfsvfs->z_parent = zfsvfs;
mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
mutex_init(&zfsvfs->z_lock, NULL, MUTEX_DEFAULT, NULL);
@@ -981,17 +994,19 @@ zfsvfs_create(const char *osname, zfsvfs_t **zfvp)
rrm_init(&zfsvfs->z_teardown_lock, B_FALSE);
rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL);
- for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
+ for (int i = 0; i != ZFS_OBJ_MTX_SZ; i++)
mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
+ error = zfsvfs_init(zfsvfs, os);
+ if (error != 0) {
+ dmu_objset_disown(os, zfsvfs);
+ *zfvp = NULL;
+ kmem_free(zfsvfs, sizeof (zfsvfs_t));
+ return (error);
+ }
+
*zfvp = zfsvfs;
return (0);
-
-out:
- dmu_objset_disown(os, zfsvfs);
- *zfvp = NULL;
- kmem_free(zfsvfs, sizeof (zfsvfs_t));
- return (error);
}
static int
@@ -2008,7 +2023,6 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname)
{
int err;
znode_t *zp;
- uint64_t sa_obj = 0;
ASSERT(RRM_WRITE_HELD(&zfsvfs->z_teardown_lock));
ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock));
@@ -2017,35 +2031,16 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname)
* 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.
*/
- VERIFY0(dmu_objset_hold(osname, zfsvfs, &zfsvfs->z_os));
- VERIFY3P(zfsvfs->z_os->os_dsl_dataset->ds_owner, ==, zfsvfs);
- VERIFY(dsl_dataset_long_held(zfsvfs->z_os->os_dsl_dataset));
- dmu_objset_rele(zfsvfs->z_os, zfsvfs);
-
- /*
- * Make sure version hasn't changed
- */
-
- err = zfs_get_zplprop(zfsvfs->z_os, ZFS_PROP_VERSION,
- &zfsvfs->z_version);
-
- if (err)
- goto bail;
-
- err = zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ,
- ZFS_SA_ATTRS, 8, 1, &sa_obj);
-
- if (err && zfsvfs->z_version >= ZPL_VERSION_SA)
- goto bail;
+ 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);
- if ((err = sa_setup(zfsvfs->z_os, sa_obj,
- zfs_attr_table, ZPL_END, &zfsvfs->z_attr_table)) != 0)
+ err = zfsvfs_init(zfsvfs, os);
+ if (err != 0)
goto bail;
- if (zfsvfs->z_version >= ZPL_VERSION_SA)
- sa_register_update_callback(zfsvfs->z_os,
- zfs_sa_upgrade);
-
VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0);
zfs_set_fuid_feature(zfsvfs);