Home Home > GIT Browse > openSUSE-15.0
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2013-03-28 13:03:03 +0100
committerDavid Sterba <dsterba@suse.cz>2013-03-28 13:03:45 +0100
commitd30f6aa29ceb16da895151e3783b30a598b73239 (patch)
tree13f7f158488ef96d75c5a0e7fe08f2a4cfecb1c0
parentb2816c655189e906752c337d1ce1d3cc6b1a3ca7 (diff)
- btrfs: deprecate subvolrootid mount option.rpm-3.0.70-0.7
- btrfs: clean snapshots one by one. - btrfs: cover more error codes in btrfs_decode_error. - Btrfs: fix EIO from btrfs send in is_extent_unchanged for punched holes. - Btrfs: fix space leak when we fail to reserve metadata space. - Btrfs: fix space accounting for unlink and rename. - Btrfs: hold the ordered operations mutex when waiting on ordered extents. - Btrfs: limit the global reserve to 512mb.
-rw-r--r--patches.suse/btrfs-8189-clean-snapshots-one-by-one.patch200
-rw-r--r--patches.suse/btrfs-8190-deprecate-subvolrootid-mount-option.patch62
-rw-r--r--patches.suse/btrfs-8191-cover-more-error-codes-in-btrfs_decode_error.patch31
-rw-r--r--patches.suse/btrfs-8192-fix-EIO-from-btrfs-send-in-is_extent_unchanged.patch39
-rw-r--r--patches.suse/btrfs-8193-fix-space-leak-when-we-fail-to-reserve-metadat.patch82
-rw-r--r--patches.suse/btrfs-8194-fix-space-accounting-for-unlink-and-rename.patch40
-rw-r--r--patches.suse/btrfs-8195-hold-the-ordered-operations-mutex-when-waiting.patch36
-rw-r--r--patches.suse/btrfs-8196-limit-the-global-reserve-to-512mb.patch32
-rw-r--r--series.conf12
9 files changed, 532 insertions, 2 deletions
diff --git a/patches.suse/btrfs-8189-clean-snapshots-one-by-one.patch b/patches.suse/btrfs-8189-clean-snapshots-one-by-one.patch
new file mode 100644
index 0000000000..609b7dd431
--- /dev/null
+++ b/patches.suse/btrfs-8189-clean-snapshots-one-by-one.patch
@@ -0,0 +1,200 @@
+From: David Sterba <dsterba@suse.cz>
+Date: Tue, 12 Mar 2013 15:13:28 +0000
+Patch-mainline: pending
+Subject: [PATCH] btrfs: clean snapshots one by one
+
+Each time pick one dead root from the list and let the caller know if
+it's needed to continue. This should improve responsiveness during
+umount and balance which at some point waits for cleaning all currently
+queued dead roots.
+
+A new dead root is added to the end of the list, so the snapshots
+disappear in the order of deletion.
+
+The snapshot cleaning work is now done only from the cleaner thread and the
+others wake it if needed.
+
+Signed-off-by: David Sterba <dsterba@suse.cz>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+---
+ fs/btrfs/disk-io.c | 10 ++++++---
+ fs/btrfs/extent-tree.c | 8 ++++++++
+ fs/btrfs/relocation.c | 3 ---
+ fs/btrfs/transaction.c | 56 +++++++++++++++++++++++++++++++++-----------------
+ fs/btrfs/transaction.h | 2 +-
+ 5 files changed, 53 insertions(+), 26 deletions(-)
+
+diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
+index 84214e5..fe82d08 100644
+--- a/fs/btrfs/disk-io.c
++++ b/fs/btrfs/disk-io.c
+@@ -1696,15 +1696,19 @@ static int cleaner_kthread(void *arg)
+ struct btrfs_root *root = arg;
+
+ do {
++ int again = 0;
++
+ if (!(root->fs_info->sb->s_flags & MS_RDONLY) &&
++ down_read_trylock(&root->fs_info->sb->s_umount) &&
+ mutex_trylock(&root->fs_info->cleaner_mutex)) {
+ btrfs_run_delayed_iputs(root);
+- btrfs_clean_old_snapshots(root);
++ again = btrfs_clean_one_deleted_snapshot(root);
+ mutex_unlock(&root->fs_info->cleaner_mutex);
+ btrfs_run_defrag_inodes(root->fs_info);
++ up_read(&root->fs_info->sb->s_umount);
+ }
+
+- if (!try_to_freeze()) {
++ if (!try_to_freeze() && !again) {
+ set_current_state(TASK_INTERRUPTIBLE);
+ if (!kthread_should_stop())
+ schedule();
+@@ -3415,8 +3419,8 @@ int btrfs_commit_super(struct btrfs_root *root)
+
+ mutex_lock(&root->fs_info->cleaner_mutex);
+ btrfs_run_delayed_iputs(root);
+- btrfs_clean_old_snapshots(root);
+ mutex_unlock(&root->fs_info->cleaner_mutex);
++ wake_up_process(root->fs_info->cleaner_kthread);
+
+ /* wait until ongoing cleanup work done */
+ down_write(&root->fs_info->cleanup_work_sem);
+diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
+index 827e463..7e91583 100644
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -7268,6 +7268,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
+ * reference count by one. if update_ref is true, this function
+ * also make sure backrefs for the shared block and all lower level
+ * blocks are properly updated.
++ *
++ * If called with for_reloc == 0, may exit early with -EAGAIN
+ */
+ int btrfs_drop_snapshot(struct btrfs_root *root,
+ struct btrfs_block_rsv *block_rsv, int update_ref,
+@@ -7368,6 +7370,12 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
+ wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root);
+
+ while (1) {
++ if (!for_reloc && btrfs_fs_closing(root->fs_info)) {
++ pr_debug("btrfs: drop snapshot early exit\n");
++ err = -EAGAIN;
++ goto out_end_trans;
++ }
++
+ ret = walk_down_tree(trans, root, path, wc);
+ if (ret < 0) {
+ err = ret;
+diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c
+index 8445000..50deb9ed 100644
+--- a/fs/btrfs/relocation.c
++++ b/fs/btrfs/relocation.c
+@@ -4148,10 +4148,7 @@ int btrfs_relocate_block_group(struct btrfs_root *extent_root, u64 group_start)
+
+ while (1) {
+ mutex_lock(&fs_info->cleaner_mutex);
+-
+- btrfs_clean_old_snapshots(fs_info->tree_root);
+ ret = relocate_block_group(rc);
+-
+ mutex_unlock(&fs_info->cleaner_mutex);
+ if (ret < 0) {
+ err = ret;
+diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
+index a6a38ef..74cf8b0 100644
+--- a/fs/btrfs/transaction.c
++++ b/fs/btrfs/transaction.c
+@@ -949,7 +949,7 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
+ int btrfs_add_dead_root(struct btrfs_root *root)
+ {
+ spin_lock(&root->fs_info->trans_lock);
+- list_add(&root->root_list, &root->fs_info->dead_roots);
++ list_add_tail(&root->root_list, &root->fs_info->dead_roots);
+ spin_unlock(&root->fs_info->trans_lock);
+ return 0;
+ }
+@@ -1874,31 +1874,49 @@ cleanup_transaction:
+ }
+
+ /*
+- * interface function to delete all the snapshots we have scheduled for deletion
++ * return < 0 if error
++ * 0 if there are no more dead_roots at the time of call
++ * 1 there are more to be processed, call me again
++ *
++ * The return value indicates there are certainly more snapshots to delete, but
++ * if there comes a new one during processing, it may return 0. We don't mind,
++ * because btrfs_commit_super will poke cleaner thread and it will process it a
++ * few seconds later.
+ */
+-int btrfs_clean_old_snapshots(struct btrfs_root *root)
++int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root)
+ {
+- LIST_HEAD(list);
++ int ret;
+ struct btrfs_fs_info *fs_info = root->fs_info;
+
++ if (fs_info->sb->s_flags & MS_RDONLY) {
++ pr_debug("btrfs: cleaner called for RO fs!\n");
++ return 0;
++ }
++
+ spin_lock(&fs_info->trans_lock);
+- list_splice_init(&fs_info->dead_roots, &list);
++ if (list_empty(&fs_info->dead_roots)) {
++ spin_unlock(&fs_info->trans_lock);
++ return 0;
++ }
++ root = list_first_entry(&fs_info->dead_roots,
++ struct btrfs_root, root_list);
++ list_del(&root->root_list);
+ spin_unlock(&fs_info->trans_lock);
+
+- while (!list_empty(&list)) {
+- int ret;
+-
+- root = list_entry(list.next, struct btrfs_root, root_list);
+- list_del(&root->root_list);
++ pr_debug("btrfs: cleaner removing %llu\n",
++ (unsigned long long)root->objectid);
+
+- btrfs_kill_all_delayed_nodes(root);
++ btrfs_kill_all_delayed_nodes(root);
+
+- if (btrfs_header_backref_rev(root->node) <
+- BTRFS_MIXED_BACKREF_REV)
+- ret = btrfs_drop_snapshot(root, NULL, 0, 0);
+- else
+- ret =btrfs_drop_snapshot(root, NULL, 1, 0);
+- BUG_ON(ret < 0);
+- }
+- return 0;
++ if (btrfs_header_backref_rev(root->node) <
++ BTRFS_MIXED_BACKREF_REV)
++ ret = btrfs_drop_snapshot(root, NULL, 0, 0);
++ else
++ ret = btrfs_drop_snapshot(root, NULL, 1, 0);
++ /*
++ * If we encounter a transaction abort during snapshot cleaning, we
++ * don't want to crash here
++ */
++ BUG_ON(ret < 0 && ret != -EAGAIN && ret != -EROFS);
++ return 1;
+ }
+diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
+index 3c8e0d2..f6edd5e 100644
+--- a/fs/btrfs/transaction.h
++++ b/fs/btrfs/transaction.h
+@@ -123,7 +123,7 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
+
+ int btrfs_add_dead_root(struct btrfs_root *root);
+ int btrfs_defrag_root(struct btrfs_root *root);
+-int btrfs_clean_old_snapshots(struct btrfs_root *root);
++int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root);
+ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root);
+ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
+--
+1.8.2
+
diff --git a/patches.suse/btrfs-8190-deprecate-subvolrootid-mount-option.patch b/patches.suse/btrfs-8190-deprecate-subvolrootid-mount-option.patch
new file mode 100644
index 0000000000..f4e7f9785f
--- /dev/null
+++ b/patches.suse/btrfs-8190-deprecate-subvolrootid-mount-option.patch
@@ -0,0 +1,62 @@
+From: David Sterba <dsterba@suse.cz>
+Date: Wed, 20 Mar 2013 13:21:10 +0000
+Patch-mainline: pending
+Subject: [PATCH] btrfs: deprecate subvolrootid mount option
+
+This mount option was a workaround when subvol= assumed path relative
+to the default subvolume, not the toplevel one. This was fixed long time
+ago and subvolrootid has no effect.
+
+Signed-off-by: David Sterba <dsterba@suse.cz>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+---
+ fs/btrfs/super.c | 17 ++++-------------
+ 1 file changed, 4 insertions(+), 13 deletions(-)
+
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -628,7 +628,7 @@ out:
+ */
+ static int btrfs_parse_early_options(const char *options, fmode_t flags,
+ void *holder, char **subvol_name, u64 *subvol_objectid,
+- u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices)
++ struct btrfs_fs_devices **fs_devices)
+ {
+ substring_t args[MAX_OPT_ARGS];
+ char *device_name, *opts, *orig, *p;
+@@ -671,16 +671,8 @@ static int btrfs_parse_early_options(con
+ }
+ break;
+ case Opt_subvolrootid:
+- intarg = 0;
+- error = match_int(&args[0], &intarg);
+- if (!error) {
+- /* we want the original fs_tree */
+- if (!intarg)
+- *subvol_rootid =
+- BTRFS_FS_TREE_OBJECTID;
+- else
+- *subvol_rootid = intarg;
+- }
++ printk(KERN_WARNING
++ "btrfs: 'subvolrootid' mount option is deprecated and has no effect\n");
+ break;
+ case Opt_device:
+ device_name = match_strdup(&args[0]);
+@@ -1087,7 +1079,6 @@ static struct dentry *btrfs_mount(struct
+ fmode_t mode = FMODE_READ;
+ char *subvol_name = NULL;
+ u64 subvol_objectid = 0;
+- u64 subvol_rootid = 0;
+ int error = 0;
+
+ if (!(flags & MS_RDONLY))
+@@ -1095,7 +1086,7 @@ static struct dentry *btrfs_mount(struct
+
+ error = btrfs_parse_early_options(data, mode, fs_type,
+ &subvol_name, &subvol_objectid,
+- &subvol_rootid, &fs_devices);
++ &fs_devices);
+ if (error) {
+ kfree(subvol_name);
+ return ERR_PTR(error);
diff --git a/patches.suse/btrfs-8191-cover-more-error-codes-in-btrfs_decode_error.patch b/patches.suse/btrfs-8191-cover-more-error-codes-in-btrfs_decode_error.patch
new file mode 100644
index 0000000000..474566a050
--- /dev/null
+++ b/patches.suse/btrfs-8191-cover-more-error-codes-in-btrfs_decode_error.patch
@@ -0,0 +1,31 @@
+From: David Sterba <dsterba@suse.cz>
+Date: Wed, 20 Mar 2013 14:29:47 +0000
+Patch-mainline: pending
+Subject: [PATCH] btrfs: cover more error codes in btrfs_decode_error
+
+Signed-off-by: David Sterba <dsterba@suse.cz>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+---
+ fs/btrfs/super.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
+index f4da2d5..984816f 100644
+--- a/fs/btrfs/super.c
++++ b/fs/btrfs/super.c
+@@ -81,6 +81,12 @@ static const char *btrfs_decode_error(int errno)
+ case -EEXIST:
+ errstr = "Object already exists";
+ break;
++ case -ENOSPC:
++ errstr = "No space left";
++ break;
++ case -ENOENT:
++ errstr = "No such entry";
++ break;
+ }
+
+ return errstr;
+--
+1.8.2
+
diff --git a/patches.suse/btrfs-8192-fix-EIO-from-btrfs-send-in-is_extent_unchanged.patch b/patches.suse/btrfs-8192-fix-EIO-from-btrfs-send-in-is_extent_unchanged.patch
new file mode 100644
index 0000000000..7fa1f6cadb
--- /dev/null
+++ b/patches.suse/btrfs-8192-fix-EIO-from-btrfs-send-in-is_extent_unchanged.patch
@@ -0,0 +1,39 @@
+From: Jan Schmidt <list.btrfs@jan-o-sch.net>
+Date: Thu, 21 Mar 2013 14:30:23 +0000
+Patch-mainline: pending
+Subject: [PATCH] Btrfs: fix EIO from btrfs send in is_extent_unchanged
+ for punched holes
+
+When you take a snapshot, punch a hole where there has been data, then take
+another snapshot and try to send an incremental stream, btrfs send would
+give you EIO. That is because is_extent_unchanged had no support for holes
+being punched. With this patch, instead of returning EIO we just return
+0 (== the extent is not unchanged) and we're good.
+
+Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
+Cc: Alexander Block <ablock84@gmail.com>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/send.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+--- a/fs/btrfs/send.c
++++ b/fs/btrfs/send.c
+@@ -3944,12 +3944,10 @@ static int is_extent_unchanged(struct se
+ found_key.type != key.type) {
+ key.offset += right_len;
+ break;
+- } else {
+- if (found_key.offset != key.offset + right_len) {
+- /* Should really not happen */
+- ret = -EIO;
+- goto out;
+- }
++ }
++ if (found_key.offset != key.offset + right_len) {
++ ret = 0;
++ goto out;
+ }
+ key = found_key;
+ }
diff --git a/patches.suse/btrfs-8193-fix-space-leak-when-we-fail-to-reserve-metadat.patch b/patches.suse/btrfs-8193-fix-space-leak-when-we-fail-to-reserve-metadat.patch
new file mode 100644
index 0000000000..38a11a8dc3
--- /dev/null
+++ b/patches.suse/btrfs-8193-fix-space-leak-when-we-fail-to-reserve-metadat.patch
@@ -0,0 +1,82 @@
+From: Josef Bacik <jbacik@fusionio.com>
+Date: Mon, 25 Mar 2013 16:03:35 -0400
+Patch-mainline: pending
+Subject: [PATCH] Btrfs: fix space leak when we fail to reserve metadata
+ space
+
+Dave reported a warning when running xfstest 275. We have been leaking delalloc
+metadata space when our reservations fail. This is because we were improperly
+calculating how much space to free for our checksum reservations. The problem
+is we would sometimes free up space that had already been freed in another
+thread and we would end up with negative usage for the delalloc space. This
+patch fixes the problem by calculating how much space the other threads would
+have already freed, and then calculate how much space we need to free had we not
+done the reservation at all, and then freeing any excess space. This makes
+xfstests 275 no longer have leaked space. Thanks
+
+Cc: stable@vger.kernel.org
+Reported-by: David Sterba <dsterba@suse.cz>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/extent-tree.c | 47 +++++++++++++++++++++++++++++++++++++++++------
+ 1 file changed, 41 insertions(+), 6 deletions(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4812,14 +4812,49 @@ out_fail:
+ * If the inodes csum_bytes is the same as the original
+ * csum_bytes then we know we haven't raced with any free()ers
+ * so we can just reduce our inodes csum bytes and carry on.
+- * Otherwise we have to do the normal free thing to account for
+- * the case that the free side didn't free up its reserve
+- * because of this outstanding reservation.
+ */
+- if (BTRFS_I(inode)->csum_bytes == csum_bytes)
++ if (BTRFS_I(inode)->csum_bytes == csum_bytes) {
+ calc_csum_metadata_size(inode, num_bytes, 0);
+- else
+- to_free = calc_csum_metadata_size(inode, num_bytes, 0);
++ } else {
++ u64 orig_csum_bytes = BTRFS_I(inode)->csum_bytes;
++ u64 bytes;
++
++ /*
++ * This is tricky, but first we need to figure out how much we
++ * free'd from any free-ers that occured during this
++ * reservation, so we reset ->csum_bytes to the csum_bytes
++ * before we dropped our lock, and then call the free for the
++ * number of bytes that were freed while we were trying our
++ * reservation.
++ */
++ bytes = csum_bytes - BTRFS_I(inode)->csum_bytes;
++ BTRFS_I(inode)->csum_bytes = csum_bytes;
++ to_free = calc_csum_metadata_size(inode, bytes, 0);
++
++
++ /*
++ * Now we need to see how much we would have freed had we not
++ * been making this reservation and our ->csum_bytes were not
++ * artificially inflated.
++ */
++ BTRFS_I(inode)->csum_bytes = csum_bytes - num_bytes;
++ bytes = csum_bytes - orig_csum_bytes;
++ bytes = calc_csum_metadata_size(inode, bytes, 0);
++
++ /*
++ * Now reset ->csum_bytes to what it should be. If bytes is
++ * more than to_free then we would have free'd more space had we
++ * not had an artificially high ->csum_bytes, so we need to free
++ * the remainder. If bytes is the same or less then we don't
++ * need to do anything, the other free-ers did the correct
++ * thing.
++ */
++ BTRFS_I(inode)->csum_bytes = orig_csum_bytes - num_bytes;
++ if (bytes > to_free)
++ to_free = bytes - to_free;
++ else
++ to_free = 0;
++ }
+ spin_unlock(&BTRFS_I(inode)->lock);
+ if (dropped)
+ to_free += btrfs_calc_trans_metadata_size(root, dropped);
diff --git a/patches.suse/btrfs-8194-fix-space-accounting-for-unlink-and-rename.patch b/patches.suse/btrfs-8194-fix-space-accounting-for-unlink-and-rename.patch
new file mode 100644
index 0000000000..7680e07334
--- /dev/null
+++ b/patches.suse/btrfs-8194-fix-space-accounting-for-unlink-and-rename.patch
@@ -0,0 +1,40 @@
+From: Josef Bacik <jbacik@fusionio.com>
+Date: Tue, 26 Mar 2013 15:26:55 -0400
+Patch-mainline: pending
+Subject: [PATCH] Btrfs: fix space accounting for unlink and rename
+
+We are way over-reserving for unlink and rename. Rename is just some random
+huge number and unlink accounts for tree log operations that don't actually
+happen during unlink, not to mention the tree log doesn't take from the trans
+block rsv anyway so it's completely useless. Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/inode.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+--- a/fs/btrfs/inode.c
++++ b/fs/btrfs/inode.c
+@@ -3694,11 +3694,9 @@ static struct btrfs_trans_handle *__unli
+ * 1 for the dir item
+ * 1 for the dir index
+ * 1 for the inode ref
+- * 1 for the inode ref in the tree log
+- * 2 for the dir entries in the log
+ * 1 for the inode
+ */
+- trans = btrfs_start_transaction(root, 8);
++ trans = btrfs_start_transaction(root, 5);
+ if (!IS_ERR(trans) || PTR_ERR(trans) != -ENOSPC)
+ return trans;
+
+@@ -8122,7 +8120,7 @@ static int btrfs_rename(struct inode *ol
+ * inodes. So 5 * 2 is 10, plus 1 for the new link, so 11 total items
+ * should cover the worst case number of items we'll modify.
+ */
+- trans = btrfs_start_transaction(root, 20);
++ trans = btrfs_start_transaction(root, 11);
+ if (IS_ERR(trans)) {
+ ret = PTR_ERR(trans);
+ goto out_notrans;
diff --git a/patches.suse/btrfs-8195-hold-the-ordered-operations-mutex-when-waiting.patch b/patches.suse/btrfs-8195-hold-the-ordered-operations-mutex-when-waiting.patch
new file mode 100644
index 0000000000..fc5390fde5
--- /dev/null
+++ b/patches.suse/btrfs-8195-hold-the-ordered-operations-mutex-when-waiting.patch
@@ -0,0 +1,36 @@
+From: Josef Bacik <jbacik@fusionio.com>
+Date: Tue, 26 Mar 2013 15:29:11 -0400
+Patch-mainline: pending
+Subject: [PATCH] Btrfs: hold the ordered operations mutex when waiting
+ on ordered extents
+
+We need to hold the ordered_operations mutex while waiting on ordered extents
+since we splice and run the ordered extents list. We need to make sure anybody
+else who wants to wait on ordered extents does actually wait for them to be
+completed. This will keep us from bailing out of flushing in case somebody is
+already waiting on ordered extents to complete. Thanks,
+
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/ordered-data.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/fs/btrfs/ordered-data.c
++++ b/fs/btrfs/ordered-data.c
+@@ -557,6 +557,7 @@ void btrfs_wait_ordered_extents(struct b
+ INIT_LIST_HEAD(&splice);
+ INIT_LIST_HEAD(&works);
+
++ mutex_lock(&root->fs_info->ordered_operations_mutex);
+ spin_lock(&root->fs_info->ordered_extent_lock);
+ list_splice_init(&root->fs_info->ordered_extents, &splice);
+ while (!list_empty(&splice)) {
+@@ -600,6 +601,7 @@ void btrfs_wait_ordered_extents(struct b
+
+ cond_resched();
+ }
++ mutex_unlock(&root->fs_info->ordered_operations_mutex);
+ }
+
+ /*
diff --git a/patches.suse/btrfs-8196-limit-the-global-reserve-to-512mb.patch b/patches.suse/btrfs-8196-limit-the-global-reserve-to-512mb.patch
new file mode 100644
index 0000000000..296c87e8a9
--- /dev/null
+++ b/patches.suse/btrfs-8196-limit-the-global-reserve-to-512mb.patch
@@ -0,0 +1,32 @@
+From: Josef Bacik <jbacik@fusionio.com>
+Date: Tue, 26 Mar 2013 15:31:45 -0400
+Patch-mainline: pending
+Subject: [PATCH] Btrfs: limit the global reserve to 512mb
+
+A user reported a problem where he was getting early ENOSPC with hundreds of
+gigs of free data space and 6 gigs of free metadata space. This is because the
+global block reserve was taking up the entire free metadata space. This is
+ridiculous, we have infrastructure in place to throttle if we start using too
+much of the global reserve, so instead of letting it get this huge just limit it
+to 512mb so that users can still get work done. This allowed the user to
+complete his rsync without issues. Thanks
+
+Cc: stable@vger.kernel.org
+Reported-and-tested-by: Stefan Priebe <s.priebe@profihost.ag>
+Signed-off-by: Josef Bacik <jbacik@fusionio.com>
+Signed-off-by: David Sterba <dsterba@suse.cz>
+---
+ fs/btrfs/extent-tree.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/fs/btrfs/extent-tree.c
++++ b/fs/btrfs/extent-tree.c
+@@ -4457,7 +4457,7 @@ static void update_global_block_rsv(stru
+ spin_lock(&sinfo->lock);
+ spin_lock(&block_rsv->lock);
+
+- block_rsv->size = num_bytes;
++ block_rsv->size = min_t(u64, num_bytes, 512 * 1024 * 1024);
+
+ num_bytes = sinfo->bytes_used + sinfo->bytes_pinned +
+ sinfo->bytes_reserved + sinfo->bytes_readonly +
diff --git a/series.conf b/series.conf
index 190bd3bd95..24fd97db8e 100644
--- a/series.conf
+++ b/series.conf
@@ -2709,9 +2709,17 @@
patches.suse/btrfs-8061-handle-errors-from-read_tree_block.patch
patches.suse/btrfs-8062-push-up-errors-in-btrfs-num-copies.patch
- patches.suse/btrfs-8077-stop-defrag-the-files-automatically-when-doin-.patch
- patches.suse/btrfs-8186-continue-after-abort-during-snapshot-drop.patch
++dsterba patches.suse/btrfs-8077-stop-defrag-the-files-automatically-when-doin-.patch
++dsterba patches.suse/btrfs-8186-continue-after-abort-during-snapshot-drop.patch
patches.suse/btrfs-8187-enhance-superblock-checks.patch
++dsterba patches.suse/btrfs-8189-clean-snapshots-one-by-one.patch
+ patches.suse/btrfs-8190-deprecate-subvolrootid-mount-option.patch
++dsterba patches.suse/btrfs-8191-cover-more-error-codes-in-btrfs_decode_error.patch
+ patches.suse/btrfs-8192-fix-EIO-from-btrfs-send-in-is_extent_unchanged.patch
+ patches.suse/btrfs-8193-fix-space-leak-when-we-fail-to-reserve-metadat.patch
+ patches.suse/btrfs-8194-fix-space-accounting-for-unlink-and-rename.patch
+ patches.suse/btrfs-8195-hold-the-ordered-operations-mutex-when-waiting.patch
+ patches.suse/btrfs-8196-limit-the-global-reserve-to-512mb.patch
patches.suse/btrfs-update-message-levels.patch
patches.suse/btrfs-8888-add-allow_unsupported-module-parameter.patch