|
@@ -1256,6 +1256,8 @@ static noinline int csum_exist_in_range(struct btrfs_fs_info *fs_info,
|
|
|
list_del(&sums->list);
|
|
|
kfree(sums);
|
|
|
}
|
|
|
+ if (ret < 0)
|
|
|
+ return ret;
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -1388,10 +1390,23 @@ next_slot:
|
|
|
goto out_check;
|
|
|
if (btrfs_extent_readonly(fs_info, disk_bytenr))
|
|
|
goto out_check;
|
|
|
- if (btrfs_cross_ref_exist(root, ino,
|
|
|
- found_key.offset -
|
|
|
- extent_offset, disk_bytenr))
|
|
|
+ ret = btrfs_cross_ref_exist(root, ino,
|
|
|
+ found_key.offset -
|
|
|
+ extent_offset, disk_bytenr);
|
|
|
+ if (ret) {
|
|
|
+ /*
|
|
|
+ * ret could be -EIO if the above fails to read
|
|
|
+ * metadata.
|
|
|
+ */
|
|
|
+ if (ret < 0) {
|
|
|
+ if (cow_start != (u64)-1)
|
|
|
+ cur_offset = cow_start;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+
|
|
|
+ WARN_ON_ONCE(nolock);
|
|
|
goto out_check;
|
|
|
+ }
|
|
|
disk_bytenr += extent_offset;
|
|
|
disk_bytenr += cur_offset - found_key.offset;
|
|
|
num_bytes = min(end + 1, extent_end) - cur_offset;
|
|
@@ -1409,10 +1424,22 @@ next_slot:
|
|
|
* this ensure that csum for a given extent are
|
|
|
* either valid or do not exist.
|
|
|
*/
|
|
|
- if (csum_exist_in_range(fs_info, disk_bytenr,
|
|
|
- num_bytes)) {
|
|
|
+ ret = csum_exist_in_range(fs_info, disk_bytenr,
|
|
|
+ num_bytes);
|
|
|
+ if (ret) {
|
|
|
if (!nolock)
|
|
|
btrfs_end_write_no_snapshotting(root);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * ret could be -EIO if the above fails to read
|
|
|
+ * metadata.
|
|
|
+ */
|
|
|
+ if (ret < 0) {
|
|
|
+ if (cow_start != (u64)-1)
|
|
|
+ cur_offset = cow_start;
|
|
|
+ goto error;
|
|
|
+ }
|
|
|
+ WARN_ON_ONCE(nolock);
|
|
|
goto out_check;
|
|
|
}
|
|
|
if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) {
|