Yan Zheng
2007-Oct-23 02:58 UTC
[btrfs-devel]A bug related to btrfs_search_slot and btrfs_extend_item
Hello, When we want to extent the size of some item in the tree, the typical function call sequence is: ... btrfs_search_slot((trans, root, key, path, size_to_extent, 1); ... btrfs_extend_item(trans, root, path, size_to_extent); There is a flaw in codes like this, to guarantee a leaf has enough free space, 'btrfs_search_slot' may call 'split_leaf' which split the leaf or insert a empty leaf. When 'split_leaf' insert a empty leaf, the lowest level of the btrfs_path points to the empty leaf. After 'btrfs_search_slot' return, 'btrfs_extend_item' is called, it will be in trouble to extent a non-exist item. Here is the test on a new formated btrfs with 8k node/leaf size. kernel module is build by the codes from btrfs-unstable trees at October 19. -- [root@localhost btrfs]# dd if=/dev/zero bs=4k count=1 of=1 2>/dev/null [root@localhost btrfs]# dd if=/dev/zero bs=4k count=1 of=2 2>/dev/null [root@localhost btrfs]# dd if=/dev/zero bs=2k count=1 of=3 2>/dev/null [root@localhost btrfs]# sync && debug-tree /dev/sdb1 ... leaf 36864 ptrs 13 free space 3139 generation 2 owner 3 ... leaf 69632 ptrs 3 free space 1772 generation 2 owner 3 item 0 key (7 12 0) itemoff 4008 itemsize 4105 inline extent data size 4096 item 1 key (8 1 0) itemoff 3904 itemsize 104 inode generation 0 size 2048 block group 0 mode 100644 links 1 item 2 key (8 12 0) itemoff 1847 itemsize 2057 inline extent data size 2048 ... Now the tree has a root node and two leaves, the first item in the second leaf is a inline extent. If we extent the inline extent to 6k, 'split_leaf' will insert a new leaf. -- [root@localhost btrfs]# dd conv=notrunc if=/dev/zero bs=2k count=1 seek=2 of=2 ... Kernel Oops ... (attachment is the full output of debug-tree) I feel this bug may also occur when extent a csum/dir item. Maybe btrfs_search_slot needs a new parameter, so that it knows what next operation is (insert item or extent item). Regards YZ -------------- next part -------------- A non-text attachment was scrubbed... Name: debug-tree.output Type: application/octet-stream Size: 5863 bytes Desc: not available Url : http://oss.oracle.com/pipermail/btrfs-devel/attachments/20071023/c2268f80/debug-tree.obj
Chris Mason
2007-Oct-23 06:19 UTC
[btrfs-devel]A bug related to btrfs_search_slot and btrfs_extend_item
On Tue, 23 Oct 2007 17:58:25 +0800 "Yan Zheng" <yanzheng@21cn.com> wrote:> Hello, > > When we want to extent the size of some item in the tree, the typical > function call sequence is: > ... > btrfs_search_slot((trans, root, key, path, size_to_extent, 1); > ... > btrfs_extend_item(trans, root, path, size_to_extent); > > There is a flaw in codes like this, to guarantee a leaf has enough > free space, 'btrfs_search_slot' may call 'split_leaf' which split the > leaf or insert a empty leaf. When 'split_leaf' insert a empty leaf, > the lowest level of the btrfs_path points to the empty leaf. After > 'btrfs_search_slot' return, 'btrfs_extend_item' is called, it will be > in trouble to extent a non-exist item.Yes, I've fixed a few mistakes in this area, but I think you're right, I need to add a parameter to search_slot that indicates insert vs extend. Thanks for this test case! -chris