diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/ubifs/io.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/ubifs/io.c')
-rw-r--r-- | fs/ubifs/io.c | 248 |
1 files changed, 177 insertions, 71 deletions
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index bcf5a16f30bb..3be645e012c9 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
@@ -31,6 +31,26 @@ | |||
31 | * buffer is full or when it is not used for some time (by timer). This is | 31 | * buffer is full or when it is not used for some time (by timer). This is |
32 | * similar to the mechanism is used by JFFS2. | 32 | * similar to the mechanism is used by JFFS2. |
33 | * | 33 | * |
34 | * UBIFS distinguishes between minimum write size (@c->min_io_size) and maximum | ||
35 | * write size (@c->max_write_size). The latter is the maximum amount of bytes | ||
36 | * the underlying flash is able to program at a time, and writing in | ||
37 | * @c->max_write_size units should presumably be faster. Obviously, | ||
38 | * @c->min_io_size <= @c->max_write_size. Write-buffers are of | ||
39 | * @c->max_write_size bytes in size for maximum performance. However, when a | ||
40 | * write-buffer is flushed, only the portion of it (aligned to @c->min_io_size | ||
41 | * boundary) which contains data is written, not the whole write-buffer, | ||
42 | * because this is more space-efficient. | ||
43 | * | ||
44 | * This optimization adds few complications to the code. Indeed, on the one | ||
45 | * hand, we want to write in optimal @c->max_write_size bytes chunks, which | ||
46 | * also means aligning writes at the @c->max_write_size bytes offsets. On the | ||
47 | * other hand, we do not want to waste space when synchronizing the write | ||
48 | * buffer, so during synchronization we writes in smaller chunks. And this makes | ||
49 | * the next write offset to be not aligned to @c->max_write_size bytes. So the | ||
50 | * have to make sure that the write-buffer offset (@wbuf->offs) becomes aligned | ||
51 | * to @c->max_write_size bytes again. We do this by temporarily shrinking | ||
52 | * write-buffer size (@wbuf->size). | ||
53 | * | ||
34 | * Write-buffers are defined by 'struct ubifs_wbuf' objects and protected by | 54 | * Write-buffers are defined by 'struct ubifs_wbuf' objects and protected by |
35 | * mutexes defined inside these objects. Since sometimes upper-level code | 55 | * mutexes defined inside these objects. Since sometimes upper-level code |
36 | * has to lock the write-buffer (e.g. journal space reservation code), many | 56 | * has to lock the write-buffer (e.g. journal space reservation code), many |
@@ -46,8 +66,8 @@ | |||
46 | * UBIFS uses padding when it pads to the next min. I/O unit. In this case it | 66 | * UBIFS uses padding when it pads to the next min. I/O unit. In this case it |
47 | * uses padding nodes or padding bytes, if the padding node does not fit. | 67 | * uses padding nodes or padding bytes, if the padding node does not fit. |
48 | * | 68 | * |
49 | * All UBIFS nodes are protected by CRC checksums and UBIFS checks all nodes | 69 | * All UBIFS nodes are protected by CRC checksums and UBIFS checks CRC when |
50 | * every time they are read from the flash media. | 70 | * they are read from the flash media. |
51 | */ | 71 | */ |
52 | 72 | ||
53 | #include <linux/crc32.h> | 73 | #include <linux/crc32.h> |
@@ -61,8 +81,8 @@ | |||
61 | */ | 81 | */ |
62 | void ubifs_ro_mode(struct ubifs_info *c, int err) | 82 | void ubifs_ro_mode(struct ubifs_info *c, int err) |
63 | { | 83 | { |
64 | if (!c->ro_media) { | 84 | if (!c->ro_error) { |
65 | c->ro_media = 1; | 85 | c->ro_error = 1; |
66 | c->no_chk_data_crc = 0; | 86 | c->no_chk_data_crc = 0; |
67 | c->vfs_sb->s_flags |= MS_RDONLY; | 87 | c->vfs_sb->s_flags |= MS_RDONLY; |
68 | ubifs_warn("switched to read-only mode, error %d", err); | 88 | ubifs_warn("switched to read-only mode, error %d", err); |
@@ -88,8 +108,12 @@ void ubifs_ro_mode(struct ubifs_info *c, int err) | |||
88 | * This function may skip data nodes CRC checking if @c->no_chk_data_crc is | 108 | * This function may skip data nodes CRC checking if @c->no_chk_data_crc is |
89 | * true, which is controlled by corresponding UBIFS mount option. However, if | 109 | * true, which is controlled by corresponding UBIFS mount option. However, if |
90 | * @must_chk_crc is true, then @c->no_chk_data_crc is ignored and CRC is | 110 | * @must_chk_crc is true, then @c->no_chk_data_crc is ignored and CRC is |
91 | * checked. Similarly, if @c->always_chk_crc is true, @c->no_chk_data_crc is | 111 | * checked. Similarly, if @c->mounting or @c->remounting_rw is true (we are |
92 | * ignored and CRC is checked. | 112 | * mounting or re-mounting to R/W mode), @c->no_chk_data_crc is ignored and CRC |
113 | * is checked. This is because during mounting or re-mounting from R/O mode to | ||
114 | * R/W mode we may read journal nodes (when replying the journal or doing the | ||
115 | * recovery) and the journal nodes may potentially be corrupted, so checking is | ||
116 | * required. | ||
93 | * | 117 | * |
94 | * This function returns zero in case of success and %-EUCLEAN in case of bad | 118 | * This function returns zero in case of success and %-EUCLEAN in case of bad |
95 | * CRC or magic. | 119 | * CRC or magic. |
@@ -131,8 +155,8 @@ int ubifs_check_node(const struct ubifs_info *c, const void *buf, int lnum, | |||
131 | node_len > c->ranges[type].max_len) | 155 | node_len > c->ranges[type].max_len) |
132 | goto out_len; | 156 | goto out_len; |
133 | 157 | ||
134 | if (!must_chk_crc && type == UBIFS_DATA_NODE && !c->always_chk_crc && | 158 | if (!must_chk_crc && type == UBIFS_DATA_NODE && !c->mounting && |
135 | c->no_chk_data_crc) | 159 | !c->remounting_rw && c->no_chk_data_crc) |
136 | return 0; | 160 | return 0; |
137 | 161 | ||
138 | crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); | 162 | crc = crc32(UBIFS_CRC32_INIT, buf + 8, node_len - 8); |
@@ -343,11 +367,17 @@ static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
343 | * | 367 | * |
344 | * This function synchronizes write-buffer @buf and returns zero in case of | 368 | * This function synchronizes write-buffer @buf and returns zero in case of |
345 | * success or a negative error code in case of failure. | 369 | * success or a negative error code in case of failure. |
370 | * | ||
371 | * Note, although write-buffers are of @c->max_write_size, this function does | ||
372 | * not necessarily writes all @c->max_write_size bytes to the flash. Instead, | ||
373 | * if the write-buffer is only partially filled with data, only the used part | ||
374 | * of the write-buffer (aligned on @c->min_io_size boundary) is synchronized. | ||
375 | * This way we waste less space. | ||
346 | */ | 376 | */ |
347 | int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | 377 | int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) |
348 | { | 378 | { |
349 | struct ubifs_info *c = wbuf->c; | 379 | struct ubifs_info *c = wbuf->c; |
350 | int err, dirt; | 380 | int err, dirt, sync_len; |
351 | 381 | ||
352 | cancel_wbuf_timer_nolock(wbuf); | 382 | cancel_wbuf_timer_nolock(wbuf); |
353 | if (!wbuf->used || wbuf->lnum == -1) | 383 | if (!wbuf->used || wbuf->lnum == -1) |
@@ -356,28 +386,54 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
356 | 386 | ||
357 | dbg_io("LEB %d:%d, %d bytes, jhead %s", | 387 | dbg_io("LEB %d:%d, %d bytes, jhead %s", |
358 | wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead)); | 388 | wbuf->lnum, wbuf->offs, wbuf->used, dbg_jhead(wbuf->jhead)); |
359 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); | ||
360 | ubifs_assert(!(wbuf->avail & 7)); | 389 | ubifs_assert(!(wbuf->avail & 7)); |
361 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); | 390 | ubifs_assert(wbuf->offs + wbuf->size <= c->leb_size); |
362 | 391 | ubifs_assert(wbuf->size >= c->min_io_size); | |
363 | if (c->ro_media) | 392 | ubifs_assert(wbuf->size <= c->max_write_size); |
393 | ubifs_assert(wbuf->size % c->min_io_size == 0); | ||
394 | ubifs_assert(!c->ro_media && !c->ro_mount); | ||
395 | if (c->leb_size - wbuf->offs >= c->max_write_size) | ||
396 | ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size)); | ||
397 | |||
398 | if (c->ro_error) | ||
364 | return -EROFS; | 399 | return -EROFS; |
365 | 400 | ||
366 | ubifs_pad(c, wbuf->buf + wbuf->used, wbuf->avail); | 401 | /* |
402 | * Do not write whole write buffer but write only the minimum necessary | ||
403 | * amount of min. I/O units. | ||
404 | */ | ||
405 | sync_len = ALIGN(wbuf->used, c->min_io_size); | ||
406 | dirt = sync_len - wbuf->used; | ||
407 | if (dirt) | ||
408 | ubifs_pad(c, wbuf->buf + wbuf->used, dirt); | ||
367 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, | 409 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, |
368 | c->min_io_size, wbuf->dtype); | 410 | sync_len, wbuf->dtype); |
369 | if (err) { | 411 | if (err) { |
370 | ubifs_err("cannot write %d bytes to LEB %d:%d", | 412 | ubifs_err("cannot write %d bytes to LEB %d:%d", |
371 | c->min_io_size, wbuf->lnum, wbuf->offs); | 413 | sync_len, wbuf->lnum, wbuf->offs); |
372 | dbg_dump_stack(); | 414 | dbg_dump_stack(); |
373 | return err; | 415 | return err; |
374 | } | 416 | } |
375 | 417 | ||
376 | dirt = wbuf->avail; | ||
377 | |||
378 | spin_lock(&wbuf->lock); | 418 | spin_lock(&wbuf->lock); |
379 | wbuf->offs += c->min_io_size; | 419 | wbuf->offs += sync_len; |
380 | wbuf->avail = c->min_io_size; | 420 | /* |
421 | * Now @wbuf->offs is not necessarily aligned to @c->max_write_size. | ||
422 | * But our goal is to optimize writes and make sure we write in | ||
423 | * @c->max_write_size chunks and to @c->max_write_size-aligned offset. | ||
424 | * Thus, if @wbuf->offs is not aligned to @c->max_write_size now, make | ||
425 | * sure that @wbuf->offs + @wbuf->size is aligned to | ||
426 | * @c->max_write_size. This way we make sure that after next | ||
427 | * write-buffer flush we are again at the optimal offset (aligned to | ||
428 | * @c->max_write_size). | ||
429 | */ | ||
430 | if (c->leb_size - wbuf->offs < c->max_write_size) | ||
431 | wbuf->size = c->leb_size - wbuf->offs; | ||
432 | else if (wbuf->offs & (c->max_write_size - 1)) | ||
433 | wbuf->size = ALIGN(wbuf->offs, c->max_write_size) - wbuf->offs; | ||
434 | else | ||
435 | wbuf->size = c->max_write_size; | ||
436 | wbuf->avail = wbuf->size; | ||
381 | wbuf->used = 0; | 437 | wbuf->used = 0; |
382 | wbuf->next_ino = 0; | 438 | wbuf->next_ino = 0; |
383 | spin_unlock(&wbuf->lock); | 439 | spin_unlock(&wbuf->lock); |
@@ -396,8 +452,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
396 | * @dtype: data type | 452 | * @dtype: data type |
397 | * | 453 | * |
398 | * This function targets the write-buffer to logical eraseblock @lnum:@offs. | 454 | * This function targets the write-buffer to logical eraseblock @lnum:@offs. |
399 | * 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 |
400 | * success and a negative error code in case of failure. | 456 | * negative error code in case of failure. |
401 | */ | 457 | */ |
402 | 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, |
403 | int dtype) | 459 | int dtype) |
@@ -409,18 +465,18 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | |||
409 | ubifs_assert(offs >= 0 && offs <= c->leb_size); | 465 | ubifs_assert(offs >= 0 && offs <= c->leb_size); |
410 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); | 466 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); |
411 | ubifs_assert(lnum != wbuf->lnum); | 467 | ubifs_assert(lnum != wbuf->lnum); |
412 | 468 | ubifs_assert(wbuf->used == 0); | |
413 | if (wbuf->used > 0) { | ||
414 | int err = ubifs_wbuf_sync_nolock(wbuf); | ||
415 | |||
416 | if (err) | ||
417 | return err; | ||
418 | } | ||
419 | 469 | ||
420 | spin_lock(&wbuf->lock); | 470 | spin_lock(&wbuf->lock); |
421 | wbuf->lnum = lnum; | 471 | wbuf->lnum = lnum; |
422 | wbuf->offs = offs; | 472 | wbuf->offs = offs; |
423 | wbuf->avail = c->min_io_size; | 473 | if (c->leb_size - wbuf->offs < c->max_write_size) |
474 | wbuf->size = c->leb_size - wbuf->offs; | ||
475 | else if (wbuf->offs & (c->max_write_size - 1)) | ||
476 | wbuf->size = ALIGN(wbuf->offs, c->max_write_size) - wbuf->offs; | ||
477 | else | ||
478 | wbuf->size = c->max_write_size; | ||
479 | wbuf->avail = wbuf->size; | ||
424 | wbuf->used = 0; | 480 | wbuf->used = 0; |
425 | spin_unlock(&wbuf->lock); | 481 | spin_unlock(&wbuf->lock); |
426 | wbuf->dtype = dtype; | 482 | wbuf->dtype = dtype; |
@@ -440,11 +496,12 @@ int ubifs_bg_wbufs_sync(struct ubifs_info *c) | |||
440 | { | 496 | { |
441 | int err, i; | 497 | int err, i; |
442 | 498 | ||
499 | ubifs_assert(!c->ro_media && !c->ro_mount); | ||
443 | if (!c->need_wbuf_sync) | 500 | if (!c->need_wbuf_sync) |
444 | return 0; | 501 | return 0; |
445 | c->need_wbuf_sync = 0; | 502 | c->need_wbuf_sync = 0; |
446 | 503 | ||
447 | if (c->ro_media) { | 504 | if (c->ro_error) { |
448 | err = -EROFS; | 505 | err = -EROFS; |
449 | goto out_timers; | 506 | goto out_timers; |
450 | } | 507 | } |
@@ -499,8 +556,9 @@ out_timers: | |||
499 | * | 556 | * |
500 | * This function writes data to flash via write-buffer @wbuf. This means that | 557 | * This function writes data to flash via write-buffer @wbuf. This means that |
501 | * the last piece of the node won't reach the flash media immediately if it | 558 | * the last piece of the node won't reach the flash media immediately if it |
502 | * does not take whole minimal I/O unit. Instead, the node will sit in RAM | 559 | * does not take whole max. write unit (@c->max_write_size). Instead, the node |
503 | * until the write-buffer is synchronized (e.g., by timer). | 560 | * will sit in RAM until the write-buffer is synchronized (e.g., by timer, or |
561 | * because more data are appended to the write-buffer). | ||
504 | * | 562 | * |
505 | * This function returns zero in case of success and a negative error code in | 563 | * This function returns zero in case of success and a negative error code in |
506 | * case of failure. If the node cannot be written because there is no more | 564 | * case of failure. If the node cannot be written because there is no more |
@@ -509,7 +567,7 @@ out_timers: | |||
509 | int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | 567 | int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) |
510 | { | 568 | { |
511 | struct ubifs_info *c = wbuf->c; | 569 | struct ubifs_info *c = wbuf->c; |
512 | int err, written, n, aligned_len = ALIGN(len, 8), offs; | 570 | int err, written, n, aligned_len = ALIGN(len, 8); |
513 | 571 | ||
514 | dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len, | 572 | dbg_io("%d bytes (%s) to jhead %s wbuf at LEB %d:%d", len, |
515 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), | 573 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), |
@@ -517,8 +575,15 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
517 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); | 575 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); |
518 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); | 576 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); |
519 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); | 577 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); |
520 | ubifs_assert(wbuf->avail > 0 && wbuf->avail <= c->min_io_size); | 578 | ubifs_assert(wbuf->avail > 0 && wbuf->avail <= wbuf->size); |
579 | ubifs_assert(wbuf->size >= c->min_io_size); | ||
580 | ubifs_assert(wbuf->size <= c->max_write_size); | ||
581 | ubifs_assert(wbuf->size % c->min_io_size == 0); | ||
521 | ubifs_assert(mutex_is_locked(&wbuf->io_mutex)); | 582 | ubifs_assert(mutex_is_locked(&wbuf->io_mutex)); |
583 | ubifs_assert(!c->ro_media && !c->ro_mount); | ||
584 | ubifs_assert(!c->space_fixup); | ||
585 | if (c->leb_size - wbuf->offs >= c->max_write_size) | ||
586 | ubifs_assert(!((wbuf->offs + wbuf->size) % c->max_write_size)); | ||
522 | 587 | ||
523 | if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) { | 588 | if (c->leb_size - wbuf->offs - wbuf->used < aligned_len) { |
524 | err = -ENOSPC; | 589 | err = -ENOSPC; |
@@ -527,7 +592,7 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
527 | 592 | ||
528 | cancel_wbuf_timer_nolock(wbuf); | 593 | cancel_wbuf_timer_nolock(wbuf); |
529 | 594 | ||
530 | if (c->ro_media) | 595 | if (c->ro_error) |
531 | return -EROFS; | 596 | return -EROFS; |
532 | 597 | ||
533 | if (aligned_len <= wbuf->avail) { | 598 | if (aligned_len <= wbuf->avail) { |
@@ -541,14 +606,18 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
541 | dbg_io("flush jhead %s wbuf to LEB %d:%d", | 606 | dbg_io("flush jhead %s wbuf to LEB %d:%d", |
542 | dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); | 607 | dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); |
543 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, | 608 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, |
544 | wbuf->offs, c->min_io_size, | 609 | wbuf->offs, wbuf->size, |
545 | wbuf->dtype); | 610 | wbuf->dtype); |
546 | if (err) | 611 | if (err) |
547 | goto out; | 612 | goto out; |
548 | 613 | ||
549 | spin_lock(&wbuf->lock); | 614 | spin_lock(&wbuf->lock); |
550 | wbuf->offs += c->min_io_size; | 615 | wbuf->offs += wbuf->size; |
551 | wbuf->avail = c->min_io_size; | 616 | if (c->leb_size - wbuf->offs >= c->max_write_size) |
617 | wbuf->size = c->max_write_size; | ||
618 | else | ||
619 | wbuf->size = c->leb_size - wbuf->offs; | ||
620 | wbuf->avail = wbuf->size; | ||
552 | wbuf->used = 0; | 621 | wbuf->used = 0; |
553 | wbuf->next_ino = 0; | 622 | wbuf->next_ino = 0; |
554 | spin_unlock(&wbuf->lock); | 623 | spin_unlock(&wbuf->lock); |
@@ -562,39 +631,63 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
562 | goto exit; | 631 | goto exit; |
563 | } | 632 | } |
564 | 633 | ||
565 | /* | 634 | written = 0; |
566 | * The node is large enough and does not fit entirely within current | 635 | |
567 | * minimal I/O unit. We have to fill and flush write-buffer and switch | 636 | if (wbuf->used) { |
568 | * to the next min. I/O unit. | 637 | /* |
569 | */ | 638 | * The node is large enough and does not fit entirely within |
570 | dbg_io("flush jhead %s wbuf to LEB %d:%d", | 639 | * current available space. We have to fill and flush |
571 | dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); | 640 | * write-buffer and switch to the next max. write unit. |
572 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); | 641 | */ |
573 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, | 642 | dbg_io("flush jhead %s wbuf to LEB %d:%d", |
574 | c->min_io_size, wbuf->dtype); | 643 | dbg_jhead(wbuf->jhead), wbuf->lnum, wbuf->offs); |
575 | if (err) | 644 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); |
576 | goto out; | 645 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, |
646 | wbuf->size, wbuf->dtype); | ||
647 | if (err) | ||
648 | goto out; | ||
649 | |||
650 | wbuf->offs += wbuf->size; | ||
651 | len -= wbuf->avail; | ||
652 | aligned_len -= wbuf->avail; | ||
653 | written += wbuf->avail; | ||
654 | } else if (wbuf->offs & (c->max_write_size - 1)) { | ||
655 | /* | ||
656 | * The write-buffer offset is not aligned to | ||
657 | * @c->max_write_size and @wbuf->size is less than | ||
658 | * @c->max_write_size. Write @wbuf->size bytes to make sure the | ||
659 | * following writes are done in optimal @c->max_write_size | ||
660 | * chunks. | ||
661 | */ | ||
662 | dbg_io("write %d bytes to LEB %d:%d", | ||
663 | wbuf->size, wbuf->lnum, wbuf->offs); | ||
664 | err = ubi_leb_write(c->ubi, wbuf->lnum, buf, wbuf->offs, | ||
665 | wbuf->size, wbuf->dtype); | ||
666 | if (err) | ||
667 | goto out; | ||
577 | 668 | ||
578 | offs = wbuf->offs + c->min_io_size; | 669 | wbuf->offs += wbuf->size; |
579 | len -= wbuf->avail; | 670 | len -= wbuf->size; |
580 | aligned_len -= wbuf->avail; | 671 | aligned_len -= wbuf->size; |
581 | written = wbuf->avail; | 672 | written += wbuf->size; |
673 | } | ||
582 | 674 | ||
583 | /* | 675 | /* |
584 | * The remaining data may take more whole min. I/O units, so write the | 676 | * The remaining data may take more whole max. write units, so write the |
585 | * remains multiple to min. I/O unit size directly to the flash media. | 677 | * remains multiple to max. write unit size directly to the flash media. |
586 | * We align node length to 8-byte boundary because we anyway flash wbuf | 678 | * We align node length to 8-byte boundary because we anyway flash wbuf |
587 | * if the remaining space is less than 8 bytes. | 679 | * if the remaining space is less than 8 bytes. |
588 | */ | 680 | */ |
589 | n = aligned_len >> c->min_io_shift; | 681 | n = aligned_len >> c->max_write_shift; |
590 | if (n) { | 682 | if (n) { |
591 | n <<= c->min_io_shift; | 683 | n <<= c->max_write_shift; |
592 | dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum, offs); | 684 | dbg_io("write %d bytes to LEB %d:%d", n, wbuf->lnum, |
593 | err = ubi_leb_write(c->ubi, wbuf->lnum, buf + written, offs, n, | 685 | wbuf->offs); |
594 | wbuf->dtype); | 686 | err = ubi_leb_write(c->ubi, wbuf->lnum, buf + written, |
687 | wbuf->offs, n, wbuf->dtype); | ||
595 | if (err) | 688 | if (err) |
596 | goto out; | 689 | goto out; |
597 | offs += n; | 690 | wbuf->offs += n; |
598 | aligned_len -= n; | 691 | aligned_len -= n; |
599 | len -= n; | 692 | len -= n; |
600 | written += n; | 693 | written += n; |
@@ -604,14 +697,17 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
604 | if (aligned_len) | 697 | if (aligned_len) |
605 | /* | 698 | /* |
606 | * And now we have what's left and what does not take whole | 699 | * And now we have what's left and what does not take whole |
607 | * min. I/O unit, so write it to the write-buffer and we are | 700 | * max. write unit, so write it to the write-buffer and we are |
608 | * done. | 701 | * done. |
609 | */ | 702 | */ |
610 | memcpy(wbuf->buf, buf + written, len); | 703 | memcpy(wbuf->buf, buf + written, len); |
611 | 704 | ||
612 | wbuf->offs = offs; | 705 | if (c->leb_size - wbuf->offs >= c->max_write_size) |
706 | wbuf->size = c->max_write_size; | ||
707 | else | ||
708 | wbuf->size = c->leb_size - wbuf->offs; | ||
709 | wbuf->avail = wbuf->size - aligned_len; | ||
613 | wbuf->used = aligned_len; | 710 | wbuf->used = aligned_len; |
614 | wbuf->avail = c->min_io_size - aligned_len; | ||
615 | wbuf->next_ino = 0; | 711 | wbuf->next_ino = 0; |
616 | spin_unlock(&wbuf->lock); | 712 | spin_unlock(&wbuf->lock); |
617 | 713 | ||
@@ -663,8 +759,10 @@ int ubifs_write_node(struct ubifs_info *c, void *buf, int len, int lnum, | |||
663 | buf_len); | 759 | buf_len); |
664 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); | 760 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt && offs >= 0); |
665 | ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size); | 761 | ubifs_assert(offs % c->min_io_size == 0 && offs < c->leb_size); |
762 | ubifs_assert(!c->ro_media && !c->ro_mount); | ||
763 | ubifs_assert(!c->space_fixup); | ||
666 | 764 | ||
667 | if (c->ro_media) | 765 | if (c->ro_error) |
668 | return -EROFS; | 766 | return -EROFS; |
669 | 767 | ||
670 | ubifs_prepare_node(c, buf, len, 1); | 768 | ubifs_prepare_node(c, buf, len, 1); |
@@ -815,7 +913,8 @@ int ubifs_read_node(const struct ubifs_info *c, void *buf, int type, int len, | |||
815 | return 0; | 913 | return 0; |
816 | 914 | ||
817 | out: | 915 | out: |
818 | ubifs_err("bad node at LEB %d:%d", lnum, offs); | 916 | ubifs_err("bad node at LEB %d:%d, LEB mapping status %d", lnum, offs, |
917 | ubi_is_mapped(c->ubi, lnum)); | ||
819 | dbg_dump_node(c, buf); | 918 | dbg_dump_node(c, buf); |
820 | dbg_dump_stack(); | 919 | dbg_dump_stack(); |
821 | return -EINVAL; | 920 | return -EINVAL; |
@@ -833,11 +932,11 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
833 | { | 932 | { |
834 | size_t size; | 933 | size_t size; |
835 | 934 | ||
836 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); | 935 | wbuf->buf = kmalloc(c->max_write_size, GFP_KERNEL); |
837 | if (!wbuf->buf) | 936 | if (!wbuf->buf) |
838 | return -ENOMEM; | 937 | return -ENOMEM; |
839 | 938 | ||
840 | size = (c->min_io_size / UBIFS_CH_SZ + 1) * sizeof(ino_t); | 939 | size = (c->max_write_size / UBIFS_CH_SZ + 1) * sizeof(ino_t); |
841 | wbuf->inodes = kmalloc(size, GFP_KERNEL); | 940 | wbuf->inodes = kmalloc(size, GFP_KERNEL); |
842 | if (!wbuf->inodes) { | 941 | if (!wbuf->inodes) { |
843 | kfree(wbuf->buf); | 942 | kfree(wbuf->buf); |
@@ -847,7 +946,14 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
847 | 946 | ||
848 | wbuf->used = 0; | 947 | wbuf->used = 0; |
849 | wbuf->lnum = wbuf->offs = -1; | 948 | wbuf->lnum = wbuf->offs = -1; |
850 | wbuf->avail = c->min_io_size; | 949 | /* |
950 | * If the LEB starts at the max. write size aligned address, then | ||
951 | * write-buffer size has to be set to @c->max_write_size. Otherwise, | ||
952 | * set it to something smaller so that it ends at the closest max. | ||
953 | * write size boundary. | ||
954 | */ | ||
955 | size = c->max_write_size - (c->leb_start % c->max_write_size); | ||
956 | wbuf->avail = wbuf->size = size; | ||
851 | wbuf->dtype = UBI_UNKNOWN; | 957 | wbuf->dtype = UBI_UNKNOWN; |
852 | wbuf->sync_callback = NULL; | 958 | wbuf->sync_callback = NULL; |
853 | mutex_init(&wbuf->io_mutex); | 959 | mutex_init(&wbuf->io_mutex); |