mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2026-05-22 10:37:35 +03:00
Fix sa_add_projid to lookup and update SA_ZPL_DXATTR (avoid DXATTR loss) (#16288)
sa_add_projid() gets called via zfs_setattr() for setting project id on old file/dir, which were created before upgrading to project quota feature. This function does lookup for all possible SA and update them all together along with project ID at needed fixed offset. But its missing lookup and update of SA_ZPL_DXATTR, effectively it losses SA_ZPL_DXATTR. Closes #16287 Signed-off-by: Jitendra Patidar <jitendra.patidar@nutanix.com> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Rob Norris <rob.norris@klarasystems.com>
This commit is contained in:
+56
-26
@@ -1501,6 +1501,42 @@ sa_lookup(sa_handle_t *hdl, sa_attr_type_t attr, void *buf, uint32_t buflen)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return size of an attribute
|
||||
*/
|
||||
|
||||
static int
|
||||
sa_size_locked(sa_handle_t *hdl, sa_attr_type_t attr, int *size)
|
||||
{
|
||||
sa_bulk_attr_t bulk;
|
||||
int error;
|
||||
|
||||
bulk.sa_data = NULL;
|
||||
bulk.sa_attr = attr;
|
||||
bulk.sa_data_func = NULL;
|
||||
|
||||
ASSERT(hdl);
|
||||
ASSERT(MUTEX_HELD(&hdl->sa_lock));
|
||||
if ((error = sa_attr_op(hdl, &bulk, 1, SA_LOOKUP, NULL)) != 0) {
|
||||
return (error);
|
||||
}
|
||||
*size = bulk.sa_size;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sa_size(sa_handle_t *hdl, sa_attr_type_t attr, int *size)
|
||||
{
|
||||
int error;
|
||||
|
||||
mutex_enter(&hdl->sa_lock);
|
||||
error = sa_size_locked(hdl, attr, size);
|
||||
mutex_exit(&hdl->sa_lock);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
#ifdef _KERNEL
|
||||
int
|
||||
sa_lookup_uio(sa_handle_t *hdl, sa_attr_type_t attr, zfs_uio_t *uio)
|
||||
@@ -1623,6 +1659,19 @@ sa_add_projid(sa_handle_t *hdl, dmu_tx_t *tx, uint64_t projid)
|
||||
if (err != 0 && err != ENOENT)
|
||||
goto out;
|
||||
|
||||
char *dxattr_obj = NULL;
|
||||
int dxattr_size = 0;
|
||||
err = sa_size_locked(hdl, SA_ZPL_DXATTR(zfsvfs), &dxattr_size);
|
||||
if (err != 0 && err != ENOENT)
|
||||
goto out;
|
||||
if (dxattr_size != 0) {
|
||||
dxattr_obj = vmem_alloc(dxattr_size, KM_SLEEP);
|
||||
err = sa_lookup_locked(hdl, SA_ZPL_DXATTR(zfsvfs), dxattr_obj,
|
||||
dxattr_size);
|
||||
if (err != 0 && err != ENOENT)
|
||||
goto out;
|
||||
}
|
||||
|
||||
zp->z_projid = projid;
|
||||
zp->z_pflags |= ZFS_PROJID;
|
||||
links = ZTONLNK(zp);
|
||||
@@ -1674,6 +1723,11 @@ sa_add_projid(sa_handle_t *hdl, dmu_tx_t *tx, uint64_t projid)
|
||||
zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP;
|
||||
}
|
||||
|
||||
if (dxattr_obj) {
|
||||
SA_ADD_BULK_ATTR(attrs, count, SA_ZPL_DXATTR(zfsvfs),
|
||||
NULL, dxattr_obj, dxattr_size);
|
||||
}
|
||||
|
||||
VERIFY(dmu_set_bonustype(db, DMU_OT_SA, tx) == 0);
|
||||
VERIFY(sa_replace_all_by_template_locked(hdl, attrs, count, tx) == 0);
|
||||
if (znode_acl.z_acl_extern_obj) {
|
||||
@@ -1688,6 +1742,8 @@ out:
|
||||
mutex_exit(&hdl->sa_lock);
|
||||
kmem_free(attrs, sizeof (sa_bulk_attr_t) * ZPL_END);
|
||||
kmem_free(bulk, sizeof (sa_bulk_attr_t) * ZPL_END);
|
||||
if (dxattr_obj)
|
||||
vmem_free(dxattr_obj, dxattr_size);
|
||||
return (err);
|
||||
}
|
||||
#endif
|
||||
@@ -2057,32 +2113,6 @@ sa_update(sa_handle_t *hdl, sa_attr_type_t type,
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return size of an attribute
|
||||
*/
|
||||
|
||||
int
|
||||
sa_size(sa_handle_t *hdl, sa_attr_type_t attr, int *size)
|
||||
{
|
||||
sa_bulk_attr_t bulk;
|
||||
int error;
|
||||
|
||||
bulk.sa_data = NULL;
|
||||
bulk.sa_attr = attr;
|
||||
bulk.sa_data_func = NULL;
|
||||
|
||||
ASSERT(hdl);
|
||||
mutex_enter(&hdl->sa_lock);
|
||||
if ((error = sa_attr_op(hdl, &bulk, 1, SA_LOOKUP, NULL)) != 0) {
|
||||
mutex_exit(&hdl->sa_lock);
|
||||
return (error);
|
||||
}
|
||||
*size = bulk.sa_size;
|
||||
|
||||
mutex_exit(&hdl->sa_lock);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
sa_bulk_lookup_locked(sa_handle_t *hdl, sa_bulk_attr_t *attrs, int count)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user