diff options
Diffstat (limited to 'fs/logfs/journal.c')
-rw-r--r-- | fs/logfs/journal.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 6ad30a4c9052..fb0a613f885b 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org> | 6 | * Copyright (c) 2005-2008 Joern Engel <joern@logfs.org> |
7 | */ | 7 | */ |
8 | #include "logfs.h" | 8 | #include "logfs.h" |
9 | #include <linux/slab.h> | ||
9 | 10 | ||
10 | static void logfs_calc_free(struct super_block *sb) | 11 | static void logfs_calc_free(struct super_block *sb) |
11 | { | 12 | { |
@@ -388,7 +389,10 @@ static void journal_get_erase_count(struct logfs_area *area) | |||
388 | static int journal_erase_segment(struct logfs_area *area) | 389 | static int journal_erase_segment(struct logfs_area *area) |
389 | { | 390 | { |
390 | struct super_block *sb = area->a_sb; | 391 | struct super_block *sb = area->a_sb; |
391 | struct logfs_segment_header sh; | 392 | union { |
393 | struct logfs_segment_header sh; | ||
394 | unsigned char c[ALIGN(sizeof(struct logfs_segment_header), 16)]; | ||
395 | } u; | ||
392 | u64 ofs; | 396 | u64 ofs; |
393 | int err; | 397 | int err; |
394 | 398 | ||
@@ -396,20 +400,21 @@ static int journal_erase_segment(struct logfs_area *area) | |||
396 | if (err) | 400 | if (err) |
397 | return err; | 401 | return err; |
398 | 402 | ||
399 | sh.pad = 0; | 403 | memset(&u, 0, sizeof(u)); |
400 | sh.type = SEG_JOURNAL; | 404 | u.sh.pad = 0; |
401 | sh.level = 0; | 405 | u.sh.type = SEG_JOURNAL; |
402 | sh.segno = cpu_to_be32(area->a_segno); | 406 | u.sh.level = 0; |
403 | sh.ec = cpu_to_be32(area->a_erase_count); | 407 | u.sh.segno = cpu_to_be32(area->a_segno); |
404 | sh.gec = cpu_to_be64(logfs_super(sb)->s_gec); | 408 | u.sh.ec = cpu_to_be32(area->a_erase_count); |
405 | sh.crc = logfs_crc32(&sh, sizeof(sh), 4); | 409 | u.sh.gec = cpu_to_be64(logfs_super(sb)->s_gec); |
410 | u.sh.crc = logfs_crc32(&u.sh, sizeof(u.sh), 4); | ||
406 | 411 | ||
407 | /* This causes a bug in segment.c. Not yet. */ | 412 | /* This causes a bug in segment.c. Not yet. */ |
408 | //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0); | 413 | //logfs_set_segment_erased(sb, area->a_segno, area->a_erase_count, 0); |
409 | 414 | ||
410 | ofs = dev_ofs(sb, area->a_segno, 0); | 415 | ofs = dev_ofs(sb, area->a_segno, 0); |
411 | area->a_used_bytes = ALIGN(sizeof(sh), 16); | 416 | area->a_used_bytes = sizeof(u); |
412 | logfs_buf_write(area, ofs, &sh, sizeof(sh)); | 417 | logfs_buf_write(area, ofs, &u, sizeof(u)); |
413 | return 0; | 418 | return 0; |
414 | } | 419 | } |
415 | 420 | ||
@@ -493,6 +498,8 @@ static void account_shadows(struct super_block *sb) | |||
493 | 498 | ||
494 | btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow); | 499 | btree_grim_visitor64(&tree->new, (unsigned long)sb, account_shadow); |
495 | btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow); | 500 | btree_grim_visitor64(&tree->old, (unsigned long)sb, account_shadow); |
501 | btree_grim_visitor32(&tree->segment_map, 0, NULL); | ||
502 | tree->no_shadowed_segments = 0; | ||
496 | 503 | ||
497 | if (li->li_block) { | 504 | if (li->li_block) { |
498 | /* | 505 | /* |
@@ -606,9 +613,9 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type, | |||
606 | if (len == 0) | 613 | if (len == 0) |
607 | return logfs_write_header(super, header, 0, type); | 614 | return logfs_write_header(super, header, 0, type); |
608 | 615 | ||
616 | BUG_ON(len > sb->s_blocksize); | ||
609 | compr_len = logfs_compress(buf, data, len, sb->s_blocksize); | 617 | compr_len = logfs_compress(buf, data, len, sb->s_blocksize); |
610 | if (compr_len < 0 || type == JE_ANCHOR) { | 618 | if (compr_len < 0 || type == JE_ANCHOR) { |
611 | BUG_ON(len > sb->s_blocksize); | ||
612 | memcpy(data, buf, len); | 619 | memcpy(data, buf, len); |
613 | compr_len = len; | 620 | compr_len = len; |
614 | compr = COMPR_NONE; | 621 | compr = COMPR_NONE; |
@@ -660,6 +667,7 @@ static int logfs_write_je_buf(struct super_block *sb, void *buf, u16 type, | |||
660 | if (ofs < 0) | 667 | if (ofs < 0) |
661 | return ofs; | 668 | return ofs; |
662 | logfs_buf_write(area, ofs, super->s_compressed_je, len); | 669 | logfs_buf_write(area, ofs, super->s_compressed_je, len); |
670 | BUG_ON(super->s_no_je >= MAX_JOURNAL_ENTRIES); | ||
663 | super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs); | 671 | super->s_je_array[super->s_no_je++] = cpu_to_be64(ofs); |
664 | return 0; | 672 | return 0; |
665 | } | 673 | } |
@@ -800,6 +808,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) | |||
800 | { | 808 | { |
801 | struct logfs_super *super = logfs_super(sb); | 809 | struct logfs_super *super = logfs_super(sb); |
802 | struct logfs_area *area = super->s_journal_area; | 810 | struct logfs_area *area = super->s_journal_area; |
811 | struct btree_head32 *head = &super->s_reserved_segments; | ||
803 | u32 segno, ec; | 812 | u32 segno, ec; |
804 | int i, err; | 813 | int i, err; |
805 | 814 | ||
@@ -807,6 +816,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb) | |||
807 | /* Drop old segments */ | 816 | /* Drop old segments */ |
808 | journal_for_each(i) | 817 | journal_for_each(i) |
809 | if (super->s_journal_seg[i]) { | 818 | if (super->s_journal_seg[i]) { |
819 | btree_remove32(head, super->s_journal_seg[i]); | ||
810 | logfs_set_segment_unreserved(sb, | 820 | logfs_set_segment_unreserved(sb, |
811 | super->s_journal_seg[i], | 821 | super->s_journal_seg[i], |
812 | super->s_journal_ec[i]); | 822 | super->s_journal_ec[i]); |
@@ -819,8 +829,13 @@ void do_logfs_journal_wl_pass(struct super_block *sb) | |||
819 | super->s_journal_seg[i] = segno; | 829 | super->s_journal_seg[i] = segno; |
820 | super->s_journal_ec[i] = ec; | 830 | super->s_journal_ec[i] = ec; |
821 | logfs_set_segment_reserved(sb, segno); | 831 | logfs_set_segment_reserved(sb, segno); |
832 | err = btree_insert32(head, segno, (void *)1, GFP_KERNEL); | ||
833 | BUG_ON(err); /* mempool should prevent this */ | ||
834 | err = logfs_erase_segment(sb, segno, 1); | ||
835 | BUG_ON(err); /* FIXME: remount-ro would be nicer */ | ||
822 | } | 836 | } |
823 | /* Manually move journal_area */ | 837 | /* Manually move journal_area */ |
838 | freeseg(sb, area->a_segno); | ||
824 | area->a_segno = super->s_journal_seg[0]; | 839 | area->a_segno = super->s_journal_seg[0]; |
825 | area->a_is_open = 0; | 840 | area->a_is_open = 0; |
826 | area->a_used_bytes = 0; | 841 | area->a_used_bytes = 0; |