|
@@ -37,6 +37,7 @@
|
|
|
#include <linux/idr.h>
|
|
|
#include <linux/kobject.h>
|
|
|
#include <linux/mutex.h>
|
|
|
+#include <linux/file.h>
|
|
|
#include <asm/uaccess.h>
|
|
|
|
|
|
|
|
@@ -567,10 +568,26 @@ static void mark_files_ro(struct super_block *sb)
|
|
|
{
|
|
|
struct file *f;
|
|
|
|
|
|
+retry:
|
|
|
file_list_lock();
|
|
|
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))
|
|
|
- f->f_mode &= ~FMODE_WRITE;
|
|
|
+ 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;
|
|
|
+ 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();
|
|
|
}
|