aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/inode.c23
1 files changed, 21 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 0ec876657923..251db68148b2 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -1271,6 +1271,15 @@ next_slot:
1271 disk_bytenr += cur_offset - found_key.offset; 1271 disk_bytenr += cur_offset - found_key.offset;
1272 num_bytes = min(end + 1, extent_end) - cur_offset; 1272 num_bytes = min(end + 1, extent_end) - cur_offset;
1273 /* 1273 /*
1274 * if there are pending snapshots for this root,
1275 * we fall into common COW way.
1276 */
1277 if (!nolock) {
1278 err = btrfs_start_nocow_write(root);
1279 if (!err)
1280 goto out_check;
1281 }
1282 /*
1274 * force cow if csum exists in the range. 1283 * force cow if csum exists in the range.
1275 * this ensure that csum for a given extent are 1284 * this ensure that csum for a given extent are
1276 * either valid or do not exist. 1285 * either valid or do not exist.
@@ -1289,6 +1298,8 @@ next_slot:
1289out_check: 1298out_check:
1290 if (extent_end <= start) { 1299 if (extent_end <= start) {
1291 path->slots[0]++; 1300 path->slots[0]++;
1301 if (!nolock && nocow)
1302 btrfs_end_nocow_write(root);
1292 goto next_slot; 1303 goto next_slot;
1293 } 1304 }
1294 if (!nocow) { 1305 if (!nocow) {
@@ -1306,8 +1317,11 @@ out_check:
1306 ret = cow_file_range(inode, locked_page, 1317 ret = cow_file_range(inode, locked_page,
1307 cow_start, found_key.offset - 1, 1318 cow_start, found_key.offset - 1,
1308 page_started, nr_written, 1); 1319 page_started, nr_written, 1);
1309 if (ret) 1320 if (ret) {
1321 if (!nolock && nocow)
1322 btrfs_end_nocow_write(root);
1310 goto error; 1323 goto error;
1324 }
1311 cow_start = (u64)-1; 1325 cow_start = (u64)-1;
1312 } 1326 }
1313 1327
@@ -1354,8 +1368,11 @@ out_check:
1354 BTRFS_DATA_RELOC_TREE_OBJECTID) { 1368 BTRFS_DATA_RELOC_TREE_OBJECTID) {
1355 ret = btrfs_reloc_clone_csums(inode, cur_offset, 1369 ret = btrfs_reloc_clone_csums(inode, cur_offset,
1356 num_bytes); 1370 num_bytes);
1357 if (ret) 1371 if (ret) {
1372 if (!nolock && nocow)
1373 btrfs_end_nocow_write(root);
1358 goto error; 1374 goto error;
1375 }
1359 } 1376 }
1360 1377
1361 extent_clear_unlock_delalloc(inode, cur_offset, 1378 extent_clear_unlock_delalloc(inode, cur_offset,
@@ -1363,6 +1380,8 @@ out_check:
1363 locked_page, EXTENT_LOCKED | 1380 locked_page, EXTENT_LOCKED |
1364 EXTENT_DELALLOC, PAGE_UNLOCK | 1381 EXTENT_DELALLOC, PAGE_UNLOCK |
1365 PAGE_SET_PRIVATE2); 1382 PAGE_SET_PRIVATE2);
1383 if (!nolock && nocow)
1384 btrfs_end_nocow_write(root);
1366 cur_offset = extent_end; 1385 cur_offset = extent_end;
1367 if (cur_offset > end) 1386 if (cur_offset > end)
1368 break; 1387 break;