Skip to contentSkip to conversation

btrfs: Skip some btrfs_cross_ref_exist() check in nocow path

PATCH In review Ethan Lien 2 participants 2 messages May 17, 2018 – May 22, 2018 Btrfs file system

lore
Share & tools
lore

Ethan Lien

author
#0 lore raw

PATCH v2 1/1 btrfs: Skip some btrfs_cross_ref_exist() check in nocow path

In nocow path, we check if the extent is snapshotted in btrfs_cross_ref_exist(). We can do the similar check earlier and avoid unnecessary search into extent tree.

A fio test on a Intel D-1531, 16GB RAM, SSD RAID-5 machine as follows:

[global]
group_reporting
time_based
thread=1
ioengine=libaio
bs=4k
iodepth=32
size=64G
runtime=180
numjobs=8
rw=randwrite

[file1]
filename=/mnt/nocow/testfile

IOPS result: unpatched patched

1 fio round: 46670 46958
snapshot

2 fio round:     51826        54498
3 fio round:     59767        61289

After snapshot, the first fio get about 5% performance gain. As we continually write to the same file, all writes will resume to nocow mode and eventually we have no performance gain.

---

V2:
Add comment and performance test.

 fs/btrfs/inode.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
fs/btrfs/inode.c +15 -0
index d241285a0d2a..177630337108 100644
@@ -1373,6 +1373,13 @@ static noinline int run_delalloc_nocow(struct inode *inode,
 			    btrfs_file_extent_encryption(leaf, fi) ||
 			    btrfs_file_extent_other_encoding(leaf, fi))
 				goto out_check;
+			/*
+			 * We can skip the checking of generation of
+			 * extent item in btrfs_cross_ref_exist().
+			 */
+			if (btrfs_file_extent_generation(leaf, fi) <=
+			    btrfs_root_last_snapshot(&root->root_item))
+				goto out_check;
 			if (extent_type == BTRFS_FILE_EXTENT_REG && !force)
 				goto out_check;
 			if (btrfs_extent_readonly(fs_info, disk_bytenr))
@@ -7368,6 +7375,14 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len,
 	    btrfs_file_extent_other_encoding(leaf, fi))
 		goto out;
 
+	/*
+	 * We can skip the checking of generation of
+	 * extent item in btrfs_cross_ref_exist().
+	 */
+	if (btrfs_file_extent_generation(leaf, fi) <=
+	    btrfs_root_last_snapshot(&root->root_item))
+		goto out;
+
 	backref_offset = btrfs_file_extent_offset(leaf, fi);
 
 	if (orig_start) {
Signature · 1 line
2.17.0
#1 lore raw
Quoted 32 lines · Ethan Lien

In nocow path, we check if the extent is snapshotted in btrfs_cross_ref_exist(). We can do the similar check earlier and avoid unnecessary search into extent tree.

A fio test on a Intel D-1531, 16GB RAM, SSD RAID-5 machine as follows:

[global]
group_reporting
time_based
thread=1
ioengine=libaio
bs=4k
iodepth=32
size=64G
runtime=180
numjobs=8
rw=randwrite

[file1]
filename=/mnt/nocow/testfile

IOPS result: unpatched patched

1 fio round: 46670 46958
snapshot

2 fio round:     51826        54498
3 fio round:     59767        61289

After snapshot, the first fio get about 5% performance gain. As we continually write to the same file, all writes will resume to nocow mode and eventually we have no performance gain.

Quoted 5 lines

---

V2:
Add comment and performance test.

Thanks, I maybe edit the comments further as do not feel like I understand why the shortcut can be safely taken just from reading it, but the code looks ok otherwise. I'll add the patch to for-next.