From: Valerie Aurora <vaurora@xxxxxxxxxx> While we can check if a file system is currently read-only, we can't guarantee that it will stay read-only. The file system can be mounted or remounted read-write at any time. This is a problem for union mounts, which require the underlying file system be read-only for the entire duration of the union mount. Add a hard read-only users count to the superblock. When this count is non-zero, don't allow any read-write mounts of this super, or any read-write remounts of existing mounts. Original-author: Valerie Aurora <vaurora@xxxxxxxxxx> Signed-off-by: David Howells <dhowells@xxxxxxxxxx> --- fs/super.c | 11 +++++++++++ include/linux/fs.h | 6 ++++++ 2 files changed, 17 insertions(+), 0 deletions(-) diff --git a/fs/super.c b/fs/super.c index f343eda..732e19b 100644 --- a/fs/super.c +++ b/fs/super.c @@ -202,6 +202,7 @@ static inline void destroy_super(struct super_block *s) #ifdef CONFIG_SMP free_percpu(s->s_files); #endif + BUG_ON(s->s_hard_readonly_users); security_sb_free(s); WARN_ON(!list_empty(&s->s_mounts)); kfree(s->s_subtype); @@ -758,6 +759,9 @@ int do_remount_sb(struct super_block *sb, int flags, void *data, int force) } } + if (!(flags & MS_RDONLY) && sb->s_hard_readonly_users) + return -EROFS; + if (sb->s_op->remount_fs) { retval = sb->s_op->remount_fs(sb, &flags, data); if (retval) { @@ -1150,9 +1154,16 @@ mount_fs(struct file_system_type *type, int flags, const char *name, void *data) WARN((sb->s_maxbytes < 0), "%s set sb->s_maxbytes to " "negative value (%lld)\n", type->name, sb->s_maxbytes); + if (!(flags & MS_RDONLY) && sb->s_hard_readonly_users) + goto out_sb_is_hard_ro; + up_write(&sb->s_umount); free_secdata(secdata); return root; + +out_sb_is_hard_ro: + up_write(&sb->s_umount); + error = -EROFS; out_sb: dput(root); deactivate_locked_super(sb); diff --git a/include/linux/fs.h b/include/linux/fs.h index d851be9..b8276c0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1496,6 +1496,12 @@ struct super_block { /* Being remounted read-only */ int s_readonly_remount; + + /* Number of mounts requiring that the underlying file system never + * transition to read-write. Protected by s_umount. Decremented by + * free_vfsmnt() if MNT_HARD_READONLY is set. + */ + int s_hard_readonly_users; }; /* superblock cache pruning functions */ -- 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