OpenVZ Forum - RDF feed
type: channel
items: [PATCH 00/25] Mount writer count and read-only bind mounts (v7)
items: [PATCH 01/25] filesystem helpers for custom 'struct file's
items: [PATCH 02/25] introduce simple_set_mnt_no_get() helper for NFS
items: [PATCH 04/25] Add vfsmount writer count
items: [PATCH 06/25] kill open files traverse on remount ro
items: [PATCH 07/25] elevate writer count for chown and friends
items: [PATCH 08/25] elevate mnt writers for callers of vfs_mkdir()
items: [PATCH 09/25] elevate write count during entire ncp_ioctl()
items: [PATCH 11/25] elevate mount count for extended attributes
items: [PATCH 12/25] mount_is_safe(): add comment
items: [PATCH 14/25] elevate write count over calls to vfs_rename()
items: [PATCH 15/25] elevate write count files are open()ed
items: [PATCH 16/25] elevate writer count for do_sys_truncate()
items: [PATCH 18/25] elevate write count for do_sys_utime() and touch_atime()
items: [PATCH 19/25] sys_mknodat(): elevate write count for vfs_mknod/create()
items: [PATCH 20/25] elevate mnt writers for vfs_unlink() callers
items: [PATCH 21/25] do_rmdir(): elevate write count
items: [PATCH 23/25] elevate writer count for custom struct_file
items: [PATCH 24/25] honor r/w changes at do_remount() time
items: [PATCH 25/25] add kerneldoc for i_nlink helpers
items: Re: [PATCH 01/25] filesystem helpers for custom 'struct file's

[PATCH 00/25] Mount writer count and read-only bind mounts (v7)
type: item
description: I figured I'd run this past the containers list one more time. These are against 2.6.19-mm1. They compile, boot and pass my little attached test script. Changes from previous version - rework helper names for doing custom 'struct file' creation --- The following series implements read-only bind mounts. This feature allows a read-only view into a read-write filesystem. In the process of doing that, it also provides infrastructure for keeping track of the number of writers to any given mount. In this version, if there are writers on a superblock, the filesystem may not be remounted r/o. The same goes for MS_BIND mounts, and writers on a vfsmount. This has a number of uses. It allows chroots to have parts of filesystems writable. It will be useful for containers in the future and is intended to replace patches that vserver has had out of the tree for several years. It allows security enhancement by making sure that parts of your filesystem read-only, when you don't want to have entire new filesystems mounted, or when you want atime selectively updated. This set makes no attempt to keep the return codes for these r/o bind mounts the same as for a real r/o filesystem or device. It would require significantly more code and be quite a bit more invasive. Using this feature requires two steps: mount --bind /source /dest mount -o remount,ro /dest I've been using the following script to test that the feature is working as desired. It takes a directory and makes a regular bind and a r/o bind mount of it. It then performs some normal filesystem operations on the three directories, including ones that are expected to fail, like creating a file on the r/o mount. #!/bin/sh DIRS="foo foo-bound foo-bound-ro" set -e function do_umount { ( umount foo-bound || true; umount foo-bound-ro || true; ) 2> /dev/null } trap do_umount ERR # just in case the last invocation left them do_umount function should_fail { "$@" > /dev/null 2>&1 \ && echo unexpected success: "$@" \ || echo GOOD: expected…
creator: Dave Hansen
date: 2006-12-11T22:30:00-00:00

