Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiri Bohac <jbohac@suse.cz>2012-08-03 11:02:17 +0200
committerJiri Bohac <jbohac@suse.cz>2012-08-03 11:02:17 +0200
commit358029eeb9381359c32371e577c908a28d6a2d89 (patch)
tree3fca9ef3cddcf7e24c22847e7cc72772c408e296
parent124aaa2d6fa98d186e80aa66badb4e6a14925ef2 (diff)
parentcf233f6f5cc178bf23de3a0aff98731ff43be9ab (diff)
Merge branch 'SLE11-SP2' of kerncvs.suse.de:/home/git/kernel-source into SLE11-SP2
-rw-r--r--kernel-source.changes85
-rw-r--r--patches.fixes/md-raid0-size-fix34
-rw-r--r--patches.fixes/reiserfs-fix-deadlock-in-quota-code54
-rw-r--r--patches.fixes/rt2800-add-chipset-revision-rt5390r-support67
-rw-r--r--patches.fixes/silence-weird-name-warning36
-rw-r--r--patches.suse/btrfs-8096-avoid-sleeping-in-verify_parent_transid-while-.patch218
-rw-r--r--patches.suse/btrfs-8097-fix-btrfs_release_extent_buffer_page-with-the-.patch40
-rw-r--r--patches.suse/btrfs-8098-do-not-check-delalloc-when-updating-disk_i_siz.patch80
-rw-r--r--patches.suse/btrfs-8102-look-into-the-extent-during-find_all_leafs.patch433
-rw-r--r--patches.suse/btrfs-8103-don-t-set-for_cow-parameter-for-tree-block-fun.patch212
-rw-r--r--patches.suse/btrfs-8105-fix-defrag-regression.patch177
-rw-r--r--patches.suse/btrfs-8106-fix-missing-inherited-flag-in-rename.patch46
-rw-r--r--patches.suse/btrfs-8107-do-not-resize-a-seeding-device.patch37
-rw-r--r--patches.suse/btrfs-8108-cast-devid-to-unsigned-long-long-for-printk-ll.patch33
-rw-r--r--patches.suse/btrfs-8109-add-a-missing-spin_lock.patch39
-rw-r--r--patches.suse/btrfs-8111-restore-restriper-state-on-all-mounts.patch139
-rw-r--r--patches.suse/btrfs-8112-resume-balance-on-rw-re-mounts-properly.patch139
-rw-r--r--patches.suse/btrfs-8114-fix-tree-log-remove-space-corner-case.patch222
-rw-r--r--patches.suse/btrfs-8115-hold-a-ref-on-the-inode-during-writepages.patch63
-rw-r--r--patches.suse/btrfs-8117-do-not-return-EINVAL-instead-of-ENOMEM-from-op.patch32
-rw-r--r--patches.suse/btrfs-8118-do-not-ignore-errors-from-btrfs_cleanup_fs_roo.patch36
-rw-r--r--patches.suse/btrfs-8119-fix-error-handling-in-__add_reloc_root.patch37
-rw-r--r--patches.suse/btrfs-8120-return-error-of-btrfs_update_inode-to-caller.patch50
-rw-r--r--patches.suse/btrfs-8121-fix-typo-in-cow_file_range_async-and-async_cow.patch42
-rw-r--r--patches.suse/btrfs-8122-fix-btrfs_is_free_space_inode-to-recognize-btr.patch40
-rw-r--r--patches.suse/btrfs-8123-kill-root-from-btrfs_is_free_space_inode.patch149
-rw-r--r--patches.suse/btrfs-8125-zero-unused-bytes-in-inode-item.patch48
-rw-r--r--patches.suse/btrfs-update-message-levels.patch142
-rw-r--r--series.conf27
29 files changed, 2676 insertions, 81 deletions
diff --git a/kernel-source.changes b/kernel-source.changes
index 35a56cf496..181da5c6ac 100644
--- a/kernel-source.changes
+++ b/kernel-source.changes
@@ -1,4 +1,89 @@
-------------------------------------------------------------------
+Fri Aug 3 04:26:48 CEST 2012 - jeffm@suse.com
+
+- patches.fixes/rt2800-add-chipset-revision-rt5390r-support:
+ rt2800: add chipset revision RT5390R support (bnc#772566).
+
+-------------------------------------------------------------------
+Fri Aug 3 03:52:04 CEST 2012 - jeffm@suse.com
+
+- patches.fixes/reiserfs-fix-deadlock-in-quota-code: reiserfs:
+ fix deadlocks with quotas (bnc#774285).
+
+-------------------------------------------------------------------
+Fri Aug 3 02:56:26 CEST 2012 - dsterba@suse.cz
+
+ btrfs fixes (3.3-3.5+)
+- patches.suse/btrfs-8096-avoid-sleeping-in-verify_parent_transid-while-.patch:
+ Btrfs: avoid sleeping in verify_parent_transid while atomic
+ (FATE#306586).
+- patches.suse/btrfs-8097-fix-btrfs_release_extent_buffer_page-with-the-.patch:
+ Btrfs: fix btrfs_release_extent_buffer_page with the right
+ usage of num_extent_pages (FATE#306586).
+- patches.suse/btrfs-8098-do-not-check-delalloc-when-updating-disk_i_siz.patch:
+ Btrfs: do not check delalloc when updating disk_i_size
+ (FATE#306586).
+- patches.suse/btrfs-8102-look-into-the-extent-during-find_all_leafs.patch:
+ Btrfs: look into the extent during find_all_leafs (FATE#306586).
+- patches.suse/btrfs-8103-don-t-set-for_cow-parameter-for-tree-block-fun.patch:
+ Btrfs: don't set for_cow parameter for tree block functions
+ (FATE#306586).
+- patches.suse/btrfs-8105-fix-defrag-regression.patch: Btrfs:
+ fix defrag regression (FATE#306586).
+- patches.suse/btrfs-8106-fix-missing-inherited-flag-in-rename.patch:
+ Btrfs: fix missing inherited flag in rename (FATE#306586).
+- patches.suse/btrfs-8107-do-not-resize-a-seeding-device.patch:
+ Btrfs: do not resize a seeding device (FATE#306586).
+- patches.suse/btrfs-8108-cast-devid-to-unsigned-long-long-for-printk-ll.patch:
+ Btrfs: cast devid to unsigned long long for printk %llu
+ (FATE#306586).
+- patches.suse/btrfs-8109-add-a-missing-spin_lock.patch: Btrfs:
+ add a missing spin_lock (FATE#306586).
+- patches.suse/btrfs-8111-restore-restriper-state-on-all-mounts.patch:
+ Btrfs: restore restriper state on all mounts (FATE#306586).
+- patches.suse/btrfs-8112-resume-balance-on-rw-re-mounts-properly.patch:
+ Btrfs: resume balance on rw (re)mounts properly (FATE#306586).
+- patches.suse/btrfs-8114-fix-tree-log-remove-space-corner-case.patch:
+ Btrfs: fix tree log remove space corner case (FATE#306586).
+- patches.suse/btrfs-8115-hold-a-ref-on-the-inode-during-writepages.patch:
+ Btrfs: hold a ref on the inode during writepages (FATE#306586).
+- patches.suse/btrfs-8117-do-not-return-EINVAL-instead-of-ENOMEM-from-op.patch:
+ Btrfs: do not return EINVAL instead of ENOMEM from open_ctree()
+ (FATE#306586).
+- patches.suse/btrfs-8118-do-not-ignore-errors-from-btrfs_cleanup_fs_roo.patch:
+ Btrfs: do not ignore errors from btrfs_cleanup_fs_roots()
+ when mounting (FATE#306586).
+- patches.suse/btrfs-8119-fix-error-handling-in-__add_reloc_root.patch:
+ Btrfs: fix error handling in __add_reloc_root() (FATE#306586).
+- patches.suse/btrfs-8120-return-error-of-btrfs_update_inode-to-caller.patch:
+ Btrfs: return error of btrfs_update_inode() to caller
+ (FATE#306586).
+- patches.suse/btrfs-8121-fix-typo-in-cow_file_range_async-and-async_cow.patch:
+ Btrfs: fix typo in cow_file_range_async and async_cow_submit
+ (FATE#306586).
+- patches.suse/btrfs-8122-fix-btrfs_is_free_space_inode-to-recognize-btr.patch:
+ Btrfs: fix btrfs_is_free_space_inode to recognize btree inode
+ (FATE#306586).
+- patches.suse/btrfs-8123-kill-root-from-btrfs_is_free_space_inode.patch:
+ Btrfs: kill root from btrfs_is_free_space_inode (FATE#306586).
+- patches.suse/btrfs-8125-zero-unused-bytes-in-inode-item.patch:
+ Btrfs: zero unused bytes in inode item (FATE#306586).
+- patches.suse/btrfs-update-message-levels.patch: Refresh.
+
+-------------------------------------------------------------------
+Fri Aug 3 02:52:58 CEST 2012 - nfbrown@suse.de
+
+- patches.fixes/silence-weird-name-warning: VFS: avoid
+ prepend_path warning about d_obtain_alias aliases (bnc#773006).
+
+-------------------------------------------------------------------
+Fri Aug 3 02:45:48 CEST 2012 - nfbrown@suse.de
+
+- patches.fixes/md-raid0-size-fix: md: Don't truncate size at 4TB
+ for RAID0 and Linear (email to Linux <linux@lists.novell.com>
+ (Big md broken after update)).
+
+-------------------------------------------------------------------
Thu Aug 2 20:50:49 CEST 2012 - jbohac@suse.cz
- patches.fixes/ntp-avoid-printk-under-xtime_lock.patch: ntp:
diff --git a/patches.fixes/md-raid0-size-fix b/patches.fixes/md-raid0-size-fix
new file mode 100644
index 0000000000..83fbbea899
--- /dev/null
+++ b/patches.fixes/md-raid0-size-fix
@@ -0,0 +1,34 @@
+From: NeilBrown <neilb@suse.de>
+Subject: md: Don't truncate size at 4TB for RAID0 and Linear
+Patch-mainline: 3.6
+References: email to Linux <linux@lists.novell.com> (Big md broken after update)
+
+A recent change to 0.90 metadata handling truncated size to 4TB as that is
+all that 0.90 can record.
+However for RAID0 and Linear, 0.90 doesn't need to record the size, so
+this truncation is not needed and causes working arrays to become too small.
+
+So avoid the truncation for RAID0 and Linear
+
+Signed-off-by: Neil Brown <neilb@suse.de>
+
+---
+ drivers/md/md.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- linux-3.0-SLE11-SP2.orig/drivers/md/md.c
++++ linux-3.0-SLE11-SP2/drivers/md/md.c
+@@ -1115,8 +1115,11 @@ static int super_90_load(mdk_rdev_t *rde
+ ret = 0;
+ }
+ rdev->sectors = rdev->sb_start;
+- /* Limit to 4TB as metadata cannot record more than that */
+- if (rdev->sectors >= (2ULL << 32))
++ /* Limit to 4TB as metadata cannot record more than that.
++ * (not needed for Linear and RAID0 as metadata doesn't
++ * record this size
++ */
++ if (rdev->sectors >= (2ULL << 32) && sb->level >= 1)
+ rdev->sectors = (2ULL << 32) - 2;
+
+ if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1)
diff --git a/patches.fixes/reiserfs-fix-deadlock-in-quota-code b/patches.fixes/reiserfs-fix-deadlock-in-quota-code
new file mode 100644
index 0000000000..7c5f6f90df
--- /dev/null
+++ b/patches.fixes/reiserfs-fix-deadlock-in-quota-code
@@ -0,0 +1,54 @@
+From: Jeff Mahoney <jeffm@suse.com>
+Subject: reiserfs: fix deadlocks with quotas
+Patch-mainline: Submitted to linux-fsdevel 2 Aug 2012
+References: bnc#774285
+
+The BKL push-down for reiserfs made lock recursion a special case that needs
+to be handled explicitly. One of the cases that was unhandled is dropping
+the quota during inode eviction. Both reiserfs_evict_inode and
+reiserfs_write_dquot take the write lock, but when the journal lock is
+taken it only drops one the references. The locking rules are that the journal
+lock be acquired before the write lock so leaving the reference open leads
+to a ABBA deadlock.
+
+This patch pushes the unlock up before end_writeback and avoids the recursive
+locking.
+
+Another ABBA situation can occur when the write lock is dropped while reading
+the bitmap buffer while in the quota code. When the lock is reacquired, it
+will deadlock against dquot->dq_lock and dqopt->dqio_mutex in the dquot_acquire
+path. It's safe to retain the lock across the bread and should be cached under
+write load.
+
+Signed-off-by: Jeff Mahoney <jeffm@suse.com>
+---
+ fs/reiserfs/bitmap.c | 2 --
+ fs/reiserfs/inode.c | 2 +-
+ 2 files changed, 1 insertion(+), 3 deletions(-)
+
+--- a/fs/reiserfs/bitmap.c
++++ b/fs/reiserfs/bitmap.c
+@@ -1334,9 +1334,7 @@ struct buffer_head *reiserfs_read_bitmap
+ else if (bitmap == 0)
+ block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
+
+- reiserfs_write_unlock(sb);
+ bh = sb_bread(sb, block);
+- reiserfs_write_lock(sb);
+ if (bh == NULL)
+ reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%u) "
+ "reading failed", __func__, block);
+--- a/fs/reiserfs/inode.c
++++ b/fs/reiserfs/inode.c
+@@ -76,10 +76,10 @@ void reiserfs_evict_inode(struct inode *
+ ;
+ }
+ out:
++ reiserfs_write_unlock_once(inode->i_sb, depth);
+ end_writeback(inode); /* note this must go after the journal_end to prevent deadlock */
+ dquot_drop(inode);
+ inode->i_blocks = 0;
+- reiserfs_write_unlock_once(inode->i_sb, depth);
+ return;
+
+ no_delete:
diff --git a/patches.fixes/rt2800-add-chipset-revision-rt5390r-support b/patches.fixes/rt2800-add-chipset-revision-rt5390r-support
new file mode 100644
index 0000000000..56b69214c6
--- /dev/null
+++ b/patches.fixes/rt2800-add-chipset-revision-rt5390r-support
@@ -0,0 +1,67 @@
+From: Anisse Astier <anisse@astier.eu>
+Subject: rt2800: add chipset revision RT5390R support
+Git-commit: 0586a11b5cc51413240e6688936e2edac9c2918e
+Patch-Mainline: v3.5-rc1
+References: bnc#772566
+
+About 70% of the chips with revision RT5390R initialize incorrectly, using
+the auxiliary antenna instead of the main one. The net result is that
+signal reception is very poor (no AP further than 1M).
+
+This chipset differs from RT5390 and RT5390F by its support of hardware
+antenna diversity. Therefore antenna selection should be done
+differently, by disabling software features and previously selected
+antenna.
+
+This changeset does just that, and makes all RT5390R work properly.
+
+This is based on Ralink's 2012_03_22_RT5572_Linux_STA_v2.6.0.0_DPO
+driver.
+
+Signed-off-by: Anisse Astier <anisse@astier.eu>
+Signed-off-by: John W. Linville <linville@tuxdriver.com>
+Signed-off-by: Ben Chou <bchou@suse.com>
+Acked-by: Jeff Mahoney <jeffm@suse.com>
+---
+ drivers/net/wireless/rt2x00/rt2800.h | 1 +
+ drivers/net/wireless/rt2x00/rt2800lib.c | 12 ++++++++++++
+ 2 files changed, 13 insertions(+)
+
+--- a/drivers/net/wireless/rt2x00/rt2800.h
++++ b/drivers/net/wireless/rt2x00/rt2800.h
+@@ -83,6 +83,7 @@
+ #define REV_RT3090E 0x0211
+ #define REV_RT3390E 0x0211
+ #define REV_RT5390F 0x0502
++#define REV_RT5390R 0x1502
+
+ /*
+ * Signal information.
+--- a/drivers/net/wireless/rt2x00/rt2800lib.c
++++ b/drivers/net/wireless/rt2x00/rt2800lib.c
+@@ -3478,6 +3478,13 @@ static int rt2800_init_bbp(struct rt2x00
+ rt2800_register_write(rt2x00dev, GPIO_CTRL_CFG, reg);
+ }
+
++ /* This chip has hardware antenna diversity*/
++ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
++ rt2800_bbp_write(rt2x00dev, 150, 0); /* Disable Antenna Software OFDM */
++ rt2800_bbp_write(rt2x00dev, 151, 0); /* Disable Antenna Software CCK */
++ rt2800_bbp_write(rt2x00dev, 154, 0); /* Clear previously selected antenna */
++ }
++
+ rt2800_bbp_read(rt2x00dev, 152, &value);
+ if (ant == 0)
+ rt2x00_set_field8(&value, BBP152_RX_DEFAULT_ANT, 1);
+@@ -4407,6 +4414,11 @@ int rt2800_init_eeprom(struct rt2x00_dev
+ rt2x00dev->default_ant.rx = ANTENNA_A;
+ }
+
++ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390R)) {
++ rt2x00dev->default_ant.tx = ANTENNA_HW_DIVERSITY; /* Unused */
++ rt2x00dev->default_ant.rx = ANTENNA_HW_DIVERSITY; /* Unused */
++ }
++
+ /*
+ * Determine external LNA informations.
+ */
diff --git a/patches.fixes/silence-weird-name-warning b/patches.fixes/silence-weird-name-warning
new file mode 100644
index 0000000000..e425a2a6fd
--- /dev/null
+++ b/patches.fixes/silence-weird-name-warning
@@ -0,0 +1,36 @@
+From: NeilBrown <neilb@suse.de>
+Subject: VFS: avoid prepend_path warning about d_obtain_alias aliases.
+Patch-mainline: 3.6
+References: bnc#773006
+
+If you lazy-unmount an NFS filesystem while some process holds a file open
+in the filesystem then "lsof" that process, the kernel will complain
+ Root dentry has weird name <>
+This is because nfs uses d_obtain_alias to create a dentry for the
+filesystem root.
+
+So change d_obtain_alias to create a similar alias to d_alloc_root()
+
+Signed-off-by: Neil Brown <neilb@suse.de>
+
+---
+ fs/dcache.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- linux-3.0-SLE11-SP2.orig/fs/dcache.c
++++ linux-3.0-SLE11-SP2/fs/dcache.c
+@@ -1580,10 +1580,13 @@ static struct dentry * d_find_any_alias(
+ * To make it easier to use in export operations a %NULL or IS_ERR inode may
+ * be passed in and will be the error will be propagate to the return value,
+ * with a %NULL @inode replaced by ERR_PTR(-ESTALE).
++ *
++ * This alias can sometimes be seen by prepend_path, so make it look
++ * the same as a d_alloc_root alias.
+ */
+ struct dentry *d_obtain_alias(struct inode *inode)
+ {
+- static const struct qstr anonstring = { .name = "" };
++ static const struct qstr anonstring = { .name = "/", .len = 1 };
+ struct dentry *tmp;
+ struct dentry *res;
+
diff --git a/patches.suse/btrfs-8096-avoid-sleeping-in-verify_parent_transid-while-.patch b/patches.suse/btrfs-8096-avoid-sleeping-in-verify_parent_transid-while-.patch
new file mode 100644
index 0000000000..9e7a060e67
--- /dev/null
+++ b/patches.suse/btrfs-8096-avoid-sleeping-in-verify_parent_transid-while-.patch
@@ -0,0 +1,218 @@
+From: Chris Mason <chris.mason@oracle.com>
+Date: Sun, 6 May 2012 07:23:47 -0400
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: b9fab919b748c7b39c19ff236ed6c5682c266dde
+Subject: [PATCH] Btrfs: avoid sleeping in verify_parent_transid while
+ atomic
+
+verify_parent_transid needs to lock the extent range to make
+sure no IO is underway, and so it can safely clear the
+uptodate bits if our checks fail.
+
+But, a few callers are using it with spinlocks held. Most
+of the time, the generation numbers are going to match, and
+we don't want to switch to a blocking lock just for the error
+case. This adds an atomic flag to verify_parent_transid,
+and changes it to return EAGAIN if it needs to block to
+properly verifiy things.
+
+Signed-off-by: Chris Mason <chris.mason@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/ctree.c | 26 +++++++++++++++++---------
+ fs/btrfs/disk-io.c | 19 +++++++++++++------
+ fs/btrfs/disk-io.h | 3 ++-
+ fs/btrfs/extent-tree.c | 2 +-
+ fs/btrfs/tree-log.c | 2 +-
+ 5 files changed, 34 insertions(+), 18 deletions(-)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -712,7 +712,7 @@ int btrfs_realloc_node(struct btrfs_tran
+
+ cur = btrfs_find_tree_block(root, blocknr, blocksize);
+ if (cur)
+- uptodate = btrfs_buffer_uptodate(cur, gen);
++ uptodate = btrfs_buffer_uptodate(cur, gen, 0);
+ else
+ uptodate = 0;
+ if (!cur || !uptodate) {
+@@ -1347,7 +1347,12 @@ static noinline int reada_for_balance(st
+ block1 = btrfs_node_blockptr(parent, slot - 1);
+ gen = btrfs_node_ptr_generation(parent, slot - 1);
+ eb = btrfs_find_tree_block(root, block1, blocksize);
+- if (eb && btrfs_buffer_uptodate(eb, gen))
++ /*
++ * if we get -eagain from btrfs_buffer_uptodate, we
++ * don't want to return eagain here. That will loop
++ * forever
++ */
++ if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
+ block1 = 0;
+ free_extent_buffer(eb);
+ }
+@@ -1355,7 +1360,7 @@ static noinline int reada_for_balance(st
+ block2 = btrfs_node_blockptr(parent, slot + 1);
+ gen = btrfs_node_ptr_generation(parent, slot + 1);
+ eb = btrfs_find_tree_block(root, block2, blocksize);
+- if (eb && btrfs_buffer_uptodate(eb, gen))
++ if (eb && btrfs_buffer_uptodate(eb, gen, 1) != 0)
+ block2 = 0;
+ free_extent_buffer(eb);
+ }
+@@ -1493,8 +1498,9 @@ read_block_for_search(struct btrfs_trans
+
+ tmp = btrfs_find_tree_block(root, blocknr, blocksize);
+ if (tmp) {
+- if (btrfs_buffer_uptodate(tmp, 0)) {
+- if (btrfs_buffer_uptodate(tmp, gen)) {
++ /* first we do an atomic uptodate check */
++ if (btrfs_buffer_uptodate(tmp, 0, 1) > 0) {
++ if (btrfs_buffer_uptodate(tmp, gen, 1) > 0) {
+ /*
+ * we found an up to date block without
+ * sleeping, return
+@@ -1512,8 +1518,9 @@ read_block_for_search(struct btrfs_trans
+ free_extent_buffer(tmp);
+ btrfs_set_path_blocking(p);
+
++ /* now we're allowed to do a blocking uptodate check */
+ tmp = read_tree_block(root, blocknr, blocksize, gen);
+- if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
++ if (tmp && btrfs_buffer_uptodate(tmp, gen, 0) > 0) {
+ *eb_ret = tmp;
+ return 0;
+ }
+@@ -1548,7 +1555,7 @@ read_block_for_search(struct btrfs_trans
+ * and give up so that our caller doesn't loop forever
+ * on our EAGAINs.
+ */
+- if (!btrfs_buffer_uptodate(tmp, 0))
++ if (!btrfs_buffer_uptodate(tmp, 0, 0))
+ ret = -EIO;
+ free_extent_buffer(tmp);
+ }
+@@ -3996,7 +4003,7 @@ again:
+ tmp = btrfs_find_tree_block(root, blockptr,
+ btrfs_level_size(root, level - 1));
+
+- if (tmp && btrfs_buffer_uptodate(tmp, gen)) {
++ if (tmp && btrfs_buffer_uptodate(tmp, gen, 1) > 0) {
+ free_extent_buffer(tmp);
+ break;
+ }
+@@ -4119,7 +4126,8 @@ next:
+ struct extent_buffer *cur;
+ cur = btrfs_find_tree_block(root, blockptr,
+ btrfs_level_size(root, level - 1));
+- if (!cur || !btrfs_buffer_uptodate(cur, gen)) {
++ if (!cur ||
++ btrfs_buffer_uptodate(cur, gen, 1) <= 0) {
+ slot++;
+ if (cur)
+ free_extent_buffer(cur);
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -322,7 +322,8 @@ static int csum_tree_block(struct btrfs_
+ * in the wrong place.
+ */
+ static int verify_parent_transid(struct extent_io_tree *io_tree,
+- struct extent_buffer *eb, u64 parent_transid)
++ struct extent_buffer *eb, u64 parent_transid,
++ int atomic)
+ {
+ struct extent_state *cached_state = NULL;
+ int ret;
+@@ -330,6 +331,9 @@ static int verify_parent_transid(struct
+ if (!parent_transid || btrfs_header_generation(eb) == parent_transid)
+ return 0;
+
++ if (atomic)
++ return -EAGAIN;
++
+ lock_extent_bits(io_tree, eb->start, eb->start + eb->len - 1,
+ 0, &cached_state);
+ if (extent_buffer_uptodate(io_tree, eb, cached_state) &&
+@@ -370,7 +374,7 @@ static int btree_read_extent_buffer_page
+ WAIT_COMPLETE,
+ btree_get_extent, mirror_num);
+ if (!ret &&
+- !verify_parent_transid(io_tree, eb, parent_transid))
++ !verify_parent_transid(io_tree, eb, parent_transid, 0))
+ return ret;
+
+ /*
+@@ -1249,7 +1253,7 @@ static int __must_check find_and_setup_r
+ root->commit_root = NULL;
+ root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
+ blocksize, generation);
+- if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
++ if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) {
+ free_extent_buffer(root->node);
+ root->node = NULL;
+ return -EIO;
+@@ -1400,7 +1404,7 @@ struct btrfs_root *btrfs_read_fs_root_no
+ blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
+ root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
+ blocksize, generation);
+- if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) {
++ if (!root->node || !btrfs_buffer_uptodate(root->node, generation, 0)) {
+ ret = -EIO;
+ goto error;
+ }
+@@ -3199,7 +3203,8 @@ int close_ctree(struct btrfs_root *root)
+ return 0;
+ }
+
+-int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid)
++int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
++ int atomic)
+ {
+ int ret;
+ struct inode *btree_inode = buf->first_page->mapping->host;
+@@ -3210,7 +3215,9 @@ int btrfs_buffer_uptodate(struct extent_
+ return ret;
+
+ ret = verify_parent_transid(&BTRFS_I(btree_inode)->io_tree, buf,
+- parent_transid);
++ parent_transid, atomic);
++ if (ret == -EAGAIN)
++ return ret;
+ return !ret;
+ }
+
+--- a/fs/btrfs/disk-io.h
++++ b/fs/btrfs/disk-io.h
+@@ -66,7 +66,8 @@ void btrfs_btree_balance_dirty(struct bt
+ void __btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr);
+ void btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root);
+ void btrfs_mark_buffer_dirty(struct extent_buffer *buf);
+-int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid);
++int btrfs_buffer_uptodate(struct extent_buffer *buf, u64 parent_transid,
++ int atomic);
+ int btrfs_set_buffer_uptodate(struct extent_buffer *buf);
+ int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid);
+ u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len);
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -6689,7 +6689,7 @@ static noinline int do_walk_down(struct
+ goto skip;
+ }
+
+- if (!btrfs_buffer_uptodate(next, generation)) {
++ if (!btrfs_buffer_uptodate(next, generation, 0)) {
+ btrfs_tree_unlock(next);
+ free_extent_buffer(next);
+ next = NULL;
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -279,7 +279,7 @@ static int process_one_buffer(struct btr
+ log->fs_info->extent_root,
+ eb->start, eb->len);
+
+- if (btrfs_buffer_uptodate(eb, gen)) {
++ if (btrfs_buffer_uptodate(eb, gen, 0)) {
+ if (wc->write)
+ btrfs_write_tree_block(eb);
+ if (wc->wait)
diff --git a/patches.suse/btrfs-8097-fix-btrfs_release_extent_buffer_page-with-the-.patch b/patches.suse/btrfs-8097-fix-btrfs_release_extent_buffer_page-with-the-.patch
new file mode 100644
index 0000000000..f566aecea0
--- /dev/null
+++ b/patches.suse/btrfs-8097-fix-btrfs_release_extent_buffer_page-with-the-.patch
@@ -0,0 +1,40 @@
+From: Wang Sheng-Hui <shhuiw@gmail.com>
+Date: Fri, 6 Apr 2012 14:35:31 +0800
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 39bab87ba6f4d8cce2b70c19e60233ad8030d7b4
+Subject: [PATCH] Btrfs: fix btrfs_release_extent_buffer_page with the
+ right usage of num_extent_pages
+
+num_extent_pages returns the number of pages in the specific range, not
+the index of the last page in the eb range.
+
+btrfs_release_extent_buffer_page is called with start_idx set 0 in current
+codes, so it's not a problem yet. But the logic is indeed wrong.
+
+Fix it here.
+
+Signed-off-by: Wang Sheng-Hui <shhuiw@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/extent_io.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -3679,12 +3679,15 @@ static void btrfs_release_extent_buffer_
+ unsigned long start_idx)
+ {
+ unsigned long index;
++ unsigned long num_pages;
+ struct page *page;
+
+ if (!eb->first_page)
+ return;
+
+ index = num_extent_pages(eb->start, eb->len);
++ num_pages = num_extent_pages(eb->start, eb->len);
++ index = start_idx + num_pages;
+ if (start_idx >= index)
+ return;
+
diff --git a/patches.suse/btrfs-8098-do-not-check-delalloc-when-updating-disk_i_siz.patch b/patches.suse/btrfs-8098-do-not-check-delalloc-when-updating-disk_i_siz.patch
new file mode 100644
index 0000000000..fa2daa09d9
--- /dev/null
+++ b/patches.suse/btrfs-8098-do-not-check-delalloc-when-updating-disk_i_siz.patch
@@ -0,0 +1,80 @@
+From: Josef Bacik <josef@redhat.com>
+Date: Wed, 2 May 2012 13:52:09 -0400
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 4e89915220e2f1341c757b610d0f0c3821f3a65f
+Subject: [PATCH] Btrfs: do not check delalloc when updating
+ disk_i_size
+
+We are checking delalloc to see if it is ok to update the i_size. There are
+2 cases it stops us from updating
+
+1) If there is delalloc between our current disk_i_size and this ordered
+extent
+
+2) If there is delalloc between our current ordered extent and the next
+ordered extent
+
+These tests are racy however since we can set delalloc for these ranges at
+any time. Also for the first case if we notice there is delalloc between
+disk_i_size and our ordered extent we will not update disk_i_size and assume
+that when that delalloc bit gets written out it will update everything
+properly. However if we crash before that we will have file extents outside
+of our i_size, which is not good, so this test is dangerous as well as racy.
+Thanks,
+
+Signed-off-by: Josef Bacik <josef@redhat.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/ordered-data.c | 19 +++----------------
+ 1 files changed, 3 insertions(+), 16 deletions(-)
+
+diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
+index 9807750..9565c02 100644
+--- a/fs/btrfs/ordered-data.c
++++ b/fs/btrfs/ordered-data.c
+@@ -751,7 +751,6 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
+ struct btrfs_ordered_extent *ordered)
+ {
+ struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
+- struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+ u64 disk_i_size;
+ u64 new_i_size;
+ u64 i_size_test;
+@@ -785,14 +784,6 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
+ }
+
+ /*
+- * we can't update the disk_isize if there are delalloc bytes
+- * between disk_i_size and this ordered extent
+- */
+- if (test_range_bit(io_tree, disk_i_size, offset - 1,
+- EXTENT_DELALLOC, 0, NULL)) {
+- goto out;
+- }
+- /*
+ * walk backward from this ordered extent to disk_i_size.
+ * if we find an ordered extent then we can't update disk i_size
+ * yet
+@@ -853,15 +844,11 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
+
+ /*
+ * i_size_test is the end of a region after this ordered
+- * extent where there are no ordered extents. As long as there
+- * are no delalloc bytes in this area, it is safe to update
+- * disk_i_size to the end of the region.
++ * extent where there are no ordered extents, we can safely set
++ * disk_i_size to this.
+ */
+- if (i_size_test > offset &&
+- !test_range_bit(io_tree, offset, i_size_test - 1,
+- EXTENT_DELALLOC, 0, NULL)) {
++ if (i_size_test > offset)
+ new_i_size = min_t(u64, i_size_test, i_size);
+- }
+ BTRFS_I(inode)->disk_i_size = new_i_size;
+ ret = 0;
+ out:
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8102-look-into-the-extent-during-find_all_leafs.patch b/patches.suse/btrfs-8102-look-into-the-extent-during-find_all_leafs.patch
new file mode 100644
index 0000000000..0cac4cae9e
--- /dev/null
+++ b/patches.suse/btrfs-8102-look-into-the-extent-during-find_all_leafs.patch
@@ -0,0 +1,433 @@
+From: Jan Schmidt <list.btrfs@jan-o-sch.net>
+Date: Thu, 17 May 2012 16:43:03 +0200
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 976b1908d97bd8cbd024ba7aafaa3fb637ea8e13
+Subject: [PATCH] Btrfs: look into the extent during find_all_leafs
+
+Before this patch we called find_all_leafs for a data extent, then called
+find_all_roots and then looked into the extent to grab the information
+we were seeking. This was done without holding the leaves locked to avoid
+deadlocks. However, this can obviouly race with concurrent tree
+modifications.
+
+Instead, we now look into the extent while we're holding the lock during
+find_all_leafs and store this information together with the leaf list.
+
+Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/backref.c | 240 ++++++++++++++++++++++++++++++++++------------------
+ fs/btrfs/backref.h | 2 +-
+ 2 files changed, 158 insertions(+), 84 deletions(-)
+
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
+index 366978c..fd13101 100644
+--- a/fs/btrfs/backref.c
++++ b/fs/btrfs/backref.c
+@@ -24,6 +24,79 @@
+ #include "delayed-ref.h"
+ #include "locking.h"
+
++struct extent_inode_elem {
++ u64 inum;
++ u64 offset;
++ struct extent_inode_elem *next;
++};
++
++static int check_extent_in_eb(struct btrfs_key *key, struct extent_buffer *eb,
++ struct btrfs_file_extent_item *fi,
++ u64 extent_item_pos,
++ struct extent_inode_elem **eie)
++{
++ u64 data_offset;
++ u64 data_len;
++ struct extent_inode_elem *e;
++
++ data_offset = btrfs_file_extent_offset(eb, fi);
++ data_len = btrfs_file_extent_num_bytes(eb, fi);
++
++ if (extent_item_pos < data_offset ||
++ extent_item_pos >= data_offset + data_len)
++ return 1;
++
++ e = kmalloc(sizeof(*e), GFP_NOFS);
++ if (!e)
++ return -ENOMEM;
++
++ e->next = *eie;
++ e->inum = key->objectid;
++ e->offset = key->offset + (extent_item_pos - data_offset);
++ *eie = e;
++
++ return 0;
++}
++
++static int find_extent_in_eb(struct extent_buffer *eb, u64 wanted_disk_byte,
++ u64 extent_item_pos,
++ struct extent_inode_elem **eie)
++{
++ u64 disk_byte;
++ struct btrfs_key key;
++ struct btrfs_file_extent_item *fi;
++ int slot;
++ int nritems;
++ int extent_type;
++ int ret;
++
++ /*
++ * from the shared data ref, we only have the leaf but we need
++ * the key. thus, we must look into all items and see that we
++ * find one (some) with a reference to our extent item.
++ */
++ nritems = btrfs_header_nritems(eb);
++ for (slot = 0; slot < nritems; ++slot) {
++ btrfs_item_key_to_cpu(eb, &key, slot);
++ if (key.type != BTRFS_EXTENT_DATA_KEY)
++ continue;
++ fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
++ extent_type = btrfs_file_extent_type(eb, fi);
++ if (extent_type == BTRFS_FILE_EXTENT_INLINE)
++ continue;
++ /* don't skip BTRFS_FILE_EXTENT_PREALLOC, we can handle that */
++ disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
++ if (disk_byte != wanted_disk_byte)
++ continue;
++
++ ret = check_extent_in_eb(&key, eb, fi, extent_item_pos, eie);
++ if (ret < 0)
++ return ret;
++ }
++
++ return 0;
++}
++
+ /*
+ * this structure records all encountered refs on the way up to the root
+ */
+@@ -103,15 +176,16 @@ static int __add_prelim_ref(struct list_head *head, u64 root_id,
+ }
+
+ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
+- struct ulist *parents,
+- struct extent_buffer *eb, int level,
+- u64 wanted_objectid, u64 wanted_disk_byte)
++ struct ulist *parents, int level,
++ struct btrfs_key *key, u64 wanted_disk_byte,
++ const u64 *extent_item_pos)
+ {
+ int ret;
+ int slot;
++ struct extent_buffer *eb = path->nodes[level];
+ struct btrfs_file_extent_item *fi;
+- struct btrfs_key key;
+ u64 disk_byte;
++ u64 wanted_objectid = key->objectid;
+
+ add_parent:
+ ret = ulist_add(parents, eb->start, 0, GFP_NOFS);
+@@ -136,9 +210,9 @@ add_parent:
+
+ eb = path->nodes[0];
+ for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) {
+- btrfs_item_key_to_cpu(eb, &key, slot);
+- if (key.objectid != wanted_objectid ||
+- key.type != BTRFS_EXTENT_DATA_KEY)
++ btrfs_item_key_to_cpu(eb, key, slot);
++ if (key->objectid != wanted_objectid ||
++ key->type != BTRFS_EXTENT_DATA_KEY)
+ return 0;
+ fi = btrfs_item_ptr(eb, slot,
+ struct btrfs_file_extent_item);
+@@ -158,7 +232,8 @@ add_parent:
+ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
+ int search_commit_root,
+ struct __prelim_ref *ref,
+- struct ulist *parents)
++ struct ulist *parents,
++ const u64 *extent_item_pos)
+ {
+ struct btrfs_path *path;
+ struct btrfs_root *root;
+@@ -219,9 +294,8 @@ static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
+ btrfs_item_key_to_cpu(eb, &key, path->slots[0]);
+ }
+
+- /* the last two parameters will only be used for level == 0 */
+- ret = add_all_parents(root, path, parents, eb, level, key.objectid,
+- ref->wanted_disk_byte);
++ ret = add_all_parents(root, path, parents, level, &key,
++ ref->wanted_disk_byte, extent_item_pos);
+ out:
+ btrfs_free_path(path);
+ return ret;
+@@ -232,7 +306,8 @@ out:
+ */
+ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
+ int search_commit_root,
+- struct list_head *head)
++ struct list_head *head,
++ const u64 *extent_item_pos)
+ {
+ int err;
+ int ret = 0;
+@@ -258,7 +333,7 @@ static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
+ if (ref->count == 0)
+ continue;
+ err = __resolve_indirect_ref(fs_info, search_commit_root,
+- ref, parents);
++ ref, parents, extent_item_pos);
+ if (err) {
+ if (ret == 0)
+ ret = err;
+@@ -675,7 +750,8 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info,
+ */
+ static int find_parent_nodes(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info, u64 bytenr,
+- u64 seq, struct ulist *refs, struct ulist *roots)
++ u64 seq, struct ulist *refs, struct ulist *roots,
++ const u64 *extent_item_pos)
+ {
+ struct btrfs_key key;
+ struct btrfs_path *path;
+@@ -778,7 +854,8 @@ again:
+ if (ret)
+ goto out;
+
+- ret = __resolve_indirect_refs(fs_info, search_commit_root, &prefs);
++ ret = __resolve_indirect_refs(fs_info, search_commit_root, &prefs,
++ extent_item_pos);
+ if (ret)
+ goto out;
+
+@@ -797,7 +874,21 @@ again:
+ BUG_ON(ret < 0);
+ }
+ if (ref->count && ref->parent) {
+- ret = ulist_add(refs, ref->parent, 0, GFP_NOFS);
++ struct extent_inode_elem *eie = NULL;
++ if (extent_item_pos) {
++ u32 bsz;
++ struct extent_buffer *eb;
++ bsz = btrfs_level_size(fs_info->extent_root,
++ info_level);
++ eb = read_tree_block(fs_info->extent_root,
++ ref->parent, bsz, 0);
++ BUG_ON(!eb);
++ ret = find_extent_in_eb(eb, bytenr,
++ *extent_item_pos, &eie);
++ free_extent_buffer(eb);
++ }
++ ret = ulist_add(refs, ref->parent,
++ (unsigned long)eie, GFP_NOFS);
+ BUG_ON(ret < 0);
+ }
+ kfree(ref);
+@@ -822,6 +913,28 @@ out:
+ return ret;
+ }
+
++static void free_leaf_list(struct ulist *blocks)
++{
++ struct ulist_node *node = NULL;
++ struct extent_inode_elem *eie;
++ struct extent_inode_elem *eie_next;
++ struct ulist_iterator uiter;
++
++ ULIST_ITER_INIT(&uiter);
++ while ((node = ulist_next(blocks, &uiter))) {
++ if (!node->aux)
++ continue;
++ eie = (struct extent_inode_elem *)node->aux;
++ for (; eie; eie = eie_next) {
++ eie_next = eie->next;
++ kfree(eie);
++ }
++ node->aux = 0;
++ }
++
++ ulist_free(blocks);
++}
++
+ /*
+ * Finds all leafs with a reference to the specified combination of bytenr and
+ * offset. key_list_head will point to a list of corresponding keys (caller must
+@@ -832,7 +945,8 @@ out:
+ */
+ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info, u64 bytenr,
+- u64 num_bytes, u64 seq, struct ulist **leafs)
++ u64 seq, struct ulist **leafs,
++ const u64 *extent_item_pos)
+ {
+ struct ulist *tmp;
+ int ret;
+@@ -846,11 +960,12 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
+ return -ENOMEM;
+ }
+
+- ret = find_parent_nodes(trans, fs_info, bytenr, seq, *leafs, tmp);
++ ret = find_parent_nodes(trans, fs_info, bytenr, seq, *leafs, tmp,
++ extent_item_pos);
+ ulist_free(tmp);
+
+ if (ret < 0 && ret != -ENOENT) {
+- ulist_free(*leafs);
++ free_leaf_list(*leafs);
+ return ret;
+ }
+
+@@ -872,7 +987,7 @@ static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans,
+ */
+ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info, u64 bytenr,
+- u64 num_bytes, u64 seq, struct ulist **roots)
++ u64 seq, struct ulist **roots)
+ {
+ struct ulist *tmp;
+ struct ulist_node *node = NULL;
+@@ -891,7 +1006,7 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
+ ULIST_ITER_INIT(&uiter);
+ while (1) {
+ ret = find_parent_nodes(trans, fs_info, bytenr, seq,
+- tmp, *roots);
++ tmp, *roots, NULL);
+ if (ret < 0 && ret != -ENOENT) {
+ ulist_free(tmp);
+ ulist_free(*roots);
+@@ -1183,67 +1298,25 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
+ return 0;
+ }
+
+-static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, u64 logical,
+- u64 orig_extent_item_objectid,
+- u64 extent_item_pos, u64 root,
++static int iterate_leaf_refs(struct extent_inode_elem *inode_list,
++ u64 root, u64 extent_item_objectid,
+ iterate_extent_inodes_t *iterate, void *ctx)
+ {
+- u64 disk_byte;
+- struct btrfs_key key;
+- struct btrfs_file_extent_item *fi;
+- struct extent_buffer *eb;
+- int slot;
+- int nritems;
++ struct extent_inode_elem *eie;
+ int ret = 0;
+- int extent_type;
+- u64 data_offset;
+- u64 data_len;
+-
+- eb = read_tree_block(fs_info->tree_root, logical,
+- fs_info->tree_root->leafsize, 0);
+- if (!eb)
+- return -EIO;
+-
+- /*
+- * from the shared data ref, we only have the leaf but we need
+- * the key. thus, we must look into all items and see that we
+- * find one (some) with a reference to our extent item.
+- */
+- nritems = btrfs_header_nritems(eb);
+- for (slot = 0; slot < nritems; ++slot) {
+- btrfs_item_key_to_cpu(eb, &key, slot);
+- if (key.type != BTRFS_EXTENT_DATA_KEY)
+- continue;
+- fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item);
+- extent_type = btrfs_file_extent_type(eb, fi);
+- if (extent_type == BTRFS_FILE_EXTENT_INLINE)
+- continue;
+- /* don't skip BTRFS_FILE_EXTENT_PREALLOC, we can handle that */
+- disk_byte = btrfs_file_extent_disk_bytenr(eb, fi);
+- if (disk_byte != orig_extent_item_objectid)
+- continue;
+-
+- data_offset = btrfs_file_extent_offset(eb, fi);
+- data_len = btrfs_file_extent_num_bytes(eb, fi);
+-
+- if (extent_item_pos < data_offset ||
+- extent_item_pos >= data_offset + data_len)
+- continue;
+
++ for (eie = inode_list; eie; eie = eie->next) {
+ pr_debug("ref for %llu resolved, key (%llu EXTEND_DATA %llu), "
+- "root %llu\n", orig_extent_item_objectid,
+- key.objectid, key.offset, root);
+- ret = iterate(key.objectid,
+- key.offset + (extent_item_pos - data_offset),
+- root, ctx);
++ "root %llu\n", extent_item_objectid,
++ eie->inum, eie->offset, root);
++ ret = iterate(eie->inum, eie->offset, root, ctx);
+ if (ret) {
+- pr_debug("stopping iteration because ret=%d\n", ret);
++ pr_debug("stopping iteration for %llu due to ret=%d\n",
++ extent_item_objectid, ret);
+ break;
+ }
+ }
+
+- free_extent_buffer(eb);
+-
+ return ret;
+ }
+
+@@ -1287,30 +1360,31 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
+ }
+
+ ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
+- extent_item_pos, seq_elem.seq,
+- &refs);
+-
++ seq_elem.seq, &refs, &extent_item_pos);
+ if (ret)
+ goto out;
+
+ ULIST_ITER_INIT(&ref_uiter);
+ while (!ret && (ref_node = ulist_next(refs, &ref_uiter))) {
+- ret = btrfs_find_all_roots(trans, fs_info, ref_node->val, -1,
++ ret = btrfs_find_all_roots(trans, fs_info, ref_node->val,
+ seq_elem.seq, &roots);
+ if (ret)
+ break;
+ ULIST_ITER_INIT(&root_uiter);
+ while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
+- pr_debug("root %llu references leaf %llu\n",
+- root_node->val, ref_node->val);
+- ret = iterate_leaf_refs(fs_info, ref_node->val,
+- extent_item_objectid,
+- extent_item_pos, root_node->val,
+- iterate, ctx);
++ pr_debug("root %llu references leaf %llu, data list "
++ "%#lx\n", root_node->val, ref_node->val,
++ ref_node->aux);
++ ret = iterate_leaf_refs(
++ (struct extent_inode_elem *)ref_node->aux,
++ root_node->val, extent_item_objectid,
++ iterate, ctx);
+ }
++ ulist_free(roots);
++ roots = NULL;
+ }
+
+- ulist_free(refs);
++ free_leaf_list(refs);
+ ulist_free(roots);
+ out:
+ if (!search_commit_root) {
+diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h
+index 57ea2e9..94ba1b2 100644
+--- a/fs/btrfs/backref.h
++++ b/fs/btrfs/backref.h
+@@ -58,7 +58,7 @@ int paths_from_inode(u64 inum, struct inode_fs_paths *ipath);
+
+ int btrfs_find_all_roots(struct btrfs_trans_handle *trans,
+ struct btrfs_fs_info *fs_info, u64 bytenr,
+- u64 num_bytes, u64 seq, struct ulist **roots);
++ u64 seq, struct ulist **roots);
+
+ struct btrfs_data_container *init_data_container(u32 total_bytes);
+ struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8103-don-t-set-for_cow-parameter-for-tree-block-fun.patch b/patches.suse/btrfs-8103-don-t-set-for_cow-parameter-for-tree-block-fun.patch
new file mode 100644
index 0000000000..5adc25b83f
--- /dev/null
+++ b/patches.suse/btrfs-8103-don-t-set-for_cow-parameter-for-tree-block-fun.patch
@@ -0,0 +1,212 @@
+From: Jan Schmidt <list.btrfs@jan-o-sch.net>
+Date: Wed, 16 May 2012 17:04:52 +0200
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 5581a51a59a1f5f51ac3d4bacafb738d35e0350b
+Subject: [PATCH] Btrfs: don't set for_cow parameter for tree block
+ functions
+
+Three callers of btrfs_free_tree_block or btrfs_alloc_tree_block passed
+parameter for_cow = 1. In fact, these two functions should never mark
+their tree modification operations as for_cow, because they can change
+the number of blocks referenced by a tree.
+
+Hence, we remove the extra for_cow parameter from these functions and
+make them pass a zero down.
+
+Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/ctree.c | 22 +++++++++++-----------
+ fs/btrfs/ctree.h | 4 ++--
+ fs/btrfs/disk-io.c | 2 +-
+ fs/btrfs/extent-tree.c | 10 +++++-----
+ fs/btrfs/ioctl.c | 2 +-
+ 5 files changed, 20 insertions(+), 20 deletions(-)
+
+--- a/fs/btrfs/ctree.c
++++ b/fs/btrfs/ctree.c
+@@ -242,7 +242,7 @@ int btrfs_copy_root(struct btrfs_trans_h
+
+ cow = btrfs_alloc_free_block(trans, root, buf->len, 0,
+ new_root_objectid, &disk_key, level,
+- buf->start, 0, 1);
++ buf->start, 0);
+ if (IS_ERR(cow))
+ return PTR_ERR(cow);
+
+@@ -454,7 +454,7 @@ static noinline int __btrfs_cow_block(st
+
+ cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start,
+ root->root_key.objectid, &disk_key,
+- level, search_start, empty_size, 1);
++ level, search_start, empty_size);
+ if (IS_ERR(cow))
+ return PTR_ERR(cow);
+
+@@ -496,7 +496,7 @@ static noinline int __btrfs_cow_block(st
+ rcu_assign_pointer(root->node, cow);
+
+ btrfs_free_tree_block(trans, root, buf, parent_start,
+- last_ref, 1);
++ last_ref);
+ free_extent_buffer(buf);
+ add_root_to_dirty_list(root);
+ } else {
+@@ -512,7 +512,7 @@ static noinline int __btrfs_cow_block(st
+ trans->transid);
+ btrfs_mark_buffer_dirty(parent);
+ btrfs_free_tree_block(trans, root, buf, parent_start,
+- last_ref, 1);
++ last_ref);
+ }
+ if (unlock_orig)
+ btrfs_tree_unlock(buf);
+@@ -974,7 +974,7 @@ static noinline int balance_level(struct
+ free_extent_buffer(mid);
+
+ root_sub_used(root, mid->len);
+- btrfs_free_tree_block(trans, root, mid, 0, 1, 0);
++ btrfs_free_tree_block(trans, root, mid, 0, 1);
+ /* once for the root ptr */
+ free_extent_buffer(mid);
+ return 0;
+@@ -1029,7 +1029,7 @@ static noinline int balance_level(struct
+ btrfs_tree_unlock(right);
+ del_ptr(trans, root, path, level + 1, pslot + 1);
+ root_sub_used(root, right->len);
+- btrfs_free_tree_block(trans, root, right, 0, 1, 0);
++ btrfs_free_tree_block(trans, root, right, 0, 1);
+ free_extent_buffer(right);
+ right = NULL;
+ } else {
+@@ -1071,7 +1071,7 @@ static noinline int balance_level(struct
+ btrfs_tree_unlock(mid);
+ del_ptr(trans, root, path, level + 1, pslot);
+ root_sub_used(root, mid->len);
+- btrfs_free_tree_block(trans, root, mid, 0, 1, 0);
++ btrfs_free_tree_block(trans, root, mid, 0, 1);
+ free_extent_buffer(mid);
+ mid = NULL;
+ } else {
+@@ -2116,7 +2116,7 @@ static noinline int insert_new_root(stru
+
+ c = btrfs_alloc_free_block(trans, root, root->nodesize, 0,
+ root->root_key.objectid, &lower_key,
+- level, root->node->start, 0, 0);
++ level, root->node->start, 0);
+ if (IS_ERR(c))
+ return PTR_ERR(c);
+
+@@ -2239,7 +2239,7 @@ static noinline int split_node(struct bt
+
+ split = btrfs_alloc_free_block(trans, root, root->nodesize, 0,
+ root->root_key.objectid,
+- &disk_key, level, c->start, 0, 0);
++ &disk_key, level, c->start, 0);
+ if (IS_ERR(split))
+ return PTR_ERR(split);
+
+@@ -2979,7 +2979,7 @@ again:
+
+ right = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
+ root->root_key.objectid,
+- &disk_key, 0, l->start, 0, 0);
++ &disk_key, 0, l->start, 0);
+ if (IS_ERR(right))
+ return PTR_ERR(right);
+
+@@ -3760,7 +3760,7 @@ static noinline void btrfs_del_leaf(stru
+
+ root_sub_used(root, leaf->len);
+
+- btrfs_free_tree_block(trans, root, leaf, 0, 1, 0);
++ btrfs_free_tree_block(trans, root, leaf, 0, 1);
+ }
+ /*
+ * delete the item at the leaf level in path. If that empties
+--- a/fs/btrfs/ctree.h
++++ b/fs/btrfs/ctree.h
+@@ -2459,11 +2459,11 @@ struct extent_buffer *btrfs_alloc_free_b
+ struct btrfs_root *root, u32 blocksize,
+ u64 parent, u64 root_objectid,
+ struct btrfs_disk_key *key, int level,
+- u64 hint, u64 empty_size, int for_cow);
++ u64 hint, u64 empty_size);
+ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct extent_buffer *buf,
+- u64 parent, int last_ref, int for_cow);
++ u64 parent, int last_ref);
+ struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ u64 bytenr, u32 blocksize,
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -1290,7 +1290,7 @@ static struct btrfs_root *alloc_log_tree
+
+ leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0,
+ BTRFS_TREE_LOG_OBJECTID, NULL,
+- 0, 0, 0, 0);
++ 0, 0, 0);
+ if (IS_ERR(leaf)) {
+ kfree(root);
+ return ERR_CAST(leaf);
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -5262,7 +5262,7 @@ out:
+ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root,
+ struct extent_buffer *buf,
+- u64 parent, int last_ref, int for_cow)
++ u64 parent, int last_ref)
+ {
+ struct btrfs_block_group_cache *cache = NULL;
+ int ret;
+@@ -5272,7 +5272,7 @@ void btrfs_free_tree_block(struct btrfs_
+ buf->start, buf->len,
+ parent, root->root_key.objectid,
+ btrfs_header_level(buf),
+- BTRFS_DROP_DELAYED_REF, NULL, for_cow);
++ BTRFS_DROP_DELAYED_REF, NULL, 0);
+ BUG_ON(ret); /* -ENOMEM */
+ }
+
+@@ -6370,7 +6370,7 @@ struct extent_buffer *btrfs_alloc_free_b
+ struct btrfs_root *root, u32 blocksize,
+ u64 parent, u64 root_objectid,
+ struct btrfs_disk_key *key, int level,
+- u64 hint, u64 empty_size, int for_cow)
++ u64 hint, u64 empty_size)
+ {
+ struct btrfs_key ins;
+ struct btrfs_block_rsv *block_rsv;
+@@ -6418,7 +6418,7 @@ struct extent_buffer *btrfs_alloc_free_b
+ ins.objectid,
+ ins.offset, parent, root_objectid,
+ level, BTRFS_ADD_DELAYED_EXTENT,
+- extent_op, for_cow);
++ extent_op, 0);
+ BUG_ON(ret); /* -ENOMEM */
+ }
+ return buf;
+@@ -6836,7 +6836,7 @@ static noinline int walk_up_proc(struct
+ btrfs_header_owner(path->nodes[level + 1]));
+ }
+
+- btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1, 0);
++ btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1);
+ out:
+ wc->refs[level] = 0;
+ wc->flags[level] = 0;
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -372,7 +372,7 @@ static noinline int create_subvol(struct
+ return PTR_ERR(trans);
+
+ leaf = btrfs_alloc_free_block(trans, root, root->leafsize,
+- 0, objectid, NULL, 0, 0, 0, 0);
++ 0, objectid, NULL, 0, 0, 0);
+ if (IS_ERR(leaf)) {
+ ret = PTR_ERR(leaf);
+ goto fail;
diff --git a/patches.suse/btrfs-8105-fix-defrag-regression.patch b/patches.suse/btrfs-8105-fix-defrag-regression.patch
new file mode 100644
index 0000000000..02eee9d390
--- /dev/null
+++ b/patches.suse/btrfs-8105-fix-defrag-regression.patch
@@ -0,0 +1,177 @@
+From: Li Zefan <lizefan@huawei.com>
+Date: Mon, 11 Jun 2012 16:03:35 +0800
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 6c282eb40ed6f64a51ff447707714df551d85b8e
+Subject: [PATCH] Btrfs: fix defrag regression
+
+If a file has 3 small extents:
+
+| ext1 | ext2 | ext3 |
+
+Running "btrfs fi defrag" will only defrag the last two extents, if those
+extent mappings hasn't been read into memory from disk.
+
+This bug was introduced by commit 17ce6ef8d731af5edac8c39e806db4c7e1f6956f
+("Btrfs: add a check to decide if we should defrag the range")
+
+The cause is, that commit looked into previous and next extents using
+lookup_extent_mapping() only.
+
+While at it, remove the code that checks the previous extent, since
+it's sufficient to check the next extent.
+
+Signed-off-by: Li Zefan <lizefan@huawei.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/ioctl.c | 97 +++++++++++++++++++++++++++--------------------------
+ 1 files changed, 49 insertions(+), 48 deletions(-)
+
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index c5254dd..a98f7d2 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -786,39 +786,57 @@ none:
+ return -ENOENT;
+ }
+
+-/*
+- * Validaty check of prev em and next em:
+- * 1) no prev/next em
+- * 2) prev/next em is an hole/inline extent
+- */
+-static int check_adjacent_extents(struct inode *inode, struct extent_map *em)
++static struct extent_map *defrag_lookup_extent(struct inode *inode, u64 start)
+ {
+ struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+- struct extent_map *prev = NULL, *next = NULL;
+- int ret = 0;
++ struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
++ struct extent_map *em;
++ u64 len = PAGE_CACHE_SIZE;
+
++ /*
++ * hopefully we have this extent in the tree already, try without
++ * the full extent lock
++ */
+ read_lock(&em_tree->lock);
+- prev = lookup_extent_mapping(em_tree, em->start - 1, (u64)-1);
+- next = lookup_extent_mapping(em_tree, em->start + em->len, (u64)-1);
++ em = lookup_extent_mapping(em_tree, start, len);
+ read_unlock(&em_tree->lock);
+
+- if ((!prev || prev->block_start >= EXTENT_MAP_LAST_BYTE) &&
+- (!next || next->block_start >= EXTENT_MAP_LAST_BYTE))
+- ret = 1;
+- free_extent_map(prev);
+- free_extent_map(next);
++ if (!em) {
++ /* get the big lock and read metadata off disk */
++ lock_extent(io_tree, start, start + len - 1);
++ em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
++ unlock_extent(io_tree, start, start + len - 1);
+
++ if (IS_ERR(em))
++ return NULL;
++ }
++
++ return em;
++}
++
++static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em)
++{
++ struct extent_map *next;
++ bool ret = true;
++
++ /* this is the last extent */
++ if (em->start + em->len >= i_size_read(inode))
++ return false;
++
++ next = defrag_lookup_extent(inode, em->start + em->len);
++ if (!next || next->block_start >= EXTENT_MAP_LAST_BYTE)
++ ret = false;
++
++ free_extent_map(next);
+ return ret;
+ }
+
+-static int should_defrag_range(struct inode *inode, u64 start, u64 len,
+- int thresh, u64 *last_len, u64 *skip,
+- u64 *defrag_end)
++static int should_defrag_range(struct inode *inode, u64 start, int thresh,
++ u64 *last_len, u64 *skip, u64 *defrag_end)
+ {
+- struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
+- struct extent_map *em = NULL;
+- struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
++ struct extent_map *em;
+ int ret = 1;
++ bool next_mergeable = true;
+
+ /*
+ * make sure that once we start defragging an extent, we keep on
+@@ -829,23 +847,9 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
+
+ *skip = 0;
+
+- /*
+- * hopefully we have this extent in the tree already, try without
+- * the full extent lock
+- */
+- read_lock(&em_tree->lock);
+- em = lookup_extent_mapping(em_tree, start, len);
+- read_unlock(&em_tree->lock);
+-
+- if (!em) {
+- /* get the big lock and read metadata off disk */
+- lock_extent(io_tree, start, start + len - 1);
+- em = btrfs_get_extent(inode, NULL, 0, start, len, 0);
+- unlock_extent(io_tree, start, start + len - 1);
+-
+- if (IS_ERR(em))
+- return 0;
+- }
++ em = defrag_lookup_extent(inode, start);
++ if (!em)
++ return 0;
+
+ /* this will cover holes, and inline extents */
+ if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
+@@ -853,18 +857,15 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
+ goto out;
+ }
+
+- /* If we have nothing to merge with us, just skip. */
+- if (check_adjacent_extents(inode, em)) {
+- ret = 0;
+- goto out;
+- }
++ next_mergeable = defrag_check_next_extent(inode, em);
+
+ /*
+- * we hit a real extent, if it is big don't bother defragging it again
++ * we hit a real extent, if it is big or the next extent is not a
++ * real extent, don't bother defragging it
+ */
+- if ((*last_len == 0 || *last_len >= thresh) && em->len >= thresh)
++ if ((*last_len == 0 || *last_len >= thresh) &&
++ (em->len >= thresh || !next_mergeable))
+ ret = 0;
+-
+ out:
+ /*
+ * last_len ends up being a counter of how many bytes we've defragged.
+@@ -1143,8 +1144,8 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
+ break;
+
+ if (!should_defrag_range(inode, (u64)i << PAGE_CACHE_SHIFT,
+- PAGE_CACHE_SIZE, extent_thresh,
+- &last_len, &skip, &defrag_end)) {
++ extent_thresh, &last_len, &skip,
++ &defrag_end)) {
+ unsigned long next;
+ /*
+ * the should_defrag function tells us how much to skip
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8106-fix-missing-inherited-flag-in-rename.patch b/patches.suse/btrfs-8106-fix-missing-inherited-flag-in-rename.patch
new file mode 100644
index 0000000000..87cfab7be8
--- /dev/null
+++ b/patches.suse/btrfs-8106-fix-missing-inherited-flag-in-rename.patch
@@ -0,0 +1,46 @@
+From: Liu Bo <liubo2009@cn.fujitsu.com>
+Date: Thu, 14 Jun 2012 02:23:18 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: bc1782374b128103ae9689e0753e0610f35b6bfd
+Subject: [PATCH] Btrfs: fix missing inherited flag in rename
+
+When we move a file into a directory with compression flag, we need to
+inherite BTRFS_INODE_COMPRESS and clear BTRFS_INODE_NOCOMPRESS as well.
+But if we move a file into a directory without compression flag, we need
+to clear both of them.
+
+It is the way how our setflags deals with compression flag, so keep
+the same behaviour here.
+
+Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
+Signed-off-by: Chris Mason <chris.mason@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/inode.c | 9 ++++++---
+ 1 files changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index 7a090fb..3f2c8cb 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -7122,10 +7122,13 @@ static void fixup_inode_flags(struct inode *dir, struct inode *inode)
+ else
+ b_inode->flags &= ~BTRFS_INODE_NODATACOW;
+
+- if (b_dir->flags & BTRFS_INODE_COMPRESS)
++ if (b_dir->flags & BTRFS_INODE_COMPRESS) {
+ b_inode->flags |= BTRFS_INODE_COMPRESS;
+- else
+- b_inode->flags &= ~BTRFS_INODE_COMPRESS;
++ b_inode->flags &= ~BTRFS_INODE_NOCOMPRESS;
++ } else {
++ b_inode->flags &= ~(BTRFS_INODE_COMPRESS |
++ BTRFS_INODE_NOCOMPRESS);
++ }
+ }
+
+ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8107-do-not-resize-a-seeding-device.patch b/patches.suse/btrfs-8107-do-not-resize-a-seeding-device.patch
new file mode 100644
index 0000000000..021032715b
--- /dev/null
+++ b/patches.suse/btrfs-8107-do-not-resize-a-seeding-device.patch
@@ -0,0 +1,37 @@
+From: Liu Bo <liubo2009@cn.fujitsu.com>
+Date: Thu, 14 Jun 2012 02:23:19 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 4e42ae1bdcda77fc958a17d7ff4ba5a9c9c207da
+Subject: [PATCH] Btrfs: do not resize a seeding device
+
+Seeding devices are not supposed to change any more.
+
+Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
+Signed-off-by: Chris Mason <chris.mason@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/ioctl.c | 7 +++++++
+ 1 files changed, 7 insertions(+), 0 deletions(-)
+
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index a98f7d2..58adbd0 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -1306,6 +1306,13 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
+ ret = -EINVAL;
+ goto out_free;
+ }
++ if (device->fs_devices && device->fs_devices->seeding) {
++ printk(KERN_INFO "btrfs: resizer unable to apply on "
++ "seeding device %llu\n", devid);
++ ret = -EINVAL;
++ goto out_free;
++ }
++
+ if (!strcmp(sizestr, "max"))
+ new_size = device->bdev->bd_inode->i_size;
+ else {
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8108-cast-devid-to-unsigned-long-long-for-printk-ll.patch b/patches.suse/btrfs-8108-cast-devid-to-unsigned-long-long-for-printk-ll.patch
new file mode 100644
index 0000000000..83c91c3a51
--- /dev/null
+++ b/patches.suse/btrfs-8108-cast-devid-to-unsigned-long-long-for-printk-ll.patch
@@ -0,0 +1,33 @@
+From: Chris Mason <chris.mason@fusionio.com>
+Date: Fri, 15 Jun 2012 20:07:17 -0400
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: a8c4a33b98b097e69cd1a10672c43d17ad0ffb25
+Subject: [PATCH] Btrfs: cast devid to unsigned long long for printk
+ %llu
+
+Avoid warning in 32 bit machines
+
+Signed-off-by: Chris Mason <chris.mason@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/ioctl.c | 3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
+index 58adbd0..0e92e57 100644
+--- a/fs/btrfs/ioctl.c
++++ b/fs/btrfs/ioctl.c
+@@ -1308,7 +1308,8 @@ static noinline int btrfs_ioctl_resize(struct btrfs_root *root,
+ }
+ if (device->fs_devices && device->fs_devices->seeding) {
+ printk(KERN_INFO "btrfs: resizer unable to apply on "
+- "seeding device %llu\n", devid);
++ "seeding device %llu\n",
++ (unsigned long long)devid);
+ ret = -EINVAL;
+ goto out_free;
+ }
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8109-add-a-missing-spin_lock.patch b/patches.suse/btrfs-8109-add-a-missing-spin_lock.patch
new file mode 100644
index 0000000000..eda50b7b25
--- /dev/null
+++ b/patches.suse/btrfs-8109-add-a-missing-spin_lock.patch
@@ -0,0 +1,39 @@
+From: Josef Bacik <josef@redhat.com>
+Date: Mon, 18 Jun 2012 07:23:18 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: e18fca734278784bd6591de63ca148cc27344ca9
+Subject: [PATCH] Btrfs: add a missing spin_lock
+
+When fixing up the locking in the delayed ref destruction work I accidently
+broke the locking myself ;(. Add back a spin_lock that should be there and
+we are now all set. Thanks,
+Btrfs: add a missing spin_lock
+
+When fixing up the locking in the delayed ref destruction work I accidently
+broke the locking myself ;(. Add back a spin_lock that should be there and
+we are now all set. Thanks,
+
+Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: Josef Bacik <josef@redhat.com>
+Signed-off-by: Chris Mason <chris.mason@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/disk-io.c | 1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index e22c5bb..7d7bc8e 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -3426,6 +3426,7 @@ int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
+ mutex_unlock(&head->mutex);
+ btrfs_put_delayed_ref(ref);
+
++ spin_lock(&delayed_refs->lock);
+ continue;
+ }
+
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8111-restore-restriper-state-on-all-mounts.patch b/patches.suse/btrfs-8111-restore-restriper-state-on-all-mounts.patch
new file mode 100644
index 0000000000..e188bf5634
--- /dev/null
+++ b/patches.suse/btrfs-8111-restore-restriper-state-on-all-mounts.patch
@@ -0,0 +1,139 @@
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 22 Jun 2012 12:24:12 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 68310a5e42f93c2242ec1836c3b18d531e0065e2
+Subject: [PATCH] Btrfs: restore restriper state on all mounts
+
+Fix a bug that triggered asserts in btrfs_balance() in both normal and
+resume modes -- restriper state was not properly restored on read-only
+mounts. This factors out resuming code from btrfs_restore_balance(),
+which is now also called earlier in the mount sequence to avoid the
+problem of some early writes getting the old profile.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/disk-io.c | 10 ++++++----
+ fs/btrfs/volumes.c | 39 +++++++++++++++++++--------------------
+ fs/btrfs/volumes.h | 2 +-
+ 3 files changed, 26 insertions(+), 25 deletions(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2411,12 +2411,17 @@ retry_root_backup:
+ BTRFS_CSUM_TREE_OBJECTID, csum_root);
+ if (ret)
+ goto recovery_tree_root;
+-
+ csum_root->track_dirty = 1;
+
+ fs_info->generation = generation;
+ fs_info->last_trans_committed = generation;
+
++ ret = btrfs_recover_balance(fs_info);
++ if (ret) {
++ printk(KERN_WARNING "btrfs: failed to recover balance\n");
++ goto fail_block_groups;
++ }
++
+ ret = btrfs_init_space_info(fs_info);
+ if (ret) {
+ printk(KERN_ERR "Failed to initial space info: %d\n", ret);
+@@ -2536,9 +2541,6 @@ retry_root_backup:
+ err = btrfs_orphan_cleanup(fs_info->tree_root);
+ up_read(&fs_info->cleanup_work_sem);
+
+- if (!err)
+- err = btrfs_recover_balance(fs_info->tree_root);
+-
+ if (err) {
+ close_ctree(tree_root);
+ free_fs_info(fs_info);
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -2846,9 +2846,8 @@ static int balance_kthread(void *data)
+ return ret;
+ }
+
+-int btrfs_recover_balance(struct btrfs_root *tree_root)
++int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
+ {
+- struct task_struct *tsk;
+ struct btrfs_balance_control *bctl;
+ struct btrfs_balance_item *item;
+ struct btrfs_disk_balance_args disk_bargs;
+@@ -2861,29 +2860,30 @@ int btrfs_recover_balance(struct btrfs_r
+ if (!path)
+ return -ENOMEM;
+
+- bctl = kzalloc(sizeof(*bctl), GFP_NOFS);
+- if (!bctl) {
+- ret = -ENOMEM;
+- goto out;
+- }
+-
+ key.objectid = BTRFS_BALANCE_OBJECTID;
+ key.type = BTRFS_BALANCE_ITEM_KEY;
+ key.offset = 0;
+
+- ret = btrfs_search_slot(NULL, tree_root, &key, path, 0, 0);
++ ret = btrfs_search_slot(NULL, fs_info->tree_root, &key, path, 0, 0);
+ if (ret < 0)
+- goto out_bctl;
++ goto out;
+ if (ret > 0) { /* ret = -ENOENT; */
+ ret = 0;
+- goto out_bctl;
++ goto out;
++ }
++
++ bctl = kzalloc(sizeof(*bctl), GFP_NOFS);
++ if (!bctl) {
++ ret = -ENOMEM;
++ goto out;
+ }
+
+ leaf = path->nodes[0];
+ item = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_balance_item);
+
+- bctl->fs_info = tree_root->fs_info;
+- bctl->flags = btrfs_balance_flags(leaf, item) | BTRFS_BALANCE_RESUME;
++ bctl->fs_info = fs_info;
++ bctl->flags = btrfs_balance_flags(leaf, item);
++ bctl->flags |= BTRFS_BALANCE_RESUME;
+
+ btrfs_balance_data(leaf, item, &disk_bargs);
+ btrfs_disk_balance_args_to_cpu(&bctl->data, &disk_bargs);
+@@ -2892,14 +2892,13 @@ int btrfs_recover_balance(struct btrfs_r
+ btrfs_balance_sys(leaf, item, &disk_bargs);
+ btrfs_disk_balance_args_to_cpu(&bctl->sys, &disk_bargs);
+
+- tsk = kthread_run(balance_kthread, bctl, "btrfs-balance");
+- if (IS_ERR(tsk))
+- ret = PTR_ERR(tsk);
+- else
+- goto out;
++ mutex_lock(&fs_info->volume_mutex);
++ mutex_lock(&fs_info->balance_mutex);
++
++ set_balance_control(bctl);
+
+-out_bctl:
+- kfree(bctl);
++ mutex_unlock(&fs_info->balance_mutex);
++ mutex_unlock(&fs_info->volume_mutex);
+ out:
+ btrfs_free_path(path);
+ return ret;
+--- a/fs/btrfs/volumes.h
++++ b/fs/btrfs/volumes.h
+@@ -275,7 +275,7 @@ int btrfs_shrink_device(struct btrfs_dev
+ int btrfs_init_new_device(struct btrfs_root *root, char *path);
+ int btrfs_balance(struct btrfs_balance_control *bctl,
+ struct btrfs_ioctl_balance_args *bargs);
+-int btrfs_recover_balance(struct btrfs_root *tree_root);
++int btrfs_recover_balance(struct btrfs_fs_info *fs_info);
+ int btrfs_pause_balance(struct btrfs_fs_info *fs_info);
+ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
+ int btrfs_chunk_readonly(struct btrfs_root *root, u64 chunk_offset);
diff --git a/patches.suse/btrfs-8112-resume-balance-on-rw-re-mounts-properly.patch b/patches.suse/btrfs-8112-resume-balance-on-rw-re-mounts-properly.patch
new file mode 100644
index 0000000000..01834e8102
--- /dev/null
+++ b/patches.suse/btrfs-8112-resume-balance-on-rw-re-mounts-properly.patch
@@ -0,0 +1,139 @@
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 22 Jun 2012 12:24:13 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 2b6ba629b5aac51e7099efbb43e2b403213aa7fb
+Subject: [PATCH] Btrfs: resume balance on rw (re)mounts properly
+
+This introduces btrfs_resume_balance_async(), which, given that
+restriper state was recovered earlier by btrfs_recover_balance(),
+resumes balance in btrfs-balance kthread.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/disk-io.c | 28 +++++++++++++++++-----------
+ fs/btrfs/super.c | 4 ++++
+ fs/btrfs/volumes.c | 36 +++++++++++++++++++++++++++---------
+ fs/btrfs/volumes.h | 1 +
+ 4 files changed, 49 insertions(+), 20 deletions(-)
+
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2534,18 +2534,24 @@ retry_root_backup:
+ goto fail_trans_kthread;
+ }
+
+- if (!(sb->s_flags & MS_RDONLY)) {
+- down_read(&fs_info->cleanup_work_sem);
+- err = btrfs_orphan_cleanup(fs_info->fs_root);
+- if (!err)
+- err = btrfs_orphan_cleanup(fs_info->tree_root);
+- up_read(&fs_info->cleanup_work_sem);
++ if (sb->s_flags & MS_RDONLY)
++ return 0;
+
+- if (err) {
+- close_ctree(tree_root);
+- free_fs_info(fs_info);
+- return ERR_PTR(err);
+- }
++ down_read(&fs_info->cleanup_work_sem);
++ if ((ret = btrfs_orphan_cleanup(fs_info->fs_root)) ||
++ (ret = btrfs_orphan_cleanup(fs_info->tree_root))) {
++ up_read(&fs_info->cleanup_work_sem);
++ close_ctree(tree_root);
++ free_fs_info(fs_info);
++ return ERR_PTR(ret);
++ }
++ up_read(&fs_info->cleanup_work_sem);
++ ret = btrfs_resume_balance_async(fs_info);
++ if (ret) {
++ printk(KERN_WARNING "btrfs: failed to resume balance\n");
++ close_ctree(tree_root);
++ free_fs_info(fs_info);
++ return ERR_PTR(ret);
+ }
+
+ return tree_root;
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -1174,6 +1174,10 @@ static int btrfs_remount(struct super_bl
+ if (ret)
+ goto restore;
+
++ ret = btrfs_resume_balance_async(root->fs_info);
++ if (ret)
++ goto restore;
++
+ sb->s_flags &= ~MS_RDONLY;
+ }
+
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
+@@ -2824,28 +2824,46 @@ out:
+
+ static int balance_kthread(void *data)
+ {
+- struct btrfs_balance_control *bctl =
+- (struct btrfs_balance_control *)data;
+- struct btrfs_fs_info *fs_info = bctl->fs_info;
++ struct btrfs_fs_info *fs_info = data;
+ int ret = 0;
+
+ mutex_lock(&fs_info->volume_mutex);
+ mutex_lock(&fs_info->balance_mutex);
+
+- set_balance_control(bctl);
+-
+- if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
+- printk(KERN_INFO "btrfs: force skipping balance\n");
+- } else {
++ if (fs_info->balance_ctl) {
+ printk(KERN_INFO "btrfs: continuing balance\n");
+- ret = btrfs_balance(bctl, NULL);
++ ret = btrfs_balance(fs_info->balance_ctl, NULL);
+ }
+
+ mutex_unlock(&fs_info->balance_mutex);
+ mutex_unlock(&fs_info->volume_mutex);
++
+ return ret;
+ }
+
++int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info)
++{
++ struct task_struct *tsk;
++
++ spin_lock(&fs_info->balance_lock);
++ if (!fs_info->balance_ctl) {
++ spin_unlock(&fs_info->balance_lock);
++ return 0;
++ }
++ spin_unlock(&fs_info->balance_lock);
++
++ if (btrfs_test_opt(fs_info->tree_root, SKIP_BALANCE)) {
++ printk(KERN_INFO "btrfs: force skipping balance\n");
++ return 0;
++ }
++
++ tsk = kthread_run(balance_kthread, fs_info, "btrfs-balance");
++ if (IS_ERR(tsk))
++ return PTR_ERR(tsk);
++
++ return 0;
++}
++
+ int btrfs_recover_balance(struct btrfs_fs_info *fs_info)
+ {
+ struct btrfs_balance_control *bctl;
+--- a/fs/btrfs/volumes.h
++++ b/fs/btrfs/volumes.h
+@@ -275,6 +275,7 @@ int btrfs_shrink_device(struct btrfs_dev
+ int btrfs_init_new_device(struct btrfs_root *root, char *path);
+ int btrfs_balance(struct btrfs_balance_control *bctl,
+ struct btrfs_ioctl_balance_args *bargs);
++int btrfs_resume_balance_async(struct btrfs_fs_info *fs_info);
+ int btrfs_recover_balance(struct btrfs_fs_info *fs_info);
+ int btrfs_pause_balance(struct btrfs_fs_info *fs_info);
+ int btrfs_cancel_balance(struct btrfs_fs_info *fs_info);
diff --git a/patches.suse/btrfs-8114-fix-tree-log-remove-space-corner-case.patch b/patches.suse/btrfs-8114-fix-tree-log-remove-space-corner-case.patch
new file mode 100644
index 0000000000..12ae7fd078
--- /dev/null
+++ b/patches.suse/btrfs-8114-fix-tree-log-remove-space-corner-case.patch
@@ -0,0 +1,222 @@
+From: Josef Bacik <jbacik@fusionio.com>
+Date: Wed, 27 Jun 2012 15:10:56 -0400
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: bdb7d303b33c1648514c9f9461d7513a4c05ce48
+Subject: [PATCH] Btrfs: fix tree log remove space corner case
+
+The tree log stuff can have allocated space that we end up having split
+across a bitmap and a real extent. The free space code does not deal with
+this, it assumes that if it finds an extent or bitmap entry that the entire
+range must fall within the entry it finds. This isn't necessarily the case,
+so rework the remove function so it can handle this case properly. This
+fixed two panics the user hit, first in the case where the space was
+initially in a bitmap and then in an extent entry, and then the reverse
+case. Thanks,
+
+Reported-and-tested-by: Shaun Reich <sreich@kde.org>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/free-space-cache.c | 145 +++++++++++++++---------------------------
+ 1 files changed, 52 insertions(+), 93 deletions(-)
+
+diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
+index 19a0d85..a70c54e 100644
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -1542,29 +1542,26 @@ again:
+ end = bitmap_info->offset + (u64)(BITS_PER_BITMAP * ctl->unit) - 1;
+
+ /*
+- * XXX - this can go away after a few releases.
+- *
+- * since the only user of btrfs_remove_free_space is the tree logging
+- * stuff, and the only way to test that is under crash conditions, we
+- * want to have this debug stuff here just in case somethings not
+- * working. Search the bitmap for the space we are trying to use to
+- * make sure its actually there. If its not there then we need to stop
+- * because something has gone wrong.
++ * We need to search for bits in this bitmap. We could only cover some
++ * of the extent in this bitmap thanks to how we add space, so we need
++ * to search for as much as it as we can and clear that amount, and then
++ * go searching for the next bit.
+ */
+ search_start = *offset;
+- search_bytes = *bytes;
++ search_bytes = ctl->unit;
+ search_bytes = min(search_bytes, end - search_start + 1);
+ ret = search_bitmap(ctl, bitmap_info, &search_start, &search_bytes);
+ BUG_ON(ret < 0 || search_start != *offset);
+
+- if (*offset > bitmap_info->offset && *offset + *bytes > end) {
+- bitmap_clear_bits(ctl, bitmap_info, *offset, end - *offset + 1);
+- *bytes -= end - *offset + 1;
+- *offset = end + 1;
+- } else if (*offset >= bitmap_info->offset && *offset + *bytes <= end) {
+- bitmap_clear_bits(ctl, bitmap_info, *offset, *bytes);
+- *bytes = 0;
+- }
++ /* We may have found more bits than what we need */
++ search_bytes = min(search_bytes, *bytes);
++
++ /* Cannot clear past the end of the bitmap */
++ search_bytes = min(search_bytes, end - search_start + 1);
++
++ bitmap_clear_bits(ctl, bitmap_info, search_start, search_bytes);
++ *offset += search_bytes;
++ *bytes -= search_bytes;
+
+ if (*bytes) {
+ struct rb_node *next = rb_next(&bitmap_info->offset_index);
+@@ -1595,7 +1592,7 @@ again:
+ * everything over again.
+ */
+ search_start = *offset;
+- search_bytes = *bytes;
++ search_bytes = ctl->unit;
+ ret = search_bitmap(ctl, bitmap_info, &search_start,
+ &search_bytes);
+ if (ret < 0 || search_start != *offset)
+@@ -1878,12 +1875,14 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
+ {
+ struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
+ struct btrfs_free_space *info;
+- struct btrfs_free_space *next_info = NULL;
+ int ret = 0;
+
+ spin_lock(&ctl->tree_lock);
+
+ again:
++ if (!bytes)
++ goto out_lock;
++
+ info = tree_search_offset(ctl, offset, 0, 0);
+ if (!info) {
+ /*
+@@ -1904,88 +1903,48 @@ again:
+ }
+ }
+
+- if (info->bytes < bytes && rb_next(&info->offset_index)) {
+- u64 end;
+- next_info = rb_entry(rb_next(&info->offset_index),
+- struct btrfs_free_space,
+- offset_index);
+-
+- if (next_info->bitmap)
+- end = next_info->offset +
+- BITS_PER_BITMAP * ctl->unit - 1;
+- else
+- end = next_info->offset + next_info->bytes;
+-
+- if (next_info->bytes < bytes ||
+- next_info->offset > offset || offset > end) {
+- printk(KERN_CRIT "Found free space at %llu, size %llu,"
+- " trying to use %llu\n",
+- (unsigned long long)info->offset,
+- (unsigned long long)info->bytes,
+- (unsigned long long)bytes);
+- WARN_ON(1);
+- ret = -EINVAL;
+- goto out_lock;
+- }
+-
+- info = next_info;
+- }
+-
+- if (info->bytes == bytes) {
++ if (!info->bitmap) {
+ unlink_free_space(ctl, info);
+- if (info->bitmap) {
+- kfree(info->bitmap);
+- ctl->total_bitmaps--;
+- }
+- kmem_cache_free(btrfs_free_space_cachep, info);
+- ret = 0;
+- goto out_lock;
+- }
+-
+- if (!info->bitmap && info->offset == offset) {
+- unlink_free_space(ctl, info);
+- info->offset += bytes;
+- info->bytes -= bytes;
+- ret = link_free_space(ctl, info);
+- WARN_ON(ret);
+- goto out_lock;
+- }
++ if (offset == info->offset) {
++ u64 to_free = min(bytes, info->bytes);
++
++ info->bytes -= to_free;
++ info->offset += to_free;
++ if (info->bytes) {
++ ret = link_free_space(ctl, info);
++ WARN_ON(ret);
++ } else {
++ kmem_cache_free(btrfs_free_space_cachep, info);
++ }
+
+- if (!info->bitmap && info->offset <= offset &&
+- info->offset + info->bytes >= offset + bytes) {
+- u64 old_start = info->offset;
+- /*
+- * we're freeing space in the middle of the info,
+- * this can happen during tree log replay
+- *
+- * first unlink the old info and then
+- * insert it again after the hole we're creating
+- */
+- unlink_free_space(ctl, info);
+- if (offset + bytes < info->offset + info->bytes) {
+- u64 old_end = info->offset + info->bytes;
++ offset += to_free;
++ bytes -= to_free;
++ goto again;
++ } else {
++ u64 old_end = info->bytes + info->offset;
+
+- info->offset = offset + bytes;
+- info->bytes = old_end - info->offset;
++ info->bytes = offset - info->offset;
+ ret = link_free_space(ctl, info);
+ WARN_ON(ret);
+ if (ret)
+ goto out_lock;
+- } else {
+- /* the hole we're creating ends at the end
+- * of the info struct, just free the info
+- */
+- kmem_cache_free(btrfs_free_space_cachep, info);
+- }
+- spin_unlock(&ctl->tree_lock);
+
+- /* step two, insert a new info struct to cover
+- * anything before the hole
+- */
+- ret = btrfs_add_free_space(block_group, old_start,
+- offset - old_start);
+- WARN_ON(ret); /* -ENOMEM */
+- goto out;
++ /* Not enough bytes in this entry to satisfy us */
++ if (old_end < offset + bytes) {
++ bytes -= old_end - offset;
++ offset = old_end;
++ goto again;
++ } else if (old_end == offset + bytes) {
++ /* all done */
++ goto out_lock;
++ }
++ spin_unlock(&ctl->tree_lock);
++
++ ret = btrfs_add_free_space(block_group, offset + bytes,
++ old_end - (offset + bytes));
++ WARN_ON(ret);
++ goto out;
++ }
+ }
+
+ ret = remove_from_bitmap(ctl, info, &offset, &bytes);
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8115-hold-a-ref-on-the-inode-during-writepages.patch b/patches.suse/btrfs-8115-hold-a-ref-on-the-inode-during-writepages.patch
new file mode 100644
index 0000000000..f8cfd989e4
--- /dev/null
+++ b/patches.suse/btrfs-8115-hold-a-ref-on-the-inode-during-writepages.patch
@@ -0,0 +1,63 @@
+From: Josef Bacik <jbacik@fusionio.com>
+Date: Wed, 27 Jun 2012 17:18:41 -0400
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 7fd1a3f73f3743b4ffd520effe288a70b0ec47c9
+Subject: [PATCH] Btrfs: hold a ref on the inode during writepages
+
+We can race with unlink and not actually be able to do our igrab in
+btrfs_add_ordered_extent. This will result in all sorts of problems.
+Instead of doing the complicated work to try and handle returning an error
+properly from btrfs_add_ordered_extent, just hold a ref to the inode during
+writepages. If we cannot grab a ref we know we're freeing this inode anyway
+and can just drop the dirty pages on the floor, because screw them we're
+going to invalidate them anyway. Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/extent_io.c | 14 ++++++++++++++
+ 1 files changed, 14 insertions(+), 0 deletions(-)
+
+diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
+index aaa12c1..01c21b6 100644
+--- a/fs/btrfs/extent_io.c
++++ b/fs/btrfs/extent_io.c
+@@ -3324,6 +3324,7 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
+ writepage_t writepage, void *data,
+ void (*flush_fn)(void *))
+ {
++ struct inode *inode = mapping->host;
+ int ret = 0;
+ int done = 0;
+ int nr_to_write_done = 0;
+@@ -3334,6 +3335,18 @@ static int extent_write_cache_pages(struct extent_io_tree *tree,
+ int scanned = 0;
+ int tag;
+
++ /*
++ * We have to hold onto the inode so that ordered extents can do their
++ * work when the IO finishes. The alternative to this is failing to add
++ * an ordered extent if the igrab() fails there and that is a huge pain
++ * to deal with, so instead just hold onto the inode throughout the
++ * writepages operation. If it fails here we are freeing up the inode
++ * anyway and we'd rather not waste our time writing out stuff that is
++ * going to be truncated anyway.
++ */
++ if (!igrab(inode))
++ return 0;
++
+ pagevec_init(&pvec, 0);
+ if (wbc->range_cyclic) {
+ index = mapping->writeback_index; /* Start from prev offset */
+@@ -3428,6 +3441,7 @@ retry:
+ index = 0;
+ goto retry;
+ }
++ btrfs_add_delayed_iput(inode);
+ return ret;
+ }
+
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8117-do-not-return-EINVAL-instead-of-ENOMEM-from-op.patch b/patches.suse/btrfs-8117-do-not-return-EINVAL-instead-of-ENOMEM-from-op.patch
new file mode 100644
index 0000000000..fbfebe8d15
--- /dev/null
+++ b/patches.suse/btrfs-8117-do-not-return-EINVAL-instead-of-ENOMEM-from-op.patch
@@ -0,0 +1,32 @@
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 22 Jun 2012 12:13:01 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: fed425c742cb1262ce90a41f2d3d211bac099533
+Subject: [PATCH] Btrfs: do not return EINVAL instead of ENOMEM from
+ open_ctree()
+
+When bailing from open_ctree() err is returned, not ret.
+
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/disk-io.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 2936ca4..fd216d9 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2244,7 +2244,7 @@ int open_ctree(struct super_block *sb,
+ ret |= btrfs_start_workers(&fs_info->caching_workers);
+ ret |= btrfs_start_workers(&fs_info->readahead_workers);
+ if (ret) {
+- ret = -ENOMEM;
++ err = -ENOMEM;
+ goto fail_sb_buffer;
+ }
+
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8118-do-not-ignore-errors-from-btrfs_cleanup_fs_roo.patch b/patches.suse/btrfs-8118-do-not-ignore-errors-from-btrfs_cleanup_fs_roo.patch
new file mode 100644
index 0000000000..63402f6131
--- /dev/null
+++ b/patches.suse/btrfs-8118-do-not-ignore-errors-from-btrfs_cleanup_fs_roo.patch
@@ -0,0 +1,36 @@
+From: Ilya Dryomov <idryomov@gmail.com>
+Date: Fri, 22 Jun 2012 12:14:13 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 44c44af2f4a6dc1595f1711cf307bd01062fd129
+Subject: [PATCH] Btrfs: do not ignore errors from
+ btrfs_cleanup_fs_roots() when mounting
+
+There used to be a BUG_ON(ret) there before EH patch (79787eaa) went in.
+Bail out with EINVAL.
+
+Cc: David Sterba <dsterba@suse.cz>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/disk-io.c | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index fd216d9..dd6676b 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -2466,8 +2466,8 @@ retry_root_backup:
+
+ if (!(sb->s_flags & MS_RDONLY)) {
+ ret = btrfs_cleanup_fs_roots(fs_info);
+- if (ret) {
+- }
++ if (ret)
++ goto fail_trans_kthread;
+
+ ret = btrfs_recover_relocation(tree_root);
+ if (ret < 0) {
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8119-fix-error-handling-in-__add_reloc_root.patch b/patches.suse/btrfs-8119-fix-error-handling-in-__add_reloc_root.patch
new file mode 100644
index 0000000000..dec7c45fd0
--- /dev/null
+++ b/patches.suse/btrfs-8119-fix-error-handling-in-__add_reloc_root.patch
@@ -0,0 +1,37 @@
+From: Dan Carpenter <dan.carpenter@oracle.com>
+Date: Mon, 25 Jun 2012 05:15:23 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 23291a044c31f9dfdeaf633b631059fb75e5c2c4
+Subject: [PATCH] Btrfs: fix error handling in __add_reloc_root()
+
+We dereferenced "node" in the error message after freeing it. Also
+btrfs_panic() can return so we should return an error code instead of
+continuing.
+
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/relocation.c | 3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 646ee21..c5dbd91 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -1239,10 +1239,11 @@ static int __must_check __add_reloc_root(struct btrfs_root *root)
+ node->bytenr, &node->rb_node);
+ spin_unlock(&rc->reloc_root_tree.lock);
+ if (rb_node) {
+- kfree(node);
+ btrfs_panic(root->fs_info, -EEXIST, "Duplicate root found "
+ "for start=%llu while inserting into relocation "
+ "tree\n");
++ kfree(node);
++ return -EEXIST;
+ }
+
+ list_add_tail(&root->root_list, &rc->reloc_roots);
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8120-return-error-of-btrfs_update_inode-to-caller.patch b/patches.suse/btrfs-8120-return-error-of-btrfs_update_inode-to-caller.patch
new file mode 100644
index 0000000000..763cf84a8b
--- /dev/null
+++ b/patches.suse/btrfs-8120-return-error-of-btrfs_update_inode-to-caller.patch
@@ -0,0 +1,50 @@
+From: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
+Date: Mon, 25 Jun 2012 21:25:22 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: b9959295151625c17723103afd79077e80b24ddd
+Subject: [PATCH] Btrfs: return error of btrfs_update_inode() to caller
+
+We didn't check error of btrfs_update_inode(), but that error looks
+easy to bubble back up.
+
+Reviewed-by: David Sterba <dsterba@suse.cz>
+Signed-off-by: Tsutomu Itoh <t-itoh@jp.fujitsu.com>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/inode.c | 2 +-
+ fs/btrfs/tree-log.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -2820,7 +2820,7 @@ err:
+
+ btrfs_i_size_write(dir, dir->i_size - name_len * 2);
+ inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+- btrfs_update_inode(trans, root, dir);
++ ret = btrfs_update_inode(trans, root, dir);
+ out:
+ return ret;
+ }
+--- a/fs/btrfs/tree-log.c
++++ b/fs/btrfs/tree-log.c
+@@ -637,7 +637,7 @@ static noinline int replay_one_extent(st
+ }
+
+ inode_set_bytes(inode, saved_nbytes);
+- btrfs_update_inode(trans, root, inode);
++ ret = btrfs_update_inode(trans, root, inode);
+ out:
+ if (inode)
+ iput(inode);
+@@ -1133,7 +1133,7 @@ static noinline int link_to_fixup_dir(st
+ btrfs_release_path(path);
+ if (ret == 0) {
+ btrfs_inc_nlink(inode);
+- btrfs_update_inode(trans, root, inode);
++ ret = btrfs_update_inode(trans, root, inode);
+ } else if (ret == -EEXIST) {
+ ret = 0;
+ } else {
diff --git a/patches.suse/btrfs-8121-fix-typo-in-cow_file_range_async-and-async_cow.patch b/patches.suse/btrfs-8121-fix-typo-in-cow_file_range_async-and-async_cow.patch
new file mode 100644
index 0000000000..f3b7d60fff
--- /dev/null
+++ b/patches.suse/btrfs-8121-fix-typo-in-cow_file_range_async-and-async_cow.patch
@@ -0,0 +1,42 @@
+From: Liu Bo <liubo2009@cn.fujitsu.com>
+Date: Thu, 28 Jun 2012 04:02:24 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 287082b0bd10060e9c6b32ed9605174ddf2f672a
+Subject: [PATCH] Btrfs: fix typo in cow_file_range_async and
+ async_cow_submit
+
+It should be 10 * 1024 * 1024.
+
+Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
+Signed-off-by: Jiri Kosina <jkosina@suse.cz>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/inode.c | 4 ++--
+ 1 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index f93a98e..18f1b44 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -1010,7 +1010,7 @@ static noinline void async_cow_submit(struct btrfs_work *work)
+ atomic_sub(nr_pages, &root->fs_info->async_delalloc_pages);
+
+ if (atomic_read(&root->fs_info->async_delalloc_pages) <
+- 5 * 1042 * 1024 &&
++ 5 * 1024 * 1024 &&
+ waitqueue_active(&root->fs_info->async_submit_wait))
+ wake_up(&root->fs_info->async_submit_wait);
+
+@@ -1035,7 +1035,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ unsigned long nr_pages;
+ u64 cur_end;
+- int limit = 10 * 1024 * 1042;
++ int limit = 10 * 1024 * 1024;
+
+ clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED,
+ 1, 0, NULL, GFP_NOFS);
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8122-fix-btrfs_is_free_space_inode-to-recognize-btr.patch b/patches.suse/btrfs-8122-fix-btrfs_is_free_space_inode-to-recognize-btr.patch
new file mode 100644
index 0000000000..0781669447
--- /dev/null
+++ b/patches.suse/btrfs-8122-fix-btrfs_is_free_space_inode-to-recognize-btr.patch
@@ -0,0 +1,40 @@
+From: Liu Bo <liubo2009@cn.fujitsu.com>
+Date: Tue, 10 Jul 2012 05:28:38 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 51a8cf9d2d97017d334f33f1b39067bd2f03bc49
+Subject: [PATCH] Btrfs: fix btrfs_is_free_space_inode to recognize
+ btree inode
+
+For btree inode, its root is also 'tree root', so btree inode can be
+misunderstood as a free space inode.
+
+We should add one more check for btree inode.
+
+Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/btrfs_inode.h | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
+index 12394a9..b168238 100644
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -194,8 +194,10 @@ static inline void btrfs_i_size_write(struct inode *inode, u64 size)
+ static inline bool btrfs_is_free_space_inode(struct btrfs_root *root,
+ struct inode *inode)
+ {
+- if (root == root->fs_info->tree_root ||
+- BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
++ if (root == root->fs_info->tree_root &&
++ btrfs_ino(inode) != BTRFS_BTREE_INODE_OBJECTID)
++ return true;
++ if (BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
+ return true;
+ return false;
+ }
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-8123-kill-root-from-btrfs_is_free_space_inode.patch b/patches.suse/btrfs-8123-kill-root-from-btrfs_is_free_space_inode.patch
new file mode 100644
index 0000000000..da83325d24
--- /dev/null
+++ b/patches.suse/btrfs-8123-kill-root-from-btrfs_is_free_space_inode.patch
@@ -0,0 +1,149 @@
+From: Liu Bo <liubo2009@cn.fujitsu.com>
+Date: Tue, 10 Jul 2012 05:28:39 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 83eea1f1bacd5dc7b44dcf84f5fdca54fdea5453
+Subject: [PATCH] Btrfs: kill root from btrfs_is_free_space_inode
+
+Since root can be fetched via BTRFS_I macro directly, we can save an args
+for btrfs_is_free_space_inode().
+
+Signed-off-by: Liu Bo <liubo2009@cn.fujitsu.com>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/btrfs_inode.h | 5 +++--
+ fs/btrfs/extent-tree.c | 2 +-
+ fs/btrfs/file-item.c | 2 +-
+ fs/btrfs/inode.c | 20 ++++++++++----------
+ 4 files changed, 15 insertions(+), 14 deletions(-)
+
+--- a/fs/btrfs/btrfs_inode.h
++++ b/fs/btrfs/btrfs_inode.h
+@@ -195,9 +195,10 @@ static inline void btrfs_i_size_write(st
+ BTRFS_I(inode)->disk_i_size = size;
+ }
+
+-static inline bool btrfs_is_free_space_inode(struct btrfs_root *root,
+- struct inode *inode)
++static inline bool btrfs_is_free_space_inode(struct inode *inode)
+ {
++ struct btrfs_root *root = BTRFS_I(inode)->root;
++
+ if (root == root->fs_info->tree_root &&
+ btrfs_ino(inode) != BTRFS_BTREE_INODE_OBJECTID)
+ return true;
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4483,7 +4483,7 @@ int btrfs_delalloc_reserve_metadata(stru
+ int ret;
+
+ /* Need to be holding the i_mutex here if we aren't free space cache */
+- if (btrfs_is_free_space_inode(root, inode))
++ if (btrfs_is_free_space_inode(inode))
+ flush = 0;
+
+ if (flush && btrfs_transaction_in_commit(root->fs_info))
+--- a/fs/btrfs/file-item.c
++++ b/fs/btrfs/file-item.c
+@@ -181,7 +181,7 @@ static int __btrfs_lookup_bio_sums(struc
+ * read from the commit root and sidestep a nasty deadlock
+ * between reading the free space cache and updating the csum tree.
+ */
+- if (btrfs_is_free_space_inode(root, inode)) {
++ if (btrfs_is_free_space_inode(inode)) {
+ path->search_commit_root = 1;
+ path->skip_locking = 1;
+ }
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -855,7 +855,7 @@ static noinline int cow_file_range(struc
+ struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
+ int ret = 0;
+
+- BUG_ON(btrfs_is_free_space_inode(root, inode));
++ BUG_ON(btrfs_is_free_space_inode(inode));
+ trans = btrfs_join_transaction(root);
+ if (IS_ERR(trans)) {
+ extent_clear_unlock_delalloc(inode,
+@@ -1179,7 +1179,7 @@ static noinline int run_delalloc_nocow(s
+ return -ENOMEM;
+ }
+
+- nolock = btrfs_is_free_space_inode(root, inode);
++ nolock = btrfs_is_free_space_inode(inode);
+
+ if (nolock)
+ trans = btrfs_join_transaction_nolock(root);
+@@ -1489,7 +1489,7 @@ static void btrfs_set_bit_hook(struct in
+ if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ u64 len = state->end + 1 - state->start;
+- bool do_list = !btrfs_is_free_space_inode(root, inode);
++ bool do_list = !btrfs_is_free_space_inode(inode);
+
+ if (*bits & EXTENT_FIRST_DELALLOC) {
+ *bits &= ~EXTENT_FIRST_DELALLOC;
+@@ -1524,7 +1524,7 @@ static void btrfs_clear_bit_hook(struct
+ if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+ u64 len = state->end + 1 - state->start;
+- bool do_list = !btrfs_is_free_space_inode(root, inode);
++ bool do_list = !btrfs_is_free_space_inode(inode);
+
+ if (*bits & EXTENT_FIRST_DELALLOC) {
+ *bits &= ~EXTENT_FIRST_DELALLOC;
+@@ -1635,7 +1635,7 @@ static int btrfs_submit_bio_hook(struct
+
+ skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
+
+- if (btrfs_is_free_space_inode(root, inode))
++ if (btrfs_is_free_space_inode(inode))
+ metadata = 2;
+
+ ret = btrfs_bio_wq_end_io(root->fs_info, bio, metadata);
+@@ -1898,7 +1898,7 @@ static int btrfs_finish_ordered_io(struc
+ return 0;
+ BUG_ON(!ordered_extent); /* Logic error */
+
+- nolock = btrfs_is_free_space_inode(root, inode);
++ nolock = btrfs_is_free_space_inode(inode);
+
+ if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
+ BUG_ON(!list_empty(&ordered_extent->list)); /* Logic error */
+@@ -2721,7 +2721,7 @@ noinline int btrfs_update_inode(struct b
+ * The data relocation inode should also be directly updated
+ * without delay
+ */
+- if (!btrfs_is_free_space_inode(root, inode)
++ if (!btrfs_is_free_space_inode(inode)
+ && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
+ ret = btrfs_delayed_update_inode(trans, root, inode);
+ if (!ret)
+@@ -3768,7 +3768,7 @@ void btrfs_evict_inode(struct inode *ino
+
+ truncate_inode_pages(&inode->i_data, 0);
+ if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
+- btrfs_is_free_space_inode(root, inode)))
++ btrfs_is_free_space_inode(inode)))
+ goto no_delete;
+
+ if (is_bad_inode(inode)) {
+@@ -4484,7 +4484,7 @@ int btrfs_write_inode(struct inode *inod
+ if (test_bit(BTRFS_INODE_DUMMY, &BTRFS_I(inode)->runtime_flags))
+ return 0;
+
+- if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(root, inode))
++ if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(inode))
+ nolock = true;
+
+ if (wbc->sync_mode == WB_SYNC_ALL) {
+@@ -7085,7 +7085,7 @@ int btrfs_drop_inode(struct inode *inode
+ struct btrfs_root *root = BTRFS_I(inode)->root;
+
+ if (btrfs_root_refs(&root->root_item) == 0 &&
+- !btrfs_is_free_space_inode(root, inode))
++ !btrfs_is_free_space_inode(inode))
+ return 1;
+ else
+ return generic_drop_inode(inode);
diff --git a/patches.suse/btrfs-8125-zero-unused-bytes-in-inode-item.patch b/patches.suse/btrfs-8125-zero-unused-bytes-in-inode-item.patch
new file mode 100644
index 0000000000..1ca29c2d28
--- /dev/null
+++ b/patches.suse/btrfs-8125-zero-unused-bytes-in-inode-item.patch
@@ -0,0 +1,48 @@
+From: Li Zefan <lizefan@huawei.com>
+Date: Tue, 10 Jul 2012 00:58:58 -0600
+Patch-mainline: yes
+References: FATE#306586
+Git-commit: 293f7e07405a63975cee4e95a2cfa0c17b34b3aa
+Subject: [PATCH] Btrfs: zero unused bytes in inode item
+
+The otime field is not zeroed, so users will see random otime in an old
+filesystem with a new kernel which has otime support in the future.
+
+The reserved bytes are also not zeroed, and we'll have compatibility
+issue if we make use of those bytes.
+
+Signed-off-by: Li Zefan <lizefan@huawei.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/delayed-inode.c | 1 +
+ fs/btrfs/inode.c | 2 ++
+ 2 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/fs/btrfs/delayed-inode.c b/fs/btrfs/delayed-inode.c
+index 21d91a8..335605c 100644
+--- a/fs/btrfs/delayed-inode.c
++++ b/fs/btrfs/delayed-inode.c
+@@ -62,6 +62,7 @@ static inline void btrfs_init_delayed_node(
+ INIT_LIST_HEAD(&delayed_node->n_list);
+ INIT_LIST_HEAD(&delayed_node->p_list);
+ delayed_node->bytes_reserved = 0;
++ memset(&delayed_node->inode_item, 0, sizeof(delayed_node->inode_item));
+ }
+
+ static inline int btrfs_is_continuous_delayed_item(
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
+index ee45ebf..144f464 100644
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -4693,6 +4693,8 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
+ inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ inode_item = btrfs_item_ptr(path->nodes[0], path->slots[0],
+ struct btrfs_inode_item);
++ memset_extent_buffer(path->nodes[0], 0, (unsigned long)inode_item,
++ sizeof(*inode_item));
+ fill_inode_item(trans, path->nodes[0], inode_item, inode);
+
+ ref = btrfs_item_ptr(path->nodes[0], path->slots[0] + 1,
+--
+1.7.6.233.gd79bc
+
diff --git a/patches.suse/btrfs-update-message-levels.patch b/patches.suse/btrfs-update-message-levels.patch
index ea34fd629e..73160a2519 100644
--- a/patches.suse/btrfs-update-message-levels.patch
+++ b/patches.suse/btrfs-update-message-levels.patch
@@ -7,17 +7,18 @@ Subject: [PATCH] Btrfs: update message levels
Signed-off-by: David Sterba <dsterba@suse.cz>
---
---
- fs/btrfs/disk-io.c | 2 +-
- fs/btrfs/extent-tree.c | 7 +++----
- fs/btrfs/inode.c | 6 +++---
- fs/btrfs/super.c | 4 ++--
- 4 files changed, 9 insertions(+), 10 deletions(-)
+ fs/btrfs/disk-io.c | 14 +++++++-------
+ fs/btrfs/extent-tree.c | 24 ++++++++++++++----------
+ fs/btrfs/free-space-cache.c | 5 +++--
+ fs/btrfs/inode.c | 8 ++++----
+ fs/btrfs/root-tree.c | 2 +-
+ fs/btrfs/super.c | 6 +++---
+ fs/btrfs/volumes.c | 8 ++++----
+ 7 files changed, 36 insertions(+), 31 deletions(-)
-Index: linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
-===================================================================
---- linux-3.0-SLE11-SP2.orig/fs/btrfs/disk-io.c
-+++ linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
-@@ -337,7 +337,7 @@ static int verify_parent_transid(struct
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -341,7 +341,7 @@ static int verify_parent_transid(struct
ret = 0;
goto out;
}
@@ -26,7 +27,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
"found %llu\n",
(unsigned long long)eb->start,
(unsigned long long)parent_transid,
-@@ -2415,13 +2415,13 @@ retry_root_backup:
+@@ -2424,13 +2424,13 @@ retry_root_backup:
ret = btrfs_init_space_info(fs_info);
if (ret) {
@@ -42,7 +43,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
goto fail_block_groups;
}
-@@ -2617,7 +2617,7 @@ static void btrfs_end_buffer_write_sync(
+@@ -2629,7 +2629,7 @@ static void btrfs_end_buffer_write_sync(
if (uptodate) {
set_buffer_uptodate(bh);
} else {
@@ -51,7 +52,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
"I/O error on %s\n",
bdevname(bh->b_bdev, b));
/* note, we dont' set_buffer_write_io_error because we have
-@@ -2790,7 +2790,7 @@ static int write_dev_flush(struct btrfs_
+@@ -2802,7 +2802,7 @@ static int write_dev_flush(struct btrfs_
wait_for_completion(&device->flush_wait);
if (bio_flagged(bio, BIO_EOPNOTSUPP)) {
@@ -60,7 +61,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
device->name);
device->nobarriers = 1;
}
-@@ -3355,7 +3355,7 @@ static int btrfs_check_super_valid(struc
+@@ -3370,7 +3370,7 @@ static int btrfs_check_super_valid(struc
return 0;
if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) {
@@ -69,7 +70,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
"running btrfsck is recommended\n");
}
-@@ -3452,7 +3452,7 @@ int btrfs_destroy_delayed_refs(struct bt
+@@ -3467,7 +3467,7 @@ int btrfs_destroy_delayed_refs(struct bt
spin_lock(&delayed_refs->lock);
if (delayed_refs->num_entries == 0) {
spin_unlock(&delayed_refs->lock);
@@ -78,10 +79,8 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/disk-io.c
return ret;
}
-Index: linux-3.0-SLE11-SP2/fs/btrfs/extent-tree.c
-===================================================================
---- linux-3.0-SLE11-SP2.orig/fs/btrfs/extent-tree.c
-+++ linux-3.0-SLE11-SP2/fs/btrfs/extent-tree.c
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
@@ -2301,7 +2301,9 @@ static noinline int run_clustered_refs(s
kfree(extent_op);
@@ -156,10 +155,29 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/extent-tree.c
}
ret = reserve_metadata_bytes(root, block_rsv, blocksize, 0);
if (!ret) {
-Index: linux-3.0-SLE11-SP2/fs/btrfs/inode.c
-===================================================================
---- linux-3.0-SLE11-SP2.orig/fs/btrfs/inode.c
-+++ linux-3.0-SLE11-SP2/fs/btrfs/inode.c
+--- a/fs/btrfs/free-space-cache.c
++++ b/fs/btrfs/free-space-cache.c
+@@ -101,7 +101,8 @@ struct inode *lookup_free_space_inode(st
+
+ spin_lock(&block_group->lock);
+ if (!((BTRFS_I(inode)->flags & flags) == flags)) {
+- printk(KERN_INFO "Old style space inode found, converting.\n");
++ printk(KERN_INFO
++ "btrfs: Old style space inode found, converting.\n");
+ BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM |
+ BTRFS_INODE_NODATACOW;
+ block_group->disk_cache_state = BTRFS_DC_CLEAR;
+@@ -797,7 +798,7 @@ int load_free_space_cache(struct btrfs_f
+
+ if (!matched) {
+ __btrfs_remove_free_space_cache(ctl);
+- printk(KERN_ERR "block group %llu has an wrong amount of free "
++ printk(KERN_ERR "btrfs: block group %llu has an wrong amount of free "
+ "space\n", block_group->key.objectid);
+ ret = -1;
+ }
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
@@ -2457,13 +2457,13 @@ int btrfs_orphan_cleanup(struct btrfs_ro
}
@@ -186,10 +204,19 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/inode.c
"delete, will truncate on mount %d\n", ret);
btrfs_orphan_del(NULL, inode);
btrfs_free_block_rsv(root, rsv);
-Index: linux-3.0-SLE11-SP2/fs/btrfs/super.c
-===================================================================
---- linux-3.0-SLE11-SP2.orig/fs/btrfs/super.c
-+++ linux-3.0-SLE11-SP2/fs/btrfs/super.c
+--- a/fs/btrfs/root-tree.c
++++ b/fs/btrfs/root-tree.c
+@@ -104,7 +104,7 @@ int btrfs_update_root(struct btrfs_trans
+
+ if (ret != 0) {
+ btrfs_print_leaf(root, path->nodes[0]);
+- printk(KERN_CRIT "unable to update root key %llu %u %llu\n",
++ printk(KERN_CRIT "btrfs: unable to update root key %llu %u %llu\n",
+ (unsigned long long)key->objectid, key->type,
+ (unsigned long long)key->offset);
+ BUG_ON(1);
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
@@ -741,7 +741,7 @@ static int btrfs_fill_super(struct super
tree_root = open_ctree(sb, fs_devices, (char *)data);
@@ -199,7 +226,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/super.c
return PTR_ERR(tree_root);
}
fs_info = tree_root->fs_info;
-@@ -1468,7 +1468,7 @@ static void btrfs_fs_dirty_inode(struct
+@@ -1472,7 +1472,7 @@ static void btrfs_fs_dirty_inode(struct
ret = btrfs_dirty_inode(inode);
if (ret)
@@ -208,7 +235,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/super.c
"error %d\n", btrfs_ino(inode), ret);
}
-@@ -1518,7 +1518,7 @@ static int btrfs_interface_init(void)
+@@ -1522,7 +1522,7 @@ static int btrfs_interface_init(void)
static void btrfs_interface_exit(void)
{
if (misc_deregister(&btrfs_misc) < 0)
@@ -217,55 +244,8 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/super.c
}
static int __init init_btrfs_fs(void)
-Index: linux-3.0-SLE11-SP2/fs/btrfs/free-space-cache.c
-===================================================================
---- linux-3.0-SLE11-SP2.orig/fs/btrfs/free-space-cache.c
-+++ linux-3.0-SLE11-SP2/fs/btrfs/free-space-cache.c
-@@ -101,7 +101,8 @@ struct inode *lookup_free_space_inode(st
-
- spin_lock(&block_group->lock);
- if (!((BTRFS_I(inode)->flags & flags) == flags)) {
-- printk(KERN_INFO "Old style space inode found, converting.\n");
-+ printk(KERN_INFO
-+ "btrfs: Old style space inode found, converting.\n");
- BTRFS_I(inode)->flags |= BTRFS_INODE_NODATASUM |
- BTRFS_INODE_NODATACOW;
- block_group->disk_cache_state = BTRFS_DC_CLEAR;
-@@ -797,7 +798,7 @@ int load_free_space_cache(struct btrfs_f
-
- if (!matched) {
- __btrfs_remove_free_space_cache(ctl);
-- printk(KERN_ERR "block group %llu has an wrong amount of free "
-+ printk(KERN_ERR "btrfs: block group %llu has an wrong amount of free "
- "space\n", block_group->key.objectid);
- ret = -1;
- }
-@@ -1884,7 +1885,7 @@ again:
-
- if (next_info->bytes < bytes ||
- next_info->offset > offset || offset > end) {
-- printk(KERN_CRIT "Found free space at %llu, size %llu,"
-+ printk(KERN_CRIT "btrfs: Found free space at %llu, size %llu,"
- " trying to use %llu\n",
- (unsigned long long)info->offset,
- (unsigned long long)info->bytes,
-Index: linux-3.0-SLE11-SP2/fs/btrfs/root-tree.c
-===================================================================
---- linux-3.0-SLE11-SP2.orig/fs/btrfs/root-tree.c
-+++ linux-3.0-SLE11-SP2/fs/btrfs/root-tree.c
-@@ -104,7 +104,7 @@ int btrfs_update_root(struct btrfs_trans
-
- if (ret != 0) {
- btrfs_print_leaf(root, path->nodes[0]);
-- printk(KERN_CRIT "unable to update root key %llu %u %llu\n",
-+ printk(KERN_CRIT "btrfs: unable to update root key %llu %u %llu\n",
- (unsigned long long)key->objectid, key->type,
- (unsigned long long)key->offset);
- BUG_ON(1);
-Index: linux-3.0-SLE11-SP2/fs/btrfs/volumes.c
-===================================================================
---- linux-3.0-SLE11-SP2.orig/fs/btrfs/volumes.c
-+++ linux-3.0-SLE11-SP2/fs/btrfs/volumes.c
+--- a/fs/btrfs/volumes.c
++++ b/fs/btrfs/volumes.c
@@ -618,7 +618,7 @@ static int __btrfs_open_devices(struct b
bdev = blkdev_get_by_path(device->name, flags, holder);
@@ -275,7 +255,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/volumes.c
goto error;
}
filemap_write_and_wait(bdev->bd_inode->i_mapping);
-@@ -3726,7 +3726,7 @@ static int __btrfs_map_block(struct btrf
+@@ -3743,7 +3743,7 @@ static int __btrfs_map_block(struct btrf
read_unlock(&em_tree->lock);
if (!em) {
@@ -284,7 +264,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/volumes.c
(unsigned long long)logical,
(unsigned long long)*length);
BUG();
-@@ -4136,7 +4136,7 @@ int btrfs_map_bio(struct btrfs_root *roo
+@@ -4153,7 +4153,7 @@ int btrfs_map_bio(struct btrfs_root *roo
total_devs = bbio->num_stripes;
if (map_length < length) {
@@ -293,7 +273,7 @@ Index: linux-3.0-SLE11-SP2/fs/btrfs/volumes.c
"len %llu\n", (unsigned long long)logical,
(unsigned long long)length,
(unsigned long long)map_length);
-@@ -4408,7 +4408,7 @@ static int read_one_dev(struct btrfs_roo
+@@ -4425,7 +4425,7 @@ static int read_one_dev(struct btrfs_roo
return -EIO;
if (!device) {
diff --git a/series.conf b/series.conf
index 85eed85aca..47b739bb1d 100644
--- a/series.conf
+++ b/series.conf
@@ -714,6 +714,8 @@
patches.fixes/large-hash-dcache_init-fix.patch
patches.fixes/mm-backing-dev-fix-wakeup-timer-races-with-bdi_unregister.patch
+ patches.fixes/silence-weird-name-warning
+
########################################################
# IPC patches
########################################################
@@ -1424,6 +1426,28 @@
patches.suse/btrfs-8093-unlock-everything-properly-in-the-error-case-f.patch
patches.suse/btrfs-8095-use-writeback_inodes_sb-_nr-_if_idle.patch
patches.suse/btrfs-8094-flush-all-the-dirty-pages-if-try_to_writeback_.patch
+ patches.suse/btrfs-8096-avoid-sleeping-in-verify_parent_transid-while-.patch
+ patches.suse/btrfs-8097-fix-btrfs_release_extent_buffer_page-with-the-.patch
+ patches.suse/btrfs-8098-do-not-check-delalloc-when-updating-disk_i_siz.patch
+ patches.suse/btrfs-8102-look-into-the-extent-during-find_all_leafs.patch
+ patches.suse/btrfs-8103-don-t-set-for_cow-parameter-for-tree-block-fun.patch
+ patches.suse/btrfs-8105-fix-defrag-regression.patch
+ patches.suse/btrfs-8106-fix-missing-inherited-flag-in-rename.patch
+ patches.suse/btrfs-8107-do-not-resize-a-seeding-device.patch
+ patches.suse/btrfs-8108-cast-devid-to-unsigned-long-long-for-printk-ll.patch
+ patches.suse/btrfs-8109-add-a-missing-spin_lock.patch
+ patches.suse/btrfs-8111-restore-restriper-state-on-all-mounts.patch
+ patches.suse/btrfs-8112-resume-balance-on-rw-re-mounts-properly.patch
+ patches.suse/btrfs-8114-fix-tree-log-remove-space-corner-case.patch
+ patches.suse/btrfs-8115-hold-a-ref-on-the-inode-during-writepages.patch
+ patches.suse/btrfs-8117-do-not-return-EINVAL-instead-of-ENOMEM-from-op.patch
+ patches.suse/btrfs-8118-do-not-ignore-errors-from-btrfs_cleanup_fs_roo.patch
+ patches.suse/btrfs-8119-fix-error-handling-in-__add_reloc_root.patch
+ patches.suse/btrfs-8120-return-error-of-btrfs_update_inode-to-caller.patch
+ patches.suse/btrfs-8121-fix-typo-in-cow_file_range_async-and-async_cow.patch
+ patches.suse/btrfs-8122-fix-btrfs_is_free_space_inode-to-recognize-btr.patch
+ patches.suse/btrfs-8123-kill-root-from-btrfs_is_free_space_inode.patch
+ patches.suse/btrfs-8125-zero-unused-bytes-in-inode-item.patch
patches.suse/btrfs-update-message-levels.patch
+dsterba patches.suse/btrfs-debug-setpagedirty-tracing.patch
@@ -1434,6 +1458,7 @@
patches.suse/reiserfs-barrier-default
patches.fixes/reiserfs-xattr-crash-fix
patches.fixes/reiserfs-writeback-buffer-lock.patch
+ patches.fixes/reiserfs-fix-deadlock-in-quota-code
########################################################
# dlm
@@ -2441,6 +2466,7 @@
#bnc758703
patches.drivers/rt2x00-RT3290-chip-support-v4.patch
patches.drivers/rt2x00-fix_rt3290_resuming.patch
+ patches.fixes/rt2800-add-chipset-revision-rt5390r-support
patches.fixes/batman-adv-bat_socket_read-missing-checks.patch
patches.fixes/batman-adv-Only-write-requested-number-of-byte-to-us.patch
@@ -3217,6 +3243,7 @@
patches.fixes/md-no-readonly.fix
patches.suse/md-raid10-disable-recovery
patches.fixes/md-record-write-mostly-status
+ patches.fixes/md-raid0-size-fix
+BTMU patches.suse/md-raid10-handle-merge_bvec_fn-in-member-devices.patch
+BMTU patches.suse/md-raid10-merge_bvec_fn.fix