diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ubifs/gc.c | 4 | ||||
-rw-r--r-- | fs/ubifs/io.c | 12 | ||||
-rw-r--r-- | fs/ubifs/journal.c | 25 |
3 files changed, 22 insertions, 19 deletions
diff --git a/fs/ubifs/gc.c b/fs/ubifs/gc.c index d70937b3f8e9..ded29f6224c2 100644 --- a/fs/ubifs/gc.c +++ b/fs/ubifs/gc.c | |||
@@ -100,6 +100,10 @@ static int switch_gc_head(struct ubifs_info *c) | |||
100 | if (err) | 100 | if (err) |
101 | return err; | 101 | return err; |
102 | 102 | ||
103 | err = ubifs_wbuf_sync_nolock(wbuf); | ||
104 | if (err) | ||
105 | return err; | ||
106 | |||
103 | err = ubifs_add_bud_to_log(c, GCHD, gc_lnum, 0); | 107 | err = ubifs_add_bud_to_log(c, GCHD, gc_lnum, 0); |
104 | if (err) | 108 | if (err) |
105 | return err; | 109 | return err; |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index 67bbde3550cf..166951e0dcd3 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -452,8 +452,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
452 | * @dtype: data type | 452 | * @dtype: data type |
453 | * | 453 | * |
454 | * This function targets the write-buffer to logical eraseblock @lnum:@offs. | 454 | * This function targets the write-buffer to logical eraseblock @lnum:@offs. |
455 | * The write-buffer is synchronized if it is not empty. Returns zero in case of | 455 | * The write-buffer has to be empty. Returns zero in case of success and a |
456 | * success and a negative error code in case of failure. | 456 | * negative error code in case of failure. |
457 | */ | 457 | */ |
458 | int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | 458 | int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, |
459 | int dtype) | 459 | int dtype) |
@@ -465,13 +465,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | |||
465 | ubifs_assert(offs >= 0 && offs <= c->leb_size); | 465 | ubifs_assert(offs >= 0 && offs <= c->leb_size); |
466 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); | 466 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); |
467 | ubifs_assert(lnum != wbuf->lnum); | 467 | ubifs_assert(lnum != wbuf->lnum); |
468 | 468 | ubifs_assert(wbuf->used == 0); | |
469 | if (wbuf->used > 0) { | ||
470 | int err = ubifs_wbuf_sync_nolock(wbuf); | ||
471 | |||
472 | if (err) | ||
473 | return err; | ||
474 | } | ||
475 | 469 | ||
476 | spin_lock(&wbuf->lock); | 470 | spin_lock(&wbuf->lock); |
477 | wbuf->lnum = lnum; | 471 | wbuf->lnum = lnum; |
diff --git a/fs/ubifs/journal.c b/fs/ubifs/journal.c index ce55a4807cdc..34b1679e6e3a 100644 --- a/fs/ubifs/journal.c +++ b/fs/ubifs/journal.c | |||
@@ -141,14 +141,8 @@ again: | |||
141 | * LEB with some empty space. | 141 | * LEB with some empty space. |
142 | */ | 142 | */ |
143 | lnum = ubifs_find_free_space(c, len, &offs, squeeze); | 143 | lnum = ubifs_find_free_space(c, len, &offs, squeeze); |
144 | if (lnum >= 0) { | 144 | if (lnum >= 0) |
145 | /* Found an LEB, add it to the journal head */ | ||
146 | err = ubifs_add_bud_to_log(c, jhead, lnum, offs); | ||
147 | if (err) | ||
148 | goto out_return; | ||
149 | /* A new bud was successfully allocated and added to the log */ | ||
150 | goto out; | 145 | goto out; |
151 | } | ||
152 | 146 | ||
153 | err = lnum; | 147 | err = lnum; |
154 | if (err != -ENOSPC) | 148 | if (err != -ENOSPC) |
@@ -203,12 +197,23 @@ again: | |||
203 | return 0; | 197 | return 0; |
204 | } | 198 | } |
205 | 199 | ||
206 | err = ubifs_add_bud_to_log(c, jhead, lnum, 0); | ||
207 | if (err) | ||
208 | goto out_return; | ||
209 | offs = 0; | 200 | offs = 0; |
210 | 201 | ||
211 | out: | 202 | out: |
203 | /* | ||
204 | * Make sure we synchronize the write-buffer before we add the new bud | ||
205 | * to the log. Otherwise we may have a power cut after the log | ||
206 | * reference node for the last bud (@lnum) is written but before the | ||
207 | * write-buffer data are written to the next-to-last bud | ||
208 | * (@wbuf->lnum). And the effect would be that the recovery would see | ||
209 | * that there is corruption in the next-to-last bud. | ||
210 | */ | ||
211 | err = ubifs_wbuf_sync_nolock(wbuf); | ||
212 | if (err) | ||
213 | goto out_return; | ||
214 | err = ubifs_add_bud_to_log(c, jhead, lnum, offs); | ||
215 | if (err) | ||
216 | goto out_return; | ||
212 | err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, wbuf->dtype); | 217 | err = ubifs_wbuf_seek_nolock(wbuf, lnum, offs, wbuf->dtype); |
213 | if (err) | 218 | if (err) |
214 | goto out_unlock; | 219 | goto out_unlock; |