diff options
| -rw-r--r-- | fs/logfs/readwrite.c | 29 | ||||
| -rw-r--r-- | fs/logfs/segment.c | 37 |
2 files changed, 51 insertions, 15 deletions
diff --git a/fs/logfs/readwrite.c b/fs/logfs/readwrite.c index 2ac4217b7901..6d663e8ea6da 100644 --- a/fs/logfs/readwrite.c +++ b/fs/logfs/readwrite.c | |||
| @@ -560,8 +560,13 @@ static void inode_free_block(struct super_block *sb, struct logfs_block *block) | |||
| 560 | static void indirect_free_block(struct super_block *sb, | 560 | static void indirect_free_block(struct super_block *sb, |
| 561 | struct logfs_block *block) | 561 | struct logfs_block *block) |
| 562 | { | 562 | { |
| 563 | ClearPagePrivate(block->page); | 563 | struct page *page = block->page; |
| 564 | block->page->private = 0; | 564 | |
| 565 | if (PagePrivate(page)) { | ||
| 566 | ClearPagePrivate(page); | ||
| 567 | page_cache_release(page); | ||
| 568 | set_page_private(page, 0); | ||
| 569 | } | ||
| 565 | __free_block(sb, block); | 570 | __free_block(sb, block); |
| 566 | } | 571 | } |
| 567 | 572 | ||
| @@ -650,8 +655,11 @@ static void alloc_data_block(struct inode *inode, struct page *page) | |||
| 650 | logfs_unpack_index(page->index, &bix, &level); | 655 | logfs_unpack_index(page->index, &bix, &level); |
| 651 | block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); | 656 | block = __alloc_block(inode->i_sb, inode->i_ino, bix, level); |
| 652 | block->page = page; | 657 | block->page = page; |
| 658 | |||
| 653 | SetPagePrivate(page); | 659 | SetPagePrivate(page); |
| 654 | page->private = (unsigned long)block; | 660 | page_cache_get(page); |
| 661 | set_page_private(page, (unsigned long) block); | ||
| 662 | |||
| 655 | block->ops = &indirect_block_ops; | 663 | block->ops = &indirect_block_ops; |
| 656 | } | 664 | } |
| 657 | 665 | ||
| @@ -1901,8 +1909,11 @@ static void move_page_to_inode(struct inode *inode, struct page *page) | |||
| 1901 | li->li_block = block; | 1909 | li->li_block = block; |
| 1902 | 1910 | ||
| 1903 | block->page = NULL; | 1911 | block->page = NULL; |
| 1904 | page->private = 0; | 1912 | if (PagePrivate(page)) { |
| 1905 | ClearPagePrivate(page); | 1913 | ClearPagePrivate(page); |
| 1914 | page_cache_release(page); | ||
| 1915 | set_page_private(page, 0); | ||
| 1916 | } | ||
| 1906 | } | 1917 | } |
| 1907 | 1918 | ||
| 1908 | static void move_inode_to_page(struct page *page, struct inode *inode) | 1919 | static void move_inode_to_page(struct page *page, struct inode *inode) |
| @@ -1918,8 +1929,12 @@ static void move_inode_to_page(struct page *page, struct inode *inode) | |||
| 1918 | BUG_ON(PagePrivate(page)); | 1929 | BUG_ON(PagePrivate(page)); |
| 1919 | block->ops = &indirect_block_ops; | 1930 | block->ops = &indirect_block_ops; |
| 1920 | block->page = page; | 1931 | block->page = page; |
| 1921 | page->private = (unsigned long)block; | 1932 | |
| 1922 | SetPagePrivate(page); | 1933 | if (!PagePrivate(page)) { |
| 1934 | SetPagePrivate(page); | ||
| 1935 | page_cache_get(page); | ||
| 1936 | set_page_private(page, (unsigned long) block); | ||
| 1937 | } | ||
| 1923 | 1938 | ||
| 1924 | block->inode = NULL; | 1939 | block->inode = NULL; |
| 1925 | li->li_block = NULL; | 1940 | li->li_block = NULL; |
diff --git a/fs/logfs/segment.c b/fs/logfs/segment.c index 9d5187353255..6aee6092860d 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 | } |
