LinuxカーネルHack: Btrfs開発最新動向(2010/10/31)

タイトルはちょっと大げさだけど、btrfs-unstableブランチとメインラインに動きがあったので、今回はその紹介。

実は、Btrfsの開発ブランチである git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable は今年の7月中旬頃から全然更新されない状況が続いていた。Btrfsのメーリングリストには、日々様々なパッチが投稿されている。Btrfsの開発者のChris Masonさんはメーリングリスト上では返事もしている。にも関わらず。

コミュニティからは、btrfs-unstableブランチはかなり古いので、別のツリーがあるのか?といった質問をされる始末。ちなみに、これに対して誰も返事していない。僕も誰か返事してくれるかな、と期待していたのだれども。

Re: Inode to bdi issue?

Tomasz Chmielewski
Wed, 20 Oct 2010 10:21:48 -0700

> Correct, this one is already fixed. Just do a git pull from Linus' tree
> and you'll get the fix.

BTW, is there a separate btrfs tree? Or, everything gets to Linus' tree
straight away?


The https://btrfs.wiki.kernel.org/index.php/Btrfs_source_repositories points to:

http://git.kernel.org/?p=linux/kernel/git/mason/btrfs-unstable.git;a=summary

which seems quite old (Mon, 19 Jul 2010 20:58:20 +0000).

http://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg06457.html

この沈黙は一体何だったんだろう?単に忙しかっただけなのかな?もともと、そういうスタンスなのかな?

個人的には、沈黙を続けて、一気に作業するより、こまめにやったほうが、状況の透明性が上がって、Btrfsの開発コミュニティも安心するし、開発コミュニティももっと活性化すると思うのだけれども。

それで、昨日久々に、btrfs-unstableをgit pullしてみたら動きがあった。大量のパッチが取り込まれている。個人的に注目していた、FujitsuのLi Zefanさんによる、LZO対応パッチ(約1週間前に投稿)は、残念ながらまだマージされていない。http://www.mail-archive.com/linux-btrfs@vger.kernel.org/msg06487.html ちなみに、BtrfsのWikiにある「Project ideas」の「LZO compression 」の項目は「(Li Zefan has submitted patches for this) 」となっていて、パッチの取り込みが期待されている状況。https://btrfs.wiki.kernel.org/index.php/Main_Page

先ほどメインラインをgit pullしたら、Linusさんによって、btrfs-unstableがマージされたのを確認できた。ただ、コミットログを読むと、LinusさんはBtrfsのマージにイライラした模様。

% git log
[...]
commit 925d169f5b86fe57e2f5264ea574cce9a89b719d
Merge: cdf01dd... 6418c96...
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sat Oct 30 09:05:48 2010 -0700

    Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable

    * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (39 commits)
      Btrfs: deal with errors from updating the tree log
      Btrfs: allow subvol deletion by unprivileged user with -o user_subvol_rm_allowed
      Btrfs: make SNAP_DESTROY async
      Btrfs: add SNAP_CREATE_ASYNC ioctl
      Btrfs: add START_SYNC, WAIT_SYNC ioctls
      Btrfs: async transaction commit
      Btrfs: fix deadlock in btrfs_commit_transaction
      Btrfs: fix lockdep warning on clone ioctl
      Btrfs: fix clone ioctl where range is adjacent to extent
      Btrfs: fix delalloc checks in clone ioctl
      Btrfs: drop unused variable in block_alloc_rsv
      Btrfs: cleanup warnings from gcc 4.6 (nonbugs)
      Btrfs: Fix variables set but not read (bugs found by gcc 4.6)
      Btrfs: Use ERR_CAST helpers
      Btrfs: use memdup_user helpers
      Btrfs: fix raid code for removing missing drives
      Btrfs: Switch the extent buffer rbtree into a radix tree
      Btrfs: restructure try_release_extent_buffer()
      Btrfs: use the flusher threads for delalloc throttling
      Btrfs: tune the chunk allocation to 5% of the FS as metadata
      ...

    Fix up trivial conflicts in fs/btrfs/super.c and fs/fs-writeback.c, and
    remove use of INIT_RCU_HEAD in fs/btrfs/extent_io.c (that init macro was
    useless and removed in commit 5e8067adfdba: "rcu head remove init")

commit cdf01dd5443d0befc8c6a32cb2e3d2f568fd2558
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sat Oct 30 08:55:52 2010 -0700

    fs-writeback.c: unify some common code

    The btrfs merge looks like hell, because it changes fs-writeback.c, and
    the crazy code has this repeated "estimate number of dirty pages"
    counting that involves three different helper functions.  And it's done
    in two different places.

    Just unify that whole calculation as a "get_nr_dirty_pages()" helper
    function, and the merge result will look half-way decent.

    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
[...]

diffを追ってみると、確かに、ヘルパー関数(get_nr_dirty_pages)を用意して、それを使うことで、コードの重複がなくなってすっきりしてる。DRY!

% git log -p --full-diff
[...]
commit cdf01dd5443d0befc8c6a32cb2e3d2f568fd2558
Author: Linus Torvalds <torvalds@linux-foundation.org>
Date:   Sat Oct 30 08:55:52 2010 -0700

    fs-writeback.c: unify some common code

    The btrfs merge looks like hell, because it changes fs-writeback.c, and
    the crazy code has this repeated "estimate number of dirty pages"
    counting that involves three different helper functions.  And it's done
    in two different places.

    Just unify that whole calculation as a "get_nr_dirty_pages()" helper
    function, and the merge result will look half-way decent.

    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index aed881a..f027382 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -707,6 +707,17 @@ get_next_work_item(struct backing_dev_info *bdi)
        return work;
 }

+/*
+ * Add in the number of potentially dirty inodes, because each inode
+ * write can dirty pagecache in the underlying blockdev.
+ */
+static unsigned long get_nr_dirty_pages(void)
+{
+       return global_page_state(NR_FILE_DIRTY) +
+               global_page_state(NR_UNSTABLE_NFS) +
+               get_nr_dirty_inodes();
+}
+
 static long wb_check_old_data_flush(struct bdi_writeback *wb)
 {
        unsigned long expired;
@@ -724,13 +735,7 @@ static long wb_check_old_data_flush(struct bdi_writeback *wb)
                return 0;

        wb->last_old_flush = jiffies;
-       /*
-        * Add in the number of potentially dirty inodes, because each inode
-        * write can dirty pagecache in the underlying blockdev.
-        */
-       nr_pages = global_page_state(NR_FILE_DIRTY) +
-                       global_page_state(NR_UNSTABLE_NFS) +
-                       get_nr_dirty_inodes();
+       nr_pages = get_nr_dirty_pages();

        if (nr_pages) {
                struct wb_writeback_work work = {
@@ -1086,8 +1091,6 @@ static void wait_sb_inodes(struct super_block *sb)
  */
 void writeback_inodes_sb(struct super_block *sb)
 {
-       unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
-       unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
        DECLARE_COMPLETION_ONSTACK(done);
        struct wb_writeback_work work = {
                .sb             = sb,
@@ -1097,7 +1100,7 @@ void writeback_inodes_sb(struct super_block *sb)

        WARN_ON(!rwsem_is_locked(&sb->s_umount));

-       work.nr_pages = nr_dirty + nr_unstable + get_nr_dirty_inodes();
+       work.nr_pages = get_nr_dirty_pages();

        bdi_queue_work(sb->s_bdi, &work);
        wait_for_completion(&done);