Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZIL claiming should not start user accounting #7163

Merged
merged 1 commit into from
Feb 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/sys/zfs_vfsops.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ extern boolean_t zfs_id_overobjquota(zfsvfs_t *zfsvfs, uint64_t usedobj,
extern boolean_t zfs_id_overquota(zfsvfs_t *zfsvfs, uint64_t usedobj,
uint64_t id);
extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers);
extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp);
extern int zfsvfs_create(const char *name, boolean_t readony, zfsvfs_t **zfvp);
extern int zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os);
extern void zfsvfs_free(zfsvfs_t *zfsvfs);
extern int zfs_check_global_label(const char *dsname, const char *hexsl);
Expand Down
19 changes: 17 additions & 2 deletions module/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,9 +726,15 @@ dmu_objset_own(const char *name, dmu_objset_type_t type,
return (err);
}

/* user accounting requires the dataset to be decrypted */
/*
* User accounting requires the dataset to be decrypted and rw.
* We also don't begin user accounting during claiming to help
* speed up pool import times and to keep this txg reserved
* completely for recovery work.
*/
if ((dmu_objset_userobjspace_upgradable(*osp) ||
dmu_objset_projectquota_upgradable(*osp)) &&
!readonly && !dp->dp_spa->spa_claiming &&
(ds->ds_dir->dd_crypto_obj == 0 || decrypt))
dmu_objset_id_quota_upgrade(*osp);

Expand Down Expand Up @@ -1897,10 +1903,19 @@ dmu_objset_do_userquota_updates(objset_t *os, dmu_tx_t *tx)
if (!dmu_objset_userused_enabled(os))
return;

/* if this is a raw receive just return and handle accounting later */
/*
* If this is a raw receive just return and handle accounting
* later when we have the keys loaded. We also don't do user
* accounting during claiming since the datasets are not owned
* for the duration of claiming and this txg should only be
* used for recovery.
*/
if (os->os_encrypted && dmu_objset_is_receiving(os))
return;

if (tx->tx_txg <= os->os_spa->spa_claim_max_txg)
return;

/* Allocate the user/group/project used objects if necessary. */
if (DMU_USERUSED_DNODE(os)->dn_type == DMU_OT_NONE) {
VERIFY0(zap_create_claim(os,
Expand Down
2 changes: 1 addition & 1 deletion module/zfs/zfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1472,7 +1472,7 @@ zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer)
int error = 0;

if (getzfsvfs(name, zfvp) != 0)
error = zfsvfs_create(name, zfvp);
error = zfsvfs_create(name, B_FALSE, zfvp);
if (error == 0) {
rrm_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
RW_READER, tag);
Expand Down
43 changes: 19 additions & 24 deletions module/zfs/zfs_vfsops.c
Original file line number Diff line number Diff line change
Expand Up @@ -1136,21 +1136,16 @@ zfsvfs_init(zfsvfs_t *zfsvfs, objset_t *os)
}

int
zfsvfs_create(const char *osname, zfsvfs_t **zfvp)
zfsvfs_create(const char *osname, boolean_t readonly, zfsvfs_t **zfvp)
{
objset_t *os;
zfsvfs_t *zfsvfs;
int error;
boolean_t ro = (readonly || (strchr(osname, '@') != NULL));

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, B_TRUE,
zfsvfs, &os);
error = dmu_objset_own(osname, DMU_OST_ZFS, ro, B_TRUE, zfsvfs, &os);
if (error != 0) {
kmem_free(zfsvfs, sizeof (zfsvfs_t));
return (error);
Expand Down Expand Up @@ -1209,14 +1204,6 @@ zfsvfs_setup(zfsvfs_t *zfsvfs, boolean_t mounting)
int error;
boolean_t readonly = zfs_is_readonly(zfsvfs);

/*
* Check for a bad on-disk format version now since we
* lied about owning the dataset readonly before.
*/
if (!readonly &&
dmu_objset_incompatible_encryption_version(zfsvfs->z_os))
return (SET_ERROR(EROFS));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To be clear, this check is no longer needed since it's now handled properly in dmu_objset_own_impl() since we're now tell the truth about the dataset being r/w.


error = zfs_register_callbacks(zfsvfs->z_vfs);
if (error)
return (error);
Expand Down Expand Up @@ -1786,24 +1773,30 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
struct inode *root_inode;
uint64_t recordsize;
int error = 0;
zfsvfs_t *zfsvfs;
zfsvfs_t *zfsvfs = NULL;
vfs_t *vfs = NULL;

ASSERT(zm);
ASSERT(osname);

error = zfsvfs_create(osname, &zfsvfs);
error = zfsvfs_parse_options(zm->mnt_data, &vfs);
if (error)
return (error);

error = zfsvfs_parse_options(zm->mnt_data, &zfsvfs->z_vfs);
if (error)
error = zfsvfs_create(osname, vfs->vfs_readonly, &zfsvfs);
if (error) {
zfsvfs_vfs_free(vfs);
goto out;
}

if ((error = dsl_prop_get_integer(osname, "recordsize",
&recordsize, NULL)))
&recordsize, NULL))) {
zfsvfs_vfs_free(vfs);
goto out;
}

