aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/delayed-inode.c
diff options
context:
space:
mode:
authorMiao Xie <miaox@cn.fujitsu.com>2013-12-26 00:07:06 -0500
committerChris Mason <clm@fb.com>2014-01-28 16:20:09 -0500
commit67de11769bd5ec339a62169f500b04f304826c00 (patch)
tree5939ead04cfd0ca9a3e99d2fa0b2cfa9ac99ba1b /fs/btrfs/delayed-inode.c
parent7cf35d91b4f143b5c7529976bf5e7573a07051cd (diff)
Btrfs: introduce the delayed inode ref deletion for the single link inode
The inode reference item is close to inode item, so we insert it simultaneously with the inode item insertion when we create a file/directory.. In fact, we also can handle the inode reference deletion by the same way. So we made this patch to introduce the delayed inode reference deletion for the single link inode(At most case, the file doesn't has hard link, so we don't take the hard link into account). This function is based on the delayed inode mechanism. After applying this patch, we can reduce the time of the file/directory deletion by ~10%. Signed-off-by: Miao Xie <miaox@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
Diffstat (limited to 'fs/btrfs/delayed-inode.c')
-rw-r--r--fs/btrfs/delayed-inode.c103
1 files changed, 99 insertions, 4 deletions
diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
index 222ca8cdc53a..451b00c86f6c 100644
--- a/fs/btrfs/delayed-inode.c
+++ b/fs/btrfs/delayed-inode.c
@@ -1015,6 +1015,18 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
1015 } 1015 }
1016} 1016}
1017 1017
1018static void btrfs_release_delayed_iref(struct btrfs_delayed_node *delayed_node)
1019{
1020 struct btrfs_delayed_root *delayed_root;
1021
1022 ASSERT(delayed_node->root);
1023 clear_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags);
1024 delayed_node->count--;
1025
1026 delayed_root = delayed_node->root->fs_info->delayed_root;
1027 finish_one_item(delayed_root);
1028}
1029
1018static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, 1030static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1019 struct btrfs_root *root, 1031 struct btrfs_root *root,
1020 struct btrfs_path *path, 1032 struct btrfs_path *path,
@@ -1023,13 +1035,19 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1023 struct btrfs_key key; 1035 struct btrfs_key key;
1024 struct btrfs_inode_item *inode_item; 1036 struct btrfs_inode_item *inode_item;
1025 struct extent_buffer *leaf; 1037 struct extent_buffer *leaf;
1038 int mod;
1026 int ret; 1039 int ret;
1027 1040
1028 key.objectid = node->inode_id; 1041 key.objectid = node->inode_id;
1029 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); 1042 btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
1030 key.offset = 0; 1043 key.offset = 0;
1031 1044
1032 ret = btrfs_lookup_inode(trans, root, path, &key, 1); 1045 if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags))
1046 mod = -1;
1047 else
1048 mod = 1;
1049
1050 ret = btrfs_lookup_inode(trans, root, path, &key, mod);
1033 if (ret > 0) { 1051 if (ret > 0) {
1034 btrfs_release_path(path); 1052 btrfs_release_path(path);
1035 return -ENOENT; 1053 return -ENOENT;
@@ -1037,19 +1055,58 @@ static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
1037 return ret; 1055 return ret;
1038 } 1056 }
1039 1057
1040 btrfs_unlock_up_safe(path, 1);
1041 leaf = path->nodes[0]; 1058 leaf = path->nodes[0];
1042 inode_item = btrfs_item_ptr(leaf, path->slots[0], 1059 inode_item = btrfs_item_ptr(leaf, path->slots[0],
1043 struct btrfs_inode_item); 1060 struct btrfs_inode_item);
1044 write_extent_buffer(leaf, &node->inode_item, (unsigned long)inode_item, 1061 write_extent_buffer(leaf, &node->inode_item, (unsigned long)inode_item,
1045 sizeof(struct btrfs_inode_item)); 1062 sizeof(struct btrfs_inode_item));
1046 btrfs_mark_buffer_dirty(leaf); 1063 btrfs_mark_buffer_dirty(leaf);
1047 btrfs_release_path(path);
1048 1064
1065 if (!test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags))
1066 goto no_iref;
1067
1068 path->slots[0]++;
1069 if (path->slots[0] >= btrfs_header_nritems(leaf))
1070 goto search;
1071again:
1072 btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
1073 if (key.objectid != node->inode_id)
1074 goto out;
1075
1076 if (key.type != BTRFS_INODE_REF_KEY &&
1077 key.type != BTRFS_INODE_EXTREF_KEY)
1078 goto out;
1079
1080 /*
1081 * Delayed iref deletion is for the inode who has only one link,
1082 * so there is only one iref. The case that several irefs are
1083 * in the same item doesn't exist.
1084 */
1085 btrfs_del_item(trans, root, path);
1086out:
1087 btrfs_release_delayed_iref(node);
1088no_iref:
1089 btrfs_release_path(path);
1090err_out:
1049 btrfs_delayed_inode_release_metadata(root, node); 1091 btrfs_delayed_inode_release_metadata(root, node);
1050 btrfs_release_delayed_inode(node); 1092 btrfs_release_delayed_inode(node);
1051 1093
1052 return 0; 1094 return ret;
1095
1096search:
1097 btrfs_release_path(path);
1098
1099 btrfs_set_key_type(&key, BTRFS_INODE_EXTREF_KEY);
1100 key.offset = -1;
1101 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
1102 if (ret < 0)
1103 goto err_out;
1104 ASSERT(ret);
1105
1106 ret = 0;
1107 leaf = path->nodes[0];
1108 path->slots[0]--;
1109 goto again;
1053} 1110}
1054 1111
1055static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, 1112static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
@@ -1793,6 +1850,41 @@ release_node:
1793 return ret; 1850 return ret;
1794} 1851}
1795 1852
1853int btrfs_delayed_delete_inode_ref(struct inode *inode)
1854{
1855 struct btrfs_delayed_node *delayed_node;
1856
1857 delayed_node = btrfs_get_or_create_delayed_node(inode);
1858 if (IS_ERR(delayed_node))
1859 return PTR_ERR(delayed_node);
1860
1861 /*
1862 * We don't reserve space for inode ref deletion is because:
1863 * - We ONLY do async inode ref deletion for the inode who has only
1864 * one link(i_nlink == 1), it means there is only one inode ref.
1865 * And in most case, the inode ref and the inode item are in the
1866 * same leaf, and we will deal with them at the same time.
1867 * Since we are sure we will reserve the space for the inode item,
1868 * it is unnecessary to reserve space for inode ref deletion.
1869 * - If the inode ref and the inode item are not in the same leaf,
1870 * We also needn't worry about enospc problem, because we reserve
1871 * much more space for the inode update than it needs.
1872 * - At the worst, we can steal some space from the global reservation.
1873 * It is very rare.
1874 */
1875 mutex_lock(&delayed_node->mutex);
1876 if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags))
1877 goto release_node;
1878
1879 set_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags);
1880 delayed_node->count++;
1881 atomic_inc(&BTRFS_I(inode)->root->fs_info->delayed_root->items);
1882release_node:
1883 mutex_unlock(&delayed_node->mutex);
1884 btrfs_release_delayed_node(delayed_node);
1885 return 0;
1886}
1887
1796static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node) 1888static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
1797{ 1889{
1798 struct btrfs_root *root = delayed_node->root; 1890 struct btrfs_root *root = delayed_node->root;
@@ -1815,6 +1907,9 @@ static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
1815 btrfs_release_delayed_item(prev_item); 1907 btrfs_release_delayed_item(prev_item);
1816 } 1908 }
1817 1909
1910 if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags))
1911 btrfs_release_delayed_iref(delayed_node);
1912
1818 if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { 1913 if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) {
1819 btrfs_delayed_inode_release_metadata(root, delayed_node); 1914 btrfs_delayed_inode_release_metadata(root, delayed_node);
1820 btrfs_release_delayed_inode(delayed_node); 1915 btrfs_release_delayed_inode(delayed_node);