[Bug 271925] chflags(1) fails to remove uarch flag with hardlinked files (ZFS)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 23 Jun 2023 01:03:14 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271925 --- Comment #5 from Jamie Landeg-Jones <jamie@catflap.org> --- (In reply to Stefan Eßer from comment #1) TThanks for the quick response! Apologies for the late reply, I haven't been at home for the last 2 weeks, so online time is more sporadic. The problem with /bin/chflags is more generic - it's just that this ZFS quirk highlighted the difference. The more general case is that whilst /bin/chflags will not modify a file if the modification isn't needed, the logic fails when files are hardlinked... Though fixing this may be not worth the effort, it's just pedantry at the end of the day, and might even be considered "correct" behaviour - i.e. "if a file is hardlinked then expect it to be accessed for each link found." Anyway, if it was fixed, I think filtering out duplicate inodes would be the cleanest and most efficient solution. For example, (and I forgot to mention in my post, sorry) I did a quick chflags(2) syscall wrapper code to set the flags on a file to 0: #include <stdio.h> #include <unistd.h> #include <string.h> #include <err.h> #include <errno.h> #include <sys/stat.h> int main (int argc, char **argv) { while (*++argv != NULL) if (lchflags (*argv, 0) == -1) warnx("%s: %s", *argv, strerror (errno)); } On tmpfs, UFS, and ZFS,touching a test file, and setting some flags, then running the above program resets the flags, and updates ctime, as expected. On all three filesystems, running it again always updates the ctime on all 3 filesystems, but on ZFS it switches on uarch. Running it again switches off uarch. Using /bin/chflags, on all three filesystems, running it again doesn't update the ctime, or on ZFS, toggle the uarch. So the consensus seems to be "chflags(2)" updates regardless, whilst /bin/chflags will stat the file and only make the chflags(2) call if necessary (of course, this gets tripped up in the hardlinked case mentioned in this bug report) > This seems to be caused by ZFS collecting multiple flag updates and by effectively mapping the setting of flags to toggling of flags. I don't think it's that - try the above test program - whilst filesystems have the logic "any change updates the ctime", ZFS has the additional "any change other than one that unsets uarch will also set uarch" - this seems to break down because when you attempt to remove uarch on a file that doesn't have uarch set, this fails the "we are removing uarch" logic. This, I suspect, should be fixed in ZFS. > but I guess that the second call sees that the new attributes are identical to the (already altered) current attributes of the file and then marks it to not need a vnode update on stable storage. I think it's the other way around. The chflags system call (and therefore ZFS) run the code even if the attributes are identical. /bin/chflags doesn't run the call if the new attributes are identical, but this logic fails if a file is hardlinked, because the initial stat shows "both" need to be updated, There are also consistencies in chmod(1) - chmod on ZFS causes an update even if no actual chmod takes place - i haven't looked more closely at this, but this opens up a whole can of worms. I guess the first question should be "If any metdata change is attempted on a file that doesn't actually result in the data being changed (because it's "changing" it to the value it already has) then whose responsibility is it to not attempt the change, and consequently update ctime? Is it userland, or is it the syscall, or is it the filesystem code itself? Cheers, Jamie -- You are receiving this mail because: You are the assignee for the bug.