Shaya Potter wrote:
Shaya Potter wrote:
Shaya Potter wrote:
Josef Sipek wrote:
On Wed, Jan 17, 2007 at 01:04:22PM -0500, Shaya Potter wrote:
Josef Sipek wrote:
On a more general level, what has higher priority a whiteout or a file?
whiteout, if it's 'valid' (i.e. serves a purpose) to exist, as all my code does is skip whiteout searching if it doesn't matter if it exists.
If whiteout is the higher priority object, then readdir should not display
the file created under these circumstances. => pushing the "problem" to
readdir :)

true, though readdir could ignore it in the right situations as well :)

I looked at unionfs_readdir() and am unsure how to get it to ignore whiteouts that can be ignored, it should be in unionfs_filldir(), but unsure how to do it (never really bothered much w/ the readdir code before as it mostly worked just fine).

quick and dirty patch to handle readdir() and helper for rmdir(), unsure if its correct, haven't tested throughly

bug in the quick and dirty patch.

it ignored all whiteouts in the bend dir, this means it didn't include the opaque whiteout in the readdir list, and hence didn't delete it and hence the vfs_rmdir() failed due to it not being empty.

this patch adds a check, in readdir_util_callback(), if the whiteout is an opaque mark, and if not pass it through to found, so it will be in the list so it can be removed by delete_whiteouts.
Index: dirfops.c
===================================================================
RCS file: /home/spotter/unionfs/2/unionfs/unionfs/dirfops.c,v
retrieving revision 1.27
diff -u -r1.27 dirfops.c
--- dirfops.c   5 Jan 2007 04:05:56 -0000       1.27
+++ dirfops.c   17 Jan 2007 20:26:21 -0000
@@ -59,6 +59,16 @@
                is_wh_entry = 1;
        }
 
+       /* If we found a whiteout in a directory where it doesn't matter
+        * i.e. the last branch the dir exists in, ignore it, as otherwise
+        * it will whiteout a file that could exist in this dir
+        */
+
+       if (is_wh_entry 
+           && (buf->rdstate->uds_bindex == buf->rdstate->uds_bend)) {
+               goto out;
+       }
+       
        found = find_filldir_node(buf->rdstate, name, namelen);
 
        if (found)
@@ -131,6 +141,7 @@
                }
        }
        bend = fbend(file);
+       uds->uds_bend = bend;
 
        while (uds->uds_bindex <= bend) {
                hidden_file = ftohf_index(file, uds->uds_bindex);
Index: dirhelper.c
===================================================================
RCS file: /home/spotter/unionfs/2/unionfs/unionfs/dirhelper.c,v
retrieving revision 1.33
diff -u -r1.33 dirhelper.c
--- dirhelper.c 28 Dec 2006 02:48:47 -0000      1.33
+++ dirhelper.c 18 Jan 2007 02:35:41 -0000
@@ -158,6 +158,7 @@
                                 loff_t offset, u64 ino, unsigned int d_type)
 {
        int err = 0;
+       int whdir = 0;
        struct unionfs_rdutil_callback *buf =
            (struct unionfs_rdutil_callback *)dirent;
        int whiteout = 0;
@@ -175,6 +176,18 @@
                namelen -= WHLEN;
                name += WHLEN;
                whiteout = 1;
+               if (!strncmp(name, UNIONFS_DIR_OPAQUE_NAME, namelen))
+                       whdir = 1;
+       }
+
+       /* If we found a whiteout in a directory where it doesn't matter
+        * i.e. the last branch the dir exists in, ignore it, as otherwise
+        * it will whiteout a file that could exist in this dir
+        */
+
+       if (!whdir && whiteout 
+           && (buf->rdstate->uds_bindex == buf->rdstate->uds_bend)) {
+               goto out;
        }
 
        found = find_filldir_node(buf->rdstate, name, namelen);
@@ -235,6 +248,7 @@
                err = -ENOMEM;
                goto out;
        }
+       buf->rdstate->uds_bend = bend;
 
        /* Process the hidden directories with rdutil_callback as a filldir. */
        for (bindex = bstart; bindex <= bend; bindex++) {
_______________________________________________
unionfs mailing list
[email protected]
http://www.fsl.cs.sunysb.edu/mailman/listinfo/unionfs

Reply via email to