<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel.git/fs/btrfs/send.c, branch linux-6.15.y</title>
<subtitle>Hosts the 0x221E linux distro kernel.
</subtitle>
<id>https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-6.15.y</id>
<link rel='self' href='https://git.0xinfinity.dev/distro/kernel.git/atom?h=linux-6.15.y'/>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/'/>
<updated>2025-08-20T16:36:31Z</updated>
<entry>
<title>btrfs: send: use fallocate for hole punching with send stream v2</title>
<updated>2025-08-20T16:36:31Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-07-18T12:07:29Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=f714559f3c1358d75c1ee8260952bd820814ae52'/>
<id>urn:sha1:f714559f3c1358d75c1ee8260952bd820814ae52</id>
<content type='text'>
commit 005b0a0c24e1628313e951516b675109a92cacfe upstream.

Currently holes are sent as writes full of zeroes, which results in
unnecessarily using disk space at the receiving end and increasing the
stream size.

In some cases we avoid sending writes of zeroes, like during a full
send operation where we just skip writes for holes.

But for some cases we fill previous holes with writes of zeroes too, like
in this scenario:

1) We have a file with a hole in the range [2M, 3M), we snapshot the
   subvolume and do a full send. The range [2M, 3M) stays as a hole at
   the receiver since we skip sending write commands full of zeroes;

2) We punch a hole for the range [3M, 4M) in our file, so that now it
   has a 2M hole in the range [2M, 4M), and snapshot the subvolume.
   Now if we do an incremental send, we will send write commands full
   of zeroes for the range [2M, 4M), removing the hole for [2M, 3M) at
   the receiver.

We could improve cases such as this last one by doing additional
comparisons of file extent items (or their absence) between the parent
and send snapshots, but that's a lot of code to add plus additional CPU
and IO costs.

Since the send stream v2 already has a fallocate command and btrfs-progs
implements a callback to execute fallocate since the send stream v2
support was added to it, update the kernel to use fallocate for punching
holes for V2+ streams.

Test coverage is provided by btrfs/284 which is a version of btrfs/007
that exercises send stream v2 instead of v1, using fsstress with random
operations and fssum to verify file contents.

Link: https://github.com/kdave/btrfs-progs/issues/1001
CC: stable@vger.kernel.org # 6.1+
Reviewed-by: Boris Burkov &lt;boris@bur.io&gt;
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
</entry>
<entry>
<title>btrfs: make btrfs_iget() return a btrfs inode instead</title>
<updated>2025-03-18T19:35:50Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-03-07T12:16:10Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=b204e5c7d4dce859bc2feed7685baf656e234f6d'/>
<id>urn:sha1:b204e5c7d4dce859bc2feed7685baf656e234f6d</id>
<content type='text'>
It's an internal function and most of the time the callers are doing a lot
of BTRFS_I() calls on the returned VFS inode to get the btrfs inode, so
change the return type to struct btrfs_inode instead.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: send: simplify return logic from send_encoded_extent()</title>
<updated>2025-03-18T19:35:50Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-03-06T17:47:34Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=08f340767dde5fd302af5b94ce6ce2d5e38a233d'/>
<id>urn:sha1:08f340767dde5fd302af5b94ce6ce2d5e38a233d</id>
<content type='text'>
The 'out' label is pointless as we don't have anything to cleanup anymore
(we used to have an inode to iput), so remove it and make error paths
directly return an error.

Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: send: remove unnecessary inode lookup at send_encoded_inline_extent()</title>
<updated>2025-03-18T19:35:50Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-03-06T17:45:40Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=0c8337c22043511549162df877cf752566aeedb9'/>
<id>urn:sha1:0c8337c22043511549162df877cf752566aeedb9</id>
<content type='text'>
We are doing a lookup of the inode but we don't use it at all. So just
remove this pointless lookup.

Reviewed-by: Qu Wenruo &lt;wqu@suse.com&gt;
Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: pass btrfs_root pointers to send ioctl parameters</title>
<updated>2025-03-18T19:35:49Z</updated>
<author>
<name>David Sterba</name>
</author>
<published>2025-03-03T14:55:17Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=4e043cd196c85bf9958148a84df65e0585a554de'/>
<id>urn:sha1:4e043cd196c85bf9958148a84df65e0585a554de</id>
<content type='text'>
The ioctl switch btrfs_ioctl() provides several parameter types for
convenience so we don't have to do the conversion in the callbacks.
Pass root pointers to the send related functions.

Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: send: simplify return logic from send_set_xattr()</title>
<updated>2025-03-18T19:35:46Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-02-18T15:40:17Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=25aff7b964521eb4ab627dc092335e4690c07e95'/>
<id>urn:sha1:25aff7b964521eb4ab627dc092335e4690c07e95</id>
<content type='text'>
There's no longer any need for the 'out' label as there are no resources
to cleanup anymore in case of an error and we can directly return if
begin_cmd() fails.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: send: avoid path allocation for the current inode when issuing commands</title>
<updated>2025-03-18T19:35:46Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-02-18T15:24:45Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=374d45af6435534a11b01b88762323abf03dd755'/>
<id>urn:sha1:374d45af6435534a11b01b88762323abf03dd755</id>
<content type='text'>
Whenever we issue a command we allocate a path and then compute it. For
the current inode this is not necessary since we have one preallocated
and computed in the send context structure, so we can use it instead
and avoid allocating and freeing a path.

