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>