zfsvfs->z_vfs->vfs_data = zfsvfs;
vfs->vfs_data = zfsvfs;
zfsvfs->z_vfs = vfs;
zfsvfs->z_sb = sb;
sb->s_fs_info = zfsvfs;
sb->s_magic = ZFS_SUPER_MAGIC;
Expand Down Expand Up @@ -1875,8 +1868,10 @@ zfs_domount(struct super_block *sb, zfs_mnt_t *zm, int silent)
zfsvfs->z_arc_prune = arc_add_prune_callback(zpl_prune_sb, sb);
out:
if (error) {
dmu_objset_disown(zfsvfs->z_os, B_TRUE, zfsvfs);
zfsvfs_free(zfsvfs);
if (zfsvfs != NULL) {
dmu_objset_disown(zfsvfs->z_os, B_TRUE, zfsvfs);
zfsvfs_free(zfsvfs);
}
/*
* make sure we don't have dangling sb->s_fs_info which
* zfs_preumount will use.
Expand Down
16 changes: 6 additions & 10 deletions module/zfs/zvol.c
Original file line number Diff line number Diff line change
Expand Up @@ -1289,10 +1289,11 @@ zvol_resume(zvol_state_t *zv)
}

static int
zvol_first_open(zvol_state_t *zv)
zvol_first_open(zvol_state_t *zv, boolean_t readonly)
{
objset_t *os;
int error, locked = 0;
boolean_t ro;

ASSERT(RW_READ_HELD(&zv->zv_suspend_lock));
ASSERT(MUTEX_HELD(&zv->zv_state_lock));
Expand Down Expand Up @@ -1321,8 +1322,8 @@ zvol_first_open(zvol_state_t *zv)
return (-SET_ERROR(ERESTARTSYS));
}

/* lie and say we're read-only */
error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, 1, 1, zv, &os);
ro = (readonly || (strchr(zv->zv_name, '@') != NULL));
error = dmu_objset_own(zv->zv_name, DMU_OST_ZVOL, ro, B_TRUE, zv, &os);
if (error)
goto out_mutex;

Expand Down Expand Up @@ -1401,17 +1402,12 @@ zvol_open(struct block_device *bdev, fmode_t flag)
ASSERT(zv->zv_open_count != 0 || RW_READ_HELD(&zv->zv_suspend_lock));

if (zv->zv_open_count == 0) {
error = zvol_first_open(zv);
error = zvol_first_open(zv, !(flag & FMODE_WRITE));
if (error)
goto out_mutex;
}

/*
* Check for a bad on-disk format version now since we
* lied about owning the dataset readonly before.
*/
if ((flag & FMODE_WRITE) && ((zv->zv_flags & ZVOL_RDONLY) ||
dmu_objset_incompatible_encryption_version(zv->zv_objset))) {
if ((flag & FMODE_WRITE) && (zv->zv_flags & ZVOL_RDONLY)) {
error = -EROFS;
goto out_open_count;
}
Expand Down