-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Description
Issue
CoW filesystems with random and frequent small writes create a lot of fragmentation which slows down file IO operations significantly.
For example. Using fresh btrfs+hdd filesystem allow to read write to partition at 100-150 MB/s speed. But when torrent got downloaded torrent file wlil be significantly fragmented and final reading speed of such file would be around 4-5 MB/s.
Here is simple fragmentation benchmark test which does:
- create 5GB file on memory
- measuring file fragmentation before start (1 2 or 50 fragments, depend on run)
- make 20000 random writes into that single file
- measure file fragmentation again, it will be about 40000 fragments.
As you can see fragmentation does not slowdown reading speeds for memory file, only affecting hdd devices.
W none: 5,61GiB 0:00:05 [ 999MiB/s] [=====================================================>] 100%
/mnt/copy: 5 extents found
fragmenting file...
/mnt/copy: 39469 extents found
R none: 5,61GiB 0:00:03 [1,66GiB/s] [=====================================================>] 100%
none 3383ms 1781793901/sec 101% (6109163520) E:-24048
W none,nodatacow: 5,61GiB 0:00:05 [1,01GiB/s] [==============================================>] 100%
/mnt/copy: 36 extents found
fragmenting file...
/mnt/copy: 35 extents found
R none,nodatacow: 5,61GiB 0:00:03 [1,67GiB/s] [==============================================>] 100%
none,nodatacow 3361ms 1793456937/sec 100% (6027808768) E:0
W none: 5,61GiB 0:00:05 [1006MiB/s] [=====================================================>] 100%
/mnt/copy: 27 extents found
fragmenting file...
/mnt/copy: 39458 extents found
R none: 5,61GiB 0:00:03 [1,60GiB/s] [=====================================================>] 100%
none 3507ms 1718793489/sec 101% (6109151232) E:-23194
W zstd: 5,61GiB 0:00:05 [ 971MiB/s] [=====================================================>] 100%
/mnt/copy: 22 extents found
fragmenting file...
/mnt/copy: 39452 extents found
R zstd: 5,61GiB 0:00:03 [1,57GiB/s] [=====================================================>] 100%
zstd 3582ms 1682805351/sec 101% (6109118464) E:-22699
W zstd: 5,61GiB 0:00:05 [ 961MiB/s] [=====================================================>] 100%
/mnt/copy: 32 extents found
fragmenting file...
/mnt/copy: 39456 extents found
R zstd: 5,61GiB 0:00:03 [1,57GiB/s] [=====================================================>] 100%
zstd 3575ms 1686100354/sec 101% (6109134848) E:-22748
Real HDD test data. Initial read/writing speed 173MB, after 100000 write operations, 118586 fragments, drops reading speed to 6MB/s.
setup: 1,00GiB 0:00:02 [ 433MiB/s] [=====================>] 100%
W none: 1,00GiB 0:00:05 [ 175MiB/s] [=====================>] 100%
/media/axet/2TB/123//copy: 1 extent found
fragmenting file...
/media/axet/2TB/123//copy: 118586 extents found
R none: 1,00GiB 0:02:50 [6,02MiB/s] [=====================>] 100%
Here is a script:
Feature request
We need option for torrent client which mark all new pre-allocated files created with NO CoW flag (ala chattr +C). And remove such flag after torrent file fully loaded.
Workaround
Here is a workaround:
- create btrfs subvolume named tmp (btrfs sub create tmp)
- mark it no CoW (chattr +C tmp)
- set torrent to use incomplete folder location at 'tmp'
Solution
Workaround is not optimal, since whole torrent got moved every time when rehashed to download portion of the torrent. Good implementation would move only torrent portion which is need to downloaded. It could be separate option for 'Incomplete Files folder' in addition to 'Incomplete Torrent folder'.
Option 'Incomplete Files folder' can be enabled automatically within hidden folder when app detects CoW filesystem. For example when I start to download 'BestMoive/{Movie.avi,README.txt} it would create BestMovie/.nocow folder using 'btrfs sub create .nocow' And then mark it using chattr +C .nocow. Then move only parts need to be downloaded and skip parts with zeros (not downloaed to avoid moving new pre allocated torrent files). Then finish download. Then move new data back to its original location. Then delete '.nocow' folder