lkml.org 
[lkml]   [2007]   [Jul]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC 22/26] union-mount: white-out changes for copy-on-open
    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 <jblunck@suse.de>
    ---
    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-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2007-07-30 18:27    [W:4.302 / U:0.084 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site