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>
This commit is contained in:
committed by
Artem Bityutskiy
parent
227c75c91d
commit
b466f17d78
@@ -830,29 +830,21 @@ out:
|
|||||||
* ubifs_destroy_idx_gc - destroy idx_gc list.
|
* ubifs_destroy_idx_gc - destroy idx_gc list.
|
||||||
* @c: UBIFS file-system description object
|
* @c: UBIFS file-system description object
|
||||||
*
|
*
|
||||||
* This function destroys the @c->idx_gc list. It is called when unmounting or
|
* This function destroys the @c->idx_gc list. It is called when unmounting
|
||||||
* remounting read-only so locks are not needed. Returns zero in case of
|
* so locks are not needed. Returns zero in case of success and a negative
|
||||||
* success and a negative error code in case of failure.
|
* error code in case of failure.
|
||||||
*/
|
*/
|
||||||
int ubifs_destroy_idx_gc(struct ubifs_info *c)
|
void ubifs_destroy_idx_gc(struct ubifs_info *c)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
|
||||||
|
|
||||||
while (!list_empty(&c->idx_gc)) {
|
while (!list_empty(&c->idx_gc)) {
|
||||||
int err;
|
|
||||||
struct ubifs_gced_idx_leb *idx_gc;
|
struct ubifs_gced_idx_leb *idx_gc;
|
||||||
|
|
||||||
idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb,
|
idx_gc = list_entry(c->idx_gc.next, struct ubifs_gced_idx_leb,
|
||||||
list);
|
list);
|
||||||
err = ubifs_change_one_lp(c, idx_gc->lnum, LPROPS_NC,
|
c->idx_gc_cnt -= 1;
|
||||||
LPROPS_NC, 0, LPROPS_TAKEN, -1);
|
|
||||||
if (err && !ret)
|
|
||||||
ret = err;
|
|
||||||
list_del(&idx_gc->list);
|
list_del(&idx_gc->list);
|
||||||
kfree(idx_gc);
|
kfree(idx_gc);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1687,10 +1687,6 @@ static void ubifs_remount_ro(struct ubifs_info *c)
|
|||||||
if (err)
|
if (err)
|
||||||
ubifs_ro_mode(c, err);
|
ubifs_ro_mode(c, err);
|
||||||
|
|
||||||
err = ubifs_destroy_idx_gc(c);
|
|
||||||
if (err)
|
|
||||||
ubifs_ro_mode(c, err);
|
|
||||||
|
|
||||||
free_wbufs(c);
|
free_wbufs(c);
|
||||||
vfree(c->orph_buf);
|
vfree(c->orph_buf);
|
||||||
c->orph_buf = NULL;
|
c->orph_buf = NULL;
|
||||||
@@ -1793,15 +1789,19 @@ static int ubifs_remount_fs(struct super_block *sb, int *flags, char *data)
|
|||||||
|
|
||||||
if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
|
if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
|
||||||
if (c->ro_media) {
|
if (c->ro_media) {
|
||||||
ubifs_msg("cannot re-mount R/W, UBIFS is working in "
|
ubifs_msg("cannot re-mount due to prior errors");
|
||||||
"R/O mode");
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
err = ubifs_remount_rw(c);
|
err = ubifs_remount_rw(c);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY))
|
} else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {
|
||||||
|
if (c->ro_media) {
|
||||||
|
ubifs_msg("cannot re-mount due to prior errors");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
ubifs_remount_ro(c);
|
ubifs_remount_ro(c);
|
||||||
|
}
|
||||||
|
|
||||||
if (c->bulk_read == 1)
|
if (c->bulk_read == 1)
|
||||||
bu_init(c);
|
bu_init(c);
|
||||||
|
@@ -1594,7 +1594,7 @@ int ubifs_replay_journal(struct ubifs_info *c);
|
|||||||
int ubifs_garbage_collect(struct ubifs_info *c, int anyway);
|
int ubifs_garbage_collect(struct ubifs_info *c, int anyway);
|
||||||
int ubifs_gc_start_commit(struct ubifs_info *c);
|
int ubifs_gc_start_commit(struct ubifs_info *c);
|
||||||
int ubifs_gc_end_commit(struct ubifs_info *c);
|
int ubifs_gc_end_commit(struct ubifs_info *c);
|
||||||
int ubifs_destroy_idx_gc(struct ubifs_info *c);
|
void ubifs_destroy_idx_gc(struct ubifs_info *c);
|
||||||
int ubifs_get_idx_gc_leb(struct ubifs_info *c);
|
int ubifs_get_idx_gc_leb(struct ubifs_info *c);
|
||||||
int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp);
|
int ubifs_garbage_collect_leb(struct ubifs_info *c, struct ubifs_lprops *lp);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user