diff options
| -rw-r--r-- | fs/btrfs/inode.c | 23 |
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: | |||
| 1289 | out_check: | 1298 | out_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; |
