Loading fs/btrfs/disk-io.c +23 −3 Original line number Original line Diff line number Diff line Loading @@ -197,9 +197,23 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page) if (found_start != start) { if (found_start != start) { printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", start, found_start, len); start, found_start, len); WARN_ON(1); goto err; } if (eb->first_page != page) { printk("bad first page %lu %lu\n", eb->first_page->index, page->index); WARN_ON(1); goto err; } if (!PageUptodate(page)) { printk("csum not up to date page %lu\n", page->index); WARN_ON(1); goto err; } } found_level = btrfs_header_level(eb); found_level = btrfs_header_level(eb); csum_tree_block(root, eb, 0); csum_tree_block(root, eb, 0); err: free_extent_buffer(eb); free_extent_buffer(eb); out: out: return 0; return 0; Loading Loading @@ -368,7 +382,10 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf) struct extent_buffer *buf) { { struct inode *btree_inode = root->fs_info->btree_inode; struct inode *btree_inode = root->fs_info->btree_inode; clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); if (btrfs_header_generation(buf) == root->fs_info->running_transaction->transid) clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); return 0; return 0; } } Loading Loading @@ -897,8 +914,11 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) void btrfs_throttle(struct btrfs_root *root) void btrfs_throttle(struct btrfs_root *root) { { if (root->fs_info->throttles) struct backing_dev_info *bdi; congestion_wait(WRITE, HZ/10); bdi = root->fs_info->sb->s_bdev->bd_inode->i_mapping->backing_dev_info; if (root->fs_info->throttles && bdi_write_congested(bdi)) congestion_wait(WRITE, HZ/20); } } void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) Loading fs/btrfs/extent-tree.c +10 −3 Original line number Original line Diff line number Diff line Loading @@ -1212,6 +1212,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, u64 header_transid = u64 header_transid = btrfs_header_generation(buf); btrfs_header_generation(buf); if (header_transid == transid) { if (header_transid == transid) { clean_tree_block(NULL, root, buf); free_extent_buffer(buf); free_extent_buffer(buf); return 1; return 1; } } Loading Loading @@ -1249,7 +1250,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root key.objectid = bytenr; key.objectid = bytenr; btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); key.offset = num_bytes; key.offset = num_bytes; path = btrfs_alloc_path(); path = btrfs_alloc_path(); if (!path) if (!path) return -ENOMEM; return -ENOMEM; Loading Loading @@ -1648,8 +1648,6 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, search_start, search_end, hint_byte, ins, search_start, search_end, hint_byte, ins, trans->alloc_exclude_start, trans->alloc_exclude_start, trans->alloc_exclude_nr, data); trans->alloc_exclude_nr, data); if (ret) printk("find free extent returns %d\n", ret); BUG_ON(ret); BUG_ON(ret); if (ret) if (ret) return ret; return ret; Loading Loading @@ -1764,7 +1762,16 @@ struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 0, 0, 0); 0, 0, 0); return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM); } } btrfs_set_header_generation(buf, trans->transid); clean_tree_block(trans, root, buf); wait_on_tree_block_writeback(root, buf); btrfs_set_buffer_uptodate(buf); btrfs_set_buffer_uptodate(buf); if (PageDirty(buf->first_page)) { printk("page %lu dirty\n", buf->first_page->index); WARN_ON(1); } set_extent_dirty(&trans->transaction->dirty_pages, buf->start, set_extent_dirty(&trans->transaction->dirty_pages, buf->start, buf->start + buf->len - 1, GFP_NOFS); buf->start + buf->len - 1, GFP_NOFS); set_extent_bits(&BTRFS_I(root->fs_info->btree_inode)->extent_tree, set_extent_bits(&BTRFS_I(root->fs_info->btree_inode)->extent_tree, Loading fs/btrfs/extent_map.c +21 −9 Original line number Original line Diff line number Diff line Loading @@ -1663,6 +1663,13 @@ void set_page_extent_mapped(struct page *page) } } } } void set_page_extent_head(struct page *page, unsigned long len) { WARN_ON(page->private && page->private == EXTENT_PAGE_PRIVATE && PageDirty(page)); set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2); } /* /* * basic readpage implementation. Locked extent state structs are inserted * basic readpage implementation. Locked extent state structs are inserted * into the tree that are removed when the IO is done (by the end_io * into the tree that are removed when the IO is done (by the end_io Loading Loading @@ -2490,8 +2497,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, mark_page_accessed(page0); mark_page_accessed(page0); set_page_extent_mapped(page0); set_page_extent_mapped(page0); WARN_ON(!PageUptodate(page0)); WARN_ON(!PageUptodate(page0)); set_page_private(page0, EXTENT_PAGE_PRIVATE_FIRST_PAGE | set_page_extent_head(page0, len); len << 2); } else { } else { i = 0; i = 0; } } Loading @@ -2505,8 +2511,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, mark_page_accessed(p); mark_page_accessed(p); if (i == 0) { if (i == 0) { eb->first_page = p; eb->first_page = p; set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | set_page_extent_head(p, len); len << 2); } else { } else { set_page_private(p, EXTENT_PAGE_PRIVATE); set_page_private(p, EXTENT_PAGE_PRIVATE); } } Loading Loading @@ -2569,8 +2574,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, if (i == 0) { if (i == 0) { eb->first_page = p; eb->first_page = p; set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | set_page_extent_head(p, len); len << 2); } else { } else { set_page_private(p, EXTENT_PAGE_PRIVATE); set_page_private(p, EXTENT_PAGE_PRIVATE); } } Loading Loading @@ -2643,6 +2647,11 @@ int clear_extent_buffer_dirty(struct extent_map_tree *tree, for (i = 0; i < num_pages; i++) { for (i = 0; i < num_pages; i++) { page = extent_buffer_page(eb, i); page = extent_buffer_page(eb, i); lock_page(page); lock_page(page); if (i == 0) set_page_extent_head(page, eb->len); else set_page_private(page, EXTENT_PAGE_PRIVATE); /* /* * if we're on the last page or the first page and the * if we're on the last page or the first page and the * block isn't aligned on a page boundary, do extra checks * block isn't aligned on a page boundary, do extra checks Loading Loading @@ -2697,9 +2706,12 @@ int set_extent_buffer_dirty(struct extent_map_tree *tree, */ */ if (i == 0) { if (i == 0) { lock_page(page); lock_page(page); set_page_private(page, set_page_extent_head(page, eb->len); EXTENT_PAGE_PRIVATE_FIRST_PAGE | } else if (PagePrivate(page) && eb->len << 2); page->private != EXTENT_PAGE_PRIVATE) { lock_page(page); set_page_extent_mapped(page); unlock_page(page); } } __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); if (i == 0) if (i == 0) Loading Loading
fs/btrfs/disk-io.c +23 −3 Original line number Original line Diff line number Diff line Loading @@ -197,9 +197,23 @@ int csum_dirty_buffer(struct btrfs_root *root, struct page *page) if (found_start != start) { if (found_start != start) { printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n", start, found_start, len); start, found_start, len); WARN_ON(1); goto err; } if (eb->first_page != page) { printk("bad first page %lu %lu\n", eb->first_page->index, page->index); WARN_ON(1); goto err; } if (!PageUptodate(page)) { printk("csum not up to date page %lu\n", page->index); WARN_ON(1); goto err; } } found_level = btrfs_header_level(eb); found_level = btrfs_header_level(eb); csum_tree_block(root, eb, 0); csum_tree_block(root, eb, 0); err: free_extent_buffer(eb); free_extent_buffer(eb); out: out: return 0; return 0; Loading Loading @@ -368,7 +382,10 @@ int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct extent_buffer *buf) struct extent_buffer *buf) { { struct inode *btree_inode = root->fs_info->btree_inode; struct inode *btree_inode = root->fs_info->btree_inode; clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); if (btrfs_header_generation(buf) == root->fs_info->running_transaction->transid) clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf); return 0; return 0; } } Loading Loading @@ -897,8 +914,11 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf) void btrfs_throttle(struct btrfs_root *root) void btrfs_throttle(struct btrfs_root *root) { { if (root->fs_info->throttles) struct backing_dev_info *bdi; congestion_wait(WRITE, HZ/10); bdi = root->fs_info->sb->s_bdev->bd_inode->i_mapping->backing_dev_info; if (root->fs_info->throttles && bdi_write_congested(bdi)) congestion_wait(WRITE, HZ/20); } } void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr) Loading
fs/btrfs/extent-tree.c +10 −3 Original line number Original line Diff line number Diff line Loading @@ -1212,6 +1212,7 @@ static int pin_down_bytes(struct btrfs_root *root, u64 bytenr, u32 num_bytes, u64 header_transid = u64 header_transid = btrfs_header_generation(buf); btrfs_header_generation(buf); if (header_transid == transid) { if (header_transid == transid) { clean_tree_block(NULL, root, buf); free_extent_buffer(buf); free_extent_buffer(buf); return 1; return 1; } } Loading Loading @@ -1249,7 +1250,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root key.objectid = bytenr; key.objectid = bytenr; btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); key.offset = num_bytes; key.offset = num_bytes; path = btrfs_alloc_path(); path = btrfs_alloc_path(); if (!path) if (!path) return -ENOMEM; return -ENOMEM; Loading Loading @@ -1648,8 +1648,6 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, search_start, search_end, hint_byte, ins, search_start, search_end, hint_byte, ins, trans->alloc_exclude_start, trans->alloc_exclude_start, trans->alloc_exclude_nr, data); trans->alloc_exclude_nr, data); if (ret) printk("find free extent returns %d\n", ret); BUG_ON(ret); BUG_ON(ret); if (ret) if (ret) return ret; return ret; Loading Loading @@ -1764,7 +1762,16 @@ struct extent_buffer *__btrfs_alloc_free_block(struct btrfs_trans_handle *trans, 0, 0, 0); 0, 0, 0); return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM); } } btrfs_set_header_generation(buf, trans->transid); clean_tree_block(trans, root, buf); wait_on_tree_block_writeback(root, buf); btrfs_set_buffer_uptodate(buf); btrfs_set_buffer_uptodate(buf); if (PageDirty(buf->first_page)) { printk("page %lu dirty\n", buf->first_page->index); WARN_ON(1); } set_extent_dirty(&trans->transaction->dirty_pages, buf->start, set_extent_dirty(&trans->transaction->dirty_pages, buf->start, buf->start + buf->len - 1, GFP_NOFS); buf->start + buf->len - 1, GFP_NOFS); set_extent_bits(&BTRFS_I(root->fs_info->btree_inode)->extent_tree, set_extent_bits(&BTRFS_I(root->fs_info->btree_inode)->extent_tree, Loading
fs/btrfs/extent_map.c +21 −9 Original line number Original line Diff line number Diff line Loading @@ -1663,6 +1663,13 @@ void set_page_extent_mapped(struct page *page) } } } } void set_page_extent_head(struct page *page, unsigned long len) { WARN_ON(page->private && page->private == EXTENT_PAGE_PRIVATE && PageDirty(page)); set_page_private(page, EXTENT_PAGE_PRIVATE_FIRST_PAGE | len << 2); } /* /* * basic readpage implementation. Locked extent state structs are inserted * basic readpage implementation. Locked extent state structs are inserted * into the tree that are removed when the IO is done (by the end_io * into the tree that are removed when the IO is done (by the end_io Loading Loading @@ -2490,8 +2497,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, mark_page_accessed(page0); mark_page_accessed(page0); set_page_extent_mapped(page0); set_page_extent_mapped(page0); WARN_ON(!PageUptodate(page0)); WARN_ON(!PageUptodate(page0)); set_page_private(page0, EXTENT_PAGE_PRIVATE_FIRST_PAGE | set_page_extent_head(page0, len); len << 2); } else { } else { i = 0; i = 0; } } Loading @@ -2505,8 +2511,7 @@ struct extent_buffer *alloc_extent_buffer(struct extent_map_tree *tree, mark_page_accessed(p); mark_page_accessed(p); if (i == 0) { if (i == 0) { eb->first_page = p; eb->first_page = p; set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | set_page_extent_head(p, len); len << 2); } else { } else { set_page_private(p, EXTENT_PAGE_PRIVATE); set_page_private(p, EXTENT_PAGE_PRIVATE); } } Loading Loading @@ -2569,8 +2574,7 @@ struct extent_buffer *find_extent_buffer(struct extent_map_tree *tree, if (i == 0) { if (i == 0) { eb->first_page = p; eb->first_page = p; set_page_private(p, EXTENT_PAGE_PRIVATE_FIRST_PAGE | set_page_extent_head(p, len); len << 2); } else { } else { set_page_private(p, EXTENT_PAGE_PRIVATE); set_page_private(p, EXTENT_PAGE_PRIVATE); } } Loading Loading @@ -2643,6 +2647,11 @@ int clear_extent_buffer_dirty(struct extent_map_tree *tree, for (i = 0; i < num_pages; i++) { for (i = 0; i < num_pages; i++) { page = extent_buffer_page(eb, i); page = extent_buffer_page(eb, i); lock_page(page); lock_page(page); if (i == 0) set_page_extent_head(page, eb->len); else set_page_private(page, EXTENT_PAGE_PRIVATE); /* /* * if we're on the last page or the first page and the * if we're on the last page or the first page and the * block isn't aligned on a page boundary, do extra checks * block isn't aligned on a page boundary, do extra checks Loading Loading @@ -2697,9 +2706,12 @@ int set_extent_buffer_dirty(struct extent_map_tree *tree, */ */ if (i == 0) { if (i == 0) { lock_page(page); lock_page(page); set_page_private(page, set_page_extent_head(page, eb->len); EXTENT_PAGE_PRIVATE_FIRST_PAGE | } else if (PagePrivate(page) && eb->len << 2); page->private != EXTENT_PAGE_PRIVATE) { lock_page(page); set_page_extent_mapped(page); unlock_page(page); } } __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); __set_page_dirty_nobuffers(extent_buffer_page(eb, i)); if (i == 0) if (i == 0) Loading