btrfs 空閑空間管理(四) fstrim


源文件
      util-linux-<version>/sys-utils/fstrim.c
      linux/fs/btrfs/ioctl.c
      linux/fs/btrfs/extent-tree.c
      linux/fs/btrfs/free-space-cache.c

用戶態工具 fstrim

fstrim 是 util-linux 軟件包中提供的工具:
      discard unused blocks on a mounted filesystem
該工具有 3 個選項跟要 discard 的范圍有關:

       -o, --offset offset
              Byte  offset  in filesystem from which to begin searching for free blocks
              to discard.  Default value is zero, starting  at  the  beginning  of  the
              filesystem.

       -l, --length length
              Number  of  bytes  after starting point to search for free blocks to dis‐
              card.  If the specified value extends past the  end  of  the  filesystem,
              fstrim  will  stop at the filesystem size boundary. Default value extends
              to the end of the filesystem.

       -m, --minimum minimum-free-extent
              Minimum contiguous free range to discard, in bytes. (This value is inter‐
              nally  rounded  up  to  a  multiple  of the filesystem block size).  Free
              ranges smaller than this will be ignored.  By increasing this value,  the
              fstrim  operation  will  complete more quickly for filesystems with badly
              fragmented freespace, although not all blocks will be discarded.  Default
              value is zero, discard every free block.

查看 fstrim.c 的源文件,可以看到,fstrim 將 3 個范圍參數封裝到結構 struct fstrim_range 中,

    struct fstrim_range {
        uint64_t start;
        uint64_t len;
        uint64_t minlen;
    };

然后通過 ioctl 命令 FITRIM 來完成實際的 discard 操作:

    ioctl(fd, FITRIM, &range)

 

ioctl 接收 FITRIM 命令

btrfs/ioctl.c 對 FITRIM 命令進行處理:

    case FITRIM:
        return btrfs_ioctl_fitrim(file, argp);

ioctl.c 文件中也定義了函數 btrfs_ioctl_fitrim,該函數對參數進行檢驗調整后(比如調整 minlen 為文件系統設備所支持的最小 discard 粒度,如果這個粒度比命令指定的 minlen 小的話,調整范圍不會超出文件末尾),轉而由 btrfs_trim_fs(fs_info->tree_root, &range) 來完成實際的工作。

btrfs_trim_fs 在 extent-tree.c 中定義,其工作就是從指定的起始地址對應的 block group 開始,對指定范圍內所覆蓋的 bg,逐個執行btrfs_trim_block_group。這就是工作的分解:
      fstrim 整個文件系統 -> 逐個 trim 文件系統內的塊組
btrfs_trim_block_group 實現在 free-space-cache.c 中。

btrfs_trim_block_group

    int btrfs_trim_block_group(struct btrfs_block_group_cache *block_group,
                   u64 *trimmed, u64 start, u64 end, u64 minlen)
    {
        int ret;
    
        *trimmed = 0;
 
        ret = trim_no_bitmap(block_group, trimmed, start, end, minlen);
        if (ret)
            return ret;
    
        ret = trim_bitmaps(block_group, trimmed, start, end, minlen);
    
        return ret;
    }

可以看出,trim bg 實際上是對 bg 下面的 extent/bitmap 空閑空間記錄進行 trim。

trim_no_bitmap 和 trim_bitmaps 都會調用 btrfs_error_discard_extent,而 btrfs_error_discard_extent 是對 btrfs_discard_extent 的簡單封裝。btrfs_discard_extent 會調用 btrfs_issue_discard,最終調用 blkdev_issue_discard 向塊設備發送 Discard/TRIM 命令

對於 free-space-cache 來說,trim 就是把對應的空閑空間記錄給銷毀

小結

fstrim 的執行流程:

fstrim -> FITRIM -> btrfs_ioctl_fitrim 
    -> btrfs_trim_fs 
        -> btrfs_trim_block_group -> trim_no_bitmap / trim_bitmaps 
            -> btrfs_error_discard_extent -> btrfs_discard_extent 
                -> btrfs_issue_discard -> blkdev_issue_discard        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM