From: Chris Mason Date: Sat, 19 Sep 2015 18:28:25 +0000 (-0700) Subject: Btrfs: deal with duplciates during extent_map insertion in btrfs_get_extent X-Git-Tag: v4.1.12-124.31.3~1212 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=54148c1a0db0cb5e2bb5fc6618baf9c5939db22c;p=users%2Fjedix%2Flinux-maple.git Btrfs: deal with duplciates during extent_map insertion in btrfs_get_extent Orabug: 27446668 When dealing with inline extents, btrfs_get_extent will incorrectly try to insert a duplicate extent_map. The dup hits -EEXIST from add_extent_map, but then we try to merge with the existing one and end up trying to insert a zero length extent_map. This actually works most of the time, except when there are extent maps past the end of the inline extent. rocksdb will trigger this sometimes because it preallocates an extent and then truncates down. Josef made a script to trigger with xfs_io: #!/bin/bash xfs_io -f -c "pwrite 0 1000" inline xfs_io -c "falloc -k 4k 1M" inline xfs_io -c "pread 0 1000" -c "fadvise -d 0 1000" -c "pread 0 1000" inline xfs_io -c "fadvise -d 0 1000" inline cat inline You'll get EIOs trying to read inline after this because add_extent_map is returning EEXIST Signed-off-by: Chris Mason (cherry picked from commit 8dff9c85341032767d7b519217a79ea04cd676b0) Signed-off-by: Liu Bo Reviewed-by: Anand Jain --- diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 37a43c15d921..c331e03e581c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -6945,7 +6945,18 @@ insert: * existing will always be non-NULL, since there must be * extent causing the -EEXIST. */ - if (start >= extent_map_end(existing) || + if (existing->start == em->start && + extent_map_end(existing) == extent_map_end(em) && + em->block_start == existing->block_start) { + /* + * these two extents are the same, it happens + * with inlines especially + */ + free_extent_map(em); + em = existing; + err = 0; + + } else if (start >= extent_map_end(existing) || start <= existing->start) { /* * The existing extent map is the one nearest to