--- /dev/null
+From bbe9051441effce51c9a533d2c56440df64db2d7 Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Fri, 19 Sep 2014 15:43:34 -0400
+Subject: Btrfs: fix build_backref_tree issue with multiple shared blocks
+
+From: Josef Bacik <jbacik@fb.com>
+
+commit bbe9051441effce51c9a533d2c56440df64db2d7 upstream.
+
+Marc Merlin sent me a broken fs image months ago where it would blow up in the
+upper->checked BUG_ON() in build_backref_tree. This is because we had a
+scenario like this
+
+block a -- level 4 (not shared)
+ |
+block b -- level 3 (reloc block, shared)
+ |
+block c -- level 2 (not shared)
+ |
+block d -- level 1 (shared)
+ |
+block e -- level 0 (shared)
+
+We go to build a backref tree for block e, we notice block d is shared and add
+it to the list of blocks to lookup it's backrefs for. Now when we loop around
+we will check edges for the block, so we will see we looked up block c last
+time. So we lookup block d and then see that the block that points to it is
+block c and we can just skip that edge since we've already been up this path.
+The problem is because we clear need_check when we see block d (as it is shared)
+we never add block b as needing to be checked. And because block c is in our
+path already we bail out before we walk up to block b and add it to the backref
+check list.
+
+To fix this we need to reset need_check if we trip over a block that doesn't
+need to be checked. This will make sure that any subsequent blocks in the path
+as we're walking up afterwards are added to the list to be processed. With this
+patch I can now mount Marc's fs image and it'll complete the balance without
+panicing. Thanks,
+
+Reported-by: Marc MERLIN <marc@merlins.org>
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/relocation.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -967,8 +967,11 @@ again:
+ need_check = false;
+ list_add_tail(&edge->list[UPPER],
+ &list);
+- } else
++ } else {
++ if (upper->checked)
++ need_check = true;
+ INIT_LIST_HEAD(&edge->list[UPPER]);
++ }
+ } else {
+ upper = rb_entry(rb_node, struct backref_node,
+ rb_node);
--- /dev/null
+From 42383020beb1cfb05f5d330cc311931bc4917a97 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage@redhat.com>
+Date: Fri, 26 Sep 2014 08:30:06 -0700
+Subject: Btrfs: fix race in WAIT_SYNC ioctl
+
+From: Sage Weil <sage@redhat.com>
+
+commit 42383020beb1cfb05f5d330cc311931bc4917a97 upstream.
+
+We check whether transid is already committed via last_trans_committed and
+then search through trans_list for pending transactions. If
+last_trans_committed is updated by btrfs_commit_transaction after we check
+it (there is no locking), we will fail to find the committed transaction
+and return EINVAL to the caller. This has been observed occasionally by
+ceph-osd (which uses this ioctl heavily).
+
+Fix by rechecking whether the provided transid <= last_trans_committed
+after the search fails, and if so return 0.
+
+Signed-off-by: Sage Weil <sage@redhat.com>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/transaction.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -524,7 +524,6 @@ int btrfs_wait_for_commit(struct btrfs_r
+ if (transid <= root->fs_info->last_trans_committed)
+ goto out;
+
+- ret = -EINVAL;
+ /* find specified transaction */
+ spin_lock(&root->fs_info->trans_lock);
+ list_for_each_entry(t, &root->fs_info->trans_list, list) {
+@@ -540,9 +539,16 @@ int btrfs_wait_for_commit(struct btrfs_r
+ }
+ }
+ spin_unlock(&root->fs_info->trans_lock);
+- /* The specified transaction doesn't exist */
+- if (!cur_trans)
++
++ /*
++ * The specified transaction doesn't exist, or we
++ * raced with btrfs_commit_transaction
++ */
++ if (!cur_trans) {
++ if (transid > root->fs_info->last_trans_committed)
++ ret = -EINVAL;
+ goto out;
++ }
+ } else {
+ /* find newest transaction that is committing | committed */
+ spin_lock(&root->fs_info->trans_lock);
--- /dev/null
+From 1d52c78afbbf80b58299e076a159617d6b42fe3c Mon Sep 17 00:00:00 2001
+From: Josef Bacik <jbacik@fb.com>
+Date: Thu, 18 Sep 2014 11:30:44 -0400
+Subject: Btrfs: try not to ENOSPC on log replay
+
+From: Josef Bacik <jbacik@fb.com>
+
+commit 1d52c78afbbf80b58299e076a159617d6b42fe3c upstream.
+
+When doing log replay we may have to update inodes, which traditionally goes
+through our delayed inode stuff. This will try to move space over from the
+trans handle, but we don't reserve space in our trans handle on replay since we
+don't know how much we will need, so instead we try to flush. But because we
+have a trans handle open we won't flush anything, so if we are out of reserve
+space we will simply return ENOSPC. Since we know that if an operation made it
+into the log then we definitely had space before the box bought the farm then we
+don't need to worry about doing this space reservation. Use the
+fs_info->log_root_recovering flag to skip the delayed inode stuff and update the
+item directly. Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fb.com>
+Signed-off-by: Chris Mason <clm@fb.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/btrfs/inode.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3545,7 +3545,8 @@ noinline int btrfs_update_inode(struct b
+ * without delay
+ */
+ if (!btrfs_is_free_space_inode(inode)
+- && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
++ && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID
++ && !root->fs_info->log_root_recovering) {
+ btrfs_update_root_times(trans, root);
+
+ ret = btrfs_delayed_update_inode(trans, root, inode);
+btrfs-try-not-to-enospc-on-log-replay.patch
+btrfs-fix-build_backref_tree-issue-with-multiple-shared-blocks.patch
+btrfs-fix-race-in-wait_sync-ioctl.patch