aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-08-07 15:52:22 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-08-07 15:52:22 -0400
commit3c69faecb8d83cb2ef085a98b196a3fecea67725 (patch)
treed764502dd93bcd767c2130518d0c1fe00a7e96ff /fs/btrfs/inode.c
parent9f3a742736cecda5a8778be70faa2f779458839f (diff)
Btrfs: Fold some btree readahead routines into something more generic.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c69
1 files changed, 2 insertions, 67 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index fa9c531c86b7..3889032fc449 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -375,40 +375,6 @@ static int btrfs_free_inode(struct btrfs_trans_handle *trans,
375} 375}
376 376
377/* 377/*
378 * truncates go from a high offset to a low offset. So, walk
379 * from hi to lo in the node and issue readas. Stop when you find
380 * keys from a different objectid
381 */
382static void reada_truncate(struct btrfs_root *root, struct btrfs_path *path,
383 u64 objectid)
384{
385 struct btrfs_node *node;
386 int i;
387 int nritems;
388 u64 item_objectid;
389 u64 blocknr;
390 int slot;
391 int ret;
392
393 if (!path->nodes[1])
394 return;
395 node = btrfs_buffer_node(path->nodes[1]);
396 slot = path->slots[1];
397 if (slot == 0)
398 return;
399 nritems = btrfs_header_nritems(&node->header);
400 for (i = slot - 1; i >= 0; i--) {
401 item_objectid = btrfs_disk_key_objectid(&node->ptrs[i].key);
402 if (item_objectid != objectid)
403 break;
404 blocknr = btrfs_node_blockptr(node, i);
405 ret = readahead_tree_block(root, blocknr);
406 if (ret)
407 break;
408 }
409}
410
411/*
412 * this can truncate away extent items, csum items and directory items. 378 * this can truncate away extent items, csum items and directory items.
413 * It starts at a high offset and removes keys until it can't find 379 * It starts at a high offset and removes keys until it can't find
414 * any higher than i_size. 380 * any higher than i_size.
@@ -434,6 +400,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
434 int del_item; 400 int del_item;
435 401
436 path = btrfs_alloc_path(); 402 path = btrfs_alloc_path();
403 path->reada = -1;
437 BUG_ON(!path); 404 BUG_ON(!path);
438 /* FIXME, add redo link to tree so we don't leak on crash */ 405 /* FIXME, add redo link to tree so we don't leak on crash */
439 key.objectid = inode->i_ino; 406 key.objectid = inode->i_ino;
@@ -450,7 +417,6 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
450 BUG_ON(path->slots[0] == 0); 417 BUG_ON(path->slots[0] == 0);
451 path->slots[0]--; 418 path->slots[0]--;
452 } 419 }
453 reada_truncate(root, path, inode->i_ino);
454 leaf = btrfs_buffer_leaf(path->nodes[0]); 420 leaf = btrfs_buffer_leaf(path->nodes[0]);
455 found_key = &leaf->items[path->slots[0]].key; 421 found_key = &leaf->items[path->slots[0]].key;
456 found_type = btrfs_disk_key_type(found_key); 422 found_type = btrfs_disk_key_type(found_key);
@@ -827,36 +793,6 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry,
827 return d_splice_alias(inode, dentry); 793 return d_splice_alias(inode, dentry);
828} 794}
829 795
830/*
831 * readahead one full node of leaves as long as their keys include
832 * the objectid supplied
833 */
834static void reada_leaves(struct btrfs_root *root, struct btrfs_path *path,
835 u64 objectid)
836{
837 struct btrfs_node *node;
838 int i;
839 u32 nritems;
840 u64 item_objectid;
841 u64 blocknr;
842 int slot;
843 int ret;
844
845 if (!path->nodes[1])
846 return;
847 node = btrfs_buffer_node(path->nodes[1]);
848 slot = path->slots[1];
849 nritems = btrfs_header_nritems(&node->header);
850 for (i = slot + 1; i < nritems; i++) {
851 item_objectid = btrfs_disk_key_objectid(&node->ptrs[i].key);
852 if (item_objectid != objectid)
853 break;
854 blocknr = btrfs_node_blockptr(node, i);
855 ret = readahead_tree_block(root, blocknr);
856 if (ret)
857 break;
858 }
859}
860static unsigned char btrfs_filetype_table[] = { 796static unsigned char btrfs_filetype_table[] = {
861 DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK 797 DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
862}; 798};
@@ -890,18 +826,17 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
890 btrfs_set_key_type(&key, key_type); 826 btrfs_set_key_type(&key, key_type);
891 key.offset = filp->f_pos; 827 key.offset = filp->f_pos;
892 path = btrfs_alloc_path(); 828 path = btrfs_alloc_path();
829 path->reada = 1;
893 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 830 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
894 if (ret < 0) 831 if (ret < 0)
895 goto err; 832 goto err;
896 advance = 0; 833 advance = 0;
897 reada_leaves(root, path, inode->i_ino);
898 while(1) { 834 while(1) {
899 leaf = btrfs_buffer_leaf(path->nodes[0]); 835 leaf = btrfs_buffer_leaf(path->nodes[0]);
900 nritems = btrfs_header_nritems(&leaf->header); 836 nritems = btrfs_header_nritems(&leaf->header);
901 slot = path->slots[0]; 837 slot = path->slots[0];
902 if (advance || slot >= nritems) { 838 if (advance || slot >= nritems) {
903 if (slot >= nritems -1) { 839 if (slot >= nritems -1) {
904 reada_leaves(root, path, inode->i_ino);
905 ret = btrfs_next_leaf(root, path); 840 ret = btrfs_next_leaf(root, path);
906 if (ret) 841 if (ret)
907 break; 842 break;