diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-20 09:35:24 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-08-20 09:35:24 -0700 |
commit | 95f858546aec320a904842f9195d4b4c1c51f479 (patch) | |
tree | 0e3619beb3699ffaedf7a47a12ca42fca7ed35cf | |
parent | 50a60b8c17c2894c415c7374ab373a03b0bf2003 (diff) | |
download | stable-queue-95f858546aec320a904842f9195d4b4c1c51f479.tar.gz |
3.0 patches
-rw-r--r-- | queue-3.0/btrfs-fix-an-oops-of-log-replay.patch | 88 | ||||
-rw-r--r-- | queue-3.0/series | 1 |
2 files changed, 89 insertions, 0 deletions
diff --git a/queue-3.0/btrfs-fix-an-oops-of-log-replay.patch b/queue-3.0/btrfs-fix-an-oops-of-log-replay.patch new file mode 100644 index 0000000000..c3fe8a8f6d --- /dev/null +++ b/queue-3.0/btrfs-fix-an-oops-of-log-replay.patch @@ -0,0 +1,88 @@ +From 34f3e4f23ca3d259fe078f62a128d97ca83508ef Mon Sep 17 00:00:00 2001 +From: liubo <liubo2009@cn.fujitsu.com> +Date: Sat, 6 Aug 2011 08:35:23 +0000 +Subject: Btrfs: fix an oops of log replay + +From: liubo <liubo2009@cn.fujitsu.com> + +commit 34f3e4f23ca3d259fe078f62a128d97ca83508ef upstream. + +When btrfs recovers from a crash, it may hit the oops below: + +------------[ cut here ]------------ +kernel BUG at fs/btrfs/inode.c:4580! +[...] +RIP: 0010:[<ffffffffa03df251>] [<ffffffffa03df251>] btrfs_add_link+0x161/0x1c0 [btrfs] +[...] +Call Trace: + [<ffffffffa03e7b31>] ? btrfs_inode_ref_index+0x31/0x80 [btrfs] + [<ffffffffa04054e9>] add_inode_ref+0x319/0x3f0 [btrfs] + [<ffffffffa0407087>] replay_one_buffer+0x2c7/0x390 [btrfs] + [<ffffffffa040444a>] walk_down_log_tree+0x32a/0x480 [btrfs] + [<ffffffffa0404695>] walk_log_tree+0xf5/0x240 [btrfs] + [<ffffffffa0406cc0>] btrfs_recover_log_trees+0x250/0x350 [btrfs] + [<ffffffffa0406dc0>] ? btrfs_recover_log_trees+0x350/0x350 [btrfs] + [<ffffffffa03d18b2>] open_ctree+0x1442/0x17d0 [btrfs] +[...] + +This comes from that while replaying an inode ref item, we forget to +check those old conflicting DIR_ITEM and DIR_INDEX items in fs/file tree, +then we will come to conflict corners which lead to BUG_ON(). + +Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com> +Tested-by: Andy Lutomirski <luto@mit.edu> +Signed-off-by: Chris Mason <chris.mason@oracle.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> + +--- + fs/btrfs/tree-log.c | 28 ++++++++++++++++++++++++---- + 1 file changed, 24 insertions(+), 4 deletions(-) + +--- a/fs/btrfs/tree-log.c ++++ b/fs/btrfs/tree-log.c +@@ -799,14 +799,15 @@ static noinline int add_inode_ref(struct + struct extent_buffer *eb, int slot, + struct btrfs_key *key) + { +- struct inode *dir; +- int ret; + struct btrfs_inode_ref *ref; ++ struct btrfs_dir_item *di; ++ struct inode *dir; + struct inode *inode; +- char *name; +- int namelen; + unsigned long ref_ptr; + unsigned long ref_end; ++ char *name; ++ int namelen; ++ int ret; + int search_done = 0; + + /* +@@ -909,6 +910,25 @@ again: + } + btrfs_release_path(path); + ++ /* look for a conflicting sequence number */ ++ di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir), ++ btrfs_inode_ref_index(eb, ref), ++ name, namelen, 0); ++ if (di && !IS_ERR(di)) { ++ ret = drop_one_dir_item(trans, root, path, dir, di); ++ BUG_ON(ret); ++ } ++ btrfs_release_path(path); ++ ++ /* look for a conflicing name */ ++ di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir), ++ name, namelen, 0); ++ if (di && !IS_ERR(di)) { ++ ret = drop_one_dir_item(trans, root, path, dir, di); ++ BUG_ON(ret); ++ } ++ btrfs_release_path(path); ++ + insert: + /* insert our name */ + ret = btrfs_add_link(trans, dir, inode, name, namelen, 0, diff --git a/queue-3.0/series b/queue-3.0/series index a18651fede..5661032c71 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -12,3 +12,4 @@ nfsv4.1-return-nfs4err_badsession-to-callbacks-during.patch x86-mtrr-lock-stop-machine-during-mtrr-rendezvous-sequence.patch btrfs-detect-wether-a-device-supports-discard.patch loop-fix-deadlock-when-sysfs-and-loop_clr_fd-race-against.patch +btrfs-fix-an-oops-of-log-replay.patch |