diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/file_table.c | 38 | ||||
-rw-r--r-- | fs/internal.h | 5 | ||||
-rw-r--r-- | fs/super.c | 39 |
3 files changed, 43 insertions, 39 deletions
diff --git a/fs/file_table.c b/fs/file_table.c index 3d66dbcebef6..334ce39881f8 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -399,6 +399,44 @@ too_bad: | |||
399 | return 0; | 399 | return 0; |
400 | } | 400 | } |
401 | 401 | ||
402 | /** | ||
403 | * mark_files_ro - mark all files read-only | ||
404 | * @sb: superblock in question | ||
405 | * | ||
406 | * All files are marked read-only. We don't care about pending | ||
407 | * delete files so this should be used in 'force' mode only. | ||
408 | */ | ||
409 | void mark_files_ro(struct super_block *sb) | ||
410 | { | ||
411 | struct file *f; | ||
412 | |||
413 | retry: | ||
414 | file_list_lock(); | ||
415 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { | ||
416 | struct vfsmount *mnt; | ||
417 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) | ||
418 | continue; | ||
419 | if (!file_count(f)) | ||
420 | continue; | ||
421 | if (!(f->f_mode & FMODE_WRITE)) | ||
422 | continue; | ||
423 | f->f_mode &= ~FMODE_WRITE; | ||
424 | if (file_check_writeable(f) != 0) | ||
425 | continue; | ||
426 | file_release_write(f); | ||
427 | mnt = mntget(f->f_path.mnt); | ||
428 | file_list_unlock(); | ||
429 | /* | ||
430 | * This can sleep, so we can't hold | ||
431 | * the file_list_lock() spinlock. | ||
432 | */ | ||
433 | mnt_drop_write(mnt); | ||
434 | mntput(mnt); | ||
435 | goto retry; | ||
436 | } | ||
437 | file_list_unlock(); | ||
438 | } | ||
439 | |||
402 | void __init files_init(unsigned long mempages) | 440 | void __init files_init(unsigned long mempages) |
403 | { | 441 | { |
404 | int n; | 442 | int n; |
diff --git a/fs/internal.h b/fs/internal.h index b4dac4fb6b61..6d4ef208ef65 100644 --- a/fs/internal.h +++ b/fs/internal.h | |||
@@ -66,3 +66,8 @@ extern void __init mnt_init(void); | |||
66 | * fs_struct.c | 66 | * fs_struct.c |
67 | */ | 67 | */ |
68 | extern void chroot_fs_refs(struct path *, struct path *); | 68 | extern void chroot_fs_refs(struct path *, struct path *); |
69 | |||
70 | /* | ||
71 | * file_table.c | ||
72 | */ | ||
73 | extern void mark_files_ro(struct super_block *); | ||
diff --git a/fs/super.c b/fs/super.c index 1943fdf655fa..c170551c23fe 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -616,45 +616,6 @@ out: | |||
616 | } | 616 | } |
617 | 617 | ||
618 | /** | 618 | /** |
619 | * mark_files_ro - mark all files read-only | ||
620 | * @sb: superblock in question | ||
621 | * | ||
622 | * All files are marked read-only. We don't care about pending | ||
623 | * delete files so this should be used in 'force' mode only. | ||
624 | */ | ||
625 | |||
626 | static void mark_files_ro(struct super_block *sb) | ||
627 | { | ||
628 | struct file *f; | ||
629 | |||
630 | retry: | ||
631 | file_list_lock(); | ||
632 | list_for_each_entry(f, &sb->s_files, f_u.fu_list) { | ||
633 | struct vfsmount *mnt; | ||
634 | if (!S_ISREG(f->f_path.dentry->d_inode->i_mode)) | ||
635 | continue; | ||
636 | if (!file_count(f)) | ||
637 | continue; | ||
638 | if (!(f->f_mode & FMODE_WRITE)) | ||
639 | continue; | ||
640 | f->f_mode &= ~FMODE_WRITE; | ||
641 | if (file_check_writeable(f) != 0) | ||
642 | continue; | ||
643 | file_release_write(f); | ||
644 | mnt = mntget(f->f_path.mnt); | ||
645 | file_list_unlock(); | ||
646 | /* | ||
647 | * This can sleep, so we can't hold | ||
648 | * the file_list_lock() spinlock. | ||
649 | */ | ||
650 | mnt_drop_write(mnt); | ||
651 | mntput(mnt); | ||
652 | goto retry; | ||
653 | } | ||
654 | file_list_unlock(); | ||
655 | } | ||
656 | |||
657 | /** | ||
658 | * do_remount_sb - asks filesystem to change mount options. | 619 | * do_remount_sb - asks filesystem to change mount options. |
659 | * @sb: superblock in question | 620 | * @sb: superblock in question |
660 | * @flags: numeric part of options | 621 | * @flags: numeric part of options |