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

Reply via email to