Skip to content

Commit c6887cd

Browse files
Josef Bacikmasoncl
Josef Bacik
authored andcommitted
Btrfs: don't do nocow check unless we have to
Before we write into prealloc/nocow space we have to make sure that there are no references to the extents we are writing into, which means checking the extent tree and csum tree in the case of nocow. So we don't want to do the nocow dance unless we can't reserve data space, since it's a serious drag on performance. With the following sequence fallocate -l10737418240 /mnt/btrfs-test/file cp --reflink /mnt/btrfs-test/file /mnt/btrfs-test/link fio --name=randwrite --rw=randwrite --bs=4k --filename=/mnt/btrfs-test/file \ --end_fsync=1 we get the worst case scenario where we have to fall back on to doing the check anyway. Without this patch lat (usec): min=5, max=111598, avg=27.65, stdev=124.51 write: io=10240MB, bw=126876KB/s, iops=31718, runt= 82646msec With this patch lat (usec): min=3, max=91210, avg=14.09, stdev=110.62 write: io=10240MB, bw=212753KB/s, iops=53188, runt= 49286msec We get twice the throughput, half of the runtime, and half of the average latency. Thanks, Signed-off-by: Josef Bacik <[email protected]> [ PAGE_CACHE_ removal related fixups ] Signed-off-by: David Sterba <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent 0f873ec commit c6887cd

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

fs/btrfs/file.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1534,30 +1534,30 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file,
15341534
reserve_bytes = round_up(write_bytes + sector_offset,
15351535
root->sectorsize);
15361536

1537-
if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
1538-
BTRFS_INODE_PREALLOC)) &&
1539-
check_can_nocow(inode, pos, &write_bytes) > 0) {
1540-
/*
1541-
* For nodata cow case, no need to reserve
1542-
* data space.
1543-
*/
1544-
only_release_metadata = true;
1545-
/*
1546-
* our prealloc extent may be smaller than
1547-
* write_bytes, so scale down.
1548-
*/
1549-
num_pages = DIV_ROUND_UP(write_bytes + offset,
1550-
PAGE_SIZE);
1551-
reserve_bytes = round_up(write_bytes + sector_offset,
1552-
root->sectorsize);
1553-
goto reserve_metadata;
1554-
}
1555-
15561537
ret = btrfs_check_data_free_space(inode, pos, write_bytes);
1557-
if (ret < 0)
1558-
break;
1538+
if (ret < 0) {
1539+
if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
1540+
BTRFS_INODE_PREALLOC)) &&
1541+
check_can_nocow(inode, pos, &write_bytes) > 0) {
1542+
/*
1543+
* For nodata cow case, no need to reserve
1544+
* data space.
1545+
*/
1546+
only_release_metadata = true;
1547+
/*
1548+
* our prealloc extent may be smaller than
1549+
* write_bytes, so scale down.
1550+
*/
1551+
num_pages = DIV_ROUND_UP(write_bytes + offset,
1552+
PAGE_SIZE);
1553+
reserve_bytes = round_up(write_bytes +
1554+
sector_offset,
1555+
root->sectorsize);
1556+
} else {
1557+
break;
1558+
}
1559+
}
15591560

1560-
reserve_metadata:
15611561
ret = btrfs_delalloc_reserve_metadata(inode, reserve_bytes);
15621562
if (ret) {
15631563
if (!only_release_metadata)

0 commit comments

Comments
 (0)