[patch 00/10] vfs: add helpers to check r/o bind mounts - Kernel

This is a discussion on [patch 00/10] vfs: add helpers to check r/o bind mounts - Kernel ; See first patch for description. This is against vfs-2.6 + two patches I posted recently. It's not for -mm yet, as it needs conversion of unionfs (will that be done by me, I wonder?) Thanks, Miklos -- -- To unsubscribe ...

+ Reply to Thread
Page 1 of 2 1 2 LastLast
Results 1 to 20 of 39

Thread: [patch 00/10] vfs: add helpers to check r/o bind mounts

  1. [patch 00/10] vfs: add helpers to check r/o bind mounts

    See first patch for description. This is against vfs-2.6 + two
    patches I posted recently.

    It's not for -mm yet, as it needs conversion of unionfs (will that be
    done by me, I wonder?)

    Thanks,
    Miklos

    --
    --
    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/

  2. [patch 06/10] vfs: add path_link()

    From: Miklos Szeredi

    Introduce path_link(). Make vfs_link() static.

    Signed-off-by: Miklos Szeredi
    ---
    fs/ecryptfs/inode.c | 10 +++++-----
    fs/namei.c | 26 ++++++++++++++++++--------
    fs/nfsd/vfs.c | 8 +++++---
    include/linux/fs.h | 2 +-
    4 files changed, 29 insertions(+), 17 deletions(-)

    Index: vfs-2.6/fs/ecryptfs/inode.c
    ================================================== =================
    --- vfs-2.6.orig/fs/ecryptfs/inode.c 2008-04-02 21:35:09.000000000 +0200
    +++ vfs-2.6/fs/ecryptfs/inode.c 2008-04-02 21:36:43.000000000 +0200
    @@ -383,7 +383,7 @@ static int ecryptfs_link(struct dentry *
    {
    struct dentry *lower_old_dentry;
    struct dentry *lower_new_dentry;
    - struct dentry *lower_dir_dentry;
    + struct path lower_dir;
    u64 file_size_save;
    int rc;

    @@ -392,9 +392,9 @@ static int ecryptfs_link(struct dentry *
    lower_new_dentry = ecryptfs_dentry_to_lower(new_dentry);
    dget(lower_old_dentry);
    dget(lower_new_dentry);
    - lower_dir_dentry = lock_parent(lower_new_dentry);
    - rc = vfs_link(lower_old_dentry, lower_dir_dentry->d_inode,
    - lower_new_dentry);
    + lower_dir.mnt = ecryptfs_dentry_to_lower_mnt(new_dentry);
    + lower_dir.dentry = lock_parent(lower_new_dentry);
    + rc = path_link(lower_old_dentry, &lower_dir, lower_new_dentry);
    if (rc || !lower_new_dentry->d_inode)
    goto out_lock;
    rc = ecryptfs_interpose(lower_new_dentry, new_dentry, dir->i_sb, 0);
    @@ -406,7 +406,7 @@ static int ecryptfs_link(struct dentry *
    ecryptfs_inode_to_lower(old_dentry->d_inode)->i_nlink;
    i_size_write(new_dentry->d_inode, file_size_save);
    out_lock:
    - unlock_dir(lower_dir_dentry);
    + unlock_dir(lower_dir.dentry);
    dput(lower_new_dentry);
    dput(lower_old_dentry);
    d_drop(lower_old_dentry);
    Index: vfs-2.6/fs/namei.c
    ================================================== =================
    --- vfs-2.6.orig/fs/namei.c 2008-04-02 21:35:09.000000000 +0200
    +++ vfs-2.6/fs/namei.c 2008-04-02 21:36:43.000000000 +0200
    @@ -2507,7 +2507,7 @@ asmlinkage long sys_symlink(const char _
    return sys_symlinkat(oldname, AT_FDCWD, newname);
    }

    -int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
    +static int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
    {
    struct inode *inode = old_dentry->d_inode;
    int error;
    @@ -2545,6 +2545,22 @@ int vfs_link(struct dentry *old_dentry,
    return error;
    }

    +int path_link(struct dentry *old_dentry, struct path *dir_path,
    + struct dentry *new_dentry)
    +{
    + int error = mnt_want_write(dir_path->mnt);
    +
    + if (!error) {
    + struct inode *dir = dir_path->dentry->d_inode;
    +
    + error = vfs_link(old_dentry, dir, new_dentry);
    + mnt_drop_write(dir_path->mnt);
    + }
    +
    + return error;
    +}
    +EXPORT_SYMBOL(path_link);
    +
    /*
    * Hardlinks are often used in delicate situations. We avoid
    * security-related surprises by not following symlinks on the
    @@ -2585,12 +2601,7 @@ asmlinkage long sys_linkat(int olddfd, c
    error = PTR_ERR(new_dentry);
    if (IS_ERR(new_dentry))
    goto out_unlock;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_dput;
    - error = vfs_link(old_nd.path.dentry, nd.path.dentry->d_inode, new_dentry);
    - mnt_drop_write(nd.path.mnt);
    -out_dput:
    + error = path_link(old_nd.path.dentry, &nd.path, new_dentry);
    dput(new_dentry);
    out_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    @@ -3010,7 +3021,6 @@ EXPORT_SYMBOL(vfs_permission);
    EXPORT_SYMBOL(file_permission);
    EXPORT_SYMBOL(unlock_rename);
    EXPORT_SYMBOL(vfs_follow_link);
    -EXPORT_SYMBOL(vfs_link);
    EXPORT_SYMBOL(generic_permission);
    EXPORT_SYMBOL(vfs_readlink);
    EXPORT_SYMBOL(vfs_rename);
    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:35:09.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:36:43.000000000 +0200
    @@ -1567,8 +1567,9 @@ __be32
    nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
    char *name, int len, struct svc_fh *tfhp)
    {
    + struct path dir_path;
    struct dentry *ddir, *dnew, *dold;
    - struct inode *dirp, *dest;
    + struct inode *dest;
    __be32 err;
    int host_err;

    @@ -1588,7 +1589,6 @@ nfsd_link(struct svc_rqst *rqstp, struct

    fh_lock_nested(ffhp, I_MUTEX_PARENT);
    ddir = ffhp->fh_dentry;
    - dirp = ddir->d_inode;

    dnew = lookup_one_len(name, ddir, len);
    host_err = PTR_ERR(dnew);
    @@ -1598,7 +1598,9 @@ nfsd_link(struct svc_rqst *rqstp, struct
    dold = tfhp->fh_dentry;
    dest = dold->d_inode;

    - host_err = vfs_link(dold, dirp, dnew);
    + dir_path.mnt = ffhp->fh_export->ex_path.mnt;
    + dir_path.dentry = ddir;
    + host_err = path_link(dold, &dir_path, dnew);
    if (!host_err) {
    if (EX_ISSYNC(ffhp->fh_export)) {
    err = nfserrno(nfsd_sync_dir(ddir));
    Index: vfs-2.6/include/linux/fs.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/fs.h 2008-04-02 21:35:09.000000000 +0200
    +++ vfs-2.6/include/linux/fs.h 2008-04-02 21:36:43.000000000 +0200
    @@ -1128,7 +1128,7 @@ extern int vfs_mkdir(struct inode *, str
    extern int path_mkdir(struct path *, struct dentry *, int);
    extern int path_mknod(struct path *, struct dentry *, int, dev_t);
    extern int path_symlink(struct path *, struct dentry *, const char *, int);
    -extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
    +extern int path_link(struct dentry *, struct path *, struct dentry *);
    extern int vfs_rmdir(struct inode *, struct dentry *);
    extern int path_rmdir(struct path *, struct dentry *);
    extern int path_unlink(struct path *, struct dentry *);

    --
    --
    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/

  3. [patch 03/10] vfs: add path_rmdir()

    From: Miklos Szeredi

    Introduce path_rmdir().

    The only user of vfs_rmdir() remaining is reiserfs_delete_xattrs().

    Signed-off-by: Miklos Szeredi
    ---
    fs/ecryptfs/inode.c | 13 +++++++------
    fs/namei.c | 20 ++++++++++++++------
    fs/nfsd/nfs4recover.c | 3 ++-
    fs/nfsd/vfs.c | 5 ++++-
    include/linux/fs.h | 1 +
    5 files changed, 28 insertions(+), 14 deletions(-)

    Index: vfs-2.6/fs/namei.c
    ================================================== =================
    --- vfs-2.6.orig/fs/namei.c 2008-04-02 21:10:28.000000000 +0200
    +++ vfs-2.6/fs/namei.c 2008-04-02 21:13:30.000000000 +0200
    @@ -2255,6 +2255,19 @@ int vfs_rmdir(struct inode *dir, struct
    return error;
    }

    +int path_rmdir(struct path *dir_path, struct dentry *dentry)
    +{
    + int error = mnt_want_write(dir_path->mnt);
    +
    + if (!error) {
    + error = vfs_rmdir(dir_path->dentry->d_inode, dentry);
    + mnt_drop_write(dir_path->mnt);
    + }
    +
    + return error;
    +}
    +EXPORT_SYMBOL(path_rmdir);
    +
    static long do_rmdir(int dfd, const char __user *pathname)
    {
    int error = 0;
    @@ -2286,12 +2299,7 @@ static long do_rmdir(int dfd, const char
    error = PTR_ERR(dentry);
    if (IS_ERR(dentry))
    goto exit2;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto exit3;
    - error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
    - mnt_drop_write(nd.path.mnt);
    -exit3:
    + error = path_rmdir(&nd.path, dentry);
    dput(dentry);
    exit2:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    Index: vfs-2.6/fs/ecryptfs/inode.c
    ================================================== =================
    --- vfs-2.6.orig/fs/ecryptfs/inode.c 2008-04-02 21:10:28.000000000 +0200
    +++ vfs-2.6/fs/ecryptfs/inode.c 2008-04-02 21:13:30.000000000 +0200
    @@ -511,20 +511,21 @@ out:
    static int ecryptfs_rmdir(struct inode *dir, struct dentry *dentry)
    {
    struct dentry *lower_dentry;
    - struct dentry *lower_dir_dentry;
    + struct path lower_dir;
    int rc;

    lower_dentry = ecryptfs_dentry_to_lower(dentry);
    dget(dentry);
    - lower_dir_dentry = lock_parent(lower_dentry);
    + lower_dir.mnt = ecryptfs_dentry_to_lower_mnt(dentry);
    + lower_dir.dentry = lock_parent(lower_dentry);
    dget(lower_dentry);
    - rc = vfs_rmdir(lower_dir_dentry->d_inode, lower_dentry);
    + rc = path_rmdir(&lower_dir, lower_dentry);
    dput(lower_dentry);
    if (!rc)
    d_delete(lower_dentry);
    - fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
    - dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
    - unlock_dir(lower_dir_dentry);
    + fsstack_copy_attr_times(dir, lower_dir.dentry->d_inode);
    + dir->i_nlink = lower_dir.dentry->d_inode->i_nlink;
    + unlock_dir(lower_dir.dentry);
    if (!rc)
    d_drop(dentry);
    dput(dentry);
    Index: vfs-2.6/fs/nfsd/nfs4recover.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/nfs4recover.c 2008-04-02 21:10:28.000000000 +0200
    +++ vfs-2.6/fs/nfsd/nfs4recover.c 2008-04-02 21:13:30.000000000 +0200
    @@ -267,6 +267,7 @@ nfsd4_remove_clid_file(struct dentry *di
    static int
    nfsd4_clear_clid_dir(struct dentry *dir, struct dentry *dentry)
    {
    + struct path dir_path = { .dentry = dir, .mnt = rec_dir.path.mnt };
    int status;

    /* For now this directory should already be empty, but we empty it of
    @@ -274,7 +275,7 @@ nfsd4_clear_clid_dir(struct dentry *dir,
    * a kernel from the future.... */
    nfsd4_list_rec_dir(dentry, nfsd4_remove_clid_file);
    mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
    - status = vfs_rmdir(dir->d_inode, dentry);
    + status = path_rmdir(&dir_path, dentry);
    mutex_unlock(&dir->d_inode->i_mutex);
    return status;
    }
    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:10:28.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:13:30.000000000 +0200
    @@ -1732,6 +1732,7 @@ __be32
    nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
    char *fname, int flen)
    {
    + struct path dir_path;
    struct dentry *dentry, *rdentry;
    struct inode *dirp;
    __be32 err;
    @@ -1762,6 +1763,8 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
    if (!type)
    type = rdentry->d_inode->i_mode & S_IFMT;

    + dir_path.mnt = fhp->fh_export->ex_path.mnt;
    + dir_path.dentry = dentry;
    if (type != S_IFDIR) { /* It's UNLINK */
    #ifdef MSNFS
    if ((fhp->fh_export->ex_flags & NFSEXP_MSNFS) &&
    @@ -1771,7 +1774,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
    #endif
    host_err = vfs_unlink(dirp, rdentry);
    } else { /* It's RMDIR */
    - host_err = vfs_rmdir(dirp, rdentry);
    + host_err = path_rmdir(&dir_path, rdentry);
    }

    dput(rdentry);
    Index: vfs-2.6/include/linux/fs.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/fs.h 2008-04-02 21:10:28.000000000 +0200
    +++ vfs-2.6/include/linux/fs.h 2008-04-02 21:13:30.000000000 +0200
    @@ -1130,6 +1130,7 @@ extern int path_mknod(struct path *, str
    extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
    extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
    extern int vfs_rmdir(struct inode *, struct dentry *);
    +extern int path_rmdir(struct path *, struct dentry *);
    extern int vfs_unlink(struct inode *, struct dentry *);
    extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);


    --
    --
    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/

  4. [patch 09/10] vfs: add path_setxattr()

    From: Miklos Szeredi

    Introduce path_setxattr(). Make vfs_setxattr() static.

    Signed-off-by: Miklos Szeredi
    ---
    fs/nfsd/vfs.c | 21 +++++++++++++--------
    fs/xattr.c | 42 ++++++++++++++++++++----------------------
    include/linux/xattr.h | 2 +-
    3 files changed, 34 insertions(+), 31 deletions(-)

    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:41:21.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:44:44.000000000 +0200
    @@ -431,7 +431,7 @@ static ssize_t nfsd_getxattr(struct dent

    #if defined(CONFIG_NFSD_V4)
    static int
    -set_nfsv4_acl_one(struct dentry *dentry, struct posix_acl *pacl, char *key)
    +set_nfsv4_acl_one(struct path *path, struct posix_acl *pacl, char *key)
    {
    int len;
    size_t buflen;
    @@ -450,7 +450,7 @@ set_nfsv4_acl_one(struct dentry *dentry,
    goto out;
    }

    - error = vfs_setxattr(dentry, key, buf, len, 0);
    + error = path_setxattr(path, key, buf, len, 0);
    out:
    kfree(buf);
    return error;
    @@ -462,7 +462,7 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
    {
    __be32 error;
    int host_error;
    - struct dentry *dentry;
    + struct path path;
    struct inode *inode;
    struct posix_acl *pacl = NULL, *dpacl = NULL;
    unsigned int flags = 0;
    @@ -472,8 +472,9 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
    if (error)
    return error;

    - dentry = fhp->fh_dentry;
    - inode = dentry->d_inode;
    + path.mnt = fhp->fh_export->ex_path.mnt;
    + path.dentry = fhp->fh_dentry;
    + inode = path.dentry->d_inode;
    if (S_ISDIR(inode->i_mode))
    flags = NFS4_ACL_DIR;

    @@ -483,12 +484,12 @@ nfsd4_set_nfs4_acl(struct svc_rqst *rqst
    } else if (host_error < 0)
    goto out_nfserr;

    - host_error = set_nfsv4_acl_one(dentry, pacl, POSIX_ACL_XATTR_ACCESS);
    + host_error = set_nfsv4_acl_one(&path, pacl, POSIX_ACL_XATTR_ACCESS);
    if (host_error < 0)
    goto out_release;

    if (S_ISDIR(inode->i_mode))
    - host_error = set_nfsv4_acl_one(dentry, dpacl, POSIX_ACL_XATTR_DEFAULT);
    + host_error = set_nfsv4_acl_one(&path, dpacl, POSIX_ACL_XATTR_DEFAULT);

    out_release:
    posix_acl_release(pacl);
    @@ -2028,6 +2029,10 @@ nfsd_get_posix_acl(struct svc_fh *fhp, i
    int
    nfsd_set_posix_acl(struct svc_fh *fhp, int type, struct posix_acl *acl)
    {
    + struct path path = {
    + .mnt = fhp->fh_export->ex_path.mnt,
    + .dentry = fhp->fh_dentry,
    + };
    struct inode *inode = fhp->fh_dentry->d_inode;
    char *name;
    void *value = NULL;
    @@ -2061,7 +2066,7 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
    size = 0;

    if (size)
    - error = vfs_setxattr(fhp->fh_dentry, name, value, size, 0);
    + error = path_setxattr(&path, name, value, size, 0);
    else {
    if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
    error = 0;
    Index: vfs-2.6/fs/xattr.c
    ================================================== =================
    --- vfs-2.6.orig/fs/xattr.c 2008-04-02 21:10:16.000000000 +0200
    +++ vfs-2.6/fs/xattr.c 2008-04-02 21:44:44.000000000 +0200
    @@ -66,7 +66,7 @@ xattr_permission(struct inode *inode, co
    return permission(inode, mask, NULL);
    }

    -int
    +static int
    vfs_setxattr(struct dentry *dentry, char *name, void *value,
    size_t size, int flags)
    {
    @@ -101,7 +101,20 @@ out:
    mutex_unlock(&inode->i_mutex);
    return error;
    }
    -EXPORT_SYMBOL_GPL(vfs_setxattr);
    +
    +int path_setxattr(struct path *path, char *name, void *value, size_t size,
    + int flags)
    +{
    + int error = mnt_want_write(path->mnt);
    +
    + if (!error) {
    + error = vfs_setxattr(path->dentry, name, value, size, flags);
    + mnt_drop_write(path->mnt);
    + }
    +
    + return error;
    +}
    +EXPORT_SYMBOL(path_setxattr);

    ssize_t
    xattr_getsecurity(struct inode *inode, const char *name, void *value,
    @@ -218,7 +231,7 @@ EXPORT_SYMBOL_GPL(vfs_removexattr);
    * Extended attribute SET operations
    */
    static long
    -setxattr(struct dentry *d, char __user *name, void __user *value,
    +setxattr(struct path *path, char __user *name, void __user *value,
    size_t size, int flags)
    {
    int error;
    @@ -246,7 +259,7 @@ setxattr(struct dentry *d, char __user *
    }
    }

    - error = vfs_setxattr(d, kname, kvalue, size, flags);
    + error = path_setxattr(path, kname, kvalue, size, flags);
    kfree(kvalue);
    return error;
    }
    @@ -261,12 +274,7 @@ sys_setxattr(char __user *path, char __u
    error = user_path_walk(path, &nd);
    if (error)
    return error;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_path_put;
    - error = setxattr(nd.path.dentry, name, value, size, flags);
    - mnt_drop_write(nd.path.mnt);
    - out_path_put:
    + error = setxattr(&nd.path, name, value, size, flags);
    path_put(&nd.path);
    return error;
    }
    @@ -281,12 +289,7 @@ sys_lsetxattr(char __user *path, char __
    error = user_path_walk_link(path, &nd);
    if (error)
    return error;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_path_put;
    - error = setxattr(nd.path.dentry, name, value, size, flags);
    - mnt_drop_write(nd.path.mnt);
    - out_path_put:
    + error = setxattr(&nd.path, name, value, size, flags);
    path_put(&nd.path);
    return error;
    }
    @@ -302,14 +305,9 @@ sys_fsetxattr(int fd, char __user *name,
    f = fget(fd);
    if (!f)
    return error;
    - error = mnt_want_write(f->f_vfsmnt);
    - if (error)
    - goto out_fput;
    dentry = f->f_path.dentry;
    audit_inode(NULL, dentry);
    - error = setxattr(dentry, name, value, size, flags);
    - mnt_drop_write(f->f_vfsmnt);
    -out_fput:
    + error = setxattr(&f->f_path, name, value, size, flags);
    fput(f);
    return error;
    }
    Index: vfs-2.6/include/linux/xattr.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/xattr.h 2008-04-02 21:10:13.000000000 +0200
    +++ vfs-2.6/include/linux/xattr.h 2008-04-02 21:44:44.000000000 +0200
    @@ -49,7 +49,7 @@ struct xattr_handler {
    ssize_t xattr_getsecurity(struct inode *, const char *, void *, size_t);
    ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
    ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
    -int vfs_setxattr(struct dentry *, char *, void *, size_t, int);
    +int path_setxattr(struct path *, char *, void *, size_t, int);
    int vfs_removexattr(struct dentry *, char *);

    ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);

    --
    --
    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/

  5. [patch 10/10] vfs: add path_removexattr()

    From: Miklos Szeredi

    Introduce path_removexattr(). Make vfs_removexattr() static.

    mnt_want_write()/mnt_drop_write() were completely missing for the
    *removexattr() syscalls.

    Signed-off-by: Miklos Szeredi
    ---
    fs/nfsd/vfs.c | 2 +-
    fs/xattr.c | 25 ++++++++++++++++++-------
    include/linux/xattr.h | 2 +-
    3 files changed, 20 insertions(+), 9 deletions(-)

    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:44:44.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:45:56.000000000 +0200
    @@ -2071,7 +2071,7 @@ nfsd_set_posix_acl(struct svc_fh *fhp, i
    if (!S_ISDIR(inode->i_mode) && type == ACL_TYPE_DEFAULT)
    error = 0;
    else {
    - error = vfs_removexattr(fhp->fh_dentry, name);
    + error = path_removexattr(&path, name);
    if (error == -ENODATA)
    error = 0;
    }
    Index: vfs-2.6/fs/xattr.c
    ================================================== =================
    --- vfs-2.6.orig/fs/xattr.c 2008-04-02 21:44:44.000000000 +0200
    +++ vfs-2.6/fs/xattr.c 2008-04-02 21:45:56.000000000 +0200
    @@ -199,7 +199,7 @@ vfs_listxattr(struct dentry *d, char *li
    }
    EXPORT_SYMBOL_GPL(vfs_listxattr);

    -int
    +static int
    vfs_removexattr(struct dentry *dentry, char *name)
    {
    struct inode *inode = dentry->d_inode;
    @@ -224,8 +224,19 @@ vfs_removexattr(struct dentry *dentry, c
    fsnotify_xattr(dentry);
    return error;
    }
    -EXPORT_SYMBOL_GPL(vfs_removexattr);

    +int path_removexattr(struct path *path, char *name)
    +{
    + int error = mnt_want_write(path->mnt);
    +
    + if (!error) {
    + error = vfs_removexattr(path->dentry, name);
    + mnt_drop_write(path->mnt);
    + }
    +
    + return error;
    +}
    +EXPORT_SYMBOL(path_removexattr);

    /*
    * Extended attribute SET operations
    @@ -471,7 +482,7 @@ sys_flistxattr(int fd, char __user *list
    * Extended attribute REMOVE operations
    */
    static long
    -removexattr(struct dentry *d, char __user *name)
    +removexattr(struct path *path, char __user *name)
    {
    int error;
    char kname[XATTR_NAME_MAX + 1];
    @@ -482,7 +493,7 @@ removexattr(struct dentry *d, char __use
    if (error < 0)
    return error;

    - return vfs_removexattr(d, kname);
    + return path_removexattr(path, kname);
    }

    asmlinkage long
    @@ -494,7 +505,7 @@ sys_removexattr(char __user *path, char
    error = user_path_walk(path, &nd);
    if (error)
    return error;
    - error = removexattr(nd.path.dentry, name);
    + error = removexattr(&nd.path, name);
    path_put(&nd.path);
    return error;
    }
    @@ -508,7 +519,7 @@ sys_lremovexattr(char __user *path, char
    error = user_path_walk_link(path, &nd);
    if (error)
    return error;
    - error = removexattr(nd.path.dentry, name);
    + error = removexattr(&nd.path, name);
    path_put(&nd.path);
    return error;
    }
    @@ -525,7 +536,7 @@ sys_fremovexattr(int fd, char __user *na
    return error;
    dentry = f->f_path.dentry;
    audit_inode(NULL, dentry);
    - error = removexattr(dentry, name);
    + error = removexattr(&f->f_path, name);
    fput(f);
    return error;
    }
    Index: vfs-2.6/include/linux/xattr.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/xattr.h 2008-04-02 21:44:44.000000000 +0200
    +++ vfs-2.6/include/linux/xattr.h 2008-04-02 21:45:56.000000000 +0200
    @@ -50,7 +50,7 @@ ssize_t xattr_getsecurity(struct inode *
    ssize_t vfs_getxattr(struct dentry *, char *, void *, size_t);
    ssize_t vfs_listxattr(struct dentry *d, char *list, size_t size);
    int path_setxattr(struct path *, char *, void *, size_t, int);
    -int vfs_removexattr(struct dentry *, char *);
    +int path_removexattr(struct path *, char *);

    ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
    ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);

    --
    --
    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/

  6. [patch 04/10] vfs: add path_unlink()

    From: Miklos Szeredi

    Introduce path_unlink(). Make vfs_unlink() static.

    Signed-off-by: Miklos Szeredi
    ---
    fs/ecryptfs/inode.c | 17 ++++++-----------
    fs/namei.c | 22 +++++++++++++++-------
    fs/nfsd/nfs4recover.c | 3 ++-
    fs/nfsd/vfs.c | 4 +---
    include/linux/fs.h | 2 +-
    ipc/mqueue.c | 10 +++++-----
    6 files changed, 30 insertions(+), 28 deletions(-)

    Index: vfs-2.6/fs/ecryptfs/inode.c
    ================================================== =================
    --- vfs-2.6.orig/fs/ecryptfs/inode.c 2008-04-02 21:13:30.000000000 +0200
    +++ vfs-2.6/fs/ecryptfs/inode.c 2008-04-02 21:35:07.000000000 +0200
    @@ -42,12 +42,6 @@ static struct dentry *lock_parent(struct
    return dir;
    }

    -static void unlock_parent(struct dentry *dentry)
    -{
    - mutex_unlock(&(dentry->d_parent->d_inode->i_mutex));
    - dput(dentry->d_parent);
    -}
    -
    static void unlock_dir(struct dentry *dir)
    {
    mutex_unlock(&dir->d_inode->i_mutex);
    @@ -425,21 +419,22 @@ static int ecryptfs_unlink(struct inode
    {
    int rc = 0;
    struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry);
    - struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir);
    + struct path lower_dir;

    - lock_parent(lower_dentry);
    - rc = vfs_unlink(lower_dir_inode, lower_dentry);
    + lower_dir.mnt = ecryptfs_dentry_to_lower_mnt(dentry);
    + lower_dir.dentry = lock_parent(lower_dentry);
    + rc = path_unlink(&lower_dir, lower_dentry);
    if (rc) {
    printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc);
    goto out_unlock;
    }
    - fsstack_copy_attr_times(dir, lower_dir_inode);
    + fsstack_copy_attr_times(dir, lower_dir.dentry->d_inode);
    dentry->d_inode->i_nlink =
    ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink;
    dentry->d_inode->i_ctime = dir->i_ctime;
    d_drop(dentry);
    out_unlock:
    - unlock_parent(lower_dentry);
    + unlock_dir(lower_dir.dentry);
    return rc;
    }

    Index: vfs-2.6/fs/namei.c
    ================================================== =================
    --- vfs-2.6.orig/fs/namei.c 2008-04-02 21:13:30.000000000 +0200
    +++ vfs-2.6/fs/namei.c 2008-04-02 21:35:07.000000000 +0200
    @@ -2315,7 +2315,7 @@ asmlinkage long sys_rmdir(const char __u
    return do_rmdir(AT_FDCWD, pathname);
    }

    -int vfs_unlink(struct inode *dir, struct dentry *dentry)
    +static int vfs_unlink(struct inode *dir, struct dentry *dentry)
    {
    int error = may_delete(dir, dentry, 0);

    @@ -2346,6 +2346,19 @@ int vfs_unlink(struct inode *dir, struct
    return error;
    }

    +int path_unlink(struct path *dir_path, struct dentry *dentry)
    +{
    + int error = mnt_want_write(dir_path->mnt);
    +
    + if (!error) {
    + error = vfs_unlink(dir_path->dentry->d_inode, dentry);
    + mnt_drop_write(dir_path->mnt);
    + }
    +
    + return error;
    +}
    +EXPORT_SYMBOL(path_unlink);
    +
    /*
    * Make sure that the actual truncation of the file will occur outside its
    * directory's i_mutex. Truncate can take a long time if there is a lot of
    @@ -2380,11 +2393,7 @@ static long do_unlinkat(int dfd, const c
    inode = dentry->d_inode;
    if (inode)
    atomic_inc(&inode->i_count);
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto exit2;
    - error = vfs_unlink(nd.path.dentry->d_inode, dentry);
    - mnt_drop_write(nd.path.mnt);
    + error = path_unlink(&nd.path, dentry);
    exit2:
    dput(dentry);
    }
    @@ -2996,6 +3005,5 @@ EXPORT_SYMBOL(vfs_readlink);
    EXPORT_SYMBOL(vfs_rename);
    EXPORT_SYMBOL(vfs_rmdir);
    EXPORT_SYMBOL(vfs_symlink);
    -EXPORT_SYMBOL(vfs_unlink);
    EXPORT_SYMBOL(dentry_unhash);
    EXPORT_SYMBOL(generic_readlink);
    Index: vfs-2.6/fs/nfsd/nfs4recover.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/nfs4recover.c 2008-04-02 21:13:30.000000000 +0200
    +++ vfs-2.6/fs/nfsd/nfs4recover.c 2008-04-02 21:15:25.000000000 +0200
    @@ -252,6 +252,7 @@ out:
    static int
    nfsd4_remove_clid_file(struct dentry *dir, struct dentry *dentry)
    {
    + struct path dir_path = { .dentry = dir, .mnt = rec_dir.path.mnt };
    int status;

    if (!S_ISREG(dir->d_inode->i_mode)) {
    @@ -259,7 +260,7 @@ nfsd4_remove_clid_file(struct dentry *di
    return -EINVAL;
    }
    mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_PARENT);
    - status = vfs_unlink(dir->d_inode, dentry);
    + status = path_unlink(&dir_path, dentry);
    mutex_unlock(&dir->d_inode->i_mutex);
    return status;
    }
    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:13:30.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:35:07.000000000 +0200
    @@ -1734,7 +1734,6 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
    {
    struct path dir_path;
    struct dentry *dentry, *rdentry;
    - struct inode *dirp;
    __be32 err;
    int host_err;

    @@ -1747,7 +1746,6 @@ nfsd_unlink(struct svc_rqst *rqstp, stru

    fh_lock_nested(fhp, I_MUTEX_PARENT);
    dentry = fhp->fh_dentry;
    - dirp = dentry->d_inode;

    rdentry = lookup_one_len(fname, dentry, flen);
    host_err = PTR_ERR(rdentry);
    @@ -1772,7 +1770,7 @@ nfsd_unlink(struct svc_rqst *rqstp, stru
    host_err = -EPERM;
    } else
    #endif
    - host_err = vfs_unlink(dirp, rdentry);
    + host_err = path_unlink(&dir_path, rdentry);
    } else { /* It's RMDIR */
    host_err = path_rmdir(&dir_path, rdentry);
    }
    Index: vfs-2.6/include/linux/fs.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/fs.h 2008-04-02 21:13:30.000000000 +0200
    +++ vfs-2.6/include/linux/fs.h 2008-04-02 21:35:07.000000000 +0200
    @@ -1131,7 +1131,7 @@ extern int vfs_symlink(struct inode *, s
    extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
    extern int vfs_rmdir(struct inode *, struct dentry *);
    extern int path_rmdir(struct path *, struct dentry *);
    -extern int vfs_unlink(struct inode *, struct dentry *);
    +extern int path_unlink(struct path *, struct dentry *);
    extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);

    /*
    Index: vfs-2.6/ipc/mqueue.c
    ================================================== =================
    --- vfs-2.6.orig/ipc/mqueue.c 2008-04-02 21:10:17.000000000 +0200
    +++ vfs-2.6/ipc/mqueue.c 2008-04-02 21:15:25.000000000 +0200
    @@ -737,6 +737,7 @@ asmlinkage long sys_mq_unlink(const char
    char *name;
    struct dentry *dentry;
    struct inode *inode = NULL;
    + struct path dir_path;

    name = getname(u_name);
    if (IS_ERR(name))
    @@ -758,11 +759,10 @@ asmlinkage long sys_mq_unlink(const char
    inode = dentry->d_inode;
    if (inode)
    atomic_inc(&inode->i_count);
    - err = mnt_want_write(mqueue_mnt);
    - if (err)
    - goto out_err;
    - err = vfs_unlink(dentry->d_parent->d_inode, dentry);
    - mnt_drop_write(mqueue_mnt);
    +
    + dir_path.mnt = mqueue_mnt;
    + dir_path.dentry = dentry->d_parent;
    + err = path_unlink(&dir_path, dentry);
    out_err:
    dput(dentry);


    --
    --
    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/

  7. [patch 01/10] vfs: add path_create() and path_mknod()

    From: Miklos Szeredi

    R/o bind mounts require operations which modify the filesystem to be
    wrapped in mnt_want_write()/mnt_drop_write(). Create helpers which do
    this, so callers won't need to bother, and more importantly, cannot
    forget! Call these path_*, analogous to vfs_*. Where there are no
    callers of vfs_* left, make them static.

    This series is a cleanup, as well as fixing several places (mostly in
    nfsd) where mnt_{want,drop}_write() were missing.

    It will also help with merging You Know What(*) security module, which
    needs to know the path within the namespace, and not just within the
    filesystem. These helpers will allow the security hooks to be in a
    common place, and need not be repeated in all callers.

    (*) AppArmor is a swear word in VFS circles, for some reason or other.

    This patch:

    Introduce path_create() and path_mknod(). Make vfs_create() and
    vfs_mknod() static.

    Signed-off-by: Miklos Szeredi
    ---
    fs/ecryptfs/inode.c | 21 +++++++-------
    fs/namei.c | 75 +++++++++++++++++++++++++++-------------------------
    fs/nfsd/vfs.c | 19 ++++++-------
    include/linux/fs.h | 4 +-
    ipc/mqueue.c | 6 +++-
    net/unix/af_unix.c | 6 ----
    6 files changed, 68 insertions(+), 63 deletions(-)

    Index: vfs-2.6/fs/namei.c
    ================================================== =================
    --- vfs-2.6.orig/fs/namei.c 2008-04-02 21:10:14.000000000 +0200
    +++ vfs-2.6/fs/namei.c 2008-04-02 21:10:17.000000000 +0200
    @@ -1574,7 +1574,7 @@ void unlock_rename(struct dentry *p1, st
    }
    }

    -int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
    +static int vfs_create(struct inode *dir, struct dentry *dentry, int mode,
    struct nameidata *nd)
    {
    int error = may_create(dir, dentry, nd);
    @@ -1596,6 +1596,20 @@ int vfs_create(struct inode *dir, struct
    return error;
    }

    +int path_create(struct path *dir_path, struct dentry *dentry, int mode,
    + struct nameidata *nd)
    +{
    + int error = mnt_want_write(dir_path->mnt);
    +
    + if (!error) {
    + error = vfs_create(dir_path->dentry->d_inode, dentry, mode, nd);
    + mnt_drop_write(dir_path->mnt);
    + }
    +
    + return error;
    +}
    +EXPORT_SYMBOL(path_create);
    +
    int may_open(struct nameidata *nd, int acc_mode, int flag)
    {
    struct dentry *dentry = nd->path.dentry;
    @@ -2015,7 +2029,7 @@ fail:
    }
    EXPORT_SYMBOL_GPL(lookup_create);

    -int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
    +static int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
    {
    int error = may_create(dir, dentry, NULL);

    @@ -2039,22 +2053,19 @@ int vfs_mknod(struct inode *dir, struct
    return error;
    }

    -static int may_mknod(mode_t mode)
    +int path_mknod(struct path *dir_path, struct dentry *dentry, int mode,
    + dev_t dev)
    {
    - switch (mode & S_IFMT) {
    - case S_IFREG:
    - case S_IFCHR:
    - case S_IFBLK:
    - case S_IFIFO:
    - case S_IFSOCK:
    - case 0: /* zero mode translates to S_IFREG */
    - return 0;
    - case S_IFDIR:
    - return -EPERM;
    - default:
    - return -EINVAL;
    + int error = mnt_want_write(dir_path->mnt);
    +
    + if (!error) {
    + error = vfs_mknod(dir_path->dentry->d_inode, dentry, mode, dev);
    + mnt_drop_write(dir_path->mnt);
    }
    +
    + return error;
    }
    +EXPORT_SYMBOL(path_mknod);

    asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
    unsigned dev)
    @@ -2080,26 +2091,22 @@ asmlinkage long sys_mknodat(int dfd, con
    }
    if (!IS_POSIXACL(nd.path.dentry->d_inode))
    mode &= ~current->fs->umask;
    - error = may_mknod(mode);
    - if (error)
    - goto out_dput;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_dput;
    switch (mode & S_IFMT) {
    - case 0: case S_IFREG:
    - error = vfs_create(nd.path.dentry->d_inode,dentry,mode,&nd);
    - break;
    - case S_IFCHR: case S_IFBLK:
    - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,
    - new_decode_dev(dev));
    - break;
    - case S_IFIFO: case S_IFSOCK:
    - error = vfs_mknod(nd.path.dentry->d_inode,dentry,mode,0);
    - break;
    + case 0: case S_IFREG:
    + error = path_create(&nd.path, dentry, mode, &nd);
    + break;
    + case S_IFCHR: case S_IFBLK:
    + error = path_mknod(&nd.path, dentry, mode, new_decode_dev(dev));
    + break;
    + case S_IFIFO: case S_IFSOCK:
    + error = path_mknod(&nd.path, dentry, mode, 0);
    + break;
    + case S_IFDIR:
    + error = -EPERM;
    + break;
    + default:
    + error = -EINVAL;
    }
    - mnt_drop_write(nd.path.mnt);
    -out_dput:
    dput(dentry);
    out_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    @@ -2966,11 +2973,9 @@ EXPORT_SYMBOL(permission);
    EXPORT_SYMBOL(vfs_permission);
    EXPORT_SYMBOL(file_permission);
    EXPORT_SYMBOL(unlock_rename);
    -EXPORT_SYMBOL(vfs_create);
    EXPORT_SYMBOL(vfs_follow_link);
    EXPORT_SYMBOL(vfs_link);
    EXPORT_SYMBOL(vfs_mkdir);
    -EXPORT_SYMBOL(vfs_mknod);
    EXPORT_SYMBOL(generic_permission);
    EXPORT_SYMBOL(vfs_readlink);
    EXPORT_SYMBOL(vfs_rename);
    Index: vfs-2.6/include/linux/fs.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/fs.h 2008-04-02 21:10:14.000000000 +0200
    +++ vfs-2.6/include/linux/fs.h 2008-04-02 21:10:17.000000000 +0200
    @@ -1123,9 +1123,9 @@ extern void unlock_super(struct super_bl
    * VFS helper functions..
    */
    extern int vfs_permission(struct nameidata *, int);
    -extern int vfs_create(struct inode *, struct dentry *, int, struct nameidata *);
    +extern int path_create(struct path *, struct dentry *, int, struct nameidata *);
    extern int vfs_mkdir(struct inode *, struct dentry *, int);
    -extern int vfs_mknod(struct inode *, struct dentry *, int, dev_t);
    +extern int path_mknod(struct path *, struct dentry *, int, dev_t);
    extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
    extern int vfs_link(struct dentry *, struct inode *, struct dentry *);
    extern int vfs_rmdir(struct inode *, struct dentry *);
    Index: vfs-2.6/fs/ecryptfs/inode.c
    ================================================== =================
    --- vfs-2.6.orig/fs/ecryptfs/inode.c 2008-04-02 21:10:15.000000000 +0200
    +++ vfs-2.6/fs/ecryptfs/inode.c 2008-04-02 21:10:17.000000000 +0200
    @@ -67,7 +67,7 @@ static void unlock_dir(struct dentry *di
    * Returns zero on success; non-zero on error condition
    */
    static int
    -ecryptfs_create_underlying_file(struct inode *lower_dir_inode,
    +ecryptfs_create_underlying_file(struct dentry *lower_dir_dentry,
    struct dentry *dentry, int mode,
    struct nameidata *nd)
    {
    @@ -79,9 +79,9 @@ ecryptfs_create_underlying_file(struct i

    dentry_save = nd->path.dentry;
    vfsmount_save = nd->path.mnt;
    - nd->path.dentry = lower_dentry;
    + nd->path.dentry = lower_dir_dentry;
    nd->path.mnt = lower_mnt;
    - rc = vfs_create(lower_dir_inode, lower_dentry, mode, nd);
    + rc = path_create(&nd->path, lower_dentry, mode, nd);
    nd->path.dentry = dentry_save;
    nd->path.mnt = vfsmount_save;
    return rc;
    @@ -117,7 +117,7 @@ ecryptfs_do_create(struct inode *directo
    rc = PTR_ERR(lower_dir_dentry);
    goto out;
    }
    - rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
    + rc = ecryptfs_create_underlying_file(lower_dir_dentry,
    ecryptfs_dentry, mode, nd);
    if (rc) {
    printk(KERN_ERR "%s: Failure to create dentry in lower fs; "
    @@ -535,20 +535,21 @@ ecryptfs_mknod(struct inode *dir, struct
    {
    int rc;
    struct dentry *lower_dentry;
    - struct dentry *lower_dir_dentry;
    + struct path lower_dir;

    lower_dentry = ecryptfs_dentry_to_lower(dentry);
    - lower_dir_dentry = lock_parent(lower_dentry);
    - rc = vfs_mknod(lower_dir_dentry->d_inode, lower_dentry, mode, dev);
    + lower_dir.mnt = ecryptfs_dentry_to_lower_mnt(dentry);
    + lower_dir.dentry = lock_parent(lower_dentry);
    + rc = path_mknod(&lower_dir, lower_dentry, mode, dev);
    if (rc || !lower_dentry->d_inode)
    goto out;
    rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
    if (rc)
    goto out;
    - fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
    - fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
    + fsstack_copy_attr_times(dir, lower_dir.dentry->d_inode);
    + fsstack_copy_inode_size(dir, lower_dir.dentry->d_inode);
    out:
    - unlock_dir(lower_dir_dentry);
    + unlock_dir(lower_dir.dentry);
    if (!dentry->d_inode)
    d_drop(dentry);
    return rc;
    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:10:14.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:10:17.000000000 +0200
    @@ -1185,6 +1185,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
    char *fname, int flen, struct iattr *iap,
    int type, dev_t rdev, struct svc_fh *resfhp)
    {
    + struct path dir_path;
    struct dentry *dentry, *dchild = NULL;
    struct inode *dirp;
    __be32 err;
    @@ -1249,13 +1250,12 @@ nfsd_create(struct svc_rqst *rqstp, stru
    iap->ia_mode = 0;
    iap->ia_mode = (iap->ia_mode & S_IALLUGO) | type;

    - /*
    - * Get the dir op function pointer.
    - */
    + dir_path.mnt = fhp->fh_export->ex_path.mnt;
    + dir_path.dentry = dentry;
    err = 0;
    switch (type) {
    case S_IFREG:
    - host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
    + host_err = path_create(&dir_path, dchild, iap->ia_mode, NULL);
    break;
    case S_IFDIR:
    host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
    @@ -1264,11 +1264,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
    case S_IFBLK:
    case S_IFIFO:
    case S_IFSOCK:
    - host_err = mnt_want_write(fhp->fh_export->ex_path.mnt);
    - if (host_err)
    - break;
    - host_err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev);
    - mnt_drop_write(fhp->fh_export->ex_path.mnt);
    + host_err = path_mknod(&dir_path, dchild, iap->ia_mode, rdev);
    break;
    default:
    printk("nfsd: bad file type %o in nfsd_create\n", type);
    @@ -1311,6 +1307,7 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
    struct svc_fh *resfhp, int createmode, u32 *verifier,
    int *truncp, int *created)
    {
    + struct path dir_path;
    struct dentry *dentry, *dchild = NULL;
    struct inode *dirp;
    __be32 err;
    @@ -1397,7 +1394,9 @@ nfsd_create_v3(struct svc_rqst *rqstp, s
    goto out;
    }

    - host_err = vfs_create(dirp, dchild, iap->ia_mode, NULL);
    + dir_path.mnt = fhp->fh_export->ex_path.mnt;
    + dir_path.dentry = dentry;
    + host_err = path_create(&dir_path, dchild, iap->ia_mode, NULL);
    if (host_err < 0)
    goto out_nfserr;
    if (created)
    Index: vfs-2.6/ipc/mqueue.c
    ================================================== =================
    --- vfs-2.6.orig/ipc/mqueue.c 2008-04-02 21:10:14.000000000 +0200
    +++ vfs-2.6/ipc/mqueue.c 2008-04-02 21:10:17.000000000 +0200
    @@ -599,6 +599,7 @@ static struct file *do_create(struct den
    {
    struct mq_attr attr;
    struct file *result;
    + struct path dir_path;
    int ret;

    if (u_attr) {
    @@ -616,7 +617,10 @@ static struct file *do_create(struct den
    ret = mnt_want_write(mqueue_mnt);
    if (ret)
    goto out;
    - ret = vfs_create(dir->d_inode, dentry, mode, NULL);
    +
    + dir_path.mnt = mqueue_mnt;
    + dir_path.dentry = dir;
    + ret = path_create(&dir_path, dentry, mode, NULL);
    dentry->d_fsdata = NULL;
    if (ret)
    goto out_drop_write;
    Index: vfs-2.6/net/unix/af_unix.c
    ================================================== =================
    --- vfs-2.6.orig/net/unix/af_unix.c 2008-04-02 21:10:14.000000000 +0200
    +++ vfs-2.6/net/unix/af_unix.c 2008-04-02 21:10:17.000000000 +0200
    @@ -819,11 +819,7 @@ static int unix_bind(struct socket *sock
    */
    mode = S_IFSOCK |
    (SOCK_INODE(sock)->i_mode & ~current->fs->umask);
    - err = mnt_want_write(nd.path.mnt);
    - if (err)
    - goto out_mknod_dput;
    - err = vfs_mknod(nd.path.dentry->d_inode, dentry, mode, 0);
    - mnt_drop_write(nd.path.mnt);
    + err = path_mknod(&nd.path, dentry, mode, 0);
    if (err)
    goto out_mknod_dput;
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);

    --
    --
    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/

  8. [patch 08/10] vfs: add path_setattr()

    From: Miklos Szeredi

    Introduce path_setattr(). Add checks to IS_IMMUTABLE(inode) and
    IS_APPEND(inode) since all callers require it. Maybe these should be
    moved into notify_change()?

    Signed-off-by: Miklos Szeredi
    ---
    fs/attr.c | 23 ++++++++++++++++-
    fs/ecryptfs/inode.c | 11 ++++----
    fs/nfsd/vfs.c | 21 +++++++++++-----
    fs/open.c | 68 ++++++----------------------------------------------
    include/linux/fs.h | 1
    5 files changed, 53 insertions(+), 71 deletions(-)

    Index: vfs-2.6/fs/open.c
    ================================================== =================
    --- vfs-2.6.orig/fs/open.c 2008-04-02 21:10:13.000000000 +0200
    +++ vfs-2.6/fs/open.c 2008-04-02 21:41:21.000000000 +0200
    @@ -578,23 +578,13 @@ asmlinkage long sys_fchmod(unsigned int

    audit_inode(NULL, dentry);

    - err = mnt_want_write(file->f_vfsmnt);
    - if (err)
    - goto out_putf;
    - err = -EPERM;
    - if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
    - goto out_drop_write;
    mutex_lock(&inode->i_mutex);
    if (mode == (mode_t) -1)
    mode = inode->i_mode;
    newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
    newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
    - err = notify_change(dentry, &newattrs);
    + err = path_setattr(&file->f_path, &newattrs);
    mutex_unlock(&inode->i_mutex);
    -
    -out_drop_write:
    - mnt_drop_write(file->f_vfsmnt);
    -out_putf:
    fput(file);
    out:
    return err;
    @@ -613,25 +603,14 @@ asmlinkage long sys_fchmodat(int dfd, co
    goto out;
    inode = nd.path.dentry->d_inode;

    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto dput_and_out;
    -
    - error = -EPERM;
    - if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
    - goto out_drop_write;
    -
    mutex_lock(&inode->i_mutex);
    if (mode == (mode_t) -1)
    mode = inode->i_mode;
    newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
    newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
    - error = notify_change(nd.path.dentry, &newattrs);
    + error = path_setattr(&nd.path, &newattrs);
    mutex_unlock(&inode->i_mutex);

    -out_drop_write:
    - mnt_drop_write(nd.path.mnt);
    -dput_and_out:
    path_put(&nd.path);
    out:
    return error;
    @@ -642,20 +621,12 @@ asmlinkage long sys_chmod(const char __u
    return sys_fchmodat(AT_FDCWD, filename, mode);
    }

    -static int chown_common(struct dentry * dentry, uid_t user, gid_t group)
    +static int chown_common(struct path *path, uid_t user, gid_t group)
    {
    - struct inode * inode;
    + struct inode *inode = path->dentry->d_inode;
    int error;
    struct iattr newattrs;

    - error = -ENOENT;
    - if (!(inode = dentry->d_inode)) {
    - printk(KERN_ERR "chown_common: NULL inode\n");
    - goto out;
    - }
    - error = -EPERM;
    - if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
    - goto out;
    newattrs.ia_valid = ATTR_CTIME;
    if (user != (uid_t) -1) {
    newattrs.ia_valid |= ATTR_UID;
    @@ -669,9 +640,8 @@ static int chown_common(struct dentry *
    newattrs.ia_valid |=
    ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;
    mutex_lock(&inode->i_mutex);
    - error = notify_change(dentry, &newattrs);
    + error = path_setattr(path, &newattrs);
    mutex_unlock(&inode->i_mutex);
    -out:
    return error;
    }

    @@ -683,12 +653,7 @@ asmlinkage long sys_chown(const char __u
    error = user_path_walk(filename, &nd);
    if (error)
    goto out;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_release;
    - error = chown_common(nd.path.dentry, user, group);
    - mnt_drop_write(nd.path.mnt);
    -out_release:
    + error = chown_common(&nd.path, user, group);
    path_put(&nd.path);
    out:
    return error;
    @@ -708,12 +673,7 @@ asmlinkage long sys_fchownat(int dfd, co
    error = __user_walk_fd(dfd, filename, follow, &nd);
    if (error)
    goto out;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_release;
    - error = chown_common(nd.path.dentry, user, group);
    - mnt_drop_write(nd.path.mnt);
    -out_release:
    + error = chown_common(&nd.path, user, group);
    path_put(&nd.path);
    out:
    return error;
    @@ -727,12 +687,7 @@ asmlinkage long sys_lchown(const char __
    error = user_path_walk_link(filename, &nd);
    if (error)
    goto out;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_release;
    - error = chown_common(nd.path.dentry, user, group);
    - mnt_drop_write(nd.path.mnt);
    -out_release:
    + error = chown_common(&nd.path, user, group);
    path_put(&nd.path);
    out:
    return error;
    @@ -749,14 +704,9 @@ asmlinkage long sys_fchown(unsigned int
    if (!file)
    goto out;

    - error = mnt_want_write(file->f_vfsmnt);
    - if (error)
    - goto out_fput;
    dentry = file->f_path.dentry;
    audit_inode(NULL, dentry);
    - error = chown_common(dentry, user, group);
    - mnt_drop_write(file->f_vfsmnt);
    -out_fput:
    + error = chown_common(&file->f_path, user, group);
    fput(file);
    out:
    return error;
    Index: vfs-2.6/fs/attr.c
    ================================================== =================
    --- vfs-2.6.orig/fs/attr.c 2008-04-02 21:10:13.000000000 +0200
    +++ vfs-2.6/fs/attr.c 2008-04-02 21:41:21.000000000 +0200
    @@ -14,6 +14,7 @@
    #include
    #include
    #include
    +#include

    /* Taken over from the old code... */

    @@ -182,5 +183,25 @@ int notify_change(struct dentry * dentry

    return error;
    }
    -
    EXPORT_SYMBOL(notify_change);
    +
    +int path_setattr(struct path *path, struct iattr *attr)
    +{
    + struct inode *inode = path->dentry->d_inode;
    + int error = mnt_want_write(path->mnt);
    +
    + if (error)
    + goto out;
    +
    + error = -EPERM;
    + if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
    + goto out_drop_write;
    +
    + error = notify_change(path->dentry, attr);
    +
    + out_drop_write:
    + mnt_drop_write(path->mnt);
    + out:
    + return error;
    +}
    +EXPORT_SYMBOL(path_setattr);
    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:37:52.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:41:21.000000000 +0200
    @@ -387,8 +387,13 @@ nfsd_setattr(struct svc_rqst *rqstp, str

    err = nfserr_notsync;
    if (!check_guard || guardtime == inode->i_ctime.tv_sec) {
    + struct path path = {
    + .mnt = fhp->fh_export->ex_path.mnt,
    + .dentry = dentry,
    + };
    +
    fh_lock(fhp);
    - host_err = notify_change(dentry, iap);
    + host_err = path_setattr(&path, iap);
    err = nfserrno(host_err);
    fh_unlock(fhp);
    }
    @@ -944,14 +949,18 @@ out:
    return err;
    }

    -static void kill_suid(struct dentry *dentry)
    +static void kill_suid(struct svc_fh *fhp)
    {
    + struct path path = {
    + .mnt = fhp->fh_export->ex_path.mnt,
    + .dentry = fhp->fh_dentry,
    + };
    struct iattr ia;
    ia.ia_valid = ATTR_KILL_SUID | ATTR_KILL_SGID | ATTR_KILL_PRIV;

    - mutex_lock(&dentry->d_inode->i_mutex);
    - notify_change(dentry, &ia);
    - mutex_unlock(&dentry->d_inode->i_mutex);
    + mutex_lock(&path.dentry->d_inode->i_mutex);
    + path_setattr(&path, &ia);
    + mutex_unlock(&path.dentry->d_inode->i_mutex);
    }

    static __be32
    @@ -1009,7 +1018,7 @@ nfsd_vfs_write(struct svc_rqst *rqstp, s

    /* clear setuid/setgid flag after write */
    if (host_err >= 0 && (inode->i_mode & (S_ISUID | S_ISGID)))
    - kill_suid(dentry);
    + kill_suid(fhp);

    if (host_err >= 0 && stable) {
    static ino_t last_ino;
    Index: vfs-2.6/include/linux/fs.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/fs.h 2008-04-02 21:37:52.000000000 +0200
    +++ vfs-2.6/include/linux/fs.h 2008-04-02 21:41:21.000000000 +0200
    @@ -1760,6 +1760,7 @@ extern int do_remount_sb(struct super_bl
    extern sector_t bmap(struct inode *, sector_t);
    #endif
    extern int notify_change(struct dentry *, struct iattr *);
    +extern int path_setattr(struct path *, struct iattr *);
    extern int permission(struct inode *, int, struct nameidata *);
    extern int generic_permission(struct inode *, int,
    int (*check_acl)(struct inode *, int));
    Index: vfs-2.6/fs/ecryptfs/inode.c
    ================================================== =================
    --- vfs-2.6.orig/fs/ecryptfs/inode.c 2008-04-02 21:37:52.000000000 +0200
    +++ vfs-2.6/fs/ecryptfs/inode.c 2008-04-02 21:41:21.000000000 +0200
    @@ -846,7 +846,7 @@ ecryptfs_permission(struct inode *inode,
    static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
    {
    int rc = 0;
    - struct dentry *lower_dentry;
    + struct path lower_path;
    struct inode *inode;
    struct inode *lower_inode;
    struct ecryptfs_crypt_stat *crypt_stat;
    @@ -856,7 +856,8 @@ static int ecryptfs_setattr(struct dentr
    ecryptfs_init_crypt_stat(crypt_stat);
    inode = dentry->d_inode;
    lower_inode = ecryptfs_inode_to_lower(inode);
    - lower_dentry = ecryptfs_dentry_to_lower(dentry);
    + lower_path.mnt = ecryptfs_dentry_to_lower_mnt(dentry);
    + lower_path.dentry = ecryptfs_dentry_to_lower(dentry);
    mutex_lock(&crypt_stat->cs_mutex);
    if (S_ISDIR(dentry->d_inode->i_mode))
    crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
    @@ -907,9 +908,9 @@ static int ecryptfs_setattr(struct dentr
    if (ia->ia_valid & (ATTR_KILL_SUID | ATTR_KILL_SGID))
    ia->ia_valid &= ~ATTR_MODE;

    - mutex_lock(&lower_dentry->d_inode->i_mutex);
    - rc = notify_change(lower_dentry, ia);
    - mutex_unlock(&lower_dentry->d_inode->i_mutex);
    + mutex_lock(&lower_path.dentry->d_inode->i_mutex);
    + rc = path_setattr(&lower_path, ia);
    + mutex_unlock(&lower_path.dentry->d_inode->i_mutex);
    out:
    fsstack_copy_attr_all(inode, lower_inode, NULL);
    return rc;

    --
    --
    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/

  9. [patch 02/10] vfs: add path_mkdir()

    From: Miklos Szeredi

    Introduce path_mkdir(). Unexport vfs_mkdir() to modules.

    The only internal user of vfs_mkdir() remaining is cgroup_clone().

    Signed-off-by: Miklos Szeredi
    ---
    fs/ecryptfs/inode.c | 15 ++++++++-------
    fs/namei.c | 21 ++++++++++++++-------
    fs/nfsd/nfs4recover.c | 6 +-----
    fs/nfsd/vfs.c | 2 +-
    include/linux/fs.h | 1 +
    5 files changed, 25 insertions(+), 20 deletions(-)

    Index: vfs-2.6/fs/ecryptfs/inode.c
    ================================================== =================
    --- vfs-2.6.orig/fs/ecryptfs/inode.c 2008-04-02 21:10:17.000000000 +0200
    +++ vfs-2.6/fs/ecryptfs/inode.c 2008-04-02 21:10:28.000000000 +0200
    @@ -487,21 +487,22 @@ static int ecryptfs_mkdir(struct inode *
    {
    int rc;
    struct dentry *lower_dentry;
    - struct dentry *lower_dir_dentry;
    + struct path lower_dir;

    lower_dentry = ecryptfs_dentry_to_lower(dentry);
    - lower_dir_dentry = lock_parent(lower_dentry);
    - rc = vfs_mkdir(lower_dir_dentry->d_inode, lower_dentry, mode);
    + lower_dir.mnt = ecryptfs_dentry_to_lower_mnt(dentry);
    + lower_dir.dentry = lock_parent(lower_dentry);
    + rc = path_mkdir(&lower_dir, lower_dentry, mode);
    if (rc || !lower_dentry->d_inode)
    goto out;
    rc = ecryptfs_interpose(lower_dentry, dentry, dir->i_sb, 0);
    if (rc)
    goto out;
    - fsstack_copy_attr_times(dir, lower_dir_dentry->d_inode);
    - fsstack_copy_inode_size(dir, lower_dir_dentry->d_inode);
    - dir->i_nlink = lower_dir_dentry->d_inode->i_nlink;
    + fsstack_copy_attr_times(dir, lower_dir.dentry->d_inode);
    + fsstack_copy_inode_size(dir, lower_dir.dentry->d_inode);
    + dir->i_nlink = lower_dir.dentry->d_inode->i_nlink;
    out:
    - unlock_dir(lower_dir_dentry);
    + unlock_dir(lower_dir.dentry);
    if (!dentry->d_inode)
    d_drop(dentry);
    return rc;
    Index: vfs-2.6/fs/namei.c
    ================================================== =================
    --- vfs-2.6.orig/fs/namei.c 2008-04-02 21:10:17.000000000 +0200
    +++ vfs-2.6/fs/namei.c 2008-04-02 21:10:28.000000000 +0200
    @@ -2144,6 +2144,19 @@ int vfs_mkdir(struct inode *dir, struct
    return error;
    }

    +int path_mkdir(struct path *dir_path, struct dentry *dentry, int mode)
    +{
    + int error = mnt_want_write(dir_path->mnt);
    +
    + if (!error) {
    + error = vfs_mkdir(dir_path->dentry->d_inode, dentry, mode);
    + mnt_drop_write(dir_path->mnt);
    + }
    +
    + return error;
    +}
    +EXPORT_SYMBOL(path_mkdir);
    +
    asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
    {
    int error = 0;
    @@ -2166,12 +2179,7 @@ asmlinkage long sys_mkdirat(int dfd, con

    if (!IS_POSIXACL(nd.path.dentry->d_inode))
    mode &= ~current->fs->umask;
    - error = mnt_want_write(nd.path.mnt);
    - if (error)
    - goto out_dput;
    - error = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
    - mnt_drop_write(nd.path.mnt);
    -out_dput:
    + error = path_mkdir(&nd.path, dentry, mode);
    dput(dentry);
    out_unlock:
    mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
    @@ -2975,7 +2983,6 @@ EXPORT_SYMBOL(file_permission);
    EXPORT_SYMBOL(unlock_rename);
    EXPORT_SYMBOL(vfs_follow_link);
    EXPORT_SYMBOL(vfs_link);
    -EXPORT_SYMBOL(vfs_mkdir);
    EXPORT_SYMBOL(generic_permission);
    EXPORT_SYMBOL(vfs_readlink);
    EXPORT_SYMBOL(vfs_rename);
    Index: vfs-2.6/fs/nfsd/nfs4recover.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/nfs4recover.c 2008-04-02 21:10:14.000000000 +0200
    +++ vfs-2.6/fs/nfsd/nfs4recover.c 2008-04-02 21:10:28.000000000 +0200
    @@ -155,11 +155,7 @@ nfsd4_create_clid_dir(struct nfs4_client
    dprintk("NFSD: nfsd4_create_clid_dir: DIRECTORY EXISTS\n");
    goto out_put;
    }
    - status = mnt_want_write(rec_dir.path.mnt);
    - if (status)
    - goto out_put;
    - status = vfs_mkdir(rec_dir.path.dentry->d_inode, dentry, S_IRWXU);
    - mnt_drop_write(rec_dir.path.mnt);
    + status = path_mkdir(&rec_dir.path, dentry, S_IRWXU);
    out_put:
    dput(dentry);
    out_unlock:
    Index: vfs-2.6/fs/nfsd/vfs.c
    ================================================== =================
    --- vfs-2.6.orig/fs/nfsd/vfs.c 2008-04-02 21:10:17.000000000 +0200
    +++ vfs-2.6/fs/nfsd/vfs.c 2008-04-02 21:10:28.000000000 +0200
    @@ -1258,7 +1258,7 @@ nfsd_create(struct svc_rqst *rqstp, stru
    host_err = path_create(&dir_path, dchild, iap->ia_mode, NULL);
    break;
    case S_IFDIR:
    - host_err = vfs_mkdir(dirp, dchild, iap->ia_mode);
    + host_err = path_mkdir(&dir_path, dchild, iap->ia_mode);
    break;
    case S_IFCHR:
    case S_IFBLK:
    Index: vfs-2.6/include/linux/fs.h
    ================================================== =================
    --- vfs-2.6.orig/include/linux/fs.h 2008-04-02 21:10:17.000000000 +0200
    +++ vfs-2.6/include/linux/fs.h 2008-04-02 21:10:28.000000000 +0200
    @@ -1125,6 +1125,7 @@ extern void unlock_super(struct super_bl
    extern int vfs_permission(struct nameidata *, int);
    extern int path_create(struct path *, struct dentry *, int, struct nameidata *);
    extern int vfs_mkdir(struct inode *, struct dentry *, int);
    +extern int path_mkdir(struct path *, struct dentry *, int);
    extern int path_mknod(struct path *, struct dentry *, int, dev_t);
    extern int vfs_symlink(struct inode *, struct dentry *, const char *, int);
    extern int vfs_link(struct dentry *, struct inode *, struct dentry *);

    --
    --
    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/

  10. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    On Wed, Apr 02, 2008 at 10:12:48PM +0200, Miklos Szeredi wrote:
    > From: Miklos Szeredi
    >
    > R/o bind mounts require operations which modify the filesystem to be
    > wrapped in mnt_want_write()/mnt_drop_write(). Create helpers which do
    > this, so callers won't need to bother, and more importantly, cannot
    > forget! Call these path_*, analogous to vfs_*. Where there are no
    > callers of vfs_* left, make them static.
    >
    > This series is a cleanup, as well as fixing several places (mostly in
    > nfsd) where mnt_{want,drop}_write() were missing.
    >
    > It will also help with merging You Know What(*) security module, which
    > needs to know the path within the namespace, and not just within the
    > filesystem. These helpers will allow the security hooks to be in a
    > common place, and need not be repeated in all callers.


    Rot.

    Places in nfsd must be fixed, LSM hooks *moved* *to* *callers*. And
    really, by that point I absolutely do not give a damn for these clowns.
    "Help with merging" implies that they can't be arsed to do _anything_
    with their code. Just as they could not be arsed to react to any
    comments (including civil ones) in any manner except "wait for a month
    and repost without changes". Sod them.

    And no, "make static where all (two of) current callers have vfsmount"
    is non-starter. path_...() is (at most) a convenience helper, not a
    fundamental interface - simply because new callers should not be
    forced into inventing a fake vfsmount just to use that.

    I'll look into missing mnt_..._write() in nfsd and fix that. The rest...
    Sorry.
    --
    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/

  11. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    On Wed, 2008-04-02 at 22:12 +0200, Miklos Szeredi wrote:
    > This series is a cleanup, as well as fixing several places (mostly in
    > nfsd) where mnt_{want,drop}_write() were missing.


    Could you elaborate on these?

    -- Dave

    --
    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/

  12. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    > > R/o bind mounts require operations which modify the filesystem to be
    > > wrapped in mnt_want_write()/mnt_drop_write(). Create helpers which do
    > > this, so callers won't need to bother, and more importantly, cannot
    > > forget! Call these path_*, analogous to vfs_*. Where there are no
    > > callers of vfs_* left, make them static.
    > >
    > > This series is a cleanup, as well as fixing several places (mostly in
    > > nfsd) where mnt_{want,drop}_write() were missing.
    > >
    > > It will also help with merging You Know What(*) security module, which
    > > needs to know the path within the namespace, and not just within the
    > > filesystem. These helpers will allow the security hooks to be in a
    > > common place, and need not be repeated in all callers.

    >
    > Rot.
    >
    > Places in nfsd must be fixed, LSM hooks *moved* *to* *callers*. And
    > really, by that point I absolutely do not give a damn for these clowns.
    > "Help with merging" implies that they can't be arsed to do _anything_
    > with their code. Just as they could not be arsed to react to any
    > comments (including civil ones) in any manner except "wait for a month
    > and repost without changes". Sod them.


    Al, calm down. I've been asked to help with merging this code, and if
    there are concerns with it, I'll help fix them. If you had bad
    experience with it in the past, I'm sorry. But let that not make this
    any harder that in need to be.

    > And no, "make static where all (two of) current callers have vfsmount"
    > is non-starter. path_...() is (at most) a convenience helper, not a
    > fundamental interface - simply because new callers should not be
    > forced into inventing a fake vfsmount just to use that.


    It is an interface with at least 3 callers at the moment: syscalls,
    nfsd and ecryptfs and unionfs in the future. It is an interface
    because all external accesses to the filesystem *are* done through the
    namespace and not directly on filesystem internals.

    Such direct access would be conceivable, but I don't think we should
    base the design on theoretically possible uses. If those uses appear,
    we can change the interface to fit that.

    This "move everything to callers" thing is wrong because it just
    results in bloat and bugs, none of which is desirable in the kernel.

    Miklos
    --
    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/

  13. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    I think these definitely all clean the code up. They might add a couple
    of lines, net, but they certainly make it easier to read. As you noted,
    they also make it much harder to screw up the locking, which is even
    better. Just looking at it from an aesthetic point of view, it looks
    good to have these helpers around.

    -- Dave

    --
    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/

  14. Re: [patch 00/10] vfs: add helpers to check r/o bind mounts

    In message <20080402201247.358430231@szeredi.hu>, Miklos Szeredi writes:
    > See first patch for description. This is against vfs-2.6 + two
    > patches I posted recently.
    >
    > It's not for -mm yet, as it needs conversion of unionfs (will that be
    > done by me, I wonder?)


    Miklos, I'll be happy to do the conversion of unionfs in -mm to use these
    path_* helpers. Is the code in these helpers going to change at all? Can I
    expect the API to remain stable?

    > Thanks,
    > Miklos


    Thanks,
    Erez.
    --
    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/

  15. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    On Wed, Apr 02, 2008 at 11:11:39PM +0200, Miklos Szeredi wrote:

    > It is an interface with at least 3 callers at the moment: syscalls,
    > nfsd and ecryptfs and unionfs in the future. It is an interface
    > because all external accesses to the filesystem *are* done through the
    > namespace and not directly on filesystem internals.
    >
    > Such direct access would be conceivable, but I don't think we should
    > base the design on theoretically possible uses. If those uses appear,
    > we can change the interface to fit that.
    >
    > This "move everything to callers" thing is wrong because it just
    > results in bloat and bugs, none of which is desirable in the kernel.


    I disagree. First of all, clear separation between operations on
    _filesystem_, which should all be namespace-agnostic and things
    that depend on vfsmount is a Good Thing(tm). Think of that as
    of separation between server (superblock and everything related
    to it, starting with dentry tree) and clients; mixing those is a
    bloody bad idea.

    What's more, I'm not at all convinced that for nfsd it's the right
    set of checks, to start with. The same goes for future users.

    As for ecryptfs, looking at their "lower_mnt" thing... I'd say that
    it's a nonsense. For one thing, duplicating a reference into ever
    dentry out there (and it's simply duplicated) makes no sense whatsoever.
    For another... I'm not at all sure that remount of the underlying
    vfsmount r/o *should* take that sucker read-only. And if it should,
    it's clearly an action that should have a visible effect on superblock
    flags of ecryptfs.

    Incidentally, looking at ecryptfs open(), WTF is protecting
    crypt_stat->flags? We take crypt_stat->cs_mutex, do nothing but
    check-and-modify of ->flags under it, then drop and several lines
    later do crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); with no ->cs_mutex
    held...
    --
    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/

  16. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    On Wed, 2008-04-02 at 22:48 +0100, Al Viro wrote:
    > I disagree. First of all, clear separation between operations on
    > _filesystem_, which should all be namespace-agnostic and things
    > that depend on vfsmount is a Good Thing(tm). Think of that as
    > of separation between server (superblock and everything related
    > to it, starting with dentry tree) and clients; mixing those is a
    > bloody bad idea.


    Speaking of which: is there any reason why we can't get rid of the
    vfsmount reference in struct file?

    Most file operations, don't involve namespace traversal at all: aside
    from fchdir(), and the *at() functions (all of which take file
    descriptors, not pointers to struct file) the only function of that
    vfsmount reference appears to be to prevent the superblock from going
    away.

    Cheers
    Trond

    --
    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/

  17. Re: [patch 02/10] vfs: add path_mkdir()

    In message <20080402201322.317327738@szeredi.hu>, Miklos Szeredi writes:
    > From: Miklos Szeredi
    >
    > Introduce path_mkdir(). Unexport vfs_mkdir() to modules.
    >
    > The only internal user of vfs_mkdir() remaining is cgroup_clone().


    > +EXPORT_SYMBOL(path_mkdir);


    Shouldn't all new exported symbols use EXPORT_SYMBOL_GPL?

    Erez.
    --
    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/

  18. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    On Wed, Apr 02, 2008 at 06:21:30PM -0400, Trond Myklebust wrote:
    > On Wed, 2008-04-02 at 22:48 +0100, Al Viro wrote:
    > > I disagree. First of all, clear separation between operations on
    > > _filesystem_, which should all be namespace-agnostic and things
    > > that depend on vfsmount is a Good Thing(tm). Think of that as
    > > of separation between server (superblock and everything related
    > > to it, starting with dentry tree) and clients; mixing those is a
    > > bloody bad idea.

    >
    > Speaking of which: is there any reason why we can't get rid of the
    > vfsmount reference in struct file?
    >
    > Most file operations, don't involve namespace traversal at all: aside
    > from fchdir(), and the *at() functions (all of which take file
    > descriptors, not pointers to struct file) the only function of that
    > vfsmount reference appears to be to prevent the superblock from going
    > away.


    Huh? Are you proposing to move that to descriptor table, of all things?
    Not to mention SCM_RIGHTS datagrams and hell knows what else...
    --
    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/

  19. Re: [patch 01/10] vfs: add path_create() and path_mknod()


    On Wed, 2008-04-02 at 23:36 +0100, Al Viro wrote:
    > On Wed, Apr 02, 2008 at 06:21:30PM -0400, Trond Myklebust wrote:
    > > On Wed, 2008-04-02 at 22:48 +0100, Al Viro wrote:
    > > > I disagree. First of all, clear separation between operations on
    > > > _filesystem_, which should all be namespace-agnostic and things
    > > > that depend on vfsmount is a Good Thing(tm). Think of that as
    > > > of separation between server (superblock and everything related
    > > > to it, starting with dentry tree) and clients; mixing those is a
    > > > bloody bad idea.

    > >
    > > Speaking of which: is there any reason why we can't get rid of the
    > > vfsmount reference in struct file?
    > >
    > > Most file operations, don't involve namespace traversal at all: aside
    > > from fchdir(), and the *at() functions (all of which take file
    > > descriptors, not pointers to struct file) the only function of that
    > > vfsmount reference appears to be to prevent the superblock from going
    > > away.

    >
    > Huh? Are you proposing to move that to descriptor table, of all things?
    > Not to mention SCM_RIGHTS datagrams and hell knows what else...


    I'm just suggesting splitting out the namespace-specific part of struct
    file into a separate structure that would be private to the VFS.
    Something like

    struct file_descriptor {
    struct file *file;
    struct vfsmount *mnt;
    atomic_t refcount;
    };

    and then having the 'struct file' hold a reference to the superblock
    instead of holding a reference to the vfsmount.

    Why would that be problematic for SCM_RIGHTS? We don't allow people to
    send arbitrary references to 'struct file' using SCM_RIGHTS now; they
    have to send descriptors.

    --
    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/

  20. Re: [patch 01/10] vfs: add path_create() and path_mknod()

    On Wed, Apr 02, 2008 at 07:19:58PM -0400, Trond Myklebust wrote:

    > I'm just suggesting splitting out the namespace-specific part of struct
    > file into a separate structure that would be private to the VFS.
    > Something like
    >
    > struct file_descriptor {
    > struct file *file;
    > struct vfsmount *mnt;
    > atomic_t refcount;
    > };
    >
    > and then having the 'struct file' hold a reference to the superblock
    > instead of holding a reference to the vfsmount.
    >
    > Why would that be problematic for SCM_RIGHTS? We don't allow people to
    > send arbitrary references to 'struct file' using SCM_RIGHTS now; they
    > have to send descriptors.


    HUH? Descriptor is a number. There is no struct file_descriptor,
    let alone refcounting for such. There is a table, indexed by number
    and containing references to struct file.

    If you want to shove pointer to vfsmount in there (what for? to waste
    some memory and make SMP protection on access more interesting?), you
    could do that, but IMO it's too ugly to consider.

    Anyway, what the hell for? It's more complex and buys you nothing
    useful.
    --
    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/

+ Reply to Thread
Page 1 of 2 1 2 LastLast