diff options
-rw-r--r-- | fs/btrfs/tree-log.c | 84 |
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 | ||
2947 | static 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 | |||
2947 | static noinline int copy_items(struct btrfs_trans_handle *trans, | 2996 | static 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); |