mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-26 12:12:13 +03:00
Add support for user/group dnode accounting & quota
This patch tracks dnode usage for each user/group in the DMU_USER/GROUPUSED_OBJECT ZAPs. ZAP entries dedicated to dnode accounting have the key prefixed with "obj-" followed by the UID/GID in string format (as done for the block accounting). A new SPA feature has been added for dnode accounting as well as a new ZPL version. The SPA feature must be enabled in the pool before upgrading the zfs filesystem. During the zfs version upgrade, a "quotacheck" will be executed by marking all dnode as dirty. ZoL-bug-id: https://github.com/zfsonlinux/zfs/issues/3500 Signed-off-by: Jinshan Xiong <jinshan.xiong@intel.com> Signed-off-by: Johann Lombardi <johann.lombardi@intel.com>
This commit is contained in:
committed by
Brian Behlendorf
parent
af322debaa
commit
1de321e626
+61
-1
@@ -244,9 +244,14 @@ static const char *userquota_perms[] = {
|
||||
ZFS_DELEG_PERM_USERQUOTA,
|
||||
ZFS_DELEG_PERM_GROUPUSED,
|
||||
ZFS_DELEG_PERM_GROUPQUOTA,
|
||||
ZFS_DELEG_PERM_USEROBJUSED,
|
||||
ZFS_DELEG_PERM_USEROBJQUOTA,
|
||||
ZFS_DELEG_PERM_GROUPOBJUSED,
|
||||
ZFS_DELEG_PERM_GROUPOBJQUOTA,
|
||||
};
|
||||
|
||||
static int zfs_ioc_userspace_upgrade(zfs_cmd_t *zc);
|
||||
static int zfs_ioc_userobjspace_upgrade(zfs_cmd_t *zc);
|
||||
static int zfs_check_settable(const char *name, nvpair_t *property,
|
||||
cred_t *cr);
|
||||
static int zfs_check_clearable(char *dataset, nvlist_t *props,
|
||||
@@ -1171,7 +1176,9 @@ zfs_secpolicy_userspace_one(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
|
||||
* themself, allow it.
|
||||
*/
|
||||
if (zc->zc_objset_type == ZFS_PROP_USERUSED ||
|
||||
zc->zc_objset_type == ZFS_PROP_USERQUOTA) {
|
||||
zc->zc_objset_type == ZFS_PROP_USERQUOTA ||
|
||||
zc->zc_objset_type == ZFS_PROP_USEROBJUSED ||
|
||||
zc->zc_objset_type == ZFS_PROP_USEROBJQUOTA) {
|
||||
if (zc->zc_guid == crgetuid(cr))
|
||||
return (0);
|
||||
} else {
|
||||
@@ -2426,6 +2433,7 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
|
||||
zc = kmem_zalloc(sizeof (zfs_cmd_t), KM_SLEEP);
|
||||
(void) strcpy(zc->zc_name, dsname);
|
||||
(void) zfs_ioc_userspace_upgrade(zc);
|
||||
(void) zfs_ioc_userobjspace_upgrade(zc);
|
||||
kmem_free(zc, sizeof (zfs_cmd_t));
|
||||
}
|
||||
break;
|
||||
@@ -3720,13 +3728,23 @@ zfs_check_settable(const char *dsname, nvpair_t *pair, cred_t *cr)
|
||||
zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA];
|
||||
const char *gq_prefix =
|
||||
zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA];
|
||||
const char *uiq_prefix =
|
||||
zfs_userquota_prop_prefixes[ZFS_PROP_USEROBJQUOTA];
|
||||
const char *giq_prefix =
|
||||
zfs_userquota_prop_prefixes[ZFS_PROP_GROUPOBJQUOTA];
|
||||
|
||||
if (strncmp(propname, uq_prefix,
|
||||
strlen(uq_prefix)) == 0) {
|
||||
perm = ZFS_DELEG_PERM_USERQUOTA;
|
||||
} else if (strncmp(propname, uiq_prefix,
|
||||
strlen(uiq_prefix)) == 0) {
|
||||
perm = ZFS_DELEG_PERM_USEROBJQUOTA;
|
||||
} else if (strncmp(propname, gq_prefix,
|
||||
strlen(gq_prefix)) == 0) {
|
||||
perm = ZFS_DELEG_PERM_GROUPQUOTA;
|
||||
} else if (strncmp(propname, giq_prefix,
|
||||
strlen(giq_prefix)) == 0) {
|
||||
perm = ZFS_DELEG_PERM_GROUPOBJQUOTA;
|
||||
} else {
|
||||
/* USERUSED and GROUPUSED are read-only */
|
||||
return (SET_ERROR(EINVAL));
|
||||
@@ -4927,6 +4945,48 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* inputs:
|
||||
* zc_name name of filesystem
|
||||
*
|
||||
* outputs:
|
||||
* none
|
||||
*/
|
||||
static int
|
||||
zfs_ioc_userobjspace_upgrade(zfs_cmd_t *zc)
|
||||
{
|
||||
objset_t *os;
|
||||
int error;
|
||||
|
||||
error = dmu_objset_hold(zc->zc_name, FTAG, &os);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
dsl_dataset_long_hold(dmu_objset_ds(os), FTAG);
|
||||
dsl_pool_rele(dmu_objset_pool(os), FTAG);
|
||||
|
||||
if (dmu_objset_userobjspace_upgradable(os)) {
|
||||
mutex_enter(&os->os_upgrade_lock);
|
||||
if (os->os_upgrade_id == 0) {
|
||||
/* clear potential error code and retry */
|
||||
os->os_upgrade_status = 0;
|
||||
mutex_exit(&os->os_upgrade_lock);
|
||||
|
||||
dmu_objset_userobjspace_upgrade(os);
|
||||
} else {
|
||||
mutex_exit(&os->os_upgrade_lock);
|
||||
}
|
||||
|
||||
taskq_wait_id(os->os_spa->spa_upgrade_taskq, os->os_upgrade_id);
|
||||
error = os->os_upgrade_status;
|
||||
}
|
||||
|
||||
dsl_dataset_long_rele(dmu_objset_ds(os), FTAG);
|
||||
dsl_dataset_rele(dmu_objset_ds(os), FTAG);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
static int
|
||||
zfs_ioc_share(zfs_cmd_t *zc)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user