aboutsummaryrefslogtreecommitdiffstats
path: root/fs/logfs/journal.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/logfs/journal.c')
-rw-r--r--fs/logfs/journal.c37
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
10static void logfs_calc_free(struct super_block *sb) 11static void logfs_calc_free(struct super_block *sb)
11{ 12{
@@ -388,7 +389,10 @@ static void journal_get_erase_count(struct logfs_area *area)
388static int journal_erase_segment(struct logfs_area *area) 389static 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;