summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/disk-io.c
diff options
context:
space:
mode:
authorChris Mason2007-05-01 14:53:32 +0200
committerDavid Woodhouse2007-05-01 14:53:32 +0200
commit090d18753c7fb73f7d846c3a89a50cd35136d144 (patch)
treee36965065fd68633c06cbe4b8312e5afe49997f4 /fs/btrfs/disk-io.c
parentBtrfs: allocator improvements, inode block groups (diff)
downloadkernel-qcow2-linux-090d18753c7fb73f7d846c3a89a50cd35136d144.tar.gz
kernel-qcow2-linux-090d18753c7fb73f7d846c3a89a50cd35136d144.tar.xz
kernel-qcow2-linux-090d18753c7fb73f7d846c3a89a50cd35136d144.zip
Btrfs: directory readahead
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r--fs/btrfs/disk-io.c29
1 files changed, 28 insertions, 1 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e1b6e13a5ae8..354524adf984 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -5,6 +5,7 @@
#include <linux/scatterlist.h>
#include <linux/swap.h>
#include <linux/radix-tree.h>
+#include <linux/file.h>
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
@@ -253,6 +254,29 @@ static struct address_space_operations btree_aops = {
.sync_page = block_sync_page,
};
+int readahead_tree_block(struct btrfs_root *root, u64 blocknr)
+{
+ struct buffer_head *bh = NULL;
+
+ bh = btrfs_find_create_tree_block(root, blocknr);
+ if (!bh)
+ return 0;
+ if (buffer_uptodate(bh))
+ goto done;
+ if (test_set_buffer_locked(bh))
+ goto done;
+ if (!buffer_uptodate(bh)) {
+ get_bh(bh);
+ bh->b_end_io = end_buffer_read_sync;
+ submit_bh(READ, bh);
+ } else {
+ unlock_buffer(bh);
+ }
+done:
+ brelse(bh);
+ return 0;
+}
+
struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
{
struct buffer_head *bh = NULL;
@@ -270,11 +294,14 @@ struct buffer_head *read_tree_block(struct btrfs_root *root, u64 blocknr)
wait_on_buffer(bh);
if (!buffer_uptodate(bh))
goto fail;
- csum_tree_block(root, bh, 1);
} else {
unlock_buffer(bh);
}
uptodate:
+ if (!buffer_checked(bh)) {
+ csum_tree_block(root, bh, 1);
+ set_buffer_checked(bh);
+ }
if (check_tree_block(root, bh))
BUG();
return bh;