aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2012-09-25 14:56:25 -0400
committerChris Mason <chris.mason@fusionio.com>2012-10-09 09:19:50 -0400
commit94edf4ae43a5f9405fe3570f670e26ce1b188476 (patch)
tree4009cd9106381d904e08d7480e2f9cdfbf154f60 /fs/btrfs
parent479ed9abdbeec5d9ed0005f3bee9c9bc06a102bb (diff)
Btrfs: don't bother committing delayed inode updates when fsyncing
We can just copy the in memory inode into the tree log directly, no sense in updating the fs tree so we can copy it into the tree log tree. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/tree-log.c84
1 files changed, 65 insertions, 19 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 179fda964601..47911fd18310 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -2944,6 +2944,55 @@ static int drop_objectid_items(struct btrfs_trans_handle *trans,
2944 return ret; 2944 return ret;
2945} 2945}
2946 2946
2947static void fill_inode_item(struct btrfs_trans_handle *trans,
2948 struct extent_buffer *leaf,
2949 struct btrfs_inode_item *item,
2950 struct inode *inode, int log_inode_only)
2951{
2952 btrfs_set_inode_uid(leaf, item, inode->i_uid);
2953 btrfs_set_inode_gid(leaf, item, inode->i_gid);
2954 btrfs_set_inode_mode(leaf, item, inode->i_mode);
2955 btrfs_set_inode_nlink(leaf, item, inode->i_nlink);
2956
2957 btrfs_set_timespec_sec(leaf, btrfs_inode_atime(item),
2958 inode->i_atime.tv_sec);
2959 btrfs_set_timespec_nsec(leaf, btrfs_inode_atime(item),
2960 inode->i_atime.tv_nsec);
2961
2962 btrfs_set_timespec_sec(leaf, btrfs_inode_mtime(item),
2963 inode->i_mtime.tv_sec);
2964 btrfs_set_timespec_nsec(leaf, btrfs_inode_mtime(item),
2965 inode->i_mtime.tv_nsec);
2966
2967 btrfs_set_timespec_sec(leaf, btrfs_inode_ctime(item),
2968 inode->i_ctime.tv_sec);
2969 btrfs_set_timespec_nsec(leaf, btrfs_inode_ctime(item),
2970 inode->i_ctime.tv_nsec);
2971
2972 btrfs_set_inode_nbytes(leaf, item, inode_get_bytes(inode));
2973
2974 btrfs_set_inode_sequence(leaf, item, inode->i_version);
2975 btrfs_set_inode_transid(leaf, item, trans->transid);
2976 btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
2977 btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
2978 btrfs_set_inode_block_group(leaf, item, 0);
2979
2980 if (log_inode_only) {
2981 /* set the generation to zero so the recover code
2982 * can tell the difference between an logging
2983 * just to say 'this inode exists' and a logging
2984 * to say 'update this inode with these values'
2985 */
2986 btrfs_set_inode_generation(leaf, item, 0);
2987 btrfs_set_inode_size(leaf, item, 0);
2988 } else {
2989 btrfs_set_inode_generation(leaf, item,
2990 BTRFS_I(inode)->generation);
2991 btrfs_set_inode_size(leaf, item, inode->i_size);
2992 }
2993
2994}
2995
2947static noinline int copy_items(struct btrfs_trans_handle *trans, 2996static noinline int copy_items(struct btrfs_trans_handle *trans,
2948 struct inode *inode, 2997 struct inode *inode,
2949 struct btrfs_path *dst_path, 2998 struct btrfs_path *dst_path,
@@ -2990,24 +3039,17 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
2990 3039
2991 src_offset = btrfs_item_ptr_offset(src, start_slot + i); 3040 src_offset = btrfs_item_ptr_offset(src, start_slot + i);
2992 3041
2993 copy_extent_buffer(dst_path->nodes[0], src, dst_offset, 3042 if (ins_keys[i].type == BTRFS_INODE_ITEM_KEY) {
2994 src_offset, ins_sizes[i]);
2995
2996 if (inode_only == LOG_INODE_EXISTS &&
2997 ins_keys[i].type == BTRFS_INODE_ITEM_KEY) {
2998 inode_item = btrfs_item_ptr(dst_path->nodes[0], 3043 inode_item = btrfs_item_ptr(dst_path->nodes[0],
2999 dst_path->slots[0], 3044 dst_path->slots[0],
3000 struct btrfs_inode_item); 3045 struct btrfs_inode_item);
3001 btrfs_set_inode_size(dst_path->nodes[0], inode_item, 0); 3046 fill_inode_item(trans, dst_path->nodes[0], inode_item,
3002 3047 inode, inode_only == LOG_INODE_EXISTS);
3003 /* set the generation to zero so the recover code 3048 } else {
3004 * can tell the difference between an logging 3049 copy_extent_buffer(dst_path->nodes[0], src, dst_offset,
3005 * just to say 'this inode exists' and a logging 3050 src_offset, ins_sizes[i]);
3006 * to say 'update this inode with these values'
3007 */
3008 btrfs_set_inode_generation(dst_path->nodes[0],
3009 inode_item, 0);
3010 } 3051 }
3052
3011 /* take a reference on file data extents so that truncates 3053 /* take a reference on file data extents so that truncates
3012 * or deletes of this inode don't have to relog the inode 3054 * or deletes of this inode don't have to relog the inode
3013 * again 3055 * again
@@ -3361,11 +3403,15 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
3361 max_key.type = (u8)-1; 3403 max_key.type = (u8)-1;
3362 max_key.offset = (u64)-1; 3404 max_key.offset = (u64)-1;
3363 3405
3364 ret = btrfs_commit_inode_delayed_items(trans, inode); 3406 /* Only run delayed items if we are a dir or a new file */
3365 if (ret) { 3407 if (S_ISDIR(inode->i_mode) ||
3366 btrfs_free_path(path); 3408 BTRFS_I(inode)->generation > root->fs_info->last_trans_committed) {
3367 btrfs_free_path(dst_path); 3409 ret = btrfs_commit_inode_delayed_items(trans, inode);
3368 return ret; 3410 if (ret) {
3411 btrfs_free_path(path);
3412 btrfs_free_path(dst_path);
3413 return ret;
3414 }
3369 } 3415 }
3370 3416
3371 mutex_lock(&BTRFS_I(inode)->log_mutex); 3417 mutex_lock(&BTRFS_I(inode)->log_mutex);