On Mon, Mar 02, 2009 at 01:06:32PM +0000, Iain Hibbert wrote: | [when the current directory is in a unionfs mount] | | Ok I found the root cause, the fix might need consideration :) | | The problem is in libc/gen/opendir.c - fts(3) uses the internal | __opendir2() entry point and always passes the DTF_REWIND flag which | causes a pause/rewind halfway through a unionfs scan because there is some | special handling for cases when a fchdir() is to be made according to the | comment. | | Because fts(3) is not always available, it is added to the tools build but | lacking the NETBSD_SOURCE definition causing the __opendir2() call to be | translated into the standard opendir() expected in the host libc. | | Our libc opendir (dating from CSRG sync in 94) is a stub call, comprising: | | return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); | | and so the essential difference is the lack of the DTF_REWIND flag. If I | add DTF_REWIND to that (as below) and rebuild libc, then | "/usr/tools/bin/nbmtree -c" works fine in a unionfs directory. | | Now, DTF_REWIND is only required in a unionfs mount situtation (I think) | but it is present for the nfs case also and so adding it to default | opendir() call might not be correct (but fts always uses it anyway) | | Thoughts? | | iain | | --- /usr/src/lib/libc/gen/opendir.c 2008-01-10 09:49:04.000000000 +0000 | +++ src/lib/libc/gen/opendir.c 2009-03-02 10:54:30.000000000 +0000 | @@ -66,7 +66,7 @@ opendir(const char *name) | | _DIAGASSERT(name != NULL); | | - return (__opendir2(name, DTF_HIDEW|DTF_NODUP)); | + return (__opendir2(name, DTF_HIDEW|DTF_NODUP|DTF_REWIND)); | } | | DIR * I think your fix will only resolve the "host libc" problem when building on a NetBSD-current system with the fix, and not other BSD-derived implementations of opendir() without the fix. The patch may be too much of a "sledgehammer" approach; it effectively forces the DTF_REWIND functionality upon all callers of opendir() that traverse NFS or union file systems. This may be a "good thing" -- correctness over performance. Further consideration of the ramifications is required. On the other hand, it makes unnecessary the "backdoor" call to __opendir2() that fts_build() is using. I haven't checked if there's other callers within the tree using that API. cheers, Luke.
Attachment:
pgp7riQ8vDW0p.pgp
Description: PGP signature