diff options
author | Chris Mason <chris.mason@oracle.com> | 2008-01-29 15:15:18 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:00 -0400 |
commit | 9c58309d6cf22471dacbcb6de54d00cef9ca20d4 (patch) | |
tree | 9f3ae79d2db86de12c4ee5152b3b491b1f1a88a4 /fs/btrfs/inode.c | |
parent | 85e21bac165b4ba1f6f90431ad6fc658ffcbaf3a (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.c | 85 |
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 | ||
1501 | static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | 1501 | static 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 | ||
1566 | static int btrfs_add_link(struct btrfs_trans_handle *trans, | 1594 | static 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 | ||
1597 | static int btrfs_add_nondir(struct btrfs_trans_handle *trans, | 1628 | static 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 { |