lkml.org 
[lkml]   [2007]   [Sep]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Subject[RFC][PATCH 5/5] make open_namei() return a filp
    From
    Date

    If open_namei() succeeds, there is potentially a mnt_want_write()
    that needs to get balanced. If the caller doesn't create a
    'struct file' and eventually __fput() it, or manually drop the
    write count on an error, we have a bug.

    Forcing open_namei() to return a filp fixes this. Any caller
    getting a 'struct file' back must consider that filp instantiated
    and fput() it normally. The callers no longer have to worry about
    ever manually releasing a mnt write count.

    ---

    lxc-dave/fs/namei.c | 16 ++++++++--------
    lxc-dave/fs/open.c | 6 +-----
    lxc-dave/include/linux/fs.h | 2 +-
    3 files changed, 10 insertions(+), 14 deletions(-)

    diff -puN fs/namei.c~make-open_namei-return-a-filp fs/namei.c
    --- lxc/fs/namei.c~make-open_namei-return-a-filp 2007-09-27 11:51:34.000000000 -0700
    +++ lxc-dave/fs/namei.c 2007-09-27 11:51:34.000000000 -0700
    @@ -1750,8 +1750,8 @@ static inline int sys_open_flags_to_name
    * system call. See sys_open_flags_to_namei_flags().
    * SMP-safe
    */
    -int open_namei(int dfd, const char *pathname, int sys_open_flag,
    - int mode, struct nameidata *nd)
    +struct file *open_namei(int dfd, const char *pathname, int sys_open_flag,
    + int mode, struct nameidata *nd)
    {
    int acc_mode, error;
    struct path path;
    @@ -1777,7 +1777,7 @@ int open_namei(int dfd, const char *path
    error = path_lookup_open(dfd, pathname, lookup_flags(flag),
    nd, flag);
    if (error)
    - return error;
    + return ERR_PTR(error);
    goto ok;
    }

    @@ -1786,7 +1786,7 @@ int open_namei(int dfd, const char *path
    */
    error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
    if (error)
    - return error;
    + return ERR_PTR(error);

    /*
    * We have the parent and last component. First of all, check
    @@ -1820,7 +1820,7 @@ do_last:
    error = __open_namei_create(nd, &path, flag, mode);
    if (error)
    goto exit;
    - return 0;
    + return nameidata_to_filp(nd, sys_open_flag);
    }

    /*
    @@ -1864,7 +1864,7 @@ ok:
    mnt_drop_write(nd->mnt);
    goto exit;
    }
    - return 0;
    + return nameidata_to_filp(nd, sys_open_flag);

    exit_mutex_unlock:
    mutex_unlock(&dir->d_inode->i_mutex);
    @@ -1874,7 +1874,7 @@ exit:
    if (!IS_ERR(nd->intent.open.file))
    release_open_intent(nd);
    path_release(nd);
    - return error;
    + return ERR_PTR(error);

    do_link:
    error = -ELOOP;
    @@ -1901,7 +1901,7 @@ do_link:
    * with "intent.open".
    */
    release_open_intent(nd);
    - return error;
    + return ERR_PTR(error);
    }
    nd->flags &= ~LOOKUP_PARENT;
    if (nd->last_type == LAST_BIND)
    diff -puN fs/open.c~make-open_namei-return-a-filp fs/open.c
    --- lxc/fs/open.c~make-open_namei-return-a-filp 2007-09-27 11:51:34.000000000 -0700
    +++ lxc-dave/fs/open.c 2007-09-27 11:51:34.000000000 -0700
    @@ -846,11 +846,7 @@ static struct file *do_filp_open(int dfd
    int error;
    struct nameidata nd;

    - error = open_namei(dfd, filename, flags, mode, &nd);
    - if (!error)
    - return nameidata_to_filp(&nd, flags);
    -
    - return ERR_PTR(error);
    + return open_namei(dfd, filename, flags, mode, &nd);
    }

    struct file *filp_open(const char *filename, int flags, int mode)
    diff -puN include/linux/fs.h~make-open_namei-return-a-filp include/linux/fs.h
    --- lxc/include/linux/fs.h~make-open_namei-return-a-filp 2007-09-27 11:51:34.000000000 -0700
    +++ lxc-dave/include/linux/fs.h 2007-09-27 11:51:34.000000000 -0700
    @@ -1716,7 +1716,7 @@ extern struct file *create_read_pipe(str
    extern struct file *create_write_pipe(void);
    extern void free_write_pipe(struct file *);

    -extern int open_namei(int dfd, const char *, int, int, struct nameidata *);
    +extern struct file *open_namei(int dfd, const char *, int, int, struct nameidata *);
    extern int may_open(struct nameidata *, int, int);

    extern int kernel_read(struct file *, unsigned long, char *, unsigned long);
    _
    -
    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-27 20:55    [W:0.033 / U:7.680 seconds]
    ©2003-2017 Jasper Spaans. hosted at Digital OceanAdvertise on this site