fstab-generator: fix spurious quota warning for xfs
Filesystems like xfs, btrfs, gfs2 and ocfs2 handle quotas internally and do not need external quotacheck/quotaon services. When usrquota or grpquota mount options are used in fstab for these filesystems, generator_hook_up_quotacheck() falls through to the !fstype_needs_quota() branch and emits a misleading warning that quotas are "not supported" when they actually work fine — the kernel handles them internally. Add fstype_has_internal_quota() to return early with a debug message, and adopt a tri-state return convention so the caller skips quotaon when quotacheck was not needed. The buggy code path was introduced in #24824 and #24880. Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
committed by
Luca Boccassi
parent
6695167aea
commit
b5d5362069
@@ -385,6 +385,17 @@ bool fstype_needs_quota(const char *fstype) {
|
||||
"f2fs");
|
||||
}
|
||||
|
||||
bool fstype_has_internal_quota(const char *fstype) {
|
||||
/* These filesystems have built-in quota support and do not need
|
||||
* external quotacheck/quotaon services - see the "nothing needed"
|
||||
* entries in fstype_needs_quota() above. */
|
||||
return STR_IN_SET(fstype,
|
||||
"xfs",
|
||||
"gfs2",
|
||||
"ocfs2",
|
||||
"btrfs");
|
||||
}
|
||||
|
||||
bool fstype_is_api_vfs(const char *fstype) {
|
||||
assert(fstype);
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ static inline int path_is_mount_point(const char *path) {
|
||||
|
||||
bool fstype_is_network(const char *fstype);
|
||||
bool fstype_needs_quota(const char *fstype);
|
||||
bool fstype_has_internal_quota(const char *fstype);
|
||||
bool fstype_is_api_vfs(const char *fstype);
|
||||
bool fstype_is_blockdev_backed(const char *fstype);
|
||||
bool fstype_is_ro(const char *fsype);
|
||||
|
||||
@@ -704,7 +704,7 @@ static int add_mount(
|
||||
if (r < 0) {
|
||||
if (r != -EOPNOTSUPP)
|
||||
return r;
|
||||
} else {
|
||||
} else if (r > 0) {
|
||||
r = generator_hook_up_quotaon(dest, where, target_unit);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
+10
-3
@@ -817,12 +817,18 @@ int generator_hook_up_quotacheck(
|
||||
|
||||
if (isempty(fstype) || streq(fstype, "auto"))
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Couldn't determine filesystem type for %s, quota cannot be activated", what);
|
||||
if (fstype_has_internal_quota(fstype)) {
|
||||
log_debug("%s handles quotas internally, skipping quotacheck/quotaon setup for %s", fstype, what);
|
||||
return 0;
|
||||
}
|
||||
if (!fstype_needs_quota(fstype))
|
||||
return log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Quota was requested for %s, but not supported, ignoring: %s", what, fstype);
|
||||
|
||||
/* quotacheck unit for system root */
|
||||
if (path_equal(where, "/"))
|
||||
return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_ROOT_SERVICE);
|
||||
if (path_equal(where, "/")) {
|
||||
r = generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_ROOT_SERVICE);
|
||||
return r < 0 ? r : 1;
|
||||
}
|
||||
|
||||
r = unit_name_path_escape(where, &instance);
|
||||
if (r < 0)
|
||||
@@ -838,7 +844,8 @@ int generator_hook_up_quotacheck(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to make unit name from path '%s': %m", where);
|
||||
|
||||
return generator_add_symlink_full(dir, where_unit, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_SERVICE, instance);
|
||||
r = generator_add_symlink_full(dir, where_unit, "wants", SYSTEM_DATA_UNIT_DIR "/" SPECIAL_QUOTACHECK_SERVICE, instance);
|
||||
return r < 0 ? r : 1;
|
||||
}
|
||||
|
||||
int generator_hook_up_quotaon(
|
||||
|
||||
Reference in New Issue
Block a user