-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Remove projectquota space upgrade and usage update of ZFS_INVALID_PROJID #16471
base: master
Are you sure you want to change the base?
Conversation
Upgrading to feature@project_quota, currently trigger upgrade task around project quota usage upgrade, which marks each inode dirty via, dmu_objset_id_quota_upgrade()->dmu_objset_id_quota_upgrade_cb()-> dmu_objset_space_upgrade(). Project quota space upgrade task marks each dnode dirty, expecting that when the dnode_sync() is done, dnode’s project usage would be accounted. But as there is no change in projid, so effectively, project quota upgrade task doesn't change anything. When actual projid is set on an object via `zfs project -p <projid> -s <file/dir>`, then object usage gets account-ed under the projid set. But usage for projid=0 (ZFS_DEFAULT_PROJID) underflows and becomes negative. Because quota update task moves usage from projid "0" to new projid set. Solution: dmu_objset_space_upgrade() for projectquota doesn't change the usage accounting, so skip it. This effectively avoids dirtying large number of dnodes, which is un-necessary. When object doesn't have projid set, means its ZFS_INVALID_PROJID, so change zpl_get_file_info() to consider projid as ZFS_INVALID_PROJID instead of ZFS_DEFAULT_PROJID=0. And skip updating usage for ZFS_INVALID_PROJID in do_*quota_update(). This effectively avoid the underflow of usage accounting on ZFS_DEFAULT_PROJID. Signed-off-by: Jitendra Patidar <jitendra.patidar@nutanix.com>
I am not really familiar with project quotas, so while from one side proposed solution kind of makes sense, from another I wonder what is the expected behavior for the case of project not being set. Should there really be a default project, and so ZFS should properly initialize it as part of the upgrade, which as I understand it does not do now, or as you have made it -- there should be no default project. Considering that on my pool where I never used projects I see reasonable space accounting for project 0, this change may be a POLA violation for people who might already use it. |
After project quota feature upgrade, new objects created by default would have project id 0 set on them and they gets accounted in project 0, so change as such not eliminating project 0 accounting. About upgrading old objects, you are correct about broken dmu_objset_space_upgrade(). Currently, upgrade task doesn't move any accounting, so it sort of no-op. This change is skipping dmu_objset_space_upgrade() for project quota, considering that its any way no-op. So, as such, this patch doesn't change the end impacts with respect to upgrade and it avoids dirtying lot of inodes un-necessary. |
@jsai20 I don't like the concept that objects created before upgrade are counted as ZFS_INVALID_PROJID, while after upgrade as project 0. It makes project 0 accounting useless, if it was ever intended otherwise. I haven't looked on the code in question and can't say out of my head how to better solve the migration, but if we go from assumption that project 0 should be valid, then upgrade fixing should be the way to go. |
ok @amotin . Let me also check bit more on correctly upgrading old objects to project 0. |
Purely theoretical, I guess it might be not updating the objects, but just accounting them. But I guess it might be impossible since the operation is not done atomically and we need to track what is already done. |
Upgrading to feature@project_quota, currently trigger upgrade task around project quota usage upgrade, which marks each inode dirty via, dmu_objset_id_quota_upgrade()->dmu_objset_id_quota_upgrade_cb()-> dmu_objset_space_upgrade().
Project quota space upgrade task marks each dnode dirty, expecting that when the dnode_sync() is done, dnode’s project usage would be accounted. But as there is no change in projid, so effectively, project quota upgrade task doesn't change anything.
When actual projid is set on an object via
zfs project -p <projid> -s <file/dir>
, then object usage gets account-ed under the projid set. But usage for projid=0 (ZFS_DEFAULT_PROJID) underflows and becomes negative. Because quota update task moves usage from projid "0" to new projid set.Solution:
dmu_objset_space_upgrade() for projectquota doesn't change the usage accounting, so skip it. This effectively avoids dirtying large number of dnodes, which is un-necessary.
When object doesn't have projid set, means its ZFS_INVALID_PROJID, so change zpl_get_file_info() to consider projid as ZFS_INVALID_PROJID instead of ZFS_DEFAULT_PROJID=0. And skip updating usage for ZFS_INVALID_PROJID in do_*quota_update(). This effectively avoid the underflow of usage accounting on ZFS_DEFAULT_PROJID.
Motivation and Context
Description
Problem:
Upgrading to feature@project_quota, currently trigger upgrade task around project quota usage upgrade, which marks each inode dirty via, dmu_objset_id_quota_upgrade()->dmu_objset_id_quota_upgrade_cb()-> dmu_objset_space_upgrade().
Project quota space upgrade task marks each dnode dirty, expecting that when the dnode_sync() is done, dnode’s project usage would be accounted. But as there is no change in projid, so effectively, project quota upgrade task doesn't change anything.
When actual projid is set on an object via
zfs project -p <projid> -s <file/dir>
, then object usage gets account-ed under the projid set. But usage for projid=0 (ZFS_DEFAULT_PROJID) underflows and becomes negative. Because quota update task moves usage from projid "0" to new projid set.Solution:
dmu_objset_space_upgrade() for projectquota doesn't change the usage accounting, so skip it. This effectively avoids dirtying large number of dnodes, which is un-necessary.
When object doesn't have projid set, means its ZFS_INVALID_PROJID, so change zpl_get_file_info() to consider projid as ZFS_INVALID_PROJID instead of ZFS_DEFAULT_PROJID=0. And skip updating usage for ZFS_INVALID_PROJID in do_*quota_update(). This effectively avoid the underflow of usage accounting on ZFS_DEFAULT_PROJID.
How Has This Been Tested?
Without fix:
With Fix:
Types of changes
Checklist:
Signed-off-by
.