Skip to content

Commit

Permalink
6874 rollback and receive need to reset ZPL state to what's on disk
Browse files Browse the repository at this point in the history
Reviewed by: George Wilson <[email protected]>
Reviewed by: Paul Dagnelie <[email protected]>
Approved by: Garrett D'Amore <[email protected]>
  • Loading branch information
ahrens committed May 11, 2016
1 parent 7ea0278 commit 1fdcbd0
Showing 1 changed file with 92 additions and 97 deletions.
189 changes: 92 additions & 97 deletions usr/src/uts/common/fs/zfs/zfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]
*/

Expand Down Expand Up @@ -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
Expand All @@ -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);
Expand All @@ -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
Expand Down Expand Up @@ -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));
Expand All @@ -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);
Expand Down

0 comments on commit 1fdcbd0

Please sign in to comment.