|
Jiri Slaby |
8cebe2 |
From: Qu Wenruo <quwenruo@cn.fujitsu.com>
|
|
Jiri Slaby |
8cebe2 |
Date: Thu, 22 Jun 2017 10:01:21 +0800
|
|
Jiri Slaby |
8cebe2 |
Subject: [PATCH] btrfs: Remove false alert when fiemap range is smaller than
|
|
Jiri Slaby |
8cebe2 |
on-disk extent
|
|
Jiri Slaby |
8cebe2 |
MIME-Version: 1.0
|
|
Jiri Slaby |
8cebe2 |
Content-Type: text/plain; charset=UTF-8
|
|
Jiri Slaby |
8cebe2 |
Content-Transfer-Encoding: 8bit
|
|
Jiri Slaby |
8cebe2 |
References: bnc#1060662
|
|
Jiri Slaby |
8cebe2 |
Patch-mainline: 4.12.7
|
|
Jiri Slaby |
8cebe2 |
Git-commit: 848c23b78fafdcd3270b06a30737f8dbd70c347f
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
commit 848c23b78fafdcd3270b06a30737f8dbd70c347f upstream.
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
Commit 4751832da990 ("btrfs: fiemap: Cache and merge fiemap extent before
|
|
Jiri Slaby |
8cebe2 |
submit it to user") introduced a warning to catch unemitted cached
|
|
Jiri Slaby |
8cebe2 |
fiemap extent.
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
However such warning doesn't take the following case into consideration:
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
0 4K 8K
|
|
Jiri Slaby |
8cebe2 |
|<---- fiemap range --->|
|
|
Jiri Slaby |
8cebe2 |
|<----------- On-disk extent ------------------>|
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
In this case, the whole 0~8K is cached, and since it's larger than
|
|
Jiri Slaby |
8cebe2 |
fiemap range, it break the fiemap extent emit loop.
|
|
Jiri Slaby |
8cebe2 |
This leaves the fiemap extent cached but not emitted, and caught by the
|
|
Jiri Slaby |
8cebe2 |
final fiemap extent sanity check, causing kernel warning.
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
This patch removes the kernel warning and renames the sanity check to
|
|
Jiri Slaby |
8cebe2 |
emit_last_fiemap_cache() since it's possible and valid to have cached
|
|
Jiri Slaby |
8cebe2 |
fiemap extent.
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
Reported-by: David Sterba <dsterba@suse.cz>
|
|
Jiri Slaby |
8cebe2 |
Reported-by: Adam Borowski <kilobyte@angband.pl>
|
|
Jiri Slaby |
8cebe2 |
Fixes: 4751832da990 ("btrfs: fiemap: Cache and merge fiemap extent ...")
|
|
Jiri Slaby |
8cebe2 |
Signed-off-by: Qu Wenruo <quwenruo@cn.fujitsu.com>
|
|
Jiri Slaby |
8cebe2 |
Signed-off-by: David Sterba <dsterba@suse.com>
|
|
Jiri Slaby |
8cebe2 |
Cc: Holger Hoffstätte <holger@applied-asynchrony.com>
|
|
Jiri Slaby |
8cebe2 |
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
|
Jiri Slaby |
8cebe2 |
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
|
Jiri Slaby |
8cebe2 |
---
|
|
Jiri Slaby |
8cebe2 |
fs/btrfs/extent_io.c | 28 ++++++++++++----------------
|
|
Jiri Slaby |
8cebe2 |
1 file changed, 12 insertions(+), 16 deletions(-)
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
|
|
Jiri Slaby |
8cebe2 |
index 3ef90e91d8be..0c7b61f72478 100644
|
|
Jiri Slaby |
8cebe2 |
--- a/fs/btrfs/extent_io.c
|
|
Jiri Slaby |
8cebe2 |
+++ b/fs/btrfs/extent_io.c
|
|
Jiri Slaby |
8cebe2 |
@@ -4463,29 +4463,25 @@ try_submit_last:
|
|
Jiri Slaby |
8cebe2 |
}
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
/*
|
|
Jiri Slaby |
8cebe2 |
- * Sanity check for fiemap cache
|
|
Jiri Slaby |
8cebe2 |
+ * Emit last fiemap cache
|
|
Jiri Slaby |
8cebe2 |
*
|
|
Jiri Slaby |
8cebe2 |
- * All fiemap cache should be submitted by emit_fiemap_extent()
|
|
Jiri Slaby |
8cebe2 |
- * Iteration should be terminated either by last fiemap extent or
|
|
Jiri Slaby |
8cebe2 |
- * fieinfo->fi_extents_max.
|
|
Jiri Slaby |
8cebe2 |
- * So no cached fiemap should exist.
|
|
Jiri Slaby |
8cebe2 |
+ * The last fiemap cache may still be cached in the following case:
|
|
Jiri Slaby |
8cebe2 |
+ * 0 4k 8k
|
|
Jiri Slaby |
8cebe2 |
+ * |<- Fiemap range ->|
|
|
Jiri Slaby |
8cebe2 |
+ * |<------------ First extent ----------->|
|
|
Jiri Slaby |
8cebe2 |
+ *
|
|
Jiri Slaby |
8cebe2 |
+ * In this case, the first extent range will be cached but not emitted.
|
|
Jiri Slaby |
8cebe2 |
+ * So we must emit it before ending extent_fiemap().
|
|
Jiri Slaby |
8cebe2 |
*/
|
|
Jiri Slaby |
8cebe2 |
-static int check_fiemap_cache(struct btrfs_fs_info *fs_info,
|
|
Jiri Slaby |
8cebe2 |
- struct fiemap_extent_info *fieinfo,
|
|
Jiri Slaby |
8cebe2 |
- struct fiemap_cache *cache)
|
|
Jiri Slaby |
8cebe2 |
+static int emit_last_fiemap_cache(struct btrfs_fs_info *fs_info,
|
|
Jiri Slaby |
8cebe2 |
+ struct fiemap_extent_info *fieinfo,
|
|
Jiri Slaby |
8cebe2 |
+ struct fiemap_cache *cache)
|
|
Jiri Slaby |
8cebe2 |
{
|
|
Jiri Slaby |
8cebe2 |
int ret;
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
if (!cache->cached)
|
|
Jiri Slaby |
8cebe2 |
return 0;
|
|
Jiri Slaby |
8cebe2 |
|
|
Jiri Slaby |
8cebe2 |
- /* Small and recoverbale problem, only to info developer */
|
|
Jiri Slaby |
8cebe2 |
-#ifdef CONFIG_BTRFS_DEBUG
|
|
Jiri Slaby |
8cebe2 |
- WARN_ON(1);
|
|
Jiri Slaby |
8cebe2 |
-#endif
|
|
Jiri Slaby |
8cebe2 |
- btrfs_warn(fs_info,
|
|
Jiri Slaby |
8cebe2 |
- "unhandled fiemap cache detected: offset=%llu phys=%llu len=%llu flags=0x%x",
|
|
Jiri Slaby |
8cebe2 |
- cache->offset, cache->phys, cache->len, cache->flags);
|
|
Jiri Slaby |
8cebe2 |
ret = fiemap_fill_next_extent(fieinfo, cache->offset, cache->phys,
|
|
Jiri Slaby |
8cebe2 |
cache->len, cache->flags);
|
|
Jiri Slaby |
8cebe2 |
cache->cached = false;
|
|
Jiri Slaby |
8cebe2 |
@@ -4701,7 +4697,7 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
|
|
Jiri Slaby |
8cebe2 |
}
|
|
Jiri Slaby |
8cebe2 |
out_free:
|
|
Jiri Slaby |
8cebe2 |
if (!ret)
|
|
Jiri Slaby |
8cebe2 |
- ret = check_fiemap_cache(root->fs_info, fieinfo, &cache);
|
|
Jiri Slaby |
8cebe2 |
+ ret = emit_last_fiemap_cache(root->fs_info, fieinfo, &cache);
|
|
Jiri Slaby |
8cebe2 |
free_extent_map(em);
|
|
Jiri Slaby |
8cebe2 |
out:
|
|
Jiri Slaby |
8cebe2 |
btrfs_free_path(path);
|
|
Jiri Slaby |
8cebe2 |
--
|
|
Jiri Slaby |
8cebe2 |
2.14.2
|
|
Jiri Slaby |
8cebe2 |
|