summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fb.com>2018-05-23 11:58:34 -0400
committerDavid Sterba <dsterba@suse.com>2018-08-06 07:12:30 -0400
commite7175a692765940f3ac3f0c005b9a766a59303d7 (patch)
tree4be2cd6437bfbcf73930f122e05d89a04ee3ffcc /fs/btrfs/tree-log.c
parentb5e6c3e170b77025b5f6174258c7ad71eed2d4de (diff)
btrfs: remove the wait ordered logic in the log_one_extent path
Since we are waiting on all ordered extents at the start of the fsync() path we don't need to wait on any logged ordered extents, and we don't need to look up the checksums on the ordered extents as they will already be on disk prior to getting here. Rework this so we're only looking up and copying the on-disk checksums for the extent range we care about. Signed-off-by: Josef Bacik <jbacik@fb.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c118
1 files changed, 10 insertions, 108 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index f8220ec02036..98cbb31ec5a8 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -4078,127 +4078,30 @@ static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
4078 return 0; 4078 return 0;
4079} 4079}
4080 4080
4081static int wait_ordered_extents(struct btrfs_trans_handle *trans, 4081static int log_extent_csums(struct btrfs_trans_handle *trans,
4082 struct inode *inode, 4082 struct btrfs_inode *inode,
4083 struct btrfs_root *root, 4083 struct btrfs_root *root,
4084 const struct extent_map *em, 4084 const struct extent_map *em)
4085 const struct list_head *logged_list,
4086 bool *ordered_io_error)
4087{ 4085{
4088 struct btrfs_fs_info *fs_info = root->fs_info; 4086 struct btrfs_fs_info *fs_info = root->fs_info;
4089 struct btrfs_ordered_extent *ordered;
4090 struct btrfs_root *log = root->log_root; 4087 struct btrfs_root *log = root->log_root;
4091 u64 mod_start = em->mod_start;
4092 u64 mod_len = em->mod_len;
4093 const bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
4094 u64 csum_offset; 4088 u64 csum_offset;
4095 u64 csum_len; 4089 u64 csum_len;
4096 LIST_HEAD(ordered_sums); 4090 LIST_HEAD(ordered_sums);
4097 int ret = 0; 4091 int ret = 0;
4098 4092
4099 *ordered_io_error = false; 4093 if (inode->flags & BTRFS_INODE_NODATASUM ||
4100 4094 test_bit(EXTENT_FLAG_PREALLOC, &em->flags) ||
4101 if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) ||
4102 em->block_start == EXTENT_MAP_HOLE) 4095 em->block_start == EXTENT_MAP_HOLE)
4103 return 0; 4096 return 0;
4104 4097
4105 /* 4098 /* If we're compressed we have to save the entire range of csums. */
4106 * Wait far any ordered extent that covers our extent map. If it
4107 * finishes without an error, first check and see if our csums are on
4108 * our outstanding ordered extents.
4109 */
4110 list_for_each_entry(ordered, logged_list, log_list) {
4111 struct btrfs_ordered_sum *sum;
4112
4113 if (!mod_len)
4114 break;
4115
4116 if (ordered->file_offset + ordered->len <= mod_start ||
4117 mod_start + mod_len <= ordered->file_offset)
4118 continue;
4119
4120 if (!test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags) &&
4121 !test_bit(BTRFS_ORDERED_IOERR, &ordered->flags) &&
4122 !test_bit(BTRFS_ORDERED_DIRECT, &ordered->flags)) {
4123 const u64 start = ordered->file_offset;
4124 const u64 end = ordered->file_offset + ordered->len - 1;
4125
4126 WARN_ON(ordered->inode != inode);
4127 filemap_fdatawrite_range(inode->i_mapping, start, end);
4128 }
4129
4130 wait_event(ordered->wait,
4131 (test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags) ||
4132 test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)));
4133
4134 if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)) {
4135 /*
4136 * Clear the AS_EIO/AS_ENOSPC flags from the inode's
4137 * i_mapping flags, so that the next fsync won't get
4138 * an outdated io error too.
4139 */
4140 filemap_check_errors(inode->i_mapping);
4141 *ordered_io_error = true;
4142 break;
4143 }
4144 /*
4145 * We are going to copy all the csums on this ordered extent, so
4146 * go ahead and adjust mod_start and mod_len in case this
4147 * ordered extent has already been logged.
4148 */
4149 if (ordered->file_offset > mod_start) {
4150 if (ordered->file_offset + ordered->len >=
4151 mod_start + mod_len)
4152 mod_len = ordered->file_offset - mod_start;
4153 /*
4154 * If we have this case
4155 *
4156 * |--------- logged extent ---------|
4157 * |----- ordered extent ----|
4158 *
4159 * Just don't mess with mod_start and mod_len, we'll
4160 * just end up logging more csums than we need and it
4161 * will be ok.
4162 */
4163 } else {
4164 if (ordered->file_offset + ordered->len <
4165 mod_start + mod_len) {
4166 mod_len = (mod_start + mod_len) -
4167 (ordered->file_offset + ordered->len);
4168 mod_start = ordered->file_offset +
4169 ordered->len;
4170 } else {
4171 mod_len = 0;
4172 }
4173 }
4174
4175 if (skip_csum)
4176 continue;
4177
4178 /*
4179 * To keep us from looping for the above case of an ordered
4180 * extent that falls inside of the logged extent.
4181 */
4182 if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM,
4183 &ordered->flags))
4184 continue;
4185
4186 list_for_each_entry(sum, &ordered->list, list) {
4187 ret = btrfs_csum_file_blocks(trans, log, sum);
4188 if (ret)
4189 break;
4190 }
4191 }
4192
4193 if (*ordered_io_error || !mod_len || ret || skip_csum)
4194 return ret;
4195
4196 if (em->compress_type) { 4099 if (em->compress_type) {
4197 csum_offset = 0; 4100 csum_offset = 0;
4198 csum_len = max(em->block_len, em->orig_block_len); 4101 csum_len = max(em->block_len, em->orig_block_len);
4199 } else { 4102 } else {
4200 csum_offset = mod_start - em->start; 4103 csum_offset = em->mod_start - em->start;
4201 csum_len = mod_len; 4104 csum_len = em->mod_len;
4202 } 4105 }
4203 4106
4204 /* block start is already adjusted for the file extent offset. */ 4107 /* block start is already adjusted for the file extent offset. */
@@ -4240,8 +4143,7 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
4240 int extent_inserted = 0; 4143 int extent_inserted = 0;
4241 bool ordered_io_err = false; 4144 bool ordered_io_err = false;
4242 4145
4243 ret = wait_ordered_extents(trans, &inode->vfs_inode, root, em, 4146 ret = log_extent_csums(trans, inode, root, em);
4244 logged_list, &ordered_io_err);
4245 if (ret) 4147 if (ret)
4246 return ret; 4148 return ret;
4247 4149