-
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
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. |
I double checked it. Upgrade neither updates the object with project 0, nor updates the usage accounting for project 0. For correctly updating accounting the old objects in project 0 (ZFS_DEFAULT_PROJID), it need to re-layout SA's on object and for that it need to set project id 0 via sa_add_projid() interface. I explored doing it, but its not feasible to use this SA layer function sa_add_projid() in dmu_objset_space_upgrade(). It needs SA handle. To get the SA handle, need to do zfs_zget() on object, which needs zfsvfs. zfsvfs is not initialised, when dmu_objset_space_update() gets called during mount. As such I don't see any real benefits of usage accounting for project 0, neither for objects created before upgrade nor for objects created after grade. Its just un-necessary work of dirtying inodes in upgrade without any real benefits . I would update a patch which doesn't account usage for project 0. |
31435b2
to
aa2f3df
Compare
@jsai20 It does not build on FreeBSD:
It looks like excessively verbose debug that should be removed. |
aa2f3df
to
d37f4e4
Compare
Updated new patch Replacing "current->comm" with getcomm() and "current->pid()" with getpid(). |
The building seems going better now, but why do you think these messages are useful enough to be seen on a console of every system? IMO its a mess. |
Ok. I would remove them. |
d37f4e4
to
638904d
Compare
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 in projid=0 (ZFS_DEFAULT_PROJID). 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. Usage accounting for projid=0 (ZFS_DEFAULT_PROJID) doesn't give any real benefit and it can't be updated for objects created before project_quota feature upgrade, so skip updating usage for ZFS_DEFAULT_PROJID in do_*quota_update() both for old and new objects. Effectively no usage accounting for ZFS_DEFAULT_PROJID. Signed-off-by: Jitendra Patidar <jitendra.patidar@nutanix.com>
638904d
to
0035e10
Compare
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
.