I have attached a log file. Note I have ran this on local file system where rm -rf works not on Network file system (I was running into some issues which I am trying to resolve ..). However, this run also gives us lot of information and demonstrates that even though rm -rf works, it is does not seem to be POSIX compliant.
Thus any filesystem that reflects updates only on open() will break. If you also want me to run on a filesystem that breaks rm -rf, I will go through the pain of setting it up ? Let me know if you need any other information. (Btw. The file system that I was talking about is Hgfs (Host/ Guest file system) located at http://open-vm-tools.sourceforge.net/) lstat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 newfstatat(AT_FDCWD, "parent", {st_mode=03, st_size=343597383680, ...}, AT_SYMLINK_NOFOLLOW) = 0 unlinkat(AT_FDCWD, "parent", 0) = -1 EISDIR (Is a directory) openat(AT_FDCWD, "parent", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW) = 3 fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 fcntl(3, F_GETFL) = 0x28800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW) fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 getdents(3, /* 3 entries */, 8192) = 80 openat(3, "Child", O_RDONLY|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW) = 4 fstat(4, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 fstat(4, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 fcntl(4, F_GETFL) = 0x28800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW) fcntl(4, F_SETFD, FD_CLOEXEC) = 0 close(3) = 0 fcntl(4, F_GETFD) = 0x1 (flags FD_CLOEXEC) fstat(4, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 getdents(4, /* 2 entries */, 8192) = 48 getdents(4, /* 0 entries */, 8192) = 0 fcntl(4, F_GETFD) = 0x1 (flags FD_CLOEXEC) /* Open 'parent' directory */ openat(4, "..", O_RDONLY) = 3 /* Close 'Child' directory */ close(4) = 0 fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 /* Remove 'Child' directory*/ unlinkat(3, "Child", AT_REMOVEDIR) = 0 fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 fcntl(3, F_GETFL) = 0x8000 (flags O_RDONLY|O_LARGEFILE) fcntl(3, F_SETFD, FD_CLOEXEC) = 0 fstat(3, {st_mode=S_IFDIR|0755, st_size=80, ...}) = 0 /* Now get directory entries of 'parent'. There are no guarantees that updates should have been reflected here, but rm -rf assumes this! Updates are guaranteed to be reflects only on next openat() */ getdents(3, /* 2 entries */, 8192) = 48 getdents(3, /* 0 entries */, 8192) = 0 fcntl(3, F_GETFD) = 0x1 (flags FD_CLOEXEC) close(3) = 0 unlinkat(AT_FDCWD, "parent", AT_REMOVEDIR) = 0 close(0) = 0 close(1) = 0 close(2) = 0 exit_group(0) = ? On Wed, Aug 26, 2009 at 11:09 AM, Jim Meyering <[email protected]> wrote: > shailesh jain wrote: > > On Wed, Aug 26, 2009 at 2:36 AM, Jim Meyering <[email protected]> wrote: > ... > >> If you can demonstrate an actual failure, or even that rm is > >> merely performing unnecessary unlinkat calls, please provide details. > > > > Thanks for consideration. I will describe how 'rm -rf parent' fails: > > --- > > mkdir parent > > cd parent > > mkdir Child > > cd .. > > cd .. > ... > > > > Now, unlinkat() will delete child directory on unlinkat() and then do > dirp = > > fdopendir(parent_fd). Then it will perform readdir() calls on parent just > to > > find out that 'Child' directory is still present and it will mark > 'Child' > > directory is unremovable... (and I think it subsequently tries to remove > > 'Child' and doesn't find 'Child' and terminates with ENOENT when I use rm > > -riv) > > > > I read from the posix semantics that fdopendir() should behave same as > > opendir(), however given that the VFS layer and the underlying filesystem > > cannot distinguish between open() and opendir(), I do not see any > reasonable > > way to do that. Thus relying on readdir() to reflect updates made by > > unlinkat() is broken (although local file systems tend to reflect this > very > > well). > > I understood your theoretical description the first time. > Please provide details showing precisely how GNU rm is misbehaving. > Either step through with a debugger or show the system calls e.g., from > strace: > > Please describe your file system (client and server system types, if > they're different) and give the output of your "strace -o log rm -riv > parent" > command as well as the "log" file that creates. > > If rm fails in a way that is contrary to POSIX, we'd > all like to know. > > Also, please be sure to use rm from coreutils-7.5. >
log
Description: Binary data
