aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);