From: Miklos Szeredi <mszeredi@xxxxxxx> Move most calls of dentry_permission() to path_permission(). The remaining few uses are all in namei.c, so dentry_permission() can be made static, further simplifying the API. This will have the side effect, that MNT_NOEXEC checking on the mount will be performed for these callers as well. But this should not cause any problems. At this point file_permission() is just a helper for path_permission(), so remove comment about not being preferred. Signed-off-by: Miklos Szeredi <mszeredi@xxxxxxx> --- fs/ecryptfs/inode.c | 7 +++++-- fs/namei.c | 12 +++--------- fs/nfsd/nfsfh.c | 11 ++++++----- fs/nfsd/vfs.c | 8 ++++++-- fs/xattr.c | 22 ++++++++++++---------- include/linux/fs.h | 1 - ipc/mqueue.c | 15 +++++++++------ 7 files changed, 41 insertions(+), 35 deletions(-) Index: linux-2.6/fs/ecryptfs/inode.c =================================================================== --- linux-2.6.orig/fs/ecryptfs/inode.c 2008-05-21 18:16:31.000000000 +0200 +++ linux-2.6/fs/ecryptfs/inode.c 2008-05-21 18:17:08.000000000 +0200 @@ -810,9 +810,12 @@ out: static int ecryptfs_permission(struct dentry *dentry, int mask, int flags) { - struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); + struct path lower_path; + + lower_path.mnt = ecryptfs_dentry_to_lower_mnt(dentry); + lower_path.dentry = ecryptfs_dentry_to_lower(dentry); - return dentry_permission(lower_dentry, mask, flags); + return path_permission(&lower_path, mask, flags); } /** Index: linux-2.6/fs/namei.c =================================================================== --- linux-2.6.orig/fs/namei.c 2008-05-21 18:16:31.000000000 +0200 +++ linux-2.6/fs/namei.c 2008-05-21 18:17:08.000000000 +0200 @@ -246,7 +246,7 @@ int exec_permission(struct inode *inode, return 0; } -int dentry_permission(struct dentry *dentry, int mask, int flags) +static int dentry_permission(struct dentry *dentry, int mask, int flags) { struct inode *inode = dentry->d_inode; int retval, submask; @@ -320,16 +320,11 @@ int path_permission(struct path *path, i * @file: file to check access rights for * @mask: right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC) * - * Used to check for read/write/execute permissions on an already opened - * file. - * - * Note: - * Do not use this function in new code. All access checks should - * be done using path_permission(). + * This is a helper for path_permission(). */ int file_permission(struct file *file, int mask) { - return dentry_permission(file->f_path.dentry, mask, 0); + return path_permission(&file->f_path, mask, 0); } /* @@ -3061,7 +3056,6 @@ EXPORT_SYMBOL(page_symlink); EXPORT_SYMBOL(page_symlink_inode_operations); EXPORT_SYMBOL(path_lookup); EXPORT_SYMBOL(vfs_path_lookup); -EXPORT_SYMBOL(dentry_permission); EXPORT_SYMBOL(path_permission); EXPORT_SYMBOL(file_permission); EXPORT_SYMBOL(unlock_rename); Index: linux-2.6/fs/nfsd/nfsfh.c =================================================================== --- linux-2.6.orig/fs/nfsd/nfsfh.c 2008-05-21 18:16:31.000000000 +0200 +++ linux-2.6/fs/nfsd/nfsfh.c 2008-05-21 18:17:08.000000000 +0200 @@ -41,7 +41,7 @@ static int nfsd_acceptable(void *expv, s struct svc_export *exp = expv; int rv; struct dentry *tdentry; - struct dentry *parent; + struct path parent = { .mnt = exp->ex_path.mnt }; if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) return 1; @@ -50,14 +50,15 @@ static int nfsd_acceptable(void *expv, s while (tdentry != exp->ex_path.dentry && !IS_ROOT(tdentry)) { /* make sure parents give x permission to user */ int err; - parent = dget_parent(tdentry); - err = dentry_permission(parent, MAY_EXEC, 0); + + parent.dentry = dget_parent(tdentry); + err = path_permission(&parent, MAY_EXEC, 0); if (err < 0) { - dput(parent); + dput(parent.dentry); break; } dput(tdentry); - tdentry = parent; + tdentry = parent.dentry; } if (tdentry != exp->ex_path.dentry) dprintk("nfsd_acceptable failed at %p %s\n", tdentry, tdentry->d_name.name); Index: linux-2.6/fs/nfsd/vfs.c =================================================================== --- linux-2.6.orig/fs/nfsd/vfs.c 2008-05-21 18:16:31.000000000 +0200 +++ linux-2.6/fs/nfsd/vfs.c 2008-05-21 18:17:08.000000000 +0200 @@ -1878,6 +1878,10 @@ nfsd_permission(struct svc_rqst *rqstp, { struct inode *inode = dentry->d_inode; int err; + struct path path = { + .mnt = exp->ex_path.mnt, + .dentry = dentry, + }; if (acc == MAY_NOP) return 0; @@ -1942,12 +1946,12 @@ nfsd_permission(struct svc_rqst *rqstp, inode->i_uid == current->fsuid) return 0; - err = dentry_permission(dentry, acc & (MAY_READ|MAY_WRITE|MAY_EXEC), 0); + err = path_permission(&path, acc & (MAY_READ|MAY_WRITE|MAY_EXEC), 0); /* Allow read access to binaries even when mode 111 */ if (err == -EACCES && S_ISREG(inode->i_mode) && acc == (MAY_READ | MAY_OWNER_OVERRIDE)) - err = dentry_permission(dentry, MAY_EXEC, 0); + err = path_permission(&path, MAY_EXEC, 0); return err? nfserrno(err) : 0; } Index: linux-2.6/ipc/mqueue.c =================================================================== --- linux-2.6.orig/ipc/mqueue.c 2008-05-21 18:16:31.000000000 +0200 +++ linux-2.6/ipc/mqueue.c 2008-05-21 18:17:08.000000000 +0200 @@ -647,19 +647,22 @@ static struct file *do_open(struct dentr static int oflag2acc[O_ACCMODE] = { MAY_READ, MAY_WRITE, MAY_READ | MAY_WRITE }; + struct path path = { + .mnt = mqueue_mnt, + .dentry = dentry, + }; + if ((oflag & O_ACCMODE) == (O_RDWR | O_WRONLY)) { - dput(dentry); - mntput(mqueue_mnt); + path_put(&path); return ERR_PTR(-EINVAL); } - if (dentry_permission(dentry, oflag2acc[oflag & O_ACCMODE], 0)) { - dput(dentry); - mntput(mqueue_mnt); + if (path_permission(&path, oflag2acc[oflag & O_ACCMODE], 0)) { + path_put(&path); return ERR_PTR(-EACCES); } - return dentry_open(dentry, mqueue_mnt, oflag); + return dentry_open(path.dentry, path.mnt, oflag); } asmlinkage long sys_mq_open(const char __user *u_name, int oflag, mode_t mode, Index: linux-2.6/fs/xattr.c =================================================================== --- linux-2.6.orig/fs/xattr.c 2008-05-21 18:16:31.000000000 +0200 +++ linux-2.6/fs/xattr.c 2008-05-21 18:17:08.000000000 +0200 @@ -26,9 +26,9 @@ * because different namespaces have very different rules. */ static int -xattr_permission(struct dentry *dentry, const char *name, int mask) +xattr_permission(struct path *path, const char *name, int mask) { - struct inode *inode = dentry->d_inode; + struct inode *inode = path->dentry->d_inode; /* * We can never set or remove an extended attribute on a read-only @@ -65,17 +65,18 @@ xattr_permission(struct dentry *dentry, return -EPERM; } - return dentry_permission(dentry, mask, 0); + return path_permission(path, mask, 0); } static int -vfs_setxattr(struct dentry *dentry, const char *name, const void *value, +vfs_setxattr(struct path *path, const char *name, const void *value, size_t size, int flags) { + struct dentry *dentry = path->dentry; struct inode *inode = dentry->d_inode; int error; - error = xattr_permission(dentry, name, MAY_WRITE); + error = xattr_permission(path, name, MAY_WRITE); if (error) return error; @@ -110,7 +111,7 @@ int path_setxattr(struct path *path, con int error = mnt_want_write(path->mnt); if (!error) { - error = vfs_setxattr(path->dentry, name, value, size, flags); + error = vfs_setxattr(path, name, value, size, flags); mnt_drop_write(path->mnt); } @@ -152,7 +153,7 @@ path_getxattr(struct path *path, const c struct inode *inode = dentry->d_inode; int error; - error = xattr_permission(dentry, name, MAY_READ); + error = xattr_permission(path, name, MAY_READ); if (error) return error; @@ -204,15 +205,16 @@ path_listxattr(struct path *path, char * EXPORT_SYMBOL_GPL(path_listxattr); static int -vfs_removexattr(struct dentry *dentry, const char *name) +vfs_removexattr(struct path *path, const char *name) { + struct dentry *dentry = path->dentry; struct inode *inode = dentry->d_inode; int error; if (!inode->i_op->removexattr) return -EOPNOTSUPP; - error = xattr_permission(dentry, name, MAY_WRITE); + error = xattr_permission(path, name, MAY_WRITE); if (error) return error; @@ -234,7 +236,7 @@ int path_removexattr(struct path *path, int error = mnt_want_write(path->mnt); if (!error) { - error = vfs_removexattr(path->dentry, name); + error = vfs_removexattr(path, name); mnt_drop_write(path->mnt); } Index: linux-2.6/include/linux/fs.h =================================================================== --- linux-2.6.orig/include/linux/fs.h 2008-05-21 18:15:02.000000000 +0200 +++ linux-2.6/include/linux/fs.h 2008-05-21 18:17:08.000000000 +0200 @@ -1758,7 +1758,6 @@ extern sector_t bmap(struct inode *, sec #endif extern int notify_change(struct dentry *, struct iattr *); extern int path_setattr(struct path *, struct iattr *); -extern int dentry_permission(struct dentry *, int, int); extern int generic_permission(struct inode *, int, int (*check_acl)(struct inode *, int)); extern int exec_permission(struct inode *, int); -- -- To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html