This patch allows LSM hooks refer previously associated "struct vfsmount" parameter so that they can calculate pathname of given "struct dentry". Signed-off-by: Tetsuo Handa --- include/linux/fs.h | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) --- linux-2.6-mm.orig/include/linux/fs.h 2007-11-14 15:14:52.000000000 +0900 +++ linux-2.6-mm/include/linux/fs.h 2007-11-14 15:20:32.000000000 +0900 @@ -1086,6 +1086,116 @@ extern int vfs_rmdir(struct inode *, str extern int vfs_unlink(struct inode *, struct dentry *); extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); +#include +#include + +static inline int vfs_create2(struct inode *dir, struct dentry *dentry, + int mode, struct nameidata *nd) +{ + int ret; + struct vfsmount *mnt = nd ? nd->path.mnt : NULL; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_create(dir, dentry, mode, nd); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + +static inline int vfs_mkdir2(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_mkdir(dir, dentry, mode); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + +static inline int vfs_mknod2(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, int mode, dev_t dev) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_mknod(dir, dentry, mode, dev); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + +static inline int vfs_symlink2(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt, const char *oldname, + int mode) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_symlink(dir, dentry, oldname, mode); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + +static inline int vfs_link2(struct dentry *old_dentry, struct inode *dir, + struct dentry *new_dentry, struct vfsmount *mnt) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_link(old_dentry, dir, new_dentry); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + +static inline int vfs_rmdir2(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_rmdir(dir, dentry); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + +static inline int vfs_unlink2(struct inode *dir, struct dentry *dentry, + struct vfsmount *mnt) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_unlink(dir, dentry); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + +static inline int vfs_rename2(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry, + struct vfsmount *mnt) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = vfs_rename(old_dir, old_dentry, new_dir, new_dentry); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + /* * VFS dentry helper functions. */ @@ -1548,6 +1658,21 @@ static inline int break_lease(struct ino extern int do_truncate(struct dentry *, loff_t start, unsigned int time_attrs, struct file *filp); + +static inline int do_truncate2(struct dentry *dentry, struct vfsmount *mnt, + loff_t length, unsigned int time_attrs, + struct file *filp) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = do_truncate(dentry, length, time_attrs, filp); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + extern long do_sys_open(int dfd, const char __user *filename, int flags, int mode); extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); @@ -1708,6 +1833,19 @@ extern int permission(struct inode *, in extern int generic_permission(struct inode *, int, int (*check_acl)(struct inode *, int)); +static inline int notify_change2(struct dentry *dentry, struct vfsmount *mnt, + struct iattr *attr) +{ + int ret; + struct task_struct *task = current; + struct vfsmount *prev_mnt = task->last_vfsmount; + task->last_vfsmount = mntget(mnt); + ret = notify_change(dentry, attr); + task->last_vfsmount = prev_mnt; + mntput(mnt); + return ret; +} + extern int get_write_access(struct inode *); extern int deny_write_access(struct file *); static inline void put_write_access(struct inode * inode) -- - 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/