aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-01-29 15:15:18 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:00 -0400
commit9c58309d6cf22471dacbcb6de54d00cef9ca20d4 (patch)
tree9f3ae79d2db86de12c4ee5152b3b491b1f1a88a4 /fs/btrfs/inode.c
parent85e21bac165b4ba1f6f90431ad6fc658ffcbaf3a (diff)
Btrfs: Add inode item and backref in one insert, reducing cpu usage
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c85
1 files changed, 63 insertions, 22 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 0a2fe51c4127..413b1012de53 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1500,6 +1500,8 @@ void btrfs_dirty_inode(struct inode *inode)
1500 1500
1501static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, 1501static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
1502 struct btrfs_root *root, 1502 struct btrfs_root *root,
1503 const char *name, int name_len,
1504 u64 ref_objectid,
1503 u64 objectid, 1505 u64 objectid,
1504 struct btrfs_block_group_cache *group, 1506 struct btrfs_block_group_cache *group,
1505 int mode) 1507 int mode)
@@ -1508,6 +1510,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
1508 struct btrfs_inode_item *inode_item; 1510 struct btrfs_inode_item *inode_item;
1509 struct btrfs_key *location; 1511 struct btrfs_key *location;
1510 struct btrfs_path *path; 1512 struct btrfs_path *path;
1513 struct btrfs_inode_ref *ref;
1514 struct btrfs_key key[2];
1515 u32 sizes[2];
1516 unsigned long ptr;
1511 int ret; 1517 int ret;
1512 int owner; 1518 int owner;
1513 1519
@@ -1530,10 +1536,25 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
1530 group = btrfs_find_block_group(root, group, 0, 0, owner); 1536 group = btrfs_find_block_group(root, group, 0, 0, owner);
1531 BTRFS_I(inode)->block_group = group; 1537 BTRFS_I(inode)->block_group = group;
1532 BTRFS_I(inode)->flags = 0; 1538 BTRFS_I(inode)->flags = 0;
1533 ret = btrfs_insert_empty_inode(trans, root, path, objectid); 1539
1534 if (ret) 1540 key[0].objectid = objectid;
1541 btrfs_set_key_type(&key[0], BTRFS_INODE_ITEM_KEY);
1542 key[0].offset = 0;
1543
1544 key[1].objectid = objectid;
1545 btrfs_set_key_type(&key[1], BTRFS_INODE_REF_KEY);
1546 key[1].offset = ref_objectid;
1547
1548 sizes[0] = sizeof(struct btrfs_inode_item);
1549 sizes[1] = name_len + sizeof(*ref);
1550
1551 ret = btrfs_insert_empty_items(trans, root, path, key, sizes, 2);
1552 if (ret != 0)
1535 goto fail; 1553 goto fail;
1536 1554
1555 if (objectid > root->highest_inode)
1556 root->highest_inode = objectid;
1557
1537 inode->i_uid = current->fsuid; 1558 inode->i_uid = current->fsuid;
1538 inode->i_gid = current->fsgid; 1559 inode->i_gid = current->fsgid;
1539 inode->i_mode = mode; 1560 inode->i_mode = mode;
@@ -1543,6 +1564,13 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
1543 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0], 1564 inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
1544 struct btrfs_inode_item); 1565 struct btrfs_inode_item);
1545 fill_inode_item(path->nodes[0], inode_item, inode); 1566 fill_inode_item(path->nodes[0], inode_item, inode);
1567
1568 ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1,
1569 struct btrfs_inode_ref);
1570 btrfs_set_inode_ref_name_len(path->nodes[0], ref, name_len);
1571 ptr = (unsigned long)(ref + 1);
1572 write_extent_buffer(path->nodes[0], name, ptr, name_len);
1573
1546 btrfs_mark_buffer_dirty(path->nodes[0]); 1574 btrfs_mark_buffer_dirty(path->nodes[0]);
1547 btrfs_free_path(path); 1575 btrfs_free_path(path);
1548 1576
@@ -1564,7 +1592,8 @@ static inline u8 btrfs_inode_type(struct inode *inode)
1564} 1592}
1565 1593
1566static int btrfs_add_link(struct btrfs_trans_handle *trans, 1594static int btrfs_add_link(struct btrfs_trans_handle *trans,
1567 struct dentry *dentry, struct inode *inode) 1595 struct dentry *dentry, struct inode *inode,
1596 int add_backref)
1568{ 1597{
1569 int ret; 1598 int ret;
1570 struct btrfs_key key; 1599 struct btrfs_key key;
@@ -1580,11 +1609,13 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
1580 dentry->d_parent->d_inode->i_ino, 1609 dentry->d_parent->d_inode->i_ino,
1581 &key, btrfs_inode_type(inode)); 1610 &key, btrfs_inode_type(inode));
1582 if (ret == 0) { 1611 if (ret == 0) {
1583 ret = btrfs_insert_inode_ref(trans, root, 1612 if (add_backref) {
1584 dentry->d_name.name, 1613 ret = btrfs_insert_inode_ref(trans, root,
1585 dentry->d_name.len, 1614 dentry->d_name.name,
1586 inode->i_ino, 1615 dentry->d_name.len,
1587 dentry->d_parent->d_inode->i_ino); 1616 inode->i_ino,
1617 dentry->d_parent->d_inode->i_ino);
1618 }
1588 parent_inode = dentry->d_parent->d_inode; 1619 parent_inode = dentry->d_parent->d_inode;
1589 parent_inode->i_size += dentry->d_name.len * 2; 1620 parent_inode->i_size += dentry->d_name.len * 2;
1590 parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; 1621 parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
@@ -1595,9 +1626,10 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
1595} 1626}
1596 1627
1597static int btrfs_add_nondir(struct btrfs_trans_handle *trans, 1628static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
1598 struct dentry *dentry, struct inode *inode) 1629 struct dentry *dentry, struct inode *inode,
1630 int backref)
1599{ 1631{
1600 int err = btrfs_add_link(trans, dentry, inode); 1632 int err = btrfs_add_link(trans, dentry, inode, backref);
1601 if (!err) { 1633 if (!err) {
1602 d_instantiate(dentry, inode); 1634 d_instantiate(dentry, inode);
1603 return 0; 1635 return 0;
@@ -1635,14 +1667,16 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
1635 goto out_unlock; 1667 goto out_unlock;
1636 } 1668 }
1637 1669
1638 inode = btrfs_new_inode(trans, root, objectid, 1670 inode = btrfs_new_inode(trans, root, dentry->d_name.name,
1671 dentry->d_name.len,
1672 dentry->d_parent->d_inode->i_ino, objectid,
1639 BTRFS_I(dir)->block_group, mode); 1673 BTRFS_I(dir)->block_group, mode);
1640 err = PTR_ERR(inode); 1674 err = PTR_ERR(inode);
1641 if (IS_ERR(inode)) 1675 if (IS_ERR(inode))
1642 goto out_unlock; 1676 goto out_unlock;
1643 1677
1644 btrfs_set_trans_block_group(trans, inode); 1678 btrfs_set_trans_block_group(trans, inode);
1645 err = btrfs_add_nondir(trans, dentry, inode); 1679 err = btrfs_add_nondir(trans, dentry, inode, 0);
1646 if (err) 1680 if (err)
1647 drop_inode = 1; 1681 drop_inode = 1;
1648 else { 1682 else {
@@ -1692,14 +1726,16 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
1692 goto out_unlock; 1726 goto out_unlock;
1693 } 1727 }
1694 1728
1695 inode = btrfs_new_inode(trans, root, objectid, 1729 inode = btrfs_new_inode(trans, root, dentry->d_name.name,
1696 BTRFS_I(dir)->block_group, mode); 1730 dentry->d_name.len,
1731 dentry->d_parent->d_inode->i_ino,
1732 objectid, BTRFS_I(dir)->block_group, mode);
1697 err = PTR_ERR(inode); 1733 err = PTR_ERR(inode);
1698 if (IS_ERR(inode)) 1734 if (IS_ERR(inode))
1699 goto out_unlock; 1735 goto out_unlock;
1700 1736
1701 btrfs_set_trans_block_group(trans, inode); 1737 btrfs_set_trans_block_group(trans, inode);
1702 err = btrfs_add_nondir(trans, dentry, inode); 1738 err = btrfs_add_nondir(trans, dentry, inode, 0);
1703 if (err) 1739 if (err)
1704 drop_inode = 1; 1740 drop_inode = 1;
1705 else { 1741 else {
@@ -1755,7 +1791,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
1755 1791
1756 btrfs_set_trans_block_group(trans, dir); 1792 btrfs_set_trans_block_group(trans, dir);
1757 atomic_inc(&inode->i_count); 1793 atomic_inc(&inode->i_count);
1758 err = btrfs_add_nondir(trans, dentry, inode); 1794 err = btrfs_add_nondir(trans, dentry, inode, 1);
1759 1795
1760 if (err) 1796 if (err)
1761 drop_inode = 1; 1797 drop_inode = 1;
@@ -1810,7 +1846,9 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1810 goto out_unlock; 1846 goto out_unlock;
1811 } 1847 }
1812 1848
1813 inode = btrfs_new_inode(trans, root, objectid, 1849 inode = btrfs_new_inode(trans, root, dentry->d_name.name,
1850 dentry->d_name.len,
1851 dentry->d_parent->d_inode->i_ino, objectid,
1814 BTRFS_I(dir)->block_group, S_IFDIR | mode); 1852 BTRFS_I(dir)->block_group, S_IFDIR | mode);
1815 if (IS_ERR(inode)) { 1853 if (IS_ERR(inode)) {
1816 err = PTR_ERR(inode); 1854 err = PTR_ERR(inode);
@@ -1827,7 +1865,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1827 if (err) 1865 if (err)
1828 goto out_fail; 1866 goto out_fail;
1829 1867
1830 err = btrfs_add_link(trans, dentry, inode); 1868 err = btrfs_add_link(trans, dentry, inode, 0);
1831 if (err) 1869 if (err)
1832 goto out_fail; 1870 goto out_fail;
1833 1871
@@ -2320,7 +2358,8 @@ static int noinline create_subvol(struct btrfs_root *root, char *name,
2320 trans = btrfs_start_transaction(new_root, 1); 2358 trans = btrfs_start_transaction(new_root, 1);
2321 BUG_ON(!trans); 2359 BUG_ON(!trans);
2322 2360
2323 inode = btrfs_new_inode(trans, new_root, new_dirid, 2361 inode = btrfs_new_inode(trans, new_root, "..", 2, new_dirid,
2362 new_dirid,
2324 BTRFS_I(dir)->block_group, S_IFDIR | 0700); 2363 BTRFS_I(dir)->block_group, S_IFDIR | 0700);
2325 if (IS_ERR(inode)) 2364 if (IS_ERR(inode))
2326 goto fail; 2365 goto fail;
@@ -2817,7 +2856,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
2817 if (ret) 2856 if (ret)
2818 goto out_fail; 2857 goto out_fail;
2819 } 2858 }
2820 ret = btrfs_add_link(trans, new_dentry, old_inode); 2859 ret = btrfs_add_link(trans, new_dentry, old_inode, 1);
2821 if (ret) 2860 if (ret)
2822 goto out_fail; 2861 goto out_fail;
2823 2862
@@ -2865,14 +2904,16 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
2865 goto out_unlock; 2904 goto out_unlock;
2866 } 2905 }
2867 2906
2868 inode = btrfs_new_inode(trans, root, objectid, 2907 inode = btrfs_new_inode(trans, root, dentry->d_name.name,
2908 dentry->d_name.len,
2909 dentry->d_parent->d_inode->i_ino, objectid,
2869 BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO); 2910 BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO);
2870 err = PTR_ERR(inode); 2911 err = PTR_ERR(inode);
2871 if (IS_ERR(inode)) 2912 if (IS_ERR(inode))
2872 goto out_unlock; 2913 goto out_unlock;
2873 2914
2874 btrfs_set_trans_block_group(trans, inode); 2915 btrfs_set_trans_block_group(trans, inode);
2875 err = btrfs_add_nondir(trans, dentry, inode); 2916 err = btrfs_add_nondir(trans, dentry, inode, 0);
2876 if (err) 2917 if (err)
2877 drop_inode = 1; 2918 drop_inode = 1;
2878 else { 2919 else {