From patchwork Mon Jul 19 05:43:23 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shaohua Li X-Patchwork-Id: 112627 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o6J5hTJa030436 for ; Mon, 19 Jul 2010 05:43:29 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752883Ab0GSFn0 (ORCPT ); Mon, 19 Jul 2010 01:43:26 -0400 Received: from mga01.intel.com ([192.55.52.88]:33935 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752850Ab0GSFn0 (ORCPT ); Mon, 19 Jul 2010 01:43:26 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga101.fm.intel.com with ESMTP; 18 Jul 2010 22:41:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.55,225,1278313200"; d="scan'208";a="587461029" Received: from sli10-conroe.sh.intel.com (HELO sli10-desk.sh.intel.com) ([10.239.36.181]) by fmsmga002.fm.intel.com with ESMTP; 18 Jul 2010 22:42:47 -0700 Received: from david by sli10-desk.sh.intel.com with local (Exim 4.71) (envelope-from ) id 1Oaj8N-0008IK-VG; Mon, 19 Jul 2010 13:43:23 +0800 Date: Mon, 19 Jul 2010 13:43:23 +0800 From: Shaohua Li To: Chris Mason Cc: "linux-btrfs@vger.kernel.org" , Arjan van de Ven , "Wu, Fengguang" Subject: Re: [patch 0/2]btrfs: add two ioctls to do metadata readahead Message-ID: <20100719054323.GA26564@sli10-desk.sh.intel.com> References: <1279094536.1528.93.camel@sli10-desk.sh.intel.com> <20100714082645.GA32458@sli10-desk.sh.intel.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20100714082645.GA32458@sli10-desk.sh.intel.com> User-Agent: Mutt/1.5.20 (2009-06-14) Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Mon, 19 Jul 2010 05:43:31 +0000 (UTC) Index: linux/fs/btrfs/disk-io.c =================================================================== --- linux.orig/fs/btrfs/disk-io.c 2010-07-19 10:58:10.000000000 +0800 +++ linux/fs/btrfs/disk-io.c 2010-07-19 10:58:13.000000000 +0800 @@ -406,30 +406,18 @@ void btrfs_set_buffer_lockdep_class(stru } #endif -static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, - struct extent_state *state) +int btree_validate_extent_buffer(struct btrfs_root *root, + struct extent_buffer *eb) { - struct extent_io_tree *tree; + int ret = 0; u64 found_start; int found_level; - unsigned long len; - struct extent_buffer *eb; - struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; - int ret = 0; - - tree = &BTRFS_I(page->mapping->host)->io_tree; - if (page->private == EXTENT_PAGE_PRIVATE) - goto out; - if (!page->private) - goto out; - - len = page->private >> 2; - WARN_ON(len == 0); - eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); + if (!test_bit(EXTENT_BUFFER_UNCHECKED, &eb->bflags)) + return 0; found_start = btrfs_header_bytenr(eb); - if (found_start != start) { + if (found_start != eb->start) { if (printk_ratelimit()) { printk(KERN_INFO "btrfs bad tree block start " "%llu %llu\n", @@ -439,13 +427,7 @@ static int btree_readpage_end_io_hook(st ret = -EIO; goto err; } - if (eb->first_page != page) { - printk(KERN_INFO "btrfs bad first page %lu %lu\n", - eb->first_page->index, page->index); - WARN_ON(1); - ret = -EIO; - goto err; - } + if (check_tree_block_fsid(root, eb)) { if (printk_ratelimit()) { printk(KERN_INFO "btrfs bad fsid on block %llu\n", @@ -461,6 +443,41 @@ static int btree_readpage_end_io_hook(st ret = csum_tree_block(root, eb, 1); if (ret) ret = -EIO; +err: + if (ret == 0) + clear_bit(EXTENT_BUFFER_UNCHECKED, &eb->bflags); + return ret; +} + +static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, + struct extent_state *state) +{ + struct extent_io_tree *tree; + unsigned long len; + struct extent_buffer *eb; + struct btrfs_root *root = BTRFS_I(page->mapping->host)->root; + int ret = 0; + + tree = &BTRFS_I(page->mapping->host)->io_tree; + if (page->private == EXTENT_PAGE_PRIVATE) + goto out; + if (!page->private) + goto out; + + len = page->private >> 2; + WARN_ON(len == 0); + + eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS); + + if (eb->first_page != page) { + printk(KERN_INFO "btrfs bad first page %lu %lu\n", + eb->first_page->index, page->index); + WARN_ON(1); + ret = -EIO; + goto err; + } + + ret = btree_validate_extent_buffer(root, eb); end = min_t(u64, eb->len, PAGE_CACHE_SIZE); end = eb->start + end - 1; Index: linux/fs/btrfs/disk-io.h =================================================================== --- linux.orig/fs/btrfs/disk-io.h 2010-07-19 10:56:33.000000000 +0800 +++ linux/fs/btrfs/disk-io.h 2010-07-19 10:58:13.000000000 +0800 @@ -36,6 +36,8 @@ static inline u64 btrfs_sb_offset(int mi struct btrfs_device; struct btrfs_fs_devices; +int btree_validate_extent_buffer(struct btrfs_root *root, + struct extent_buffer *eb); struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, u64 parent_transid); int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, Index: linux/fs/btrfs/extent_io.c =================================================================== --- linux.orig/fs/btrfs/extent_io.c 2010-07-19 10:56:33.000000000 +0800 +++ linux/fs/btrfs/extent_io.c 2010-07-19 10:58:13.000000000 +0800 @@ -14,6 +14,7 @@ #include "extent_map.h" #include "compat.h" #include "ctree.h" +#include "disk-io.h" #include "btrfs_inode.h" static struct kmem_cache *extent_state_cache; @@ -3162,6 +3163,7 @@ struct extent_buffer *alloc_extent_buffe uptodate = 0; unlock_page(p); } + set_bit(EXTENT_BUFFER_UNCHECKED, &eb->bflags); if (uptodate) set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); @@ -3387,9 +3389,10 @@ int read_extent_buffer_pages(struct exte unsigned long num_pages; struct bio *bio = NULL; unsigned long bio_flags = 0; + struct btrfs_root *root = BTRFS_I(tree->mapping->host)->root; if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) - return 0; + goto out; if (test_range_bit(tree, eb->start, eb->start + eb->len - 1, EXTENT_UPTODATE, 1, NULL)) { @@ -3454,8 +3457,10 @@ int read_extent_buffer_pages(struct exte ret = -EIO; } - if (!ret) + if (!ret) { set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); + goto out; + } return ret; unlock_exit: @@ -3466,6 +3471,11 @@ unlock_exit: unlock_page(page); locked_pages--; } +out: + if (!ret && test_bit(EXTENT_BUFFER_UNCHECKED, &eb->bflags) && + test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags)) + return btree_validate_extent_buffer(root, eb); + return ret; } Index: linux/fs/btrfs/extent_io.h =================================================================== --- linux.orig/fs/btrfs/extent_io.h 2010-07-19 10:56:33.000000000 +0800 +++ linux/fs/btrfs/extent_io.h 2010-07-19 10:58:13.000000000 +0800 @@ -27,6 +27,7 @@ #define EXTENT_BUFFER_UPTODATE 0 #define EXTENT_BUFFER_BLOCKING 1 #define EXTENT_BUFFER_DIRTY 2 +#define EXTENT_BUFFER_UNCHECKED 3 /* these are flags for extent_clear_unlock_delalloc */ #define EXTENT_CLEAR_UNLOCK_PAGE 0x1 Index: linux/fs/btrfs/extent-tree.c =================================================================== --- linux.orig/fs/btrfs/extent-tree.c 2010-07-19 10:56:33.000000000 +0800 +++ linux/fs/btrfs/extent-tree.c 2010-07-19 10:58:13.000000000 +0800 @@ -5277,6 +5277,7 @@ struct extent_buffer *btrfs_init_new_buf clean_tree_block(trans, root, buf); btrfs_set_lock_blocking(buf); + clear_bit(EXTENT_BUFFER_UNCHECKED, &buf->bflags); btrfs_set_buffer_uptodate(buf); if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) {