diff options
| author | Adrian Hunter <ext-adrian.hunter@nokia.com> | 2009-01-29 05:59:33 -0500 |
|---|---|---|
| committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2009-01-29 09:19:36 -0500 |
| commit | b466f17d780c5b72427f36aef22ecdec9f1d0689 (patch) | |
| tree | 09346513db7a7563f9a79ec0e6ec56b8536fabe9 | |
| parent | 227c75c91dbfa037d109ab7ef45b7f5ba9cab6d0 (diff) | |
UBIFS: remount ro fixes
- preserve the idx_gc list - it will be needed in the same
state, should UBIFS be remounted rw again
- prevent remounting ro if we have switched to read only
mode (due to a fatal error)
Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
| -rw-r--r-- | fs/ubifs/gc.c | 18 | ||||
| -rw-r--r-- | fs/ubifs/super.c | 14 | ||||
| -rw-r--r-- | fs/ubifs/ubifs.h | 2 |
3 files changed, 13 insertions, 21 deletions
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index bad3339a800d..a711d33b3d3e 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
| @@ -830,29 +830,21 @@ out: | |||
| 830 | * ubifs_destroy_idx_gc - destroy idx_gc list. | 830 | * ubifs_destroy_idx_gc - destroy idx_gc list. |
| 831 | * @c: UBIFS file-system description object | 831 | * @c: UBIFS file-system description object |
| 832 | * | 832 | * |
| 833 | * This function destroys the @c->idx_gc list. It is called when unmounting or | 833 | * This function destroys the @c->idx_gc list. It is called when unmounting |
| 834 | * remounting read-only so locks are not needed. Returns zero in case of | 834 | * so locks are not needed. Returns zero in case of success and a negative |
| 835 | * success and a negative error code in case of failure. | 835 | * error code in case of failure. |
| 836 | */ | 836 | */ |
| 837 | int ubifs_destroy_idx_gc(struct ubifs_info *c) | 837 | void ubifs_destroy_idx_gc(struct ubifs_info *c) |
| 838 | { | 838 | { |
| 839 | int ret = 0; | ||
| 840 | |||
| 841 | while (!list_empty(&c->idx_gc)) { | 839 | while (!list_empty(&c->idx_gc)) { |
| 842 | int err; | ||
| 843 | struct ubifs_gced_idx_leb *idx_gc; | 840 | struct ubifs_gced_idx_leb *idx_gc; |
| 844 | 841 | ||
| 845 | idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, | 842 | idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb, |
| 846 | list); | 843 | list); |
| 847 | err = ubifs_change_one_lp(c, idx_gc->lnum, LPROPS_NC, | 844 | c->idx_gc_cnt -= 1; |
| 848 | LPROPS_NC, 0, LPROPS_TAKEN, -1); | ||
| 849 | if (err && !ret) | ||
| 850 | ret = err; | ||
| 851 | list_del(&idx_gc->list); | 845 | list_del(&idx_gc->list); |
| 852 | kfree(idx_gc); | 846 | kfree(idx_gc); |
| 853 | } | 847 | } |
| 854 | |||
| 855 | return ret; | ||
| 856 | } | 848 | } |
| 857 | 849 | ||
| 858 | /** | 850 | /** |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 3ddd754262b4..daa679d3a03e 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -1687,10 +1687,6 @@ static void ubifs_remount_ro(struct ubifs_info *c) | |||
| 1687 | if (err) | 1687 | if (err) |
| 1688 | ubifs_ro_mode(c, err); | 1688 | ubifs_ro_mode(c, err); |
| 1689 | 1689 | ||
| 1690 | err = ubifs_destroy_idx_gc(c); | ||
| 1691 | if (err) | ||
| 1692 | ubifs_ro_mode(c, err); | ||
| 1693 | |||
| 1694 | free_wbufs(c); | 1690 | free_wbufs(c); |
| 1695 | vfree(c->orph_buf); | 1691 | vfree(c->orph_buf); |
| 1696 | c->orph_buf = NULL; | 1692 | c->orph_buf = NULL; |
| @@ -1793,15 +1789,19 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data) | |||
| 1793 | 1789 | ||
| 1794 | if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { | 1790 | if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { |
| 1795 | if (c->ro_media) { | 1791 | if (c->ro_media) { |
| 1796 | ubifs_msg("cannot re-mount R/W, UBIFS is working in " | 1792 | ubifs_msg("cannot re-mount due to prior errors"); |
| 1797 | "R/O mode"); | ||
| 1798 | return -EINVAL; | 1793 | return -EINVAL; |
| 1799 | } | 1794 | } |
| 1800 | err = ubifs_remount_rw(c); | 1795 | err = ubifs_remount_rw(c); |
| 1801 | if (err) | 1796 | if (err) |
| 1802 | return err; | 1797 | return err; |
| 1803 | } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) | 1798 | } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { |
| 1799 | if (c->ro_media) { | ||
| 1800 | ubifs_msg("cannot re-mount due to prior errors"); | ||
| 1801 | return -EINVAL; | ||
| 1802 | } | ||
| 1804 | ubifs_remount_ro(c); | 1803 | ubifs_remount_ro(c); |
| 1804 | } | ||
| 1805 | 1805 | ||
| 1806 | if (c->bulk_read == 1) | 1806 | if (c->bulk_read == 1) |
| 1807 | bu_init(c); | 1807 | bu_init(c); |
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 29dfa816077b..535f87426791 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
| @@ -1594,7 +1594,7 @@ int ubifs_replay_journal(struct ubifs_info *c); | |||
| 1594 | int ubifs_garbage_collect(struct ubifs_info *c, int anyway); | 1594 | int ubifs_garbage_collect(struct ubifs_info *c, int anyway); |
| 1595 | int ubifs_gc_start_commit(struct ubifs_info *c); | 1595 | int ubifs_gc_start_commit(struct ubifs_info *c); |
| 1596 | int ubifs_gc_end_commit(struct ubifs_info *c); | 1596 | int ubifs_gc_end_commit(struct ubifs_info *c); |
| 1597 | int ubifs_destroy_idx_gc(struct ubifs_info *c); | 1597 | void ubifs_destroy_idx_gc(struct ubifs_info *c); |
| 1598 | int ubifs_get_idx_gc_leb(struct ubifs_info *c); | 1598 | int ubifs_get_idx_gc_leb(struct ubifs_info *c); |
| 1599 | int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp); | 1599 | int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp); |
| 1600 | 1600 | ||
