Fix projid accounting for xattr objects

zpool upgraded with 'feature@project_quota' needs re-layout of SA's
to fix the SA_ZPL_PROJID at SA_PROJID_OFFSET (128). Its necessary for
the correct accounting of object usage against its projid.
Old object (created before upgrade) when gets a projid assigned, its
SA gets re-layout via sa_add_projid(). If object has xattr dir, SA
of xattr dir also gets re-layout. But SA re-layout of xattr objects
inside a xattr dir is not done.

Fix zfs_setattr_dir() to re-layout SA's on xattr objects, when setting
projid on old xattr object (created before upgrade).

Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Jitendra Patidar <jitendra.patidar@nutanix.com>
Closes #16355
Closes #16356
This commit is contained in:
Jitendra Patidar
2024-08-15 06:29:19 +05:30
committed by GitHub
parent 244ea5c488
commit d2ccc21552
2 changed files with 37 additions and 10 deletions
+20 -8
View File
@@ -1789,24 +1789,36 @@ zfs_setattr_dir(znode_t *dzp)
&gid, sizeof (gid));
}
if (zp->z_projid != dzp->z_projid) {
uint64_t projid = dzp->z_projid;
if (zp->z_projid != projid) {
if (!(zp->z_pflags & ZFS_PROJID)) {
zp->z_pflags |= ZFS_PROJID;
SA_ADD_BULK_ATTR(bulk, count,
SA_ZPL_FLAGS(zfsvfs), NULL, &zp->z_pflags,
sizeof (zp->z_pflags));
err = sa_add_projid(zp->z_sa_hdl, tx, projid);
if (unlikely(err == EEXIST)) {
err = 0;
} else if (err != 0) {
goto sa_add_projid_err;
} else {
projid = ZFS_INVALID_PROJID;
}
}
zp->z_projid = dzp->z_projid;
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PROJID(zfsvfs),
NULL, &zp->z_projid, sizeof (zp->z_projid));
if (projid != ZFS_INVALID_PROJID) {
zp->z_projid = projid;
SA_ADD_BULK_ATTR(bulk, count,
SA_ZPL_PROJID(zfsvfs), NULL, &zp->z_projid,
sizeof (zp->z_projid));
}
}
sa_add_projid_err:
mutex_exit(&dzp->z_lock);
if (likely(count > 0)) {
err = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
dmu_tx_commit(tx);
} else if (projid == ZFS_INVALID_PROJID) {
dmu_tx_commit(tx);
} else {
dmu_tx_abort(tx);
}