diff options
author | Paul Mundt <lethal@linux-sh.org> | 2010-04-26 03:08:27 -0400 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2010-04-26 03:08:27 -0400 |
commit | e19553427c2e8fdb04fdd98e407164bb59a840ba (patch) | |
tree | 5332234b2dad07c03c27e4608afb16f297f41e61 /fs/logfs | |
parent | 35f6cd4a06432034665a1499ca4b022437423aac (diff) | |
parent | 83515bc7df812555e20cda48614674e2f346f9f5 (diff) |
Merge branch 'sh/stable-updates'
Conflicts:
arch/sh/kernel/dwarf.c
drivers/dma/shdma.c
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'fs/logfs')
-rw-r--r-- | fs/logfs/dev_bdev.c | 1 | ||||
-rw-r--r-- | fs/logfs/dir.c | 2 | ||||
-rw-r--r-- | fs/logfs/gc.c | 9 | ||||
-rw-r--r-- | fs/logfs/inode.c | 1 | ||||
-rw-r--r-- | fs/logfs/journal.c | 30 | ||||
-rw-r--r-- | fs/logfs/logfs.h | 15 | ||||
-rw-r--r-- | fs/logfs/readwrite.c | 76 | ||||
-rw-r--r-- | fs/logfs/segment.c | 9 | ||||
-rw-r--r-- | fs/logfs/super.c | 12 |
9 files changed, 99 insertions, 56 deletions
diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index a5d0c56d3ebc..243c00071f76 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/bio.h> | 9 | #include <linux/bio.h> |
10 | #include <linux/blkdev.h> | 10 | #include <linux/blkdev.h> |
11 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
12 | #include <linux/gfp.h> | ||
12 | 13 | ||
13 | #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1)) | 14 | #define PAGE_OFS(ofs) ((ofs) & (PAGE_SIZE-1)) |
14 | 15 | ||
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index c76b4b5c7ff6..2396a85c0f55 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
@@ -6,7 +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 | 9 | #include <linux/slab.h> | |
10 | 10 | ||
11 | /* | 11 | /* |
12 | * Atomic dir operations | 12 | * Atomic dir operations |
diff --git a/fs/logfs/gc.c b/fs/logfs/gc.c index 92949f95a901..76c242fbe1b0 100644 --- a/fs/logfs/gc.c +++ b/fs/logfs/gc.c | |||
@@ -7,6 +7,7 @@ | |||
7 | */ | 7 | */ |
8 | #include "logfs.h" | 8 | #include "logfs.h" |
9 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
10 | #include <linux/slab.h> | ||
10 | 11 | ||
11 | /* | 12 | /* |
12 | * Wear leveling needs to kick in when the difference between low erase | 13 | * Wear leveling needs to kick in when the difference between low erase |
@@ -458,6 +459,14 @@ static void __logfs_gc_pass(struct super_block *sb, int target) | |||
458 | struct logfs_block *block; | 459 | struct logfs_block *block; |
459 | int round, progress, last_progress = 0; | 460 | int round, progress, last_progress = 0; |
460 | 461 | ||
462 | /* | ||
463 | * Doing too many changes to the segfile at once would result | ||
464 | * in a large number of aliases. Write the journal before | ||
465 | * things get out of hand. | ||
466 | */ | ||
467 | if (super->s_shadow_tree.no_shadowed_segments >= MAX_OBJ_ALIASES) | ||
468 | logfs_write_anchor(sb); | ||
469 | |||
461 | if (no_free_segments(sb) >= target && | 470 | if (no_free_segments(sb) >= target && |
462 | super->s_no_object_aliases < MAX_OBJ_ALIASES) | 471 | super->s_no_object_aliases < MAX_OBJ_ALIASES) |
463 | return; | 472 | return; |
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index 33ec1aeaeec4..14ed27274da2 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.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 | #include <linux/writeback.h> | 10 | #include <linux/writeback.h> |
10 | #include <linux/backing-dev.h> | 11 | #include <linux/backing-dev.h> |
11 | 12 | ||
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index d57c7b07b60b..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 | } |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index b84b0eec6024..0a3df1a0c936 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
@@ -257,10 +257,14 @@ struct logfs_shadow { | |||
257 | * struct shadow_tree | 257 | * struct shadow_tree |
258 | * @new: shadows where old_ofs==0, indexed by new_ofs | 258 | * @new: shadows where old_ofs==0, indexed by new_ofs |
259 | * @old: shadows where old_ofs!=0, indexed by old_ofs | 259 | * @old: shadows where old_ofs!=0, indexed by old_ofs |
260 | * @segment_map: bitfield of segments containing shadows | ||
261 | * @no_shadowed_segment: number of segments containing shadows | ||
260 | */ | 262 | */ |
261 | struct shadow_tree { | 263 | struct shadow_tree { |
262 | struct btree_head64 new; | 264 | struct btree_head64 new; |
263 | struct btree_head64 old; | 265 | struct btree_head64 old; |
266 | struct btree_head32 segment_map; | ||
267 | int no_shadowed_segments; | ||
264 | }; | 268 | }; |
265 | 269 | ||
266 | struct object_alias_item { | 270 | struct object_alias_item { |
@@ -305,13 +309,14 @@ typedef int write_alias_t(struct super_block *sb, u64 ino, u64 bix, | |||
305 | level_t level, int child_no, __be64 val); | 309 | level_t level, int child_no, __be64 val); |
306 | struct logfs_block_ops { | 310 | struct logfs_block_ops { |
307 | void (*write_block)(struct logfs_block *block); | 311 | void (*write_block)(struct logfs_block *block); |
308 | gc_level_t (*block_level)(struct logfs_block *block); | ||
309 | void (*free_block)(struct super_block *sb, struct logfs_block*block); | 312 | void (*free_block)(struct super_block *sb, struct logfs_block*block); |
310 | int (*write_alias)(struct super_block *sb, | 313 | int (*write_alias)(struct super_block *sb, |
311 | struct logfs_block *block, | 314 | struct logfs_block *block, |
312 | write_alias_t *write_one_alias); | 315 | write_alias_t *write_one_alias); |
313 | }; | 316 | }; |
314 | 317 | ||
318 | #define MAX_JOURNAL_ENTRIES 256 | ||
319 | |||
315 | struct logfs_super { | 320 | struct logfs_super { |
316 | struct mtd_info *s_mtd; /* underlying device */ | 321 | struct mtd_info *s_mtd; /* underlying device */ |
317 | struct block_device *s_bdev; /* underlying device */ | 322 | struct block_device *s_bdev; /* underlying device */ |
@@ -378,7 +383,7 @@ struct logfs_super { | |||
378 | u32 s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */ | 383 | u32 s_journal_ec[LOGFS_JOURNAL_SEGS]; /* journal erasecounts */ |
379 | u64 s_last_version; | 384 | u64 s_last_version; |
380 | struct logfs_area *s_journal_area; /* open journal segment */ | 385 | struct logfs_area *s_journal_area; /* open journal segment */ |
381 | __be64 s_je_array[64]; | 386 | __be64 s_je_array[MAX_JOURNAL_ENTRIES]; |
382 | int s_no_je; | 387 | int s_no_je; |
383 | 388 | ||
384 | int s_sum_index; /* for the 12 summaries */ | 389 | int s_sum_index; /* for the 12 summaries */ |
@@ -722,4 +727,10 @@ static inline struct logfs_area *get_area(struct super_block *sb, | |||
722 | return logfs_super(sb)->s_area[(__force u8)gc_level]; | 727 | return logfs_super(sb)->s_area[(__force u8)gc_level]; |
723 | } | 728 | } |
724 | 729 | ||
730 | static inline void logfs_mempool_destroy(mempool_t *pool) | ||
731 | { | ||
732 | if (pool) | ||
733 | mempool_destroy(pool); | ||
734 | } | ||
735 | |||
725 | #endif | 736 | #endif |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index c3a3a6814b84..3159db6958e5 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
@@ -18,6 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | #include "logfs.h" | 19 | #include "logfs.h" |
20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
21 | #include <linux/slab.h> | ||
21 | 22 | ||
22 | static u64 adjust_bix(u64 bix, level_t level) | 23 | static u64 adjust_bix(u64 bix, level_t level) |
23 | { | 24 | { |
@@ -429,25 +430,6 @@ static void inode_write_block(struct logfs_block *block) | |||
429 | } | 430 | } |
430 | } | 431 | } |
431 | 432 | ||
432 | static gc_level_t inode_block_level(struct logfs_block *block) | ||
433 | { | ||
434 | BUG_ON(block->inode->i_ino == LOGFS_INO_MASTER); | ||
435 | return GC_LEVEL(LOGFS_MAX_LEVELS); | ||
436 | } | ||
437 | |||
438 | static gc_level_t indirect_block_level(struct logfs_block *block) | ||
439 | { | ||
440 | struct page *page; | ||
441 | struct inode *inode; | ||
442 | u64 bix; | ||
443 | level_t level; | ||
444 | |||
445 | page = block->page; | ||
446 | inode = page->mapping->host; | ||
447 | logfs_unpack_index(page->index, &bix, &level); | ||
448 | return expand_level(inode->i_ino, level); | ||
449 | } | ||
450 | |||
451 | /* | 433 | /* |
452 | * This silences a false, yet annoying gcc warning. I hate it when my editor | 434 | * This silences a false, yet annoying gcc warning. I hate it when my editor |
453 | * jumps into bitops.h each time I recompile this file. | 435 | * jumps into bitops.h each time I recompile this file. |
@@ -586,14 +568,12 @@ static void indirect_free_block(struct super_block *sb, | |||
586 | 568 | ||
587 | static struct logfs_block_ops inode_block_ops = { | 569 | static struct logfs_block_ops inode_block_ops = { |
588 | .write_block = inode_write_block, | 570 | .write_block = inode_write_block, |
589 | .block_level = inode_block_level, | ||
590 | .free_block = inode_free_block, | 571 | .free_block = inode_free_block, |
591 | .write_alias = inode_write_alias, | 572 | .write_alias = inode_write_alias, |
592 | }; | 573 | }; |
593 | 574 | ||
594 | struct logfs_block_ops indirect_block_ops = { | 575 | struct logfs_block_ops indirect_block_ops = { |
595 | .write_block = indirect_write_block, | 576 | .write_block = indirect_write_block, |
596 | .block_level = indirect_block_level, | ||
597 | .free_block = indirect_free_block, | 577 | .free_block = indirect_free_block, |
598 | .write_alias = indirect_write_alias, | 578 | .write_alias = indirect_write_alias, |
599 | }; | 579 | }; |
@@ -1240,6 +1220,18 @@ static void free_shadow(struct inode *inode, struct logfs_shadow *shadow) | |||
1240 | mempool_free(shadow, super->s_shadow_pool); | 1220 | mempool_free(shadow, super->s_shadow_pool); |
1241 | } | 1221 | } |
1242 | 1222 | ||
1223 | static void mark_segment(struct shadow_tree *tree, u32 segno) | ||
1224 | { | ||
1225 | int err; | ||
1226 | |||
1227 | if (!btree_lookup32(&tree->segment_map, segno)) { | ||
1228 | err = btree_insert32(&tree->segment_map, segno, (void *)1, | ||
1229 | GFP_NOFS); | ||
1230 | BUG_ON(err); | ||
1231 | tree->no_shadowed_segments++; | ||
1232 | } | ||
1233 | } | ||
1234 | |||
1243 | /** | 1235 | /** |
1244 | * fill_shadow_tree - Propagate shadow tree changes due to a write | 1236 | * fill_shadow_tree - Propagate shadow tree changes due to a write |
1245 | * @inode: Inode owning the page | 1237 | * @inode: Inode owning the page |
@@ -1287,6 +1279,8 @@ static void fill_shadow_tree(struct inode *inode, struct page *page, | |||
1287 | 1279 | ||
1288 | super->s_dirty_used_bytes += shadow->new_len; | 1280 | super->s_dirty_used_bytes += shadow->new_len; |
1289 | super->s_dirty_free_bytes += shadow->old_len; | 1281 | super->s_dirty_free_bytes += shadow->old_len; |
1282 | mark_segment(tree, shadow->old_ofs >> super->s_segshift); | ||
1283 | mark_segment(tree, shadow->new_ofs >> super->s_segshift); | ||
1290 | } | 1284 | } |
1291 | } | 1285 | } |
1292 | 1286 | ||
@@ -1844,19 +1838,37 @@ static int __logfs_truncate(struct inode *inode, u64 size) | |||
1844 | return logfs_truncate_direct(inode, size); | 1838 | return logfs_truncate_direct(inode, size); |
1845 | } | 1839 | } |
1846 | 1840 | ||
1847 | int logfs_truncate(struct inode *inode, u64 size) | 1841 | /* |
1842 | * Truncate, by changing the segment file, can consume a fair amount | ||
1843 | * of resources. So back off from time to time and do some GC. | ||
1844 | * 8 or 2048 blocks should be well within safety limits even if | ||
1845 | * every single block resided in a different segment. | ||
1846 | */ | ||
1847 | #define TRUNCATE_STEP (8 * 1024 * 1024) | ||
1848 | int logfs_truncate(struct inode *inode, u64 target) | ||
1848 | { | 1849 | { |
1849 | struct super_block *sb = inode->i_sb; | 1850 | struct super_block *sb = inode->i_sb; |
1850 | int err; | 1851 | u64 size = i_size_read(inode); |
1852 | int err = 0; | ||
1851 | 1853 | ||
1852 | logfs_get_wblocks(sb, NULL, 1); | 1854 | size = ALIGN(size, TRUNCATE_STEP); |
1853 | err = __logfs_truncate(inode, size); | 1855 | while (size > target) { |
1854 | if (!err) | 1856 | if (size > TRUNCATE_STEP) |
1855 | err = __logfs_write_inode(inode, 0); | 1857 | size -= TRUNCATE_STEP; |
1856 | logfs_put_wblocks(sb, NULL, 1); | 1858 | else |
1859 | size = 0; | ||
1860 | if (size < target) | ||
1861 | size = target; | ||
1862 | |||
1863 | logfs_get_wblocks(sb, NULL, 1); | ||
1864 | err = __logfs_truncate(inode, target); | ||
1865 | if (!err) | ||
1866 | err = __logfs_write_inode(inode, 0); | ||
1867 | logfs_put_wblocks(sb, NULL, 1); | ||
1868 | } | ||
1857 | 1869 | ||
1858 | if (!err) | 1870 | if (!err) |
1859 | err = vmtruncate(inode, size); | 1871 | err = vmtruncate(inode, target); |
1860 | 1872 | ||
1861 | /* I don't trust error recovery yet. */ | 1873 | /* I don't trust error recovery yet. */ |
1862 | WARN_ON(err); | 1874 | WARN_ON(err); |
@@ -2250,8 +2262,6 @@ void logfs_cleanup_rw(struct super_block *sb) | |||
2250 | struct logfs_super *super = logfs_super(sb); | 2262 | struct logfs_super *super = logfs_super(sb); |
2251 | 2263 | ||
2252 | destroy_meta_inode(super->s_segfile_inode); | 2264 | destroy_meta_inode(super->s_segfile_inode); |
2253 | if (super->s_block_pool) | 2265 | logfs_mempool_destroy(super->s_block_pool); |
2254 | mempool_destroy(super->s_block_pool); | 2266 | logfs_mempool_destroy(super->s_shadow_pool); |
2255 | if (super->s_shadow_pool) | ||
2256 | mempool_destroy(super->s_shadow_pool); | ||
2257 | } | 2267 | } |
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index 0ecd8f07c11e..f77ce2b470ba 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * three kinds of objects: inodes, dentries and blocks, both data and indirect. | 10 | * three kinds of objects: inodes, dentries and blocks, both data and indirect. |
11 | */ | 11 | */ |
12 | #include "logfs.h" | 12 | #include "logfs.h" |
13 | #include <linux/slab.h> | ||
13 | 14 | ||
14 | static int logfs_mark_segment_bad(struct super_block *sb, u32 segno) | 15 | static int logfs_mark_segment_bad(struct super_block *sb, u32 segno) |
15 | { | 16 | { |
@@ -182,14 +183,8 @@ static int btree_write_alias(struct super_block *sb, struct logfs_block *block, | |||
182 | return 0; | 183 | return 0; |
183 | } | 184 | } |
184 | 185 | ||
185 | static gc_level_t btree_block_level(struct logfs_block *block) | ||
186 | { | ||
187 | return expand_level(block->ino, block->level); | ||
188 | } | ||
189 | |||
190 | static struct logfs_block_ops btree_block_ops = { | 186 | static struct logfs_block_ops btree_block_ops = { |
191 | .write_block = btree_write_block, | 187 | .write_block = btree_write_block, |
192 | .block_level = btree_block_level, | ||
193 | .free_block = __free_block, | 188 | .free_block = __free_block, |
194 | .write_alias = btree_write_alias, | 189 | .write_alias = btree_write_alias, |
195 | }; | 190 | }; |
@@ -918,7 +913,7 @@ err: | |||
918 | for (i--; i >= 0; i--) | 913 | for (i--; i >= 0; i--) |
919 | free_area(super->s_area[i]); | 914 | free_area(super->s_area[i]); |
920 | free_area(super->s_journal_area); | 915 | free_area(super->s_journal_area); |
921 | mempool_destroy(super->s_alias_pool); | 916 | logfs_mempool_destroy(super->s_alias_pool); |
922 | return -ENOMEM; | 917 | return -ENOMEM; |
923 | } | 918 | } |
924 | 919 | ||
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index 9d856c49afc5..5866ee6e1327 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
@@ -11,6 +11,8 @@ | |||
11 | */ | 11 | */ |
12 | #include "logfs.h" | 12 | #include "logfs.h" |
13 | #include <linux/bio.h> | 13 | #include <linux/bio.h> |
14 | #include <linux/slab.h> | ||
15 | #include <linux/blkdev.h> | ||
14 | #include <linux/mtd/mtd.h> | 16 | #include <linux/mtd/mtd.h> |
15 | #include <linux/statfs.h> | 17 | #include <linux/statfs.h> |
16 | #include <linux/buffer_head.h> | 18 | #include <linux/buffer_head.h> |
@@ -136,6 +138,10 @@ static int logfs_sb_set(struct super_block *sb, void *_super) | |||
136 | sb->s_fs_info = super; | 138 | sb->s_fs_info = super; |
137 | sb->s_mtd = super->s_mtd; | 139 | sb->s_mtd = super->s_mtd; |
138 | sb->s_bdev = super->s_bdev; | 140 | sb->s_bdev = super->s_bdev; |
141 | if (sb->s_bdev) | ||
142 | sb->s_bdi = &bdev_get_queue(sb->s_bdev)->backing_dev_info; | ||
143 | if (sb->s_mtd) | ||
144 | sb->s_bdi = sb->s_mtd->backing_dev_info; | ||
139 | return 0; | 145 | return 0; |
140 | } | 146 | } |
141 | 147 | ||
@@ -451,6 +457,8 @@ static int logfs_read_sb(struct super_block *sb, int read_only) | |||
451 | 457 | ||
452 | btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool); | 458 | btree_init_mempool64(&super->s_shadow_tree.new, super->s_btree_pool); |
453 | btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool); | 459 | btree_init_mempool64(&super->s_shadow_tree.old, super->s_btree_pool); |
460 | btree_init_mempool32(&super->s_shadow_tree.segment_map, | ||
461 | super->s_btree_pool); | ||
454 | 462 | ||
455 | ret = logfs_init_mapping(sb); | 463 | ret = logfs_init_mapping(sb); |
456 | if (ret) | 464 | if (ret) |
@@ -515,8 +523,8 @@ static void logfs_kill_sb(struct super_block *sb) | |||
515 | if (super->s_erase_page) | 523 | if (super->s_erase_page) |
516 | __free_page(super->s_erase_page); | 524 | __free_page(super->s_erase_page); |
517 | super->s_devops->put_device(sb); | 525 | super->s_devops->put_device(sb); |
518 | mempool_destroy(super->s_btree_pool); | 526 | logfs_mempool_destroy(super->s_btree_pool); |
519 | mempool_destroy(super->s_alias_pool); | 527 | logfs_mempool_destroy(super->s_alias_pool); |
520 | kfree(super); | 528 | kfree(super); |
521 | log_super("LogFS: Finished unmounting\n"); | 529 | log_super("LogFS: Finished unmounting\n"); |
522 | } | 530 | } |