mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2025-05-10 02:38:26 +03:00
Report default quotas via kernel interfaces
Ensure default user/group/project quotas are visible through quota tools and filesystem stats when no per-ID quota is configured. This maintains consistency between quota visibility and configured defaults. Signed-off-by: Ameer Hamza <ahamza@ixsystems.com> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Reviewed-by: Tony Hutter <hutter2@llnl.gov>
This commit is contained in:
parent
20705a8430
commit
9cb9a59e1c
@ -241,35 +241,40 @@ zfs_getquota(zfsvfs_t *zfsvfs, uid_t id, int isgroup, struct dqblk64 *dqp)
|
|||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
char buf[32];
|
char buf[32];
|
||||||
uint64_t usedobj, quotaobj;
|
uint64_t usedobj, quotaobj, defaultquota;
|
||||||
uint64_t quota, used = 0;
|
uint64_t quota, used = 0;
|
||||||
timespec_t now;
|
timespec_t now;
|
||||||
|
|
||||||
usedobj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT;
|
usedobj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT;
|
||||||
quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj;
|
quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj;
|
||||||
|
defaultquota = isgroup ? zfsvfs->z_defaultgroupquota :
|
||||||
|
zfsvfs->z_defaultuserquota;
|
||||||
|
|
||||||
|
if (zfsvfs->z_replay)
|
||||||
|
return (ENOENT);
|
||||||
|
|
||||||
if (quotaobj == 0 || zfsvfs->z_replay) {
|
|
||||||
error = ENOENT;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
(void) sprintf(buf, "%llx", (longlong_t)id);
|
(void) sprintf(buf, "%llx", (longlong_t)id);
|
||||||
if ((error = zap_lookup(zfsvfs->z_os, quotaobj,
|
if (quotaobj == 0) {
|
||||||
buf, sizeof (quota), 1, "a)) != 0) {
|
if (defaultquota == 0)
|
||||||
dprintf("%s(%d): quotaobj lookup failed\n",
|
return (ENOENT);
|
||||||
__FUNCTION__, __LINE__);
|
quota = defaultquota;
|
||||||
goto done;
|
} else {
|
||||||
|
error = zap_lookup(zfsvfs->z_os, quotaobj, buf, sizeof (quota),
|
||||||
|
1, "a);
|
||||||
|
if (error && (quota = defaultquota) == 0)
|
||||||
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* quota(8) uses bsoftlimit as "quoota", and hardlimit as "limit".
|
* quota(8) uses bsoftlimit as "quoota", and hardlimit as "limit".
|
||||||
* So we set them to be the same.
|
* So we set them to be the same.
|
||||||
*/
|
*/
|
||||||
dqp->dqb_bsoftlimit = dqp->dqb_bhardlimit = btodb(quota);
|
dqp->dqb_bsoftlimit = dqp->dqb_bhardlimit = btodb(quota);
|
||||||
error = zap_lookup(zfsvfs->z_os, usedobj, buf, sizeof (used), 1, &used);
|
error = zap_lookup(zfsvfs->z_os, usedobj, buf, sizeof (used), 1, &used);
|
||||||
if (error && error != ENOENT) {
|
if (error == ENOENT)
|
||||||
dprintf("%s(%d): usedobj failed; %d\n",
|
error = 0;
|
||||||
__FUNCTION__, __LINE__, error);
|
if (error)
|
||||||
goto done;
|
return (error);
|
||||||
}
|
|
||||||
dqp->dqb_curblocks = btodb(used);
|
dqp->dqb_curblocks = btodb(used);
|
||||||
dqp->dqb_ihardlimit = dqp->dqb_isoftlimit = 0;
|
dqp->dqb_ihardlimit = dqp->dqb_isoftlimit = 0;
|
||||||
vfs_timestamp(&now);
|
vfs_timestamp(&now);
|
||||||
@ -279,7 +284,6 @@ zfs_getquota(zfsvfs_t *zfsvfs, uid_t id, int isgroup, struct dqblk64 *dqp)
|
|||||||
* particularly useful.
|
* particularly useful.
|
||||||
*/
|
*/
|
||||||
dqp->dqb_btime = dqp->dqb_itime = now.tv_sec;
|
dqp->dqb_btime = dqp->dqb_itime = now.tv_sec;
|
||||||
done:
|
|
||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1068,15 +1068,19 @@ zfs_statfs_project(zfsvfs_t *zfsvfs, znode_t *zp, struct kstatfs *statp,
|
|||||||
if (err)
|
if (err)
|
||||||
return (err);
|
return (err);
|
||||||
|
|
||||||
if (zfsvfs->z_projectquota_obj == 0)
|
if (zfsvfs->z_projectquota_obj == 0) {
|
||||||
|
if (zfsvfs->z_defaultprojectquota == 0)
|
||||||
goto objs;
|
goto objs;
|
||||||
|
quota = zfsvfs->z_defaultprojectquota;
|
||||||
|
} else {
|
||||||
err = zap_lookup(zfsvfs->z_os, zfsvfs->z_projectquota_obj,
|
err = zap_lookup(zfsvfs->z_os, zfsvfs->z_projectquota_obj,
|
||||||
buf + offset, 8, 1, "a);
|
buf + offset, 8, 1, "a);
|
||||||
|
if (err && (quota = zfsvfs->z_defaultprojectquota) == 0) {
|
||||||
if (err == ENOENT)
|
if (err == ENOENT)
|
||||||
goto objs;
|
goto objs;
|
||||||
else if (err)
|
|
||||||
return (err);
|
return (err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err = zap_lookup(zfsvfs->z_os, DMU_PROJECTUSED_OBJECT,
|
err = zap_lookup(zfsvfs->z_os, DMU_PROJECTUSED_OBJECT,
|
||||||
buf + offset, 8, 1, &used);
|
buf + offset, 8, 1, &used);
|
||||||
@ -1102,15 +1106,21 @@ zfs_statfs_project(zfsvfs_t *zfsvfs, znode_t *zp, struct kstatfs *statp,
|
|||||||
statp->f_bavail = statp->f_bfree;
|
statp->f_bavail = statp->f_bfree;
|
||||||
|
|
||||||
objs:
|
objs:
|
||||||
if (zfsvfs->z_projectobjquota_obj == 0)
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
|
if (zfsvfs->z_projectobjquota_obj == 0) {
|
||||||
|
if (zfsvfs->z_defaultprojectobjquota == 0)
|
||||||
|
return (0);
|
||||||
|
quota = zfsvfs->z_defaultprojectobjquota;
|
||||||
|
} else {
|
||||||
err = zap_lookup(zfsvfs->z_os, zfsvfs->z_projectobjquota_obj,
|
err = zap_lookup(zfsvfs->z_os, zfsvfs->z_projectobjquota_obj,
|
||||||
buf + offset, 8, 1, "a);
|
buf + offset, 8, 1, "a);
|
||||||
|
if (err && (quota = zfsvfs->z_defaultprojectobjquota) == 0) {
|
||||||
if (err == ENOENT)
|
if (err == ENOENT)
|
||||||
return (0);
|
return (0);
|
||||||
else if (err)
|
|
||||||
return (err);
|
return (err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
err = zap_lookup(zfsvfs->z_os, DMU_PROJECTUSED_OBJECT,
|
err = zap_lookup(zfsvfs->z_os, DMU_PROJECTUSED_OBJECT,
|
||||||
buf, 8, 1, &used);
|
buf, 8, 1, &used);
|
||||||
|
Loading…
Reference in New Issue
Block a user