On btrfs, trying to disable FS_NOCOW_FL on a file that has data
already written will fail silently without reporting an error. To
catch such cases, let's query the flags again if the IOC_SETFLAGS
ioctl() succeeds to make sure the flags we tried to configure we're
actually accepted by the kernel.
}
if (ioctl(fd, FS_IOC_SETFLAGS, &new_attr) >= 0) {
- if (ret_previous)
- *ret_previous = old_attr;
- if (ret_final)
- *ret_final = new_attr;
- return 1;
+ unsigned attr;
+
+ /* Some filesystems (BTRFS) silently fail when a flag cannot be set. Let's make sure our
+ * changes actually went through by querying the flags again and verifying they're equal to
+ * the flags we tried to configure. */
+
+ if (ioctl(fd, FS_IOC_GETFLAGS, &attr) < 0)
+ return -errno;
+
+ if (new_attr == attr) {
+ if (ret_previous)
+ *ret_previous = old_attr;
+ if (ret_final)
+ *ret_final = new_attr;
+ return 1;
+ }
+
+ /* Trigger the fallback logic. */
+ errno = EINVAL;
}
if ((errno != EINVAL && !ERRNO_IS_NOT_SUPPORTED(errno)) ||