Skip to content
Open
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
1 change: 1 addition & 0 deletions include/sys/dmu_objset.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ boolean_t dmu_objset_projectquota_enabled(objset_t *os);
boolean_t dmu_objset_projectquota_present(objset_t *os);
boolean_t dmu_objset_projectquota_upgradable(objset_t *os);
void dmu_objset_id_quota_upgrade(objset_t *os);
void dmu_objset_id_projectquota_upgrade(objset_t *os);
int dmu_get_file_info(objset_t *os, dmu_object_type_t bonustype,
const void *data, zfs_file_info_t *zfi);

Expand Down
24 changes: 24 additions & 0 deletions module/zfs/dmu_objset.c
Original file line number Diff line number Diff line change
Expand Up @@ -2439,6 +2439,30 @@ dmu_objset_id_quota_upgrade(objset_t *os)
dmu_objset_upgrade(os, dmu_objset_id_quota_upgrade_cb);
}

static int
dmu_objset_id_projectquota_upgrade_cb(objset_t *os)
{
if (dmu_objset_projectquota_present(os))
return (0);
if (!dmu_objset_projectquota_enabled(os))
return (SET_ERROR(ENOTSUP));

dmu_objset_ds(os)->ds_feature_activation[
SPA_FEATURE_PROJECT_QUOTA] = (void *)B_TRUE;

if (dmu_objset_projectquota_enabled(os))
os->os_flags |= OBJSET_FLAG_PROJECTQUOTA_COMPLETE;

txg_wait_synced(dmu_objset_pool(os), 0);
return (0);
}

void
dmu_objset_id_projectquota_upgrade(objset_t *os)
{
dmu_objset_upgrade(os, dmu_objset_id_projectquota_upgrade_cb);
}

boolean_t
dmu_objset_userobjspace_upgradable(objset_t *os)
{
Expand Down
71 changes: 71 additions & 0 deletions module/zfs/zfs_ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -3104,6 +3104,67 @@ zfs_ioc_inherit_prop(zfs_cmd_t *zc)
return (err);
}

static int
zfs_projectquota_upgrade_cb(const char *dataset, void *arg)
{
zfsvfs_t *zfsvfs;
int error;

(void) arg;

error = getzfsvfs(dataset, &zfsvfs);

if (error != 0)
return (0);

if (!dmu_objset_projectquota_enabled(zfsvfs->z_os)) {
/*
* If projectquota is not enabled, it may be because the objset
* needs to be closed & reopened (to grow the objset_phys_t).
* Suspend/resume the fs will do that.
*/
dsl_dataset_t *ds, *newds;

ds = dmu_objset_ds(zfsvfs->z_os);
error = zfs_suspend_fs(zfsvfs);
if (error == 0) {
dmu_objset_refresh_ownership(ds, &newds,
B_TRUE, zfsvfs);
error = zfs_resume_fs(zfsvfs, newds);
}
}

if (error == 0) {
mutex_enter(&zfsvfs->z_os->os_upgrade_lock);
if (zfsvfs->z_os->os_upgrade_id == 0) {
/* clear potential error code and retry */
zfsvfs->z_os->os_upgrade_status = 0;
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);

dsl_pool_config_enter(
dmu_objset_pool(zfsvfs->z_os), FTAG);
dmu_objset_id_projectquota_upgrade(zfsvfs->z_os);
dsl_pool_config_exit(
dmu_objset_pool(zfsvfs->z_os), FTAG);
} else {
mutex_exit(&zfsvfs->z_os->os_upgrade_lock);
}

taskq_wait_id(zfsvfs->z_os->os_spa->spa_upgrade_taskq,
zfsvfs->z_os->os_upgrade_id);
error = zfsvfs->z_os->os_upgrade_status;
}

zfs_vfs_rele(zfsvfs);

if (error != 0)
cmn_err(CE_WARN,
"Failed to activate the project quota feature on dataset "
"%s (%d).", dataset, error);

return (0);
}

static int
zfs_ioc_pool_set_props(zfs_cmd_t *zc)
{
Expand Down Expand Up @@ -3143,6 +3204,16 @@ zfs_ioc_pool_set_props(zfs_cmd_t *zc)

error = spa_prop_set(spa, props);

/*
* If we are enabling the project quota feature, try to re-initialize
* the active file systems on that pool and activate the feature -- all
* in best effort.
*/
if ((error == 0) && nvlist_exists(props, "feature@project_quota"))
Copy link
Author

Choose a reason for hiding this comment

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

feature@project_quota is hard coded though I am not sure if I should write a function to get the name from SPA_FEATURE_PROJECT_QUOTA just to be used here.

(void) dmu_objset_find(spa_name(spa),
zfs_projectquota_upgrade_cb,
NULL, DS_FIND_CHILDREN);

nvlist_free(props);
spa_close(spa, FTAG);

Expand Down
Loading