Old kernels returned EINVAL if quota was off but we tried to manipulate
it anyway. Since
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=
8a36e408d40606e21cd4e2dd9601004a67b14868
this changed: now ENOTCONN is returned. This of course is a kernel API
compat breakage, but let's not make a fuss and just map EINVAL to
ENOTCONN to make it recognizable the same way everywhere.
Fixes: #15896
for (c = 0;; c++) {
if (ioctl(fd, BTRFS_IOC_QGROUP_CREATE, &args) < 0) {
- /* If quota is not enabled, we get EINVAL. Turn this into a recognizable error */
- if (errno == EINVAL)
- return -ENOPROTOOPT;
+ /* On old kernels if quota is not enabled, we get EINVAL. On newer kernels we get
+ * ENOTCONN. Let's always convert this to ENOTCONN to make this recognizable
+ * everywhere the same way. */
+
+ if (IN_SET(errno, EINVAL, ENOTCONN))
+ return -ENOTCONN;
if (errno == EBUSY && c < 10) {
(void) btrfs_quota_scan_wait(fd);
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (unsupported fs or dir not a subvolume): %m", i->path);
else if (r == -EROFS)
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (fs is read-only).", i->path);
- else if (r == -ENOPROTOOPT)
+ else if (r == -ENOTCONN)
log_debug_errno(r, "Couldn't adjust quota for subvolume \"%s\" (quota support is disabled).", i->path);
else if (r < 0)
q = log_error_errno(r, "Failed to adjust quota for subvolume \"%s\": %m", i->path);