lkml.org 
[lkml]   [2007]   [Sep]   [25]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 08/25] Unionfs: lower nameidata support for nfsv4
    Date
    Pass nameidata structures as needed to the lower file system, support
    LOOKUP_ACCESS/OPEN intents. This makes unionfs work on top of nfsv4.

    Signed-off-by: Erez Zadok <ezk@cs.sunysb.edu>
    Acked-by: Josef 'Jeff' Sipek <jsipek@cs.sunysb.edu>
    ---
    fs/unionfs/dentry.c | 11 +++++++++--
    fs/unionfs/inode.c | 8 +++++++-
    fs/unionfs/lookup.c | 20 +++++++++++++++++---
    3 files changed, 33 insertions(+), 6 deletions(-)

    diff --git a/fs/unionfs/dentry.c b/fs/unionfs/dentry.c
    index b21f1e3..52bcb18 100644
    --- a/fs/unionfs/dentry.c
    +++ b/fs/unionfs/dentry.c
    @@ -156,8 +156,15 @@ static bool __unionfs_d_revalidate_one(struct dentry *dentry,
    if (!lower_dentry || !lower_dentry->d_op
    || !lower_dentry->d_op->d_revalidate)
    continue;
    - if (!lower_dentry->d_op->d_revalidate(lower_dentry,
    - &lowernd))
    + /*
    + * Don't pass nameidata to lower file system, because we
    + * don't want an arbitrary lower file being opened or
    + * returned to us: it may be useless to us because of the
    + * fanout nature of unionfs (cf. file/directory open-file
    + * invariants). We will open lower files as and when needed
    + * later on.
    + */
    + if (!lower_dentry->d_op->d_revalidate(lower_dentry, NULL))
    valid = false;
    }

    diff --git a/fs/unionfs/inode.c b/fs/unionfs/inode.c
    index f8b2c88..7ee4760 100644
    --- a/fs/unionfs/inode.c
    +++ b/fs/unionfs/inode.c
    @@ -27,6 +27,7 @@ static int unionfs_create(struct inode *parent, struct dentry *dentry,
    struct dentry *lower_parent_dentry = NULL;
    char *name = NULL;
    int valid = 0;
    + struct nameidata lower_nd;

    unionfs_read_lock(dentry->d_sb);
    unionfs_lock_dentry(dentry);
    @@ -113,7 +114,12 @@ static int unionfs_create(struct inode *parent, struct dentry *dentry,
    goto out;
    }

    - err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode, nd);
    + err = init_lower_nd(&lower_nd, LOOKUP_CREATE);
    + if (err < 0)
    + goto out;
    + err = vfs_create(lower_parent_dentry->d_inode, lower_dentry, mode,
    + &lower_nd);
    + release_lower_nd(&lower_nd, err);

    if (!err) {
    err = PTR_ERR(unionfs_interpose(dentry, parent->i_sb, 0));
    diff --git a/fs/unionfs/lookup.c b/fs/unionfs/lookup.c
    index 963d622..2109714 100644
    --- a/fs/unionfs/lookup.c
    +++ b/fs/unionfs/lookup.c
    @@ -583,6 +583,11 @@ void update_bstart(struct dentry *dentry)
    * Inside that nd structure, this function may also return an allocated
    * struct file (for open intents). The caller, when done with this nd, must
    * kfree the intent file (using release_lower_nd).
    + *
    + * XXX: this code, and the callers of this code, should be redone using
    + * vfs_path_lookup() when (1) the nameidata structure is refactored into a
    + * separate intent-structure, and (2) open_namei() is broken into a VFS-only
    + * function and a method that other file systems can call.
    */
    int init_lower_nd(struct nameidata *nd, unsigned int flags)
    {
    @@ -597,11 +602,16 @@ int init_lower_nd(struct nameidata *nd, unsigned int flags)
    #endif /* ALLOC_LOWER_ND_FILE */

    memset(nd, 0, sizeof(struct nameidata));
    + if (!flags)
    + return err;

    switch (flags) {
    case LOOKUP_CREATE:
    - nd->flags = LOOKUP_CREATE;
    - nd->intent.open.flags = FMODE_READ | FMODE_WRITE | O_CREAT;
    + nd->intent.open.flags |= O_CREAT;
    + /* fall through: shared code for create/open cases */
    + case LOOKUP_OPEN:
    + nd->flags = flags;
    + nd->intent.open.flags |= (FMODE_READ | FMODE_WRITE);
    #ifdef ALLOC_LOWER_ND_FILE
    file = kzalloc(sizeof(struct file), GFP_KERNEL);
    if (!file) {
    @@ -611,11 +621,15 @@ int init_lower_nd(struct nameidata *nd, unsigned int flags)
    nd->intent.open.file = file;
    #endif /* ALLOC_LOWER_ND_FILE */
    break;
    + case LOOKUP_ACCESS:
    + nd->flags = flags;
    + break;
    default:
    /*
    * We should never get here, for now.
    * We can add new cases here later on.
    */
    + dprintk("unionfs: unknown nameidata flag 0x%x\n", flags);
    BUG();
    break;
    }
    @@ -627,7 +641,7 @@ void release_lower_nd(struct nameidata *nd, int err)
    {
    if (!nd->intent.open.file)
    return;
    - if (!err)
    + else if (!err)
    release_open_intent(nd);
    #ifdef ALLOC_LOWER_ND_FILE
    kfree(nd->intent.open.file);
    --
    1.5.2.2
    -
    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-09-26 05:33    [W:0.026 / U:0.116 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site