[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>
This commit is contained in:
parent
aceaf78da9
commit
49e0d02cf0
19
fs/super.c
19
fs/super.c
|
@ -37,6 +37,7 @@
|
||||||
#include <linux/idr.h>
|
#include <linux/idr.h>
|
||||||
#include <linux/kobject.h>
|
#include <linux/kobject.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
|
#include <linux/file.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -567,10 +568,26 @@ static void mark_files_ro(struct super_block *sb)
|
||||||
{
|
{
|
||||||
struct file *f;
|
struct file *f;
|
||||||
|
|
||||||
|
retry:
|
||||||
file_list_lock();
|
file_list_lock();
|
||||||
list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
|
list_for_each_entry(f, &sb->s_files, f_u.fu_list) {
|
||||||
if (S_ISREG(f->f_path.dentry->d_inode->i_mode) && file_count(f))
|
struct vfsmount *mnt;
|
||||||
|
if (!S_ISREG(f->f_path.dentry->d_inode->i_mode))
|
||||||
|
continue;
|
||||||
|
if (!file_count(f))
|
||||||
|
continue;
|
||||||
|
if (!(f->f_mode & FMODE_WRITE))
|
||||||
|
continue;
|
||||||
f->f_mode &= ~FMODE_WRITE;
|
f->f_mode &= ~FMODE_WRITE;
|
||||||
|
mnt = mntget(f->f_path.mnt);
|
||||||
|
file_list_unlock();
|
||||||
|
/*
|
||||||
|
* This can sleep, so we can't hold
|
||||||
|
* the file_list_lock() spinlock.
|
||||||
|
*/
|
||||||
|
mnt_drop_write(mnt);
|
||||||
|
mntput(mnt);
|
||||||
|
goto retry;
|
||||||
}
|
}
|
||||||
file_list_unlock();
|
file_list_unlock();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue