When files on an upper layer of the union stack are removed we need to
white-out the removed filename.

Signed-off-by: Jan Blunck <[EMAIL PROTECTED]>
---
 fs/namei.c |   46 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 44 insertions(+), 2 deletions(-)

--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2253,6 +2253,13 @@ do_last:
 
        /* Negative dentry, just create the file */
        if (!path.dentry->d_inode || S_ISWHT(path.dentry->d_inode->i_mode)) {
+               if (path.dentry->d_parent != dir) {
+                       dput_path(&path, nd);
+                       path.dentry = __lookup_hash_kern(&nd->last, dir, nd);
+                       path.mnt = nd->mnt;
+                       goto do_last;
+               }
+
                error = open_namei_create(nd, &path, flag, mode);
                if (error)
                        goto exit;
@@ -2373,6 +2380,16 @@ int lookup_create(struct nameidata *nd, 
 {
        int err = -EEXIST;
 
+       if (is_unionized(nd->dentry, nd->mnt)) {
+               err = union_relookup_topmost(nd, nd->flags & ~LOOKUP_PARENT);
+               if (err) {
+                       /* FIXME: This really sucks */
+                       mutex_lock_nested(&nd->dentry->d_inode->i_mutex,
+                                         I_MUTEX_PARENT);
+                       goto fail;
+               }
+       }
+
        mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
        /*
         * Yucky last component or no last component at all?
@@ -2391,6 +2408,16 @@ int lookup_create(struct nameidata *nd, 
        if (err)
                goto fail;
 
+       /* Special case - we found a whiteout */
+       if (path->dentry->d_inode && S_ISWHT(path->dentry->d_inode->i_mode)) {
+               if (path->dentry->d_parent != nd->dentry) {
+                       dput_path(path, nd);
+                       path->dentry = __lookup_hash_kern(&nd->last, nd->dentry,
+                                                         nd);
+                       path->mnt = nd->mnt;
+               }
+       }
+
        /*
         * Special case - lookup gave negative, but... we had foo/bar/
         * From the vfs_mknod() POV we just have a negative dentry -
@@ -2682,6 +2709,15 @@ static int do_whiteout(struct nameidata 
        if (isdir && !directory_is_empty(path->dentry, path->mnt))
                goto out;
 
+       mutex_unlock(&nd->dentry->d_inode->i_mutex);
+       err = union_relookup_topmost(nd, nd->flags & ~LOOKUP_PARENT);
+       if (err) {
+               mutex_lock_nested(&nd->dentry->d_inode->i_mutex,
+                                 I_MUTEX_PARENT);
+               goto out;
+       }
+       mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+
        /* safe the name for a later lookup */
        err = -ENOMEM;
        name.name = kmalloc(dentry->d_name.len, GFP_KERNEL);
@@ -3012,7 +3048,10 @@ static long do_rmdir(int dfd, const char
        error = hash_lookup_union(&nd, &nd.last, &path);
        if (error)
                goto exit2;
-       error = vfs_rmdir(nd.dentry->d_inode, path.dentry);
+       if (is_unionized(nd.dentry, nd.mnt))
+               error = do_whiteout(&nd, &path, 1);
+       else
+               error = vfs_rmdir(nd.dentry->d_inode, path.dentry);
        dput_path(&path, &nd);
 exit2:
        mutex_unlock(&nd.dentry->d_inode->i_mutex);
@@ -3091,7 +3130,10 @@ static long do_unlinkat(int dfd, const c
                inode = path.dentry->d_inode;
                if (inode)
                        atomic_inc(&inode->i_count);
-               error = vfs_unlink(nd.dentry->d_inode, path.dentry);
+               if (is_unionized(nd.dentry, nd.mnt))
+                       error = do_whiteout(&nd, &path, 0);
+               else
+                       error = vfs_unlink(nd.dentry->d_inode, path.dentry);
        exit2:
                dput_path(&path, &nd);
        }

-- 

-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to