[PATCH 01/25] filesystem helpers for custom 'struct file's
type: item
description: Some filesystems forego the vfs and may_open() and create their own 'struct file's. This patch creates a couple of helper functions which can be used by these filesystems, and will provide a unified place which the r/o bind mount code may patch. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/file_table.c | 30 ++++++++++++++++++++++++++++++ lxc-dave/fs/hugetlbfs/inode.c | 22 +++++++++------------- lxc-dave/include/linux/file.h | 8 ++++++++ lxc-dave/mm/shmem.c | 7 ++----- lxc-dave/mm/tiny-shmem.c | 24 +++++++++--------------- lxc-dave/net/socket.c | 18 +++++++++--------- 6 files changed, 67 insertions(+), 42 deletions(-) diff -puN fs/file_table.c~01-24-filesystem-helpers-for-custom-struct-file-s fs/file_table.c --- lxc/fs/file_table.c~01-24-filesystem-helpers-for-custom-struct-file-s 2006-12-11 14:21:56.000000000 -0800 +++ lxc-dave/fs/file_table.c 2006-12-11 14:21:56.000000000 -0800 @@ -139,6 +139,36 @@ fail: EXPORT_SYMBOL(get_empty_filp); +struct file *alloc_file(struct vfsmount *mnt, struct dentry *dentry, + mode_t mode, const struct file_operations *fop) +{ + struct file *file; + + file = get_empty_filp(); + if (!file) + return NULL; + + init_file(file, mnt, dentry, mode, fop); + return file; +} + +EXPORT_SYMBOL(alloc_file); + +int init_file(struct file *file, struct vfsmount *mnt, + struct dentry *dentry, mode_t mode, + const struct file_operations *fop) +{ + int error = 0; + file->f_vfsmnt = mntget(mnt); + file->f_dentry = dentry; + file->f_mapping = dentry->d_inode->i_mapping; + file->f_mode = mode; + file->f_op = fop; + return error; +} + +EXPORT_SYMBOL(init_file); + void fastcall fput(struct file *file) { if (atomic_dec_and_test(&file->f_count)) diff -puN fs/hugetlbfs/inode.c~01-24-filesystem-helpers-for-custom-struct-file-s fs/hugetlbfs/inode.c --- lxc/fs/hugetlbfs/inode.c~01-24-filesystem-helpers-for-custom-struct-file-s 2006-12-11 14:21:56.000000000 -0800 +++ lxc-dave/fs/hugetlbfs/inode.c 2006-12-11 14:21:56.000000000 -0800 @@ -756,16 +756…
creator: Dave Hansen
date: 2006-12-11T22:30:02-00:00

[PATCH 02/25] introduce simple_set_mnt_no_get() helper for NFS
type: item
description: The next patch will introduce a list of all mounts for a given superblock. In order to keep the list, we need to make sure all filesystems attaching a mount to a superblock get added to this list. NFS currently bypasses the simple_set_mnt() function, and sets mnt_sb directly. This patch makes it use a helper function, instead. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namespace.c | 13 ++++++++++--- lxc-dave/fs/nfs/super.c | 10 +++++----- lxc-dave/include/linux/fs.h | 1 + 3 files changed, 16 insertions(+), 8 deletions(-) diff -puN fs/namespace.c~reintroduce-list-of-vfsmounts-over-superblock fs/namespace.c --- lxc/fs/namespace.c~reintroduce-list-of-vfsmounts-over-superblock 2006-12-11 14:21:57.000000000 -0800 +++ lxc-dave/fs/namespace.c 2006-12-11 14:21:57.000000000 -0800 @@ -77,13 +77,20 @@ struct vfsmount *alloc_vfsmnt(const char return mnt; } -int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) +int simple_set_mnt_no_get(struct vfsmount *mnt, struct super_block *sb) { - mnt->mnt_sb = sb; - mnt->mnt_root = dget(sb->s_root); + mnt->mnt_sb = sb; return 0; } +EXPORT_SYMBOL(simple_set_mnt_no_get); + +int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb) +{ + mnt->mnt_root = dget(sb->s_root); + return simple_set_mnt_no_get(mnt, sb); +} + EXPORT_SYMBOL(simple_set_mnt); void free_vfsmnt(struct vfsmount *mnt) diff -puN fs/nfs/super.c~reintroduce-list-of-vfsmounts-over-superblock fs/nfs/super.c --- lxc/fs/nfs/super.c~reintroduce-list-of-vfsmounts-over-superblock 2006-12-11 14:21:57.000000000 -0800 +++ lxc-dave/fs/nfs/super.c 2006-12-11 14:21:57.000000000 -0800 @@ -653,7 +653,7 @@ static int nfs_get_sb(struct file_system } s->s_flags |= MS_ACTIVE; - mnt->mnt_sb = s; + simple_set_mnt_no_get(mnt, s); mnt->mnt_root = mntroot; return 0; @@ -726,7 +726,7 @@ static int nfs_xdev_get_sb(struct file_s } s->s_flags |= MS_ACTIVE; - mnt->mnt_sb = s; + simple_set_mnt_no_get(mnt, s); mnt->mnt_root = mntroot; dprintk("<-- nfs_xdev_get_sb() = 0\…
creator: Dave Hansen
date: 2006-12-11T22:30:03-00:00

[PATCH 04/25] Add vfsmount writer count
type: item
description: Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namespace.c | 63 +++++++++++++++++++++++++++++++++++++++ lxc-dave/fs/super.c | 66 +++++++++++++++++++++++++++++++++++++---- lxc-dave/include/linux/fs.h | 2 + lxc-dave/include/linux/mount.h | 18 +++++++++++ 4 files changed, 144 insertions(+), 5 deletions(-) diff -puN fs/namespace.c~03-24-add-vfsmount-writer-count fs/namespace.c --- lxc/fs/namespace.c~03-24-add-vfsmount-writer-count 2006-12-11 14:21:58.000000000 -0800 +++ lxc-dave/fs/namespace.c 2006-12-11 14:21:58.000000000 -0800 @@ -57,6 +57,7 @@ struct vfsmount *alloc_vfsmnt(const char if (mnt) { memset(mnt, 0, sizeof(struct vfsmount)); atomic_set(&mnt->mnt_count, 1); + atomic_set(&mnt->mnt_writers, 0); INIT_LIST_HEAD(&mnt->mnt_hash); INIT_LIST_HEAD(&mnt->mnt_child); INIT_LIST_HEAD(&mnt->mnt_mounts); @@ -894,6 +895,60 @@ out_unlock: return err; } +int mnt_make_readonly(struct vfsmount *mnt) +{ + int ret = 0; + + WARN_ON(__mnt_is_readonly(mnt)); + + /* + * This flag set is actually redundant with what + * happens in do_remount(), but since we do this + * under the lock, anyone attempting to get a write + * on it after this will fail. + */ + spin_lock(&mnt->mnt_sb->s_mnt_writers_lock); + if (!atomic_read(&mnt->mnt_writers)) + mnt->mnt_flags |= MNT_READONLY; + else + ret = -EBUSY; + spin_unlock(&mnt->mnt_sb->s_mnt_writers_lock); + return ret; +} + +int mnt_want_write(struct vfsmount *mnt) +{ + int ret = 0; +repeat: + if (atomic_add_unless(&mnt->mnt_writers, 1, 0)) + return 0; + + spin_lock(&mnt->mnt_sb->s_mnt_writers_lock); + if (__mnt_is_readonly(mnt)) { + ret = -EROFS; + goto out; + } + if (atomic_add_return(1, &mnt->mnt_writers) != 1) { + atomic_dec(&mnt->mnt_writers); + spin_unlock(&mnt->mnt_sb->s_mnt_writers_lock); + goto repeat; + } + atomic_inc(&mnt->mnt_sb->s_mnt_writers); +out: + spin_unlock(&mnt->mnt_sb->s_mnt_writers_lock); + return ret; +} + +void mnt_drop_write(struct vfsmount *mnt) +{ + if (!atomic_dec_and_lock(&mnt->mnt_writers, + &mnt->mn…
creator: Dave Hansen
date: 2006-12-11T22:30:04-00:00

[PATCH 06/25] kill open files traverse on remount ro
type: item
description: Now that we have the sb writer count, we don't need to go looking at all of the individual open files. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/file_table.c | 25 ------------------------- lxc-dave/fs/super.c | 1 - lxc-dave/include/linux/fs.h | 2 -- 3 files changed, 28 deletions(-) diff -puN fs/file_table.c~05-24-kill-open-files-traverse-on-remount-ro fs/file_table.c --- lxc/fs/file_table.c~05-24-kill-open-files-traverse-on-remount-ro 2006-12-11 14:22:00.000000000 -0800 +++ lxc-dave/fs/file_table.c 2006-12-11 14:22:00.000000000 -0800 @@ -293,31 +293,6 @@ void file_kill(struct file *file) } } -int fs_may_remount_ro(struct super_block *sb) -{ - struct list_head *p; - - /* Check that no files are currently opened for writing. */ - file_list_lock(); - list_for_each(p, &sb->s_files) { - struct file *file = list_entry(p, struct file, f_u.fu_list); - struct inode *inode = file->f_path.dentry->d_inode; - - /* File with pending delete? */ - if (inode->i_nlink == 0) - goto too_bad; - - /* Writeable file? */ - if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE)) - goto too_bad; - } - file_list_unlock(); - return 1; /* Tis' cool bro. */ -too_bad: - file_list_unlock(); - return 0; -} - void __init files_init(unsigned long mempages) { int n; diff -puN fs/super.c~05-24-kill-open-files-traverse-on-remount-ro fs/super.c --- lxc/fs/super.c~05-24-kill-open-files-traverse-on-remount-ro 2006-12-11 14:22:00.000000000 -0800 +++ lxc-dave/fs/super.c 2006-12-11 14:22:00.000000000 -0800 @@ -606,7 +606,6 @@ static void sb_mounts_clear_flag(struct static int sb_remount_ro(struct super_block *sb) { - return fs_may_remount_ro(sb); spin_lock(&sb->s_mnt_writers_lock); if (atomic_read(&sb->s_mnt_writers) > 0) { spin_unlock(&sb->s_mnt_writers_lock); diff -puN include/linux/fs.h~05-24-kill-open-files-traverse-on-remount-ro include/linux/fs.h --- lxc/include/linux/fs.h~05-24-kill-open-files-traverse-on-remount-ro 2006-12-11 14:22:00.000000000 -0800 +++ lxc-dave/include/lin…
creator: Dave Hansen
date: 2006-12-11T22:30:05-00:00

[PATCH 07/25] elevate writer count for chown and friends
type: item
description: chown/chmod,etc... don't call permission in the same way that the normal "open for write" calls do. They still write to the filesystem, so bump the write count during these operations. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/open.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff -puN fs/open.c~06-24-elevate-writer-count-for-chown-and-friends fs/open.c --- lxc/fs/open.c~06-24-elevate-writer-count-for-chown-and-friends 2006-12-11 14:22:01.000000000 -0800 +++ lxc-dave/fs/open.c 2006-12-11 14:22:01.000000000 -0800 @@ -511,9 +511,12 @@ asmlinkage long sys_fchmod(unsigned int err = -EROFS; if (IS_RDONLY(inode)) goto out_putf; + err = mnt_want_write(file->f_vfsmnt); + if (err) + goto out_putf; err = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out_putf; + goto out_drop_write; mutex_lock(&inode->i_mutex); if (mode == (mode_t) -1) mode = inode->i_mode; @@ -522,6 +525,8 @@ asmlinkage long sys_fchmod(unsigned int err = notify_change(dentry, &newattrs); mutex_unlock(&inode->i_mutex); +out_drop_write: + mnt_drop_write(file->f_vfsmnt); out_putf: fput(file); out: @@ -541,13 +546,16 @@ asmlinkage long sys_fchmodat(int dfd, co goto out; inode = nd.dentry->d_inode; + error = mnt_want_write(nd.mnt); + if (error) + goto dput_and_out; error = -EROFS; if (IS_RDONLY(inode)) - goto dput_and_out; + goto out_drop_write; error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto dput_and_out; + goto out_drop_write; mutex_lock(&inode->i_mutex); if (mode == (mode_t) -1) @@ -557,6 +565,8 @@ asmlinkage long sys_fchmodat(int dfd, co error = notify_change(nd.dentry, &newattrs); mutex_unlock(&inode->i_mutex); +out_drop_write: + mnt_drop_write(nd.mnt); dput_and_out: path_release(&nd); out: @@ -582,7 +592,7 @@ static int chown_common(struct dentry * error = -EROFS; if (IS_RDONLY(inode)) goto out; - error = -EPERM; + error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) goto out; newattrs.ia_valid =…
creator: Dave Hansen
date: 2006-12-11T22:30:06-00:00

[PATCH 08/25] elevate mnt writers for callers of vfs_mkdir()
type: item
description: Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namei.c | 5 +++++ lxc-dave/fs/nfsd/nfs4recover.c | 4 ++++ 2 files changed, 9 insertions(+) diff -puN fs/namei.c~07-24-elevate-mnt-writers-for-callers-of-vfs-mkdir fs/namei.c --- lxc/fs/namei.c~07-24-elevate-mnt-writers-for-callers-of-vfs-mkdir 2006-12-11 14:22:01.000000000 -0800 +++ lxc-dave/fs/namei.c 2006-12-11 14:22:01.000000000 -0800 @@ -1959,7 +1959,12 @@ asmlinkage long sys_mkdirat(int dfd, con if (!IS_POSIXACL(nd.dentry->d_inode)) mode &= ~current->fs->umask; + error = mnt_want_write(nd.mnt); + if (error) + goto out_dput; error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); + mnt_drop_write(nd.mnt); +out_dput: dput(dentry); out_unlock: mutex_unlock(&nd.dentry->d_inode->i_mutex); diff -puN fs/nfsd/nfs4recover.c~07-24-elevate-mnt-writers-for-callers-of-vfs-mkdir fs/nfsd/nfs4recover.c --- lxc/fs/nfsd/nfs4recover.c~07-24-elevate-mnt-writers-for-callers-of-vfs-mkdir 2006-12-11 14:22:01.000000000 -0800 +++ lxc-dave/fs/nfsd/nfs4recover.c 2006-12-11 14:22:01.000000000 -0800 @@ -156,7 +156,11 @@ 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.mnt); + if (status) + goto out_put; status = vfs_mkdir(rec_dir.dentry->d_inode, dentry, S_IRWXU); + mnt_drop_write(rec_dir.mnt); out_put: dput(dentry); out_unlock: _ _______________________________________________ Containers mailing list Containers@lists.osdl.org https://lists.osdl.org/mailman/listinfo/containers
creator: Dave Hansen
date: 2006-12-11T22:30:07-00:00

[PATCH 09/25] elevate write count during entire ncp_ioctl()
type: item
description: Some ioctls need write access, but others don't. Make a helper function to decide when write access is needed, and take it. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/ncpfs/ioctl.c | 55 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff -puN fs/ncpfs/ioctl.c~08-24-elevate-write-count-during-entire-ncp-ioctl fs/ncpfs/ioctl.c --- lxc/fs/ncpfs/ioctl.c~08-24-elevate-write-count-during-entire-ncp-ioctl 2006-12-11 14:22:02.000000000 -0800 +++ lxc-dave/fs/ncpfs/ioctl.c 2006-12-11 14:22:02.000000000 -0800 @@ -14,6 +14,7 @@ #include <linux/ioctl.h> #include <linux/time.h> #include <linux/mm.h> +#include <linux/mount.h> #include <linux/highuid.h> #include <linux/smp_lock.h> #include <linux/vmalloc.h> @@ -260,7 +261,7 @@ ncp_get_charsets(struct ncp_server* serv } #endif /* CONFIG_NCPFS_NLS */ -int ncp_ioctl(struct inode *inode, struct file *filp, +static int __ncp_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { struct ncp_server *server = NCP_SERVER(inode); @@ -821,6 +822,58 @@ outrel: return -EINVAL; } +static int ncp_ioctl_need_write(unsigned int cmd) +{ + switch (cmd) { + case NCP_IOC_GET_FS_INFO: + case NCP_IOC_GET_FS_INFO_V2: + case NCP_IOC_NCPREQUEST: + case NCP_IOC_SETDENTRYTTL: + case NCP_IOC_SIGN_INIT: + case NCP_IOC_LOCKUNLOCK: + case NCP_IOC_SET_SIGN_WANTED: + return 1; + case NCP_IOC_GETOBJECTNAME: + case NCP_IOC_SETOBJECTNAME: + case NCP_IOC_GETPRIVATEDATA: + case NCP_IOC_SETPRIVATEDATA: + case NCP_IOC_SETCHARSETS: + case NCP_IOC_GETCHARSETS: + case NCP_IOC_CONN_LOGGED_IN: + case NCP_IOC_GETDENTRYTTL: + case NCP_IOC_GETMOUNTUID2: + case NCP_IOC_SIGN_WANTED: + case NCP_IOC_GETROOT: + case NCP_IOC_SETROOT: + return 0; + default: + /* unkown IOCTL command, assume write */ + WARN_ON(1); + } + return 1; +} + +int ncp_ioctl(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + int ret; + + if (ncp_ioctl_need_write(cmd)) { + /* + * ins…
creator: Dave Hansen
date: 2006-12-11T22:30:08-00:00

[PATCH 11/25] elevate mount count for extended attributes
type: item
description: This basically audits the callers of xattr_permission(), which calls permission() and can perform writes to the filesystem. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/nfsd/nfs4proc.c | 7 ++++++- lxc-dave/fs/xattr.c | 14 ++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff -puN fs/nfsd/nfs4proc.c~10-24-elevate-mount-count-for-extended-attributes fs/nfsd/nfs4proc.c --- lxc/fs/nfsd/nfs4proc.c~10-24-elevate-mount-count-for-extended-attributes 2006-12-11 14:22:03.000000000 -0800 +++ lxc-dave/fs/nfsd/nfs4proc.c 2006-12-11 14:22:03.000000000 -0800 @@ -626,14 +626,19 @@ nfsd4_setattr(struct svc_rqst *rqstp, st return status; } } + status = mnt_want_write(current_fh->fh_export->ex_mnt); + if (status) + return status; status = nfs_ok; if (setattr->sa_acl != NULL) status = nfsd4_set_nfs4_acl(rqstp, &cstate->current_fh, setattr->sa_acl); if (status) - return status; + goto out; status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr, 0, (time_t)0); +out: + mnt_drop_write(current_fh->fh_export->ex_mnt); return status; } diff -puN fs/xattr.c~10-24-elevate-mount-count-for-extended-attributes fs/xattr.c --- lxc/fs/xattr.c~10-24-elevate-mount-count-for-extended-attributes 2006-12-11 14:22:03.000000000 -0800 +++ lxc-dave/fs/xattr.c 2006-12-11 14:22:03.000000000 -0800 @@ -12,6 +12,7 @@ #include <linux/smp_lock.h> #include <linux/file.h> #include <linux/xattr.h> +#include <linux/mount.h> #include <linux/namei.h> #include <linux/security.h> #include <linux/syscalls.h> @@ -237,7 +238,11 @@ sys_setxattr(char __user *path, char __u error = user_path_walk(path, &nd); if (error) return error; + error = mnt_want_write(nd.mnt); + if (error) + return error; error = setxattr(nd.dentry, name, value, size, flags); + mnt_drop_write(nd.mnt); path_release(&nd); return error; } @@ -252,7 +257,11 @@ sys_lsetxattr(char __user *path, char __ error = user_path_walk_link(path, &nd); if (error) return error; + error = mnt_want_write(nd.mnt); + if (error) + …
creator: Dave Hansen
date: 2006-12-11T22:30:09-00:00

[PATCH 12/25] mount_is_safe(): add comment
type: item
description: This area of code is currently #ifdef'd out, so add a comment for the time when it is actually used. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namespace.c | 4 ++++ 1 file changed, 4 insertions(+) diff -puN fs/namespace.c~11-24-mount-is-safe-add-comment fs/namespace.c --- lxc/fs/namespace.c~11-24-mount-is-safe-add-comment 2006-12-11 14:22:04.000000000 -0800 +++ lxc-dave/fs/namespace.c 2006-12-11 14:22:04.000000000 -0800 @@ -700,6 +700,10 @@ static int mount_is_safe(struct nameidat if (current->uid != nd->dentry->d_inode->i_uid) return -EPERM; } + /* + * We will eventually check for the mnt->writer_count here, + * but since the code is not used now, skip it - Dave Hansen + */ if (vfs_permission(nd, MAY_WRITE)) return -EPERM; return 0; _ _______________________________________________ Containers mailing list Containers@lists.osdl.org https://lists.osdl.org/mailman/listinfo/containers
creator: Dave Hansen
date: 2006-12-11T22:30:10-00:00

[PATCH 14/25] elevate write count over calls to vfs_rename()
type: item
description: This does create a little helper in the NFS code to make an if() a little bit less ugly. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namei.c | 4 ++++ lxc-dave/fs/nfsd/vfs.c | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff -puN fs/namei.c~13-24-elevate-write-count-over-calls-to-vfs-rename fs/namei.c --- lxc/fs/namei.c~13-24-elevate-write-count-over-calls-to-vfs-rename 2006-12-11 14:22:05.000000000 -0800 +++ lxc-dave/fs/namei.c 2006-12-11 14:22:05.000000000 -0800 @@ -2563,8 +2563,12 @@ static int do_rename(int olddfd, const c if (new_dentry == trap) goto exit5; + error = mnt_want_write(oldnd.mnt); + if (error) + goto exit5; error = vfs_rename(old_dir->d_inode, old_dentry, new_dir->d_inode, new_dentry); + mnt_drop_write(oldnd.mnt); exit5: dput(new_dentry); exit4: diff -puN fs/nfsd/vfs.c~13-24-elevate-write-count-over-calls-to-vfs-rename fs/nfsd/vfs.c --- lxc/fs/nfsd/vfs.c~13-24-elevate-write-count-over-calls-to-vfs-rename 2006-12-11 14:22:05.000000000 -0800 +++ lxc-dave/fs/nfsd/vfs.c 2006-12-11 14:22:05.000000000 -0800 @@ -1566,6 +1566,14 @@ out_nfserr: goto out_unlock; } +static inline int svc_msnfs(struct svc_fh *ffhp) +{ +#ifdef MSNFS + return (ffhp->fh_export->ex_flags & NFSEXP_MSNFS); +#else + return 0; +#endif +} /* * Rename a file * N.B. After this call _both_ ffhp and tfhp need an fh_put @@ -1627,13 +1635,20 @@ nfsd_rename(struct svc_rqst *rqstp, stru if (ndentry == trap) goto out_dput_new; -#ifdef MSNFS - if ((ffhp->fh_export->ex_flags & NFSEXP_MSNFS) && + if (svc_msnfs(ffhp) && ((atomic_read(&odentry->d_count) > 1) || (atomic_read(&ndentry->d_count) > 1))) { host_err = -EPERM; - } else -#endif + goto out_dput_new; + } + + host_err = -EXDEV; + if (ffhp->fh_export->ex_mnt != tfhp->fh_export->ex_mnt) + goto out_dput_new; + host_err = mnt_want_write(ffhp->fh_export->ex_mnt); + if (host_err) + goto out_dput_new; + host_err = vfs_rename(fdir, odentry, tdir, ndentry); if (!host_err && EX_ISSYNC(tfhp->fh_export)…
creator: Dave Hansen
date: 2006-12-11T22:30:11-00:00

[PATCH 15/25] elevate write count files are open()ed
type: item
description: This is the first really tricky patch in the series. It elevates the writer count on a mount each time a non-special file is opened for write. This is not completely apparent in the patch because the two if() conditions in may_open() above the mnt_want_write() call are, combined, equivalent to special_file(). There is also an elevated count around the vfs_create() call in open_namei(). The count needs to be kept elevated all the way into the may_open() call. Otherwise, when the write is dropped, a ro->rw transisition could occur. This would lead to having rw access on the newly created file, while the vfsmount is ro. That is bad. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/file_table.c | 5 ++++- lxc-dave/fs/namei.c | 22 ++++++++++++++++++---- lxc-dave/ipc/mqueue.c | 3 +++ 3 files changed, 25 insertions(+), 5 deletions(-) diff -puN fs/file_table.c~14-24-tricky-elevate-write-count-files-are-open-ed fs/file_table.c --- lxc/fs/file_table.c~14-24-tricky-elevate-write-count-files-are-open-ed 2006-12-11 14:22:06.000000000 -0800 +++ lxc-dave/fs/file_table.c 2006-12-11 14:22:06.000000000 -0800 @@ -202,8 +202,11 @@ void fastcall __fput(struct file *file) if (unlikely(S_ISCHR(inode->i_mode) && inode->i_cdev != NULL)) cdev_put(inode->i_cdev); fops_put(file->f_op); - if (file->f_mode & FMODE_WRITE) + if (file->f_mode & FMODE_WRITE) { put_write_access(inode); + if(!special_file(inode->i_mode)) + mnt_drop_write(mnt); + } put_pid(file->f_owner.pid); file_kill(file); file->f_path.dentry = NULL; diff -puN fs/namei.c~14-24-tricky-elevate-write-count-files-are-open-ed fs/namei.c --- lxc/fs/namei.c~14-24-tricky-elevate-write-count-files-are-open-ed 2006-12-11 14:22:06.000000000 -0800 +++ lxc-dave/fs/namei.c 2006-12-11 14:22:06.000000000 -0800 @@ -1544,8 +1544,17 @@ int may_open(struct nameidata *nd, int a return -EACCES; flag &= ~O_TRUNC; - } else if (IS_RDONLY(inode) && (flag & FMODE_WRITE)) - return -EROFS; + } else if (flag & FMODE_WRITE) { + /* + * effectively: …
creator: Dave Hansen
date: 2006-12-11T22:30:12-00:00

[PATCH 16/25] elevate writer count for do_sys_truncate()
type: item
description: Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/open.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff -puN fs/open.c~15-24-elevate-writer-count-for-do-sys-truncate fs/open.c --- lxc/fs/open.c~15-24-elevate-writer-count-for-do-sys-truncate 2006-12-11 14:22:07.000000000 -0800 +++ lxc-dave/fs/open.c 2006-12-11 14:22:07.000000000 -0800 @@ -241,28 +241,32 @@ static long do_sys_truncate(const char _ if (!S_ISREG(inode->i_mode)) goto dput_and_out; - error = vfs_permission(&nd, MAY_WRITE); + error = mnt_want_write(nd.mnt); if (error) goto dput_and_out; + error = vfs_permission(&nd, MAY_WRITE); + if (error) + goto mnt_drop_write_and_out; + error = -EROFS; if (IS_RDONLY(inode)) - goto dput_and_out; + goto mnt_drop_write_and_out; error = -EPERM; if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto dput_and_out; + goto mnt_drop_write_and_out; /* * Make sure that there are no leases. */ error = break_lease(inode, FMODE_WRITE); if (error) - goto dput_and_out; + goto mnt_drop_write_and_out; error = get_write_access(inode); if (error) - goto dput_and_out; + goto mnt_drop_write_and_out; error = locks_verify_truncate(inode, NULL, length); if (!error) { @@ -271,6 +275,8 @@ static long do_sys_truncate(const char _ } put_write_access(inode); +mnt_drop_write_and_out: + mnt_drop_write(nd.mnt); dput_and_out: path_release(&nd); out: _ _______________________________________________ Containers mailing list Containers@lists.osdl.org https://lists.osdl.org/mailman/listinfo/containers
creator: Dave Hansen
date: 2006-12-11T22:30:13-00:00

[PATCH 18/25] elevate write count for do_sys_utime() and touch_atime()
type: item
description: Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/inode.c | 20 ++++++++++++-------- lxc-dave/fs/utimes.c | 15 +++++++++++---- 2 files changed, 23 insertions(+), 12 deletions(-) diff -puN fs/inode.c~17-24-elevate-write-count-for-do-sys-utime-and-touch-atime fs/inode.c --- lxc/fs/inode.c~17-24-elevate-write-count-for-do-sys-utime-and-touch-atime 2006-12-11 14:22:08.000000000 -0800 +++ lxc-dave/fs/inode.c 2006-12-11 14:22:08.000000000 -0800 @@ -1167,22 +1167,23 @@ void touch_atime(struct vfsmount *mnt, s if (IS_RDONLY(inode)) return; - if (inode->i_flags & S_NOATIME) + if (mnt && mnt_want_write(mnt)) return; + if (inode->i_flags & S_NOATIME) + goto out; if (inode->i_sb->s_flags & MS_NOATIME) - return; + goto out; if ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)) - return; + goto out; /* * We may have a NULL vfsmount when coming from NFSD */ if (mnt) { if (mnt->mnt_flags & MNT_NOATIME) - return; + goto out; if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) - return; - + goto out; if (mnt->mnt_flags & MNT_RELATIME) { /* * With relative atime, only update atime if the @@ -1193,16 +1194,19 @@ void touch_atime(struct vfsmount *mnt, s &inode->i_atime) < 0 && timespec_compare(&inode->i_ctime, &inode->i_atime) < 0) - return; + goto out; } } now = current_fs_time(inode->i_sb); if (timespec_equal(&inode->i_atime, &now)) - return; + goto out; inode->i_atime = now; mark_inode_dirty_sync(inode); +out: + if (mnt) + mnt_drop_write(mnt); } EXPORT_SYMBOL(touch_atime); diff -puN fs/utimes.c~17-24-elevate-write-count-for-do-sys-utime-and-touch-atime fs/utimes.c --- lxc/fs/utimes.c~17-24-elevate-write-count-for-do-sys-utime-and-touch-atime 2006-12-11 14:22:08.000000000 -0800 +++ lxc-dave/fs/utimes.c 2006-12-11 14:22:08.000000000 -0800 @@ -3,6 +3,7 @@ #include <linux/linkage.h> #include <linux/namei.h> #include <linux/sched.h> +#include <linux/mount.h> #include <linux/utime.h> #include <asm/uaccess.h> #include <asm/unistd.h> @@ -32,6 +33,10…
creator: Dave Hansen
date: 2006-12-11T22:30:14-00:00

[PATCH 19/25] sys_mknodat(): elevate write count for vfs_mknod/create()
type: item
description: This takes care of all of the direct callers of vfs_mknod(). Since a few of these cases also handle normal file creation as well, this also covers some calls to vfs_create(). Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namei.c | 12 ++++++++++++ lxc-dave/fs/nfsd/vfs.c | 4 ++++ lxc-dave/net/unix/af_unix.c | 4 ++++ 3 files changed, 20 insertions(+) diff -puN fs/namei.c~18-24-sys-mknodat-elevate-write-count-for-vfs-mknod-create fs/namei.c --- lxc/fs/namei.c~18-24-sys-mknodat-elevate-write-count-for-vfs-mknod-create 2006-12-11 14:22:09.000000000 -0800 +++ lxc-dave/fs/namei.c 2006-12-11 14:22:09.000000000 -0800 @@ -1899,14 +1899,26 @@ asmlinkage long sys_mknodat(int dfd, con if (!IS_ERR(dentry)) { switch (mode & S_IFMT) { case 0: case S_IFREG: + error = mnt_want_write(nd.mnt); + if (error) + break; error = vfs_create(nd.dentry->d_inode,dentry,mode,&nd); + mnt_drop_write(nd.mnt); break; case S_IFCHR: case S_IFBLK: + error = mnt_want_write(nd.mnt); + if (error) + break; error = vfs_mknod(nd.dentry->d_inode,dentry,mode, new_decode_dev(dev)); + mnt_drop_write(nd.mnt); break; case S_IFIFO: case S_IFSOCK: + error = mnt_want_write(nd.mnt); + if (error) + break; error = vfs_mknod(nd.dentry->d_inode,dentry,mode,0); + mnt_drop_write(nd.mnt); break; case S_IFDIR: error = -EPERM; diff -puN fs/nfsd/vfs.c~18-24-sys-mknodat-elevate-write-count-for-vfs-mknod-create fs/nfsd/vfs.c --- lxc/fs/nfsd/vfs.c~18-24-sys-mknodat-elevate-write-count-for-vfs-mknod-create 2006-12-11 14:22:09.000000000 -0800 +++ lxc-dave/fs/nfsd/vfs.c 2006-12-11 14:22:09.000000000 -0800 @@ -665,6 +665,9 @@ nfsd_open(struct svc_rqst *rqstp, struct /* Disallow write access to files with the append-only bit set * or any access when mandatory locking enabled */ + err = mnt_want_write(fhp->fh_export->ex_mnt); + if (err) + goto out_nfserr; err = nfserr_perm; if (IS_APPEND(inode) && (access & MAY_WRITE)) goto out; @@ -1199,6 +1202,7 @@ nfsd_create(struct svc_rqst *rqstp, stru printk("nfsd: bad file type %…
creator: Dave Hansen
date: 2006-12-11T22:30:15-00:00

[PATCH 20/25] elevate mnt writers for vfs_unlink() callers
type: item
description: Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namei.c | 4 ++++ lxc-dave/ipc/mqueue.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff -puN fs/namei.c~19-24-elevate-mnt-writers-for-vfs-unlink-callers fs/namei.c --- lxc/fs/namei.c~19-24-elevate-mnt-writers-for-vfs-unlink-callers 2006-12-11 14:22:10.000000000 -0800 +++ lxc-dave/fs/namei.c 2006-12-11 14:22:10.000000000 -0800 @@ -2177,7 +2177,11 @@ static long do_unlinkat(int dfd, const c inode = dentry->d_inode; if (inode) atomic_inc(&inode->i_count); + error = mnt_want_write(nd.mnt); + if (error) + goto exit2; error = vfs_unlink(nd.dentry->d_inode, dentry); + mnt_drop_write(nd.mnt); exit2: dput(dentry); } diff -puN ipc/mqueue.c~19-24-elevate-mnt-writers-for-vfs-unlink-callers ipc/mqueue.c --- lxc/ipc/mqueue.c~19-24-elevate-mnt-writers-for-vfs-unlink-callers 2006-12-11 14:22:10.000000000 -0800 +++ lxc-dave/ipc/mqueue.c 2006-12-11 14:22:10.000000000 -0800 @@ -749,8 +749,11 @@ 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); out_err: dput(dentry); _ _______________________________________________ Containers mailing list Containers@lists.osdl.org https://lists.osdl.org/mailman/listinfo/containers
creator: Dave Hansen
date: 2006-12-11T22:30:16-00:00

[PATCH 21/25] do_rmdir(): elevate write count
type: item
description: Elevate the write count during the vfs_rmdir() call. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namei.c | 5 +++++ 1 file changed, 5 insertions(+) diff -puN fs/namei.c~20-24-do-rmdir-elevate-write-count fs/namei.c --- lxc/fs/namei.c~20-24-do-rmdir-elevate-write-count 2006-12-11 14:22:10.000000000 -0800 +++ lxc-dave/fs/namei.c 2006-12-11 14:22:10.000000000 -0800 @@ -2097,7 +2097,12 @@ static long do_rmdir(int dfd, const char error = PTR_ERR(dentry); if (IS_ERR(dentry)) goto exit2; + error = mnt_want_write(nd.mnt); + if (error) + goto exit3; error = vfs_rmdir(nd.dentry->d_inode, dentry); + mnt_drop_write(nd.mnt); +exit3: dput(dentry); exit2: mutex_unlock(&nd.dentry->d_inode->i_mutex); _ _______________________________________________ Containers mailing list Containers@lists.osdl.org https://lists.osdl.org/mailman/listinfo/containers
creator: Dave Hansen
date: 2006-12-11T22:30:17-00:00

[PATCH 23/25] elevate writer count for custom struct_file
type: item
description: Some filesystems forego the use of normal vfs calls to create struct files. Make sure that these users elevate the mnt writer count. These probably don't have any real meaning because there is no real backing store for these mounts, but it is here for consistency. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/file_table.c | 4 ++++ 1 file changed, 4 insertions(+) diff -puN fs/file_table.c~22-24-elevate-writer-count-for-custom-struct-file fs/file_table.c --- lxc/fs/file_table.c~22-24-elevate-writer-count-for-custom-struct-file 2006-12-11 14:22:12.000000000 -0800 +++ lxc-dave/fs/file_table.c 2006-12-11 14:22:12.000000000 -0800 @@ -164,6 +164,10 @@ int init_file(struct file *file, struct file->f_mapping = dentry->d_inode->i_mapping; file->f_mode = mode; file->f_op = fop; + if (mode & FMODE_WRITE) { + error = mnt_want_write(mnt); + WARN_ON(error); + } return error; } _ _______________________________________________ Containers mailing list Containers@lists.osdl.org https://lists.osdl.org/mailman/listinfo/containers
creator: Dave Hansen
date: 2006-12-11T22:30:18-00:00

[PATCH 24/25] honor r/w changes at do_remount() time
type: item
description: Originally from: Herbert Poetzl <herbert@13thfloor.at> This is the core of the read-only bind mount patch set. Note that this does _not_ add a "ro" option directly to the bind mount operation. If you require such a mount, you must first do the bind, then follow it up with a 'mount -o remount,ro' operation. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/fs/namespace.c | 24 ++++++++++++++++++++++-- lxc-dave/fs/open.c | 2 +- 2 files changed, 23 insertions(+), 3 deletions(-) diff -puN fs/namespace.c~23-24-honor-r-w-changes-at-do-remount-time fs/namespace.c --- lxc/fs/namespace.c~23-24-honor-r-w-changes-at-do-remount-time 2006-12-11 14:22:12.000000000 -0800 +++ lxc-dave/fs/namespace.c 2006-12-11 14:22:12.000000000 -0800 @@ -399,7 +399,7 @@ static int show_vfsmnt(struct seq_file * seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); seq_putc(m, ' '); mangle(m, mnt->mnt_sb->s_type->name); - seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); + seq_puts(m, __mnt_is_readonly(mnt) ? " ro" : " rw"); for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { if (mnt->mnt_sb->s_flags & fs_infop->flag) seq_puts(m, fs_infop->str); @@ -1023,6 +1023,23 @@ out: } EXPORT_SYMBOL_GPL(mnt_want_write); +static int change_mount_flags(struct vfsmount *mnt, int ms_flags) +{ + int error = 0; + int readonly_request = 0; + + if (ms_flags & MS_RDONLY) + readonly_request = 1; + if (readonly_request == __mnt_is_readonly(mnt)) + return 0; + + if (readonly_request) + error = mnt_make_readonly(mnt); + else + __mnt_unmake_readonly(mnt); + return error; +} + /* * change filesystem flags. dir should be a physical root of filesystem. * If you've mounted a non-root directory somewhere and want to do remount @@ -1044,7 +1061,10 @@ static int do_remount(struct nameidata * return -EINVAL; down_write(&sb->s_umount); - err = do_remount_sb(sb, flags, data, 0); + if (flags & MS_BIND) + err = change_mount_flags(nd->mnt, flags); + else + err = do_remount_sb(sb, flags, data, 0); if (!(sb->s_flags & MS_…
creator: Dave Hansen
date: 2006-12-11T22:30:19-00:00

[PATCH 25/25] add kerneldoc for i_nlink helpers
type: item
description: I left this until the end of the series because some of the descriptions here really don't make any sense until this series is complete. Signed-off-by: Dave Hansen <haveblue@us.ibm.com> --- lxc-dave/include/linux/fs.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff -puN include/linux/fs.h~24-24-add-kerneldoc-for-i-nlink-helpers include/linux/fs.h --- lxc/include/linux/fs.h~24-24-add-kerneldoc-for-i-nlink-helpers 2006-12-11 14:22:13.000000000 -0800 +++ lxc-dave/include/linux/fs.h 2006-12-11 14:22:13.000000000 -0800 @@ -1242,6 +1242,14 @@ static inline void mark_inode_dirty_sync __mark_inode_dirty(inode, I_DIRTY_SYNC); } +/** + * inc_nlink - directly increment an inode's link count + * @inode: inode + * + * This is a low-level filesystem helper to replace any + * direct filesystem manipulation of i_nlink. Currently, + * it is only here for parity with dec_nlink(). + */ static inline void inc_nlink(struct inode *inode) { inode->i_nlink++; @@ -1253,6 +1261,18 @@ static inline void inode_inc_link_count( mark_inode_dirty(inode); } +/** + * check_nlink - check an inode's status after direct + * i_nlink modification. + * @inode: inode + * + * Some filesystems can not make simple incremental changes + * to i_nlink, most notably clustered ones. They must do + * direct manipulation of i_nlink. This function must be + * called after such modifications are complete to make + * sure that the VFS knows that the inode is going to go + * away. + */ static inline void check_nlink(struct inode *inode) { if (inode->i_nlink) @@ -1262,12 +1282,36 @@ static inline void check_nlink(struct in atomic_inc(&inode->i_sb->s_mnt_writers); } +/** + * drop_nlink - directly drop an inode's link count + * @inode: inode + * + * This is a low-level filesystem helper to replace any + * direct filesystem manipulation of i_nlink. In cases + * where we are attempting to track writes to the + * filesystem, a decrement to zero means an imminent + * write when the file …
creator: Dave Hansen
date: 2006-12-11T22:30:20-00:00

Re: [PATCH 01/25] filesystem helpers for custom 'struct file's
type: item
description: On Mon, Dec 11, 2006 at 02:30:02PM -0800, Dave Hansen wrote: > > > Some filesystems forego the vfs and may_open() and create their > own 'struct file's. > > This patch creates a couple of helper functions which can be > used by these filesystems, and will provide a unified place > which the r/o bind mount code may patch. Can you get rid of init_file by reordering the code in the socket and shmem code a little bit? I'd prefer to completly get rid of the get_empty_filp export long-term. Also why do you export init_file and alloc_file? There don't seem to be any modular users. _______________________________________________ Containers mailing list Containers@lists.osdl.org https://lists.osdl.org/mailman/listinfo/containers
creator: Christoph Hellwig
date: 2006-12-12T10:30:40-00:00