aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-06-07 22:13:21 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-06-07 22:13:21 -0400
commitfabb568183de7996257080260d3537fa75b3667e (patch)
tree60d047f6d5b264347e8f51f16ccd6dc07277c23d /fs/btrfs/super.c
parentfbdc762b4e1833b5d75cada5aabeadccd8379792 (diff)
Btrfs: d_type optimization
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c66
1 files changed, 57 insertions, 9 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 0eb64d6eaf9d..b58b4cf66766 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -43,6 +43,18 @@ static int drop_extents(struct btrfs_trans_handle *trans,
43static int btrfs_get_block(struct inode *inode, sector_t iblock, 43static int btrfs_get_block(struct inode *inode, sector_t iblock,
44 struct buffer_head *result, int create); 44 struct buffer_head *result, int create);
45 45
46
47#define S_SHIFT 12
48static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = {
49 [S_IFREG >> S_SHIFT] = BTRFS_FT_REG_FILE,
50 [S_IFDIR >> S_SHIFT] = BTRFS_FT_DIR,
51 [S_IFCHR >> S_SHIFT] = BTRFS_FT_CHRDEV,
52 [S_IFBLK >> S_SHIFT] = BTRFS_FT_BLKDEV,
53 [S_IFIFO >> S_SHIFT] = BTRFS_FT_FIFO,
54 [S_IFSOCK >> S_SHIFT] = BTRFS_FT_SOCK,
55 [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK,
56};
57
46static void btrfs_read_locked_inode(struct inode *inode) 58static void btrfs_read_locked_inode(struct inode *inode)
47{ 59{
48 struct btrfs_path *path; 60 struct btrfs_path *path;
@@ -785,6 +797,9 @@ static void reada_leaves(struct btrfs_root *root, struct btrfs_path *path,
785 break; 797 break;
786 } 798 }
787} 799}
800static unsigned char btrfs_filetype_table[] = {
801 DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK
802};
788 803
789static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 804static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
790{ 805{
@@ -799,7 +814,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
799 struct btrfs_leaf *leaf; 814 struct btrfs_leaf *leaf;
800 int slot; 815 int slot;
801 int advance; 816 int advance;
802 unsigned char d_type = DT_UNKNOWN; 817 unsigned char d_type;
803 int over = 0; 818 int over = 0;
804 u32 di_cur; 819 u32 di_cur;
805 u32 di_total; 820 u32 di_total;
@@ -853,6 +868,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
853 di_cur = 0; 868 di_cur = 0;
854 di_total = btrfs_item_size(leaf->items + slot); 869 di_total = btrfs_item_size(leaf->items + slot);
855 while(di_cur < di_total) { 870 while(di_cur < di_total) {
871 d_type = btrfs_filetype_table[btrfs_dir_type(di)];
856 over = filldir(dirent, (const char *)(di + 1), 872 over = filldir(dirent, (const char *)(di + 1),
857 btrfs_dir_name_len(di), 873 btrfs_dir_name_len(di),
858 btrfs_disk_key_offset(&item->key), 874 btrfs_disk_key_offset(&item->key),
@@ -1012,6 +1028,11 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
1012 return inode; 1028 return inode;
1013} 1029}
1014 1030
1031static inline u8 btrfs_inode_type(struct inode *inode)
1032{
1033 return btrfs_type_by_mode[(inode->i_mode & S_IFMT) >> S_SHIFT];
1034}
1035
1015static int btrfs_add_link(struct btrfs_trans_handle *trans, 1036static int btrfs_add_link(struct btrfs_trans_handle *trans,
1016 struct dentry *dentry, struct inode *inode) 1037 struct dentry *dentry, struct inode *inode)
1017{ 1038{
@@ -1026,7 +1047,7 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
1026 ret = btrfs_insert_dir_item(trans, root, 1047 ret = btrfs_insert_dir_item(trans, root,
1027 dentry->d_name.name, dentry->d_name.len, 1048 dentry->d_name.name, dentry->d_name.len,
1028 dentry->d_parent->d_inode->i_ino, 1049 dentry->d_parent->d_inode->i_ino,
1029 &key, 0); 1050 &key, btrfs_inode_type(inode));
1030 if (ret == 0) { 1051 if (ret == 0) {
1031 dentry->d_parent->d_inode->i_size += dentry->d_name.len * 2; 1052 dentry->d_parent->d_inode->i_size += dentry->d_name.len * 2;
1032 ret = btrfs_update_inode(trans, root, 1053 ret = btrfs_update_inode(trans, root,
@@ -1150,12 +1171,12 @@ static int btrfs_make_empty_dir(struct btrfs_trans_handle *trans,
1150 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); 1171 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
1151 1172
1152 ret = btrfs_insert_dir_item(trans, root, buf, 1, objectid, 1173 ret = btrfs_insert_dir_item(trans, root, buf, 1, objectid,
1153 &key, 1); 1174 &key, BTRFS_FT_DIR);
1154 if (ret) 1175 if (ret)
1155 goto error; 1176 goto error;
1156 key.objectid = dirid; 1177 key.objectid = dirid;
1157 ret = btrfs_insert_dir_item(trans, root, buf, 2, objectid, 1178 ret = btrfs_insert_dir_item(trans, root, buf, 2, objectid,
1158 &key, 1); 1179 &key, BTRFS_FT_DIR);
1159 if (ret) 1180 if (ret)
1160 goto error; 1181 goto error;
1161error: 1182error:
@@ -1265,6 +1286,10 @@ printk("btrfs sync_fs\n");
1265 return 0; 1286 return 0;
1266} 1287}
1267 1288
1289#define BTRFS_GET_BLOCK_NO_CREATE 0
1290#define BTRFS_GET_BLOCK_CREATE 1
1291#define BTRFS_GET_BLOCK_NO_DIRECT 2
1292
1268static int btrfs_get_block_lock(struct inode *inode, sector_t iblock, 1293static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1269 struct buffer_head *result, int create) 1294 struct buffer_head *result, int create)
1270{ 1295{
@@ -1286,7 +1311,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1286 path = btrfs_alloc_path(); 1311 path = btrfs_alloc_path();
1287 BUG_ON(!path); 1312 BUG_ON(!path);
1288 btrfs_init_path(path); 1313 btrfs_init_path(path);
1289 if (create) { 1314 if (create & BTRFS_GET_BLOCK_CREATE) {
1290 WARN_ON(1); 1315 WARN_ON(1);
1291 /* this almost but not quite works */ 1316 /* this almost but not quite works */
1292 trans = btrfs_start_transaction(root, 1); 1317 trans = btrfs_start_transaction(root, 1);
@@ -1349,6 +1374,11 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1349 char *ptr; 1374 char *ptr;
1350 char *map; 1375 char *map;
1351 u32 size; 1376 u32 size;
1377
1378 if (create & BTRFS_GET_BLOCK_NO_DIRECT) {
1379 err = -EINVAL;
1380 goto out;
1381 }
1352 size = btrfs_file_extent_inline_len(leaf->items + 1382 size = btrfs_file_extent_inline_len(leaf->items +
1353 path->slots[0]); 1383 path->slots[0]);
1354 extent_end = (extent_start + size) >> inode->i_blkbits; 1384 extent_end = (extent_start + size) >> inode->i_blkbits;
@@ -1367,7 +1397,7 @@ static int btrfs_get_block_lock(struct inode *inode, sector_t iblock,
1367 btrfs_map_bh_to_logical(root, result, 0); 1397 btrfs_map_bh_to_logical(root, result, 0);
1368 } 1398 }
1369not_found: 1399not_found:
1370 if (create) { 1400 if (create & BTRFS_GET_BLOCK_CREATE) {
1371 struct btrfs_key ins; 1401 struct btrfs_key ins;
1372 ret = btrfs_alloc_extent(trans, root, inode->i_ino, 1402 ret = btrfs_alloc_extent(trans, root, inode->i_ino,
1373 1, alloc_hint, (u64)-1, 1403 1, alloc_hint, (u64)-1,
@@ -1399,6 +1429,21 @@ static int btrfs_get_block(struct inode *inode, sector_t iblock,
1399 return err; 1429 return err;
1400} 1430}
1401 1431
1432static int btrfs_get_block_bmap(struct inode *inode, sector_t iblock,
1433 struct buffer_head *result, int create)
1434{
1435 struct btrfs_root *root = BTRFS_I(inode)->root;
1436 mutex_lock(&root->fs_info->fs_mutex);
1437 btrfs_get_block_lock(inode, iblock, result, BTRFS_GET_BLOCK_NO_DIRECT);
1438 mutex_unlock(&root->fs_info->fs_mutex);
1439 return 0;
1440}
1441
1442static sector_t btrfs_bmap(struct address_space *as, sector_t block)
1443{
1444 return generic_block_bmap(as, block, btrfs_get_block_bmap);
1445}
1446
1402static int btrfs_prepare_write(struct file *file, struct page *page, 1447static int btrfs_prepare_write(struct file *file, struct page *page,
1403 unsigned from, unsigned to) 1448 unsigned from, unsigned to)
1404{ 1449{
@@ -2428,7 +2473,8 @@ static int create_subvol(struct btrfs_root *root, char *name, int namelen)
2428 key.offset = (u64)-1; 2473 key.offset = (u64)-1;
2429 dir = root->fs_info->sb->s_root->d_inode; 2474 dir = root->fs_info->sb->s_root->d_inode;
2430 ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, 2475 ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root,
2431 name, namelen, dir->i_ino, &key, 0); 2476 name, namelen, dir->i_ino, &key,
2477 BTRFS_FT_DIR);
2432 BUG_ON(ret); 2478 BUG_ON(ret);
2433 2479
2434 ret = btrfs_commit_transaction(trans, root); 2480 ret = btrfs_commit_transaction(trans, root);
@@ -2505,7 +2551,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen)
2505 ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root, 2551 ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root,
2506 name, namelen, 2552 name, namelen,
2507 root->fs_info->sb->s_root->d_inode->i_ino, 2553 root->fs_info->sb->s_root->d_inode->i_ino,
2508 &key, 0); 2554 &key, BTRFS_FT_DIR);
2509 2555
2510 BUG_ON(ret); 2556 BUG_ON(ret);
2511 2557
@@ -2833,7 +2879,8 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
2833 btrfs_release_path(root, path); 2879 btrfs_release_path(root, path);
2834 2880
2835 ret = btrfs_insert_dir_item(trans, root, "..", 2, 2881 ret = btrfs_insert_dir_item(trans, root, "..", 2,
2836 old_inode->i_ino, location, 0); 2882 old_inode->i_ino, location,
2883 BTRFS_FT_DIR);
2837 if (ret) 2884 if (ret)
2838 goto out_fail; 2885 goto out_fail;
2839 } 2886 }
@@ -3003,6 +3050,7 @@ static struct address_space_operations btrfs_aops = {
3003 .sync_page = block_sync_page, 3050 .sync_page = block_sync_page,
3004 .prepare_write = btrfs_prepare_write, 3051 .prepare_write = btrfs_prepare_write,
3005 .commit_write = btrfs_commit_write, 3052 .commit_write = btrfs_commit_write,
3053 .bmap = btrfs_bmap,
3006}; 3054};
3007 3055
3008static struct address_space_operations btrfs_symlink_aops = { 3056static struct address_space_operations btrfs_symlink_aops = {