Hello, the FTS module does not seem to be ready for a remount during traversal. As a minimal example we can take the following situation:
https://bugzilla.redhat.com/show_bug.cgi?id=501848#c20 Descending a directory triggers a shrinkable mount which implies a change of the device number. However FTS data structures keep the old value of device number, not reflecting this change. And later, when returning back to the same directory through "..", fts_safe_changedir() fails for no good reason (caused by std_dev mismatch). The attached patch seems to solve the problem by calling fstatat() again after opening a directory (and updating the device number). The patch is not supposed to be applied as-is. It's more likely an idea how the problem could be solved. Maybe something like that might be available via an option to keep the original behavior unchanged (and eventually gain better performance in some cases). Another approach is a workaround proposed by Ondra: https://bugzilla.redhat.com/attachment.cgi?id=354464 Any idea how to solve the problem? Thanks in advance! Kamil
diff --git a/lib/fts.c b/lib/fts.c index 40a837e..1394693 100644 --- a/lib/fts.c +++ b/lib/fts.c @@ -1269,6 +1269,21 @@ fts_build (register FTS *sp, int type) if (cur->fts_info == FTS_NSOK) cur->fts_info = fts_stat(sp, cur, false); + else /* TODO: check for an option here */ { + FTSENT tmp = *cur; + fts_stat (sp, &tmp, false); + if (cur->fts_statp->st_ino == tmp.fts_statp->st_ino + && cur->fts_statp->st_dev != tmp.fts_statp->st_dev) { + LEAVE_DIR (sp, cur, "4"); + cur->fts_statp->st_dev = tmp.fts_statp->st_dev; + if (! enter_dir (sp, cur)) + { + __set_errno (ENOMEM); + return NULL; + } + } + } + /* * Nlinks is the number of possible entries of type directory in the * directory if we're cheating on stat calls, 0 if we're not doing