For example if we have 100 extents to send (100 write commands) for a
file, we are allocating and freeing paths 100 times.

So improve on this by avoiding path allocation and freeing whenever a
command is for the current inode by using the current inode's path
stored in the send context structure.

A test was run before applying this patch and the previous one in the
series:

  "btrfs: send: keep the current inode's path cached"

The test script is the following:

  $ cat test.sh
  #!/bin/bash

  DEV=/dev/nullb0
  MNT=/mnt/nullb0

  mkfs.btrfs -f $DEV &gt; /dev/null
  mount $DEV $MNT

  DIR="$MNT/one/two/three/four"
  FILE="$DIR/foobar"

  mkdir -p $DIR

  # Create some empty files to get a deeper btree and therefore make
  # path computations slower.
  for ((i = 1; i &lt;= 30000; i++)); do
      echo -n &gt; "$DIR/filler_$i"
  done

  for ((i = 0; i &lt; 10000; i += 2)); do
     offset=$(( i * 4096 ))
     xfs_io -f -c "pwrite -S 0xab $offset 4K" $FILE &gt; /dev/null
  done

  btrfs subvolume snapshot -r $MNT $MNT/snap

  start=$(date +%s%N)
  btrfs send -f /dev/null $MNT/snap
  end=$(date +%s%N)

  echo -e "\nsend took $(( (end - start) / 1000000 )) milliseconds"

  umount $MNT

Result before applying the 2 patches:  1121 milliseconds
Result after applying the 2 patches:    815 milliseconds  (-31.6%)

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: send: keep the current inode's path cached</title>
<updated>2025-03-18T19:35:46Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-02-13T17:08:44Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=fc746acb7aa9aeaa2cb5dcba449323319ba5c8eb'/>
<id>urn:sha1:fc746acb7aa9aeaa2cb5dcba449323319ba5c8eb</id>
<content type='text'>
Whenever we need to send a command for the current inode, like sending
writes, xattr updates, truncates, utimes, etc, we compute the inode's
path each time, which implies doing some memory allocations and traversing
the inode hierarchy to extract the name of the inode and each ancestor
directory, and that implies doing lookups in the subvolume tree amongst
other operations.

Most of the time, by far, the current inode's path doesn't change while
we are processing it (like if we need to issue 100 write commands, the
path remains the same and it's pointless to compute it 100 times).

To avoid this keep the current inode's path cached in the send context
and invalidate it or update it whenever it's needed (after unlinks or
renames).

A performance test, and its results, is mentioned in the next patch in
the series (subject: "btrfs: send: avoid path allocation for the current
inode when issuing commands").

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: send: simplify return logic from send_rmdir()</title>
<updated>2025-03-18T19:35:46Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-02-20T10:59:13Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=d7d56ccf100adb140c5655c624fedf7545d569e0'/>
<id>urn:sha1:d7d56ccf100adb140c5655c624fedf7545d569e0</id>
<content type='text'>
There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
<entry>
<title>btrfs: send: simplify return logic from send_unlink()</title>
<updated>2025-03-18T19:35:46Z</updated>
<author>
<name>Filipe Manana</name>
</author>
<published>2025-02-20T10:58:38Z</published>
<link rel='alternate' type='text/html' href='https://git.0xinfinity.dev/distro/kernel.git/commit/?id=26605cc9d0d556618893a5e05abde9b36efe7a3e'/>
<id>urn:sha1:26605cc9d0d556618893a5e05abde9b36efe7a3e</id>
<content type='text'>
There is no need to have an 'out' label and jump into it since there are
no resource cleanups to perform (release locks, free memory, etc), so
make this simpler by removing the label and goto and instead return
directly.

Signed-off-by: Filipe Manana &lt;fdmanana@suse.com&gt;
Reviewed-by: David Sterba &lt;dsterba@suse.com&gt;
Signed-off-by: David Sterba &lt;dsterba@suse.com&gt;
</content>
</entry>
</feed>
