aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/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/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/inode.c')
-rw-r--r--fs/btrfs/inode.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 06bcf5b53cb0..9eaa1c8ed385 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3309,6 +3309,7 @@ static void btrfs_read_locked_inode(struct inode *inode)
3309 struct btrfs_timespec *tspec; 3309 struct btrfs_timespec *tspec;
3310 struct btrfs_root *root = BTRFS_I(inode)->root; 3310 struct btrfs_root *root = BTRFS_I(inode)->root;
3311 struct btrfs_key location; 3311 struct btrfs_key location;
3312 unsigned long ptr;
3312 int maybe_acls; 3313 int maybe_acls;
3313 u32 rdev; 3314 u32 rdev;
3314 int ret; 3315 int ret;
@@ -3332,7 +3333,7 @@ static void btrfs_read_locked_inode(struct inode *inode)
3332 leaf = path->nodes[0]; 3333 leaf = path->nodes[0];
3333 3334
3334 if (filled) 3335 if (filled)
3335 goto cache_acl; 3336 goto cache_index;
3336 3337
3337 inode_item = btrfs_item_ptr(leaf, path->slots[0], 3338 inode_item = btrfs_item_ptr(leaf, path->slots[0],
3338 struct btrfs_inode_item); 3339 struct btrfs_inode_item);
@@ -3375,6 +3376,30 @@ static void btrfs_read_locked_inode(struct inode *inode)
3375 3376
3376 BTRFS_I(inode)->index_cnt = (u64)-1; 3377 BTRFS_I(inode)->index_cnt = (u64)-1;
3377 BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item); 3378 BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
3379
3380cache_index:
3381 path->slots[0]++;
3382 if (inode->i_nlink != 1 ||
3383 path->slots[0] >= btrfs_header_nritems(leaf))
3384 goto cache_acl;
3385
3386 btrfs_item_key_to_cpu(leaf, &location, path->slots[0]);
3387 if (location.objectid != btrfs_ino(inode))
3388 goto cache_acl;
3389
3390 ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
3391 if (location.type == BTRFS_INODE_REF_KEY) {
3392 struct btrfs_inode_ref *ref;
3393
3394 ref = (struct btrfs_inode_ref *)ptr;
3395 BTRFS_I(inode)->dir_index = btrfs_inode_ref_index(leaf, ref);
3396 } else if (location.type == BTRFS_INODE_EXTREF_KEY) {
3397 struct btrfs_inode_extref *extref;
3398
3399 extref = (struct btrfs_inode_extref *)ptr;
3400 BTRFS_I(inode)->dir_index = btrfs_inode_extref_index(leaf,
3401 extref);
3402 }
3378cache_acl: 3403cache_acl:
3379 /* 3404 /*
3380 * try to precache a NULL acl entry for files that don't have 3405 * try to precache a NULL acl entry for files that don't have
@@ -3587,6 +3612,24 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
3587 goto err; 3612 goto err;
3588 btrfs_release_path(path); 3613 btrfs_release_path(path);
3589 3614
3615 /*
3616 * If we don't have dir index, we have to get it by looking up
3617 * the inode ref, since we get the inode ref, remove it directly,
3618 * it is unnecessary to do delayed deletion.
3619 *
3620 * But if we have dir index, needn't search inode ref to get it.
3621 * Since the inode ref is close to the inode item, it is better
3622 * that we delay to delete it, and just do this deletion when
3623 * we update the inode item.
3624 */
3625 if (BTRFS_I(inode)->dir_index) {
3626 ret = btrfs_delayed_delete_inode_ref(inode);
3627 if (!ret) {
3628 index = BTRFS_I(inode)->dir_index;
3629 goto skip_backref;
3630 }
3631 }
3632
3590 ret = btrfs_del_inode_ref(trans, root, name, name_len, ino, 3633 ret = btrfs_del_inode_ref(trans, root, name, name_len, ino,
3591 dir_ino, &index); 3634 dir_ino, &index);
3592 if (ret) { 3635 if (ret) {
@@ -3596,7 +3639,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
3596 btrfs_abort_transaction(trans, root, ret); 3639 btrfs_abort_transaction(trans, root, ret);
3597 goto err; 3640 goto err;
3598 } 3641 }
3599 3642skip_backref:
3600 ret = btrfs_delete_delayed_dir_index(trans, root, dir, index); 3643 ret = btrfs_delete_delayed_dir_index(trans, root, dir, index);
3601 if (ret) { 3644 if (ret) {
3602 btrfs_abort_transaction(trans, root, ret); 3645 btrfs_abort_transaction(trans, root, ret);
@@ -5465,6 +5508,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
5465 * number 5508 * number
5466 */ 5509 */
5467 BTRFS_I(inode)->index_cnt = 2; 5510 BTRFS_I(inode)->index_cnt = 2;
5511 BTRFS_I(inode)->dir_index = *index;
5468 BTRFS_I(inode)->root = root; 5512 BTRFS_I(inode)->root = root;
5469 BTRFS_I(inode)->generation = trans->transid; 5513 BTRFS_I(inode)->generation = trans->transid;
5470 inode->i_generation = BTRFS_I(inode)->generation; 5514 inode->i_generation = BTRFS_I(inode)->generation;
@@ -5809,6 +5853,8 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
5809 goto fail; 5853 goto fail;
5810 } 5854 }
5811 5855
5856 /* There are several dir indexes for this inode, clear the cache. */
5857 BTRFS_I(inode)->dir_index = 0ULL;
5812 inc_nlink(inode); 5858 inc_nlink(inode);
5813 inode_inc_iversion(inode); 5859 inode_inc_iversion(inode);
5814 inode->i_ctime = CURRENT_TIME; 5860 inode->i_ctime = CURRENT_TIME;
@@ -7861,6 +7907,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
7861 ei->flags = 0; 7907 ei->flags = 0;
7862 ei->csum_bytes = 0; 7908 ei->csum_bytes = 0;
7863 ei->index_cnt = (u64)-1; 7909 ei->index_cnt = (u64)-1;
7910 ei->dir_index = 0;
7864 ei->last_unlink_trans = 0; 7911 ei->last_unlink_trans = 0;
7865 ei->last_log_commit = 0; 7912 ei->last_log_commit = 0;
7866 7913
@@ -8148,6 +8195,7 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
8148 if (ret) 8195 if (ret)
8149 goto out_fail; 8196 goto out_fail;
8150 8197
8198 BTRFS_I(old_inode)->dir_index = 0ULL;
8151 if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) { 8199 if (unlikely(old_ino == BTRFS_FIRST_FREE_OBJECTID)) {
8152 /* force full log commit if subvolume involved. */ 8200 /* force full log commit if subvolume involved. */
8153 root->fs_info->last_trans_log_full_commit = trans->transid; 8201 root->fs_info->last_trans_log_full_commit = trans->transid;
@@ -8236,6 +8284,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
8236 goto out_fail; 8284 goto out_fail;
8237 } 8285 }
8238 8286
8287 if (old_inode->i_nlink == 1)
8288 BTRFS_I(old_inode)->dir_index = index;
8289
8239 if (old_ino != BTRFS_FIRST_FREE_OBJECTID) { 8290 if (old_ino != BTRFS_FIRST_FREE_OBJECTID) {
8240 struct dentry *parent = new_dentry->d_parent; 8291 struct dentry *parent = new_dentry->d_parent;
8241 btrfs_log_new_name(trans, old_inode, old_dir, parent); 8292 btrfs_log_new_name(trans, old_inode, old_dir, parent);