diff options
| -rw-r--r-- | MAINTAINERS | 1 | ||||
| -rw-r--r-- | fs/logfs/dir.c | 2 | ||||
| -rw-r--r-- | fs/logfs/file.c | 2 | ||||
| -rw-r--r-- | fs/logfs/gc.c | 2 | ||||
| -rw-r--r-- | fs/logfs/inode.c | 4 | ||||
| -rw-r--r-- | fs/logfs/journal.c | 1 | ||||
| -rw-r--r-- | fs/logfs/logfs.h | 5 | ||||
| -rw-r--r-- | fs/logfs/readwrite.c | 51 | ||||
| -rw-r--r-- | fs/logfs/segment.c | 51 | ||||
| -rw-r--r-- | fs/logfs/super.c | 3 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 4 |
11 files changed, 89 insertions, 37 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 6803338dc885..a1fce9a3ab20 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
| @@ -4140,6 +4140,7 @@ F: fs/partitions/ldm.* | |||
| 4140 | 4140 | ||
| 4141 | LogFS | 4141 | LogFS |
| 4142 | M: Joern Engel <joern@logfs.org> | 4142 | M: Joern Engel <joern@logfs.org> |
| 4143 | M: Prasad Joshi <prasadjoshi.linux@gmail.com> | ||
| 4143 | L: logfs@logfs.org | 4144 | L: logfs@logfs.org |
| 4144 | W: logfs.org | 4145 | W: logfs.org |
| 4145 | S: Maintained | 4146 | S: Maintained |
diff --git a/fs/logfs/dir.c b/fs/logfs/dir.c index 501043e8966c..3de7a32cadbe 100644 --- a/fs/logfs/dir.c +++ b/fs/logfs/dir.c | |||
| @@ -71,7 +71,7 @@ static int write_dir(struct inode *dir, struct logfs_disk_dentry *dd, | |||
| 71 | 71 | ||
| 72 | static int write_inode(struct inode *inode) | 72 | static int write_inode(struct inode *inode) |
| 73 | { | 73 | { |
| 74 | return __logfs_write_inode(inode, WF_LOCK); | 74 | return __logfs_write_inode(inode, NULL, WF_LOCK); |
| 75 | } | 75 | } |
| 76 | 76 | ||
| 77 | static s64 dir_seek_data(struct inode *inode, s64 pos) | 77 | static s64 dir_seek_data(struct inode *inode, s64 pos) |
diff --git a/fs/logfs/file.c b/fs/logfs/file.c index b548c87a86f1..3886cded283c 100644 --- a/fs/logfs/file.c +++ b/fs/logfs/file.c | |||
| @@ -230,7 +230,9 @@ int logfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | |||
| 230 | return ret; | 230 | return ret; |
| 231 | 231 | ||
| 232 | mutex_lock(&inode->i_mutex); | 232 | mutex_lock(&inode->i_mutex); |
| 233 | logfs_get_wblocks(sb, NULL, WF_LOCK); | ||
| 233 | logfs_write_anchor(sb); | 234 | logfs_write_anchor(sb); |
| 235 | logfs_put_wblocks(sb, NULL, WF_LOCK); | ||
| 234 | mutex_unlock(&inode->i_mutex); | 236 | mutex_unlock(&inode->i_mutex); |
| 235 | 237 | ||
| 236 | return 0; | 238 | return 0; |
diff --git a/fs/logfs/gc.c b/fs/logfs/gc.c index caa4419285dc..d4efb061bdc5 100644 --- a/fs/logfs/gc.c +++ b/fs/logfs/gc.c | |||
| @@ -367,7 +367,7 @@ static struct gc_candidate *get_candidate(struct super_block *sb) | |||
| 367 | int i, max_dist; | 367 | int i, max_dist; |
| 368 | struct gc_candidate *cand = NULL, *this; | 368 | struct gc_candidate *cand = NULL, *this; |
| 369 | 369 | ||
| 370 | max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS); | 370 | max_dist = min(no_free_segments(sb), LOGFS_NO_AREAS - 1); |
| 371 | 371 | ||
| 372 | for (i = max_dist; i >= 0; i--) { | 372 | for (i = max_dist; i >= 0; i--) { |
| 373 | this = first_in_list(&super->s_low_list[i]); | 373 | this = first_in_list(&super->s_low_list[i]); |
diff --git a/fs/logfs/inode.c b/fs/logfs/inode.c index 388df1aa35e5..a422f42238b2 100644 --- a/fs/logfs/inode.c +++ b/fs/logfs/inode.c | |||
| @@ -286,7 +286,7 @@ static int logfs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
| 286 | if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN) | 286 | if (logfs_inode(inode)->li_flags & LOGFS_IF_STILLBORN) |
| 287 | return 0; | 287 | return 0; |
| 288 | 288 | ||
| 289 | ret = __logfs_write_inode(inode, flags); | 289 | ret = __logfs_write_inode(inode, NULL, flags); |
| 290 | LOGFS_BUG_ON(ret, inode->i_sb); | 290 | LOGFS_BUG_ON(ret, inode->i_sb); |
| 291 | return ret; | 291 | return ret; |
| 292 | } | 292 | } |
| @@ -363,7 +363,9 @@ static void logfs_init_once(void *_li) | |||
| 363 | 363 | ||
| 364 | static int logfs_sync_fs(struct super_block *sb, int wait) | 364 | static int logfs_sync_fs(struct super_block *sb, int wait) |
| 365 | { | 365 | { |
| 366 | logfs_get_wblocks(sb, NULL, WF_LOCK); | ||
| 366 | logfs_write_anchor(sb); | 367 | logfs_write_anchor(sb); |
| 368 | logfs_put_wblocks(sb, NULL, WF_LOCK); | ||
| 367 | return 0; | 369 | return 0; |
| 368 | } | 370 | } |
| 369 | 371 | ||
diff --git a/fs/logfs/journal.c b/fs/logfs/journal.c index 9da29706f91c..1e1c369df22b 100644 --- a/fs/logfs/journal.c +++ b/fs/logfs/journal.c | |||
| @@ -612,7 +612,6 @@ static size_t __logfs_write_je(struct super_block *sb, void *buf, u16 type, | |||
| 612 | if (len == 0) | 612 | if (len == 0) |
| 613 | return logfs_write_header(super, header, 0, type); | 613 | return logfs_write_header(super, header, 0, type); |
| 614 | 614 | ||
| 615 | BUG_ON(len > sb->s_blocksize); | ||
| 616 | compr_len = logfs_compress(buf, data, len, sb->s_blocksize); | 615 | compr_len = logfs_compress(buf, data, len, sb->s_blocksize); |
| 617 | if (compr_len < 0 || type == JE_ANCHOR) { | 616 | if (compr_len < 0 || type == JE_ANCHOR) { |
| 618 | memcpy(data, buf, len); | 617 | memcpy(data, buf, len); |
diff --git a/fs/logfs/logfs.h b/fs/logfs/logfs.h index 926373866a55..5f0937609465 100644 --- a/fs/logfs/logfs.h +++ b/fs/logfs/logfs.h | |||
| @@ -528,7 +528,7 @@ void logfs_destroy_inode_cache(void); | |||
| 528 | void logfs_set_blocks(struct inode *inode, u64 no); | 528 | void logfs_set_blocks(struct inode *inode, u64 no); |
| 529 | /* these logically belong into inode.c but actually reside in readwrite.c */ | 529 | /* these logically belong into inode.c but actually reside in readwrite.c */ |
| 530 | int logfs_read_inode(struct inode *inode); | 530 | int logfs_read_inode(struct inode *inode); |
| 531 | int __logfs_write_inode(struct inode *inode, long flags); | 531 | int __logfs_write_inode(struct inode *inode, struct page *, long flags); |
| 532 | void logfs_evict_inode(struct inode *inode); | 532 | void logfs_evict_inode(struct inode *inode); |
| 533 | 533 | ||
| 534 | /* journal.c */ | 534 | /* journal.c */ |
| @@ -577,6 +577,8 @@ void initialize_block_counters(struct page *page, struct logfs_block *block, | |||
| 577 | __be64 *array, int page_is_empty); | 577 | __be64 *array, int page_is_empty); |
| 578 | int logfs_exist_block(struct inode *inode, u64 bix); | 578 | int logfs_exist_block(struct inode *inode, u64 bix); |
| 579 | int get_page_reserve(struct inode *inode, struct page *page); | 579 | int get_page_reserve(struct inode *inode, struct page *page); |
| 580 | void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock); | ||
| 581 | void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock); | ||
| 580 | extern struct logfs_block_ops indirect_block_ops; | 582 | extern struct logfs_block_ops indirect_block_ops; |
| 581 | 583 | ||
| 582 | /* segment.c */ | 584 | /* segment.c */ |
| @@ -594,6 +596,7 @@ int logfs_init_mapping(struct super_block *sb); | |||
| 594 | void logfs_sync_area(struct logfs_area *area); | 596 | void logfs_sync_area(struct logfs_area *area); |
| 595 | void logfs_sync_segments(struct super_block *sb); | 597 | void logfs_sync_segments(struct super_block *sb); |
| 596 | void freeseg(struct super_block *sb, u32 segno); | 598 | void freeseg(struct super_block *sb, u32 segno); |
| 599 | void free_areas(struct super_block *sb); | ||
| 597 | 600 | ||
| 598 | /* area handling */ | 601 | /* area handling */ |
| 599 | int logfs_init_areas(struct super_block *sb); | 602 | int logfs_init_areas(struct super_block *sb); |
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 2ac4217b7901..4153e65b0148 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
| @@ -244,8 +244,7 @@ static void preunlock_page(struct super_block *sb, struct page *page, int lock) | |||
| 244 | * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked | 244 | * is waiting for s_write_mutex. We annotate this fact by setting PG_pre_locked |
| 245 | * in addition to PG_locked. | 245 | * in addition to PG_locked. |
| 246 | */ | 246 | */ |
| 247 | static void logfs_get_wblocks(struct super_block *sb, struct page *page, | 247 | void logfs_get_wblocks(struct super_block *sb, struct page *page, int lock) |
| 248 | int lock) | ||
| 249 | { | 248 | { |
| 250 | struct logfs_super *super = logfs_super(sb); | 249 | struct logfs_super *super = logfs_super(sb); |
| 251 | 250 | ||
| @@ -260,8 +259,7 @@ static void logfs_get_wblocks(struct super_block *sb, struct page *page, | |||
| 260 | } | 259 | } |
| 261 | } | 260 | } |
| 262 | 261 | ||
| 263 | static void logfs_put_wblocks(struct super_block *sb, struct page *page, | 262 | void logfs_put_wblocks(struct super_block *sb, struct page *page, int lock) |
| 264 | int lock) | ||
| 265 | { | 263 | { |
| 266 | struct logfs_super *super = logfs_super(sb); | 264 | struct logfs_super *super = logfs_super(sb); |
| 267 | 265 | ||
| @@ -424,7 +422,7 @@ static void inode_write_block(struct logfs_block *block) | |||
| 424 | if (inode->i_ino == LOGFS_INO_MASTER) | 422 | if (inode->i_ino == LOGFS_INO_MASTER) |
| 425 | logfs_write_anchor(inode->i_sb); | 423 | logfs_write_anchor(inode->i_sb); |
| 426 | else { | 424 | else { |
| 427 | ret = __logfs_write_inode(inode, 0); | 425 | ret = __logfs_write_inode(inode, NULL, 0); |
| 428 | /* see indirect_write_block comment */ | 426 | /* see indirect_write_block comment */ |
| 429 | BUG_ON(ret); | 427 | BUG_ON(ret); |
| 430 | } | 428 | } |
| @@ -560,8 +558,13 @@ static void inode_free_block(struct super_block *sb, struct logfs_block *block) | |||
| 560 | static void indirect_free_block(struct super_block *sb, | 558 | static void indirect_free_block(struct super_block *sb, |
| 561 | struct logfs_block *block) | 559 | struct logfs_block *block) |
| 562 | { | 560 | { |
| 563 | ClearPagePrivate(block->page); | 561 | struct page *page = block->page; |
| 564 | block->page->private = 0; | 562 | |
| 563 | if (PagePrivate(page)) { | ||
| 564 | ClearPagePrivate(page); | ||
| 565 | page_cache_release(page); | ||
| 566 | set_page_private(page, 0); | ||
| 567 | } | ||
| 565 | __free_block(sb, block); | 568 | __free_block(sb, block); |
| 566 | } | 569 | } |
| 567 | 570 | ||
| @@ -650,8 +653,11 @@ static void alloc_data_block(struct inode *inode, struct page *page) | |||
| 650 | logfs_unpack_index(page->index, &bix, &level); | 653 | logfs_unpack_index(page->index, &bix, &level); |
| 651 | block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); | 654 | block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); |
| 652 | block->page = page; | 655 | block->page = page; |
| 656 | |||
| 653 | SetPagePrivate(page); | 657 | SetPagePrivate(page); |
| 654 | page->private = (unsigned long)block; | 658 | page_cache_get(page); |
| 659 | set_page_private(page, (unsigned long) block); | ||
| 660 | |||
| 655 | block->ops = &indirect_block_ops; | 661 | block->ops = &indirect_block_ops; |
| 656 | } | 662 | } |
| 657 | 663 | ||
| @@ -1570,11 +1576,15 @@ int logfs_write_buf(struct inode *inode, struct page *page, long flags) | |||
| 1570 | static int __logfs_delete(struct inode *inode, struct page *page) | 1576 | static int __logfs_delete(struct inode *inode, struct page *page) |
| 1571 | { | 1577 | { |
| 1572 | long flags = WF_DELETE; | 1578 | long flags = WF_DELETE; |
| 1579 | int err; | ||
| 1573 | 1580 | ||
| 1574 | inode->i_ctime = inode->i_mtime = CURRENT_TIME; | 1581 | inode->i_ctime = inode->i_mtime = CURRENT_TIME; |
| 1575 | 1582 | ||
| 1576 | if (page->index < I0_BLOCKS) | 1583 | if (page->index < I0_BLOCKS) |
| 1577 | return logfs_write_direct(inode, page, flags); | 1584 | return logfs_write_direct(inode, page, flags); |
| 1585 | err = grow_inode(inode, page->index, 0); | ||
| 1586 | if (err) | ||
| 1587 | return err; | ||
| 1578 | return logfs_write_rec(inode, page, page->index, 0, flags); | 1588 | return logfs_write_rec(inode, page, page->index, 0, flags); |
| 1579 | } | 1589 | } |
| 1580 | 1590 | ||
| @@ -1623,7 +1633,7 @@ int logfs_rewrite_block(struct inode *inode, u64 bix, u64 ofs, | |||
| 1623 | if (inode->i_ino == LOGFS_INO_MASTER) | 1633 | if (inode->i_ino == LOGFS_INO_MASTER) |
| 1624 | logfs_write_anchor(inode->i_sb); | 1634 | logfs_write_anchor(inode->i_sb); |
| 1625 | else { | 1635 | else { |
| 1626 | err = __logfs_write_inode(inode, flags); | 1636 | err = __logfs_write_inode(inode, page, flags); |
| 1627 | } | 1637 | } |
| 1628 | } | 1638 | } |
| 1629 | } | 1639 | } |
| @@ -1873,7 +1883,7 @@ int logfs_truncate(struct inode *inode, u64 target) | |||
| 1873 | logfs_get_wblocks(sb, NULL, 1); | 1883 | logfs_get_wblocks(sb, NULL, 1); |
| 1874 | err = __logfs_truncate(inode, size); | 1884 | err = __logfs_truncate(inode, size); |
| 1875 | if (!err) | 1885 | if (!err) |
| 1876 | err = __logfs_write_inode(inode, 0); | 1886 | err = __logfs_write_inode(inode, NULL, 0); |
| 1877 | logfs_put_wblocks(sb, NULL, 1); | 1887 | logfs_put_wblocks(sb, NULL, 1); |
| 1878 | } | 1888 | } |
| 1879 | 1889 | ||
| @@ -1901,8 +1911,11 @@ static void move_page_to_inode(struct inode *inode, struct page *page) | |||
| 1901 | li->li_block = block; | 1911 | li->li_block = block; |
| 1902 | 1912 | ||
| 1903 | block->page = NULL; | 1913 | block->page = NULL; |
| 1904 | page->private = 0; | 1914 | if (PagePrivate(page)) { |
| 1905 | ClearPagePrivate(page); | 1915 | ClearPagePrivate(page); |
| 1916 | page_cache_release(page); | ||
| 1917 | set_page_private(page, 0); | ||
| 1918 | } | ||
| 1906 | } | 1919 | } |
| 1907 | 1920 | ||
| 1908 | static void move_inode_to_page(struct page *page, struct inode *inode) | 1921 | static void move_inode_to_page(struct page *page, struct inode *inode) |
| @@ -1918,8 +1931,12 @@ static void move_inode_to_page(struct page *page, struct inode *inode) | |||
| 1918 | BUG_ON(PagePrivate(page)); | 1931 | BUG_ON(PagePrivate(page)); |
| 1919 | block->ops = &indirect_block_ops; | 1932 | block->ops = &indirect_block_ops; |
| 1920 | block->page = page; | 1933 | block->page = page; |
| 1921 | page->private = (unsigned long)block; | 1934 | |
| 1922 | SetPagePrivate(page); | 1935 | if (!PagePrivate(page)) { |
| 1936 | SetPagePrivate(page); | ||
| 1937 | page_cache_get(page); | ||
| 1938 | set_page_private(page, (unsigned long) block); | ||
| 1939 | } | ||
| 1923 | 1940 | ||
| 1924 | block->inode = NULL; | 1941 | block->inode = NULL; |
| 1925 | li->li_block = NULL; | 1942 | li->li_block = NULL; |
| @@ -2106,14 +2123,14 @@ void logfs_set_segment_unreserved(struct super_block *sb, u32 segno, u32 ec) | |||
| 2106 | ec_level); | 2123 | ec_level); |
| 2107 | } | 2124 | } |
| 2108 | 2125 | ||
| 2109 | int __logfs_write_inode(struct inode *inode, long flags) | 2126 | int __logfs_write_inode(struct inode *inode, struct page *page, long flags) |
| 2110 | { | 2127 | { |
| 2111 | struct super_block *sb = inode->i_sb; | 2128 | struct super_block *sb = inode->i_sb; |
| 2112 | int ret; | 2129 | int ret; |
| 2113 | 2130 | ||
| 2114 | logfs_get_wblocks(sb, NULL, flags & WF_LOCK); | 2131 | logfs_get_wblocks(sb, page, flags & WF_LOCK); |
| 2115 | ret = do_write_inode(inode); | 2132 | ret = do_write_inode(inode); |
| 2116 | logfs_put_wblocks(sb, NULL, flags & WF_LOCK); | 2133 | logfs_put_wblocks(sb, page, flags & WF_LOCK); |
| 2117 | return ret; | 2134 | return ret; |
| 2118 | } | 2135 | } |
| 2119 | 2136 | ||
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index 9d5187353255..ab798ed1cc88 100644 --- a/fs/logfs/segment.c +++ b/fs/logfs/segment.c | |||
| @@ -86,7 +86,11 @@ int __logfs_buf_write(struct logfs_area *area, u64 ofs, void *buf, size_t len, | |||
| 86 | BUG_ON(!page); /* FIXME: reserve a pool */ | 86 | BUG_ON(!page); /* FIXME: reserve a pool */ |
| 87 | SetPageUptodate(page); | 87 | SetPageUptodate(page); |
| 88 | memcpy(page_address(page) + offset, buf, copylen); | 88 | memcpy(page_address(page) + offset, buf, copylen); |
| 89 | SetPagePrivate(page); | 89 | |
| 90 | if (!PagePrivate(page)) { | ||
| 91 | SetPagePrivate(page); | ||
| 92 | page_cache_get(page); | ||
| 93 | } | ||
| 90 | page_cache_release(page); | 94 | page_cache_release(page); |
| 91 | 95 | ||
| 92 | buf += copylen; | 96 | buf += copylen; |
| @@ -110,7 +114,10 @@ static void pad_partial_page(struct logfs_area *area) | |||
| 110 | page = get_mapping_page(sb, index, 0); | 114 | page = get_mapping_page(sb, index, 0); |
| 111 | BUG_ON(!page); /* FIXME: reserve a pool */ | 115 | BUG_ON(!page); /* FIXME: reserve a pool */ |
| 112 | memset(page_address(page) + offset, 0xff, len); | 116 | memset(page_address(page) + offset, 0xff, len); |
| 113 | SetPagePrivate(page); | 117 | if (!PagePrivate(page)) { |
| 118 | SetPagePrivate(page); | ||
| 119 | page_cache_get(page); | ||
| 120 | } | ||
| 114 | page_cache_release(page); | 121 | page_cache_release(page); |
| 115 | } | 122 | } |
| 116 | } | 123 | } |
| @@ -130,7 +137,10 @@ static void pad_full_pages(struct logfs_area *area) | |||
| 130 | BUG_ON(!page); /* FIXME: reserve a pool */ | 137 | BUG_ON(!page); /* FIXME: reserve a pool */ |
| 131 | SetPageUptodate(page); | 138 | SetPageUptodate(page); |
| 132 | memset(page_address(page), 0xff, PAGE_CACHE_SIZE); | 139 | memset(page_address(page), 0xff, PAGE_CACHE_SIZE); |
| 133 | SetPagePrivate(page); | 140 | if (!PagePrivate(page)) { |
| 141 | SetPagePrivate(page); | ||
| 142 | page_cache_get(page); | ||
| 143 | } | ||
| 134 | page_cache_release(page); | 144 | page_cache_release(page); |
| 135 | index++; | 145 | index++; |
| 136 | no_indizes--; | 146 | no_indizes--; |
| @@ -485,8 +495,12 @@ static void move_btree_to_page(struct inode *inode, struct page *page, | |||
| 485 | mempool_free(item, super->s_alias_pool); | 495 | mempool_free(item, super->s_alias_pool); |
| 486 | } | 496 | } |
| 487 | block->page = page; | 497 | block->page = page; |
| 488 | SetPagePrivate(page); | 498 | |
| 489 | page->private = (unsigned long)block; | 499 | if (!PagePrivate(page)) { |
| 500 | SetPagePrivate(page); | ||
| 501 | page_cache_get(page); | ||
| 502 | set_page_private(page, (unsigned long) block); | ||
| 503 | } | ||
| 490 | block->ops = &indirect_block_ops; | 504 | block->ops = &indirect_block_ops; |
| 491 | initialize_block_counters(page, block, data, 0); | 505 | initialize_block_counters(page, block, data, 0); |
| 492 | } | 506 | } |
| @@ -536,8 +550,12 @@ void move_page_to_btree(struct page *page) | |||
| 536 | list_add(&item->list, &block->item_list); | 550 | list_add(&item->list, &block->item_list); |
| 537 | } | 551 | } |
| 538 | block->page = NULL; | 552 | block->page = NULL; |
| 539 | ClearPagePrivate(page); | 553 | |
| 540 | page->private = 0; | 554 | if (PagePrivate(page)) { |
| 555 | ClearPagePrivate(page); | ||
| 556 | page_cache_release(page); | ||
| 557 | set_page_private(page, 0); | ||
| 558 | } | ||
| 541 | block->ops = &btree_block_ops; | 559 | block->ops = &btree_block_ops; |
| 542 | err = alias_tree_insert(block->sb, block->ino, block->bix, block->level, | 560 | err = alias_tree_insert(block->sb, block->ino, block->bix, block->level, |
| 543 | block); | 561 | block); |
| @@ -702,7 +720,10 @@ void freeseg(struct super_block *sb, u32 segno) | |||
| 702 | page = find_get_page(mapping, ofs >> PAGE_SHIFT); | 720 | page = find_get_page(mapping, ofs >> PAGE_SHIFT); |
| 703 | if (!page) | 721 | if (!page) |
| 704 | continue; | 722 | continue; |
| 705 | ClearPagePrivate(page); | 723 | if (PagePrivate(page)) { |
| 724 | ClearPagePrivate(page); | ||
| 725 | page_cache_release(page); | ||
| 726 | } | ||
| 706 | page_cache_release(page); | 727 | page_cache_release(page); |
| 707 | } | 728 | } |
| 708 | } | 729 | } |
| @@ -841,6 +862,16 @@ static void free_area(struct logfs_area *area) | |||
| 841 | kfree(area); | 862 | kfree(area); |
| 842 | } | 863 | } |
| 843 | 864 | ||
| 865 | void free_areas(struct super_block *sb) | ||
| 866 | { | ||
| 867 | struct logfs_super *super = logfs_super(sb); | ||
| 868 | int i; | ||
| 869 | |||
| 870 | for_each_area(i) | ||
| 871 | free_area(super->s_area[i]); | ||
| 872 | free_area(super->s_journal_area); | ||
| 873 | } | ||
| 874 | |||
| 844 | static struct logfs_area *alloc_area(struct super_block *sb) | 875 | static struct logfs_area *alloc_area(struct super_block *sb) |
| 845 | { | 876 | { |
| 846 | struct logfs_area *area; | 877 | struct logfs_area *area; |
| @@ -923,10 +954,6 @@ err: | |||
| 923 | void logfs_cleanup_areas(struct super_block *sb) | 954 | void logfs_cleanup_areas(struct super_block *sb) |
| 924 | { | 955 | { |
| 925 | struct logfs_super *super = logfs_super(sb); | 956 | struct logfs_super *super = logfs_super(sb); |
| 926 | int i; | ||
| 927 | 957 | ||
| 928 | btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias); | 958 | btree_grim_visitor128(&super->s_object_alias_tree, 0, kill_alias); |
| 929 | for_each_area(i) | ||
| 930 | free_area(super->s_area[i]); | ||
| 931 | free_area(super->s_journal_area); | ||
| 932 | } | 959 | } |
diff --git a/fs/logfs/super.c b/fs/logfs/super.c index e795c234ea33..c9ee7f5d1caf 100644 --- a/fs/logfs/super.c +++ b/fs/logfs/super.c | |||
| @@ -486,14 +486,15 @@ static void logfs_kill_sb(struct super_block *sb) | |||
| 486 | /* Alias entries slow down mount, so evict as many as possible */ | 486 | /* Alias entries slow down mount, so evict as many as possible */ |
| 487 | sync_filesystem(sb); | 487 | sync_filesystem(sb); |
| 488 | logfs_write_anchor(sb); | 488 | logfs_write_anchor(sb); |
| 489 | free_areas(sb); | ||
| 489 | 490 | ||
| 490 | /* | 491 | /* |
| 491 | * From this point on alias entries are simply dropped - and any | 492 | * From this point on alias entries are simply dropped - and any |
| 492 | * writes to the object store are considered bugs. | 493 | * writes to the object store are considered bugs. |
| 493 | */ | 494 | */ |
| 494 | super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; | ||
| 495 | log_super("LogFS: Now in shutdown\n"); | 495 | log_super("LogFS: Now in shutdown\n"); |
| 496 | generic_shutdown_super(sb); | 496 | generic_shutdown_super(sb); |
| 497 | super->s_flags |= LOGFS_SB_FLAG_SHUTDOWN; | ||
| 497 | 498 | ||
| 498 | BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes); | 499 | BUG_ON(super->s_dirty_used_bytes || super->s_dirty_free_bytes); |
| 499 | 500 | ||
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 1a81fde8f333..221295208fd0 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h | |||
| @@ -441,7 +441,7 @@ static inline void mtd_resume(struct mtd_info *mtd) | |||
| 441 | static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) | 441 | static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) |
| 442 | { | 442 | { |
| 443 | if (!mtd->block_isbad) | 443 | if (!mtd->block_isbad) |
| 444 | return -EOPNOTSUPP; | 444 | return 0; |
| 445 | return mtd->block_isbad(mtd, ofs); | 445 | return mtd->block_isbad(mtd, ofs); |
| 446 | } | 446 | } |
| 447 | 447 | ||
| @@ -489,7 +489,7 @@ static inline int mtd_has_oob(const struct mtd_info *mtd) | |||
| 489 | 489 | ||
| 490 | static inline int mtd_can_have_bb(const struct mtd_info *mtd) | 490 | static inline int mtd_can_have_bb(const struct mtd_info *mtd) |
| 491 | { | 491 | { |
| 492 | return !!mtd->block_isbad; | 492 | return 0; |
| 493 | } | 493 | } |
| 494 | 494 | ||
| 495 | /* Kernel-side ioctl definitions */ | 495 | /* Kernel-side ioctl definitions */ |
