From be6d46c1fef1d6732cdbe26d271d4ed18046c469 Mon Sep 17 00:00:00 2001 From: Miao Xie Date: Thu, 20 Dec 2012 11:19:09 +0000 Subject: [PATCH] --- yaml --- r: 360391 b: refs/heads/master c: da633a42170165cbf20a2d3886c7480ccc832ec3 h: refs/heads/master i: 360389: a79c372b58af38a6bbc8cffd51dff70ccb19652c 360387: 79b64c5d4c13f6508276b9f8c048b19cbf919e59 360383: aa9403088f7fdfc7ceaa0f1c6821cc0c44b5ee3b v: v3 --- [refs] | 2 +- trunk/fs/btrfs/extent-tree.c | 40 ++++++++++++++++++++++++++++-------- 2 files changed, 32 insertions(+), 10 deletions(-) diff --git a/[refs] b/[refs] index 0f5b8488eb8b..bc9e46b527f8 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 093486c453a55230ccdad4b48863b872fe68c46e +refs/heads/master: da633a42170165cbf20a2d3886c7480ccc832ec3 diff --git a/trunk/fs/btrfs/extent-tree.c b/trunk/fs/btrfs/extent-tree.c index b4cb8186035f..d5e60d25ca51 100644 --- a/trunk/fs/btrfs/extent-tree.c +++ b/trunk/fs/btrfs/extent-tree.c @@ -3695,12 +3695,15 @@ static int can_overcommit(struct btrfs_root *root, return 0; } -static int writeback_inodes_sb_nr_if_idle_safe(struct super_block *sb, - unsigned long nr_pages, - enum wb_reason reason) +static inline int writeback_inodes_sb_nr_if_idle_safe(struct super_block *sb, + unsigned long nr_pages, + enum wb_reason reason) { - if (!writeback_in_progress(sb->s_bdi) && - down_read_trylock(&sb->s_umount)) { + /* the flusher is dealing with the dirty inodes now. */ + if (writeback_in_progress(sb->s_bdi)) + return 1; + + if (down_read_trylock(&sb->s_umount)) { writeback_inodes_sb_nr(sb, nr_pages, reason); up_read(&sb->s_umount); return 1; @@ -3709,6 +3712,28 @@ static int writeback_inodes_sb_nr_if_idle_safe(struct super_block *sb, return 0; } +void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root, + unsigned long nr_pages) +{ + struct super_block *sb = root->fs_info->sb; + int started; + + /* If we can not start writeback, just sync all the delalloc file. */ + started = writeback_inodes_sb_nr_if_idle_safe(sb, nr_pages, + WB_REASON_FS_FREE_SPACE); + if (!started) { + /* + * We needn't worry the filesystem going from r/w to r/o though + * we don't acquire ->s_umount mutex, because the filesystem + * should guarantee the delalloc inodes list be empty after + * the filesystem is readonly(all dirty pages are written to + * the disk). + */ + btrfs_start_delalloc_inodes(root, 0); + btrfs_wait_ordered_extents(root, 0); + } +} + /* * shrink metadata reservation for delalloc */ @@ -3741,10 +3766,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig, while (delalloc_bytes && loops < 3) { max_reclaim = min(delalloc_bytes, to_reclaim); nr_pages = max_reclaim >> PAGE_CACHE_SHIFT; - writeback_inodes_sb_nr_if_idle_safe(root->fs_info->sb, - nr_pages, - WB_REASON_FS_FREE_SPACE); - + btrfs_writeback_inodes_sb_nr(root, nr_pages); /* * We need to wait for the async pages to actually start before * we do anything.