The patch titled r/o bind mounts: Add vfsmount writer count has been added to the -mm tree. Its filename is ro-bind-mounts-add-vfsmount-writer-count.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: r/o bind mounts: Add vfsmount writer count From: Dave Hansen <haveblue@xxxxxxxxxx> This allows a vfsmount to keep track of how many instances of files open for write there are at a given time. A mount can refuse to allow writers. This can be because it is a read-only bind mount, or for other functionality in the future. A mount can also now refuse to make a transition from r/w to r/o whenever it has currently active writers. Note that this version of the patch does not use an explicit mount flag. It is redundant along with the information in the reference count. The WARN_ON()s can go away before this is merged into mainline provided it has had some time in -mm or equivalent. Signed-off-by: Dave Hansen <haveblue@xxxxxxxxxx> Cc: Serge Hallyn <serue@xxxxxxxxxx> Cc: Herbert Poetzl <herbert@xxxxxxxxxxxx> Cc: Al Viro <viro@xxxxxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- fs/namespace.c | 1 include/linux/mount.h | 49 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff -puN fs/namespace.c~ro-bind-mounts-add-vfsmount-writer-count fs/namespace.c --- a/fs/namespace.c~ro-bind-mounts-add-vfsmount-writer-count +++ a/fs/namespace.c @@ -66,6 +66,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, 1); INIT_LIST_HEAD(&mnt->mnt_hash); INIT_LIST_HEAD(&mnt->mnt_child); INIT_LIST_HEAD(&mnt->mnt_mounts); diff -puN include/linux/mount.h~ro-bind-mounts-add-vfsmount-writer-count include/linux/mount.h --- a/include/linux/mount.h~ro-bind-mounts-add-vfsmount-writer-count +++ a/include/linux/mount.h @@ -12,6 +12,8 @@ #define _LINUX_MOUNT_H #ifdef __KERNEL__ +#include <linux/err.h> +#include <linux/fs.h> #include <linux/types.h> #include <linux/list.h> #include <linux/spinlock.h> @@ -43,6 +45,10 @@ struct vfsmount { struct list_head mnt_mounts; /* list of children, anchored here */ struct list_head mnt_child; /* and going through their mnt_child */ atomic_t mnt_count; + atomic_t mnt_writers; /* 0 - mount is r/o + * >0 - mount is r/w, there are + * mnt_writers-1 writers + */ int mnt_flags; int mnt_expiry_mark; /* true if marked for expiry */ char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ @@ -63,6 +69,49 @@ static inline struct vfsmount *mntget(st return mnt; } +/* + * Must be called under write lock on mnt->mnt_sb->s_umount, + * this prevents concurrent decrements which could make the + * value -1, and test in mnt_want_write() wrongly succeed + */ +static inline int mnt_make_readonly(struct vfsmount *mnt) +{ + if (!atomic_dec_and_test(&mnt->mnt_writers)) { + atomic_inc(&mnt->mnt_writers); + return -EBUSY; + } + return 0; +} + +/* + * This can race with itself, so it must be serialized. + * It must also be called with mnt->mnt_writers == 0 + */ +static inline void __mnt_make_writable(struct vfsmount *mnt) +{ + WARN_ON(atomic_read(&mnt->mnt_writers)); + atomic_inc(&mnt->mnt_writers); +} + +static inline int __mnt_is_readonly(struct vfsmount *mnt) +{ + return (atomic_read(&mnt->mnt_writers) == 0); +} + +static inline int mnt_want_write(struct vfsmount *mnt) +{ + int ret = 0; + if (!atomic_add_unless(&mnt->mnt_writers, 1, 0)) + ret = -EROFS; + return ret; +} + +static inline void mnt_drop_write(struct vfsmount *mnt) +{ + atomic_dec(&mnt->mnt_writers); + WARN_ON(atomic_read(&mnt->mnt_writers) < 1); +} + extern void mntput_no_expire(struct vfsmount *mnt); extern void mnt_pin(struct vfsmount *mnt); extern void mnt_unpin(struct vfsmount *mnt); _ Patches currently in -mm which might be from haveblue@xxxxxxxxxx are origin.patch catch-notification-of-memory-add-event-of-acpi-via-container-driver-register-start-func-for-memory-device.patch catch-notification-of-memory-add-event-of-acpi-via-container-driveravoid-redundant-call-add_memory.patch pgdat-allocation-for-new-node-add-specify-node-id.patch pgdat-allocation-for-new-node-add-get-node-id-by-acpi.patch pgdat-allocation-for-new-node-add-generic-alloc-node_data.patch pgdat-allocation-for-new-node-add-refresh-node_data.patch pgdat-allocation-for-new-node-add-export-kswapd-start-func.patch pgdat-allocation-for-new-node-add-call-pgdat-allocation.patch node-hotplug-register-cpu-remove-node-struct.patch acpi-dock-driver.patch ro-bind-mounts-prepare-for-write-access-checks-collapse-if.patch ro-bind-mounts-r-o-bind-mount-prepwork-move-open_nameis-vfs_create.patch ro-bind-mounts-add-vfsmount-writer-count.patch ro-bind-mounts-elevate-mnt-writers-for-callers-of-vfs_mkdir.patch ro-bind-mounts-elevate-write-count-during-entire-ncp_ioctl.patch ro-bind-mounts-sys_symlinkat-elevate-write-count-around-vfs_symlink.patch ro-bind-mounts-elevate-mount-count-for-extended-attributes.patch ro-bind-mounts-sys_linkat-elevate-write-count-around-vfs_link.patch ro-bind-mounts-mount_is_safe-add-comment.patch ro-bind-mounts-unix_find_other-elevate-write-count-for-touch_atime.patch ro-bind-mounts-elevate-write-count-over-calls-to-vfs_rename.patch ro-bind-mounts-tricky-elevate-write-count-files-are-opened.patch ro-bind-mounts-elevate-writer-count-for-do_sys_truncate.patch ro-bind-mounts-elevate-write-count-for-do_utimes.patch ro-bind-mounts-elevate-write-count-for-do_sys_utime-and-touch_atime.patch ro-bind-mounts-sys_mknodat-elevate-write-count-for-vfs_mknod-create.patch ro-bind-mounts-elevate-mnt-writers-for-vfs_unlink-callers.patch ro-bind-mounts-do_rmdir-elevate-write-count.patch ro-bind-mounts-elevate-writer-count-for-custom-struct-file.patch ro-bind-mounts-honor-r-w-changes-at-do_remount-time.patch page-owner-tracking-leak-detector.patch x86-e820-debugging.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html