diff options
author | Dave Hansen <haveblue@us.ibm.com> | 2008-02-15 17:37:32 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-04-19 00:25:33 -0400 |
commit | 49e0d02cf018d4edf24bfc8531a816a26367e4ce (patch) | |
tree | f1695d9ec2298b726ff39f42aaf8d4fd3ade8487 /fs/super.c | |
parent | aceaf78da92a53f5e1b105649a1b8c0afdb2135c (diff) |
[PATCH] r/o bind mounts: drop write during emergency remount
The emergency remount code forcibly removes FMODE_WRITE from
filps. The r/o bind mount code notices that this was done
without a proper mnt_drop_write() and properly gives a
warning.
This patch does a mnt_drop_write() to keep everything
balanced.
Acked-by: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Dave Hansen <haveblue@us.ibm.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/super.c')
-rw-r--r-- | fs/super.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/super.c b/fs/super.c index 09008dbd264e..01d5c40e9119 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/idr.h> | 37 | #include <linux/idr.h> |
38 | #include <linux/kobject.h> | 38 | #include <linux/kobject.h> |
39 | #include <linux/mutex.h> | 39 | #include <linux/mutex.h> |
40 | #include <linux/file.h> | ||
40 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
41 | 42 | ||
42 | 43 | ||
@@ -567,10 +568,26 @@ static void mark_files_ro(struct super_block *sb) | |||
567 | { | 568 | { |
568 | struct file *f; | 569 | struct file *f; |
569 | 570 | ||
571 | retry: | ||
570 | file_list_lock(); | 572 | file_list_lock(); |
571 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { | 573 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { |
572 | if (S_ISREG(f->f_path.dentry->d_inode->i_mode) && file_count(f)) | 574 | struct vfsmount *mnt; |
573 | f->f_mode &= ~FMODE_WRITE; | 575 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) |
576 | continue; | ||
577 | if (!file_count(f)) | ||
578 | continue; | ||
579 | if (!(f->f_mode & FMODE_WRITE)) | ||
580 | continue; | ||
581 | f->f_mode &= ~FMODE_WRITE; | ||
582 | mnt = mntget(f->f_path.mnt); | ||
583 | file_list_unlock(); | ||
584 | /* | ||
585 | * This can sleep, so we can't hold | ||
586 | * the file_list_lock() spinlock. | ||
587 | */ | ||
588 | mnt_drop_write(mnt); | ||
589 | mntput(mnt); | ||
590 | goto retry; | ||
574 | } | 591 | } |
575 | file_list_unlock(); | 592 | file_list_unlock(); |
576 | } | 593 | } |