linux-btrfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* ENOSPC fixes
@ 2011-01-24 21:43 Josef Bacik
  2011-01-24 21:43 ` [PATCH 1/3] Btrfs: fix check_path_shared so it returns the right value Josef Bacik
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Josef Bacik @ 2011-01-24 21:43 UTC (permalink / raw)
  To: linux-btrfs

We were failing xfstests 224 by either hanging or failing to remove files.
These patches fix it so that we can now pass 224.  The first patch is obvious,
and the 2nd one is as well, but the 3rd one could use a good hard look.  Thanks,

Josef

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] Btrfs: fix check_path_shared so it returns the right value
  2011-01-24 21:43 ENOSPC fixes Josef Bacik
@ 2011-01-24 21:43 ` Josef Bacik
  2011-01-24 21:43 ` [PATCH 2/3] Btrfs: do not release more reserved bytes to the global_block_rsv than we need Josef Bacik
  2011-01-24 21:43 ` [PATCH 3/3] Btrfs: use the global block reserve if we cannot reserve space Josef Bacik
  2 siblings, 0 replies; 4+ messages in thread
From: Josef Bacik @ 2011-01-24 21:43 UTC (permalink / raw)
  To: linux-btrfs

When running xfstests 224 I kept getting ENOSPC when trying to remove the files,
and this is because we were returning ret from check_path_shared while it was
uninitalized, which isn't right.  Fix this to return 0 properly, and now
xfstests 224 doesn't freak out when it tries to clean itself up.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
---
 fs/btrfs/inode.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 160b55b..e353da5 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2714,9 +2714,10 @@ static int check_path_shared(struct btrfs_root *root,
 	struct extent_buffer *eb;
 	int level;
 	u64 refs = 1;
-	int uninitialized_var(ret);
 
 	for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
+		int ret;
+
 		if (!path->nodes[level])
 			break;
 		eb = path->nodes[level];
@@ -2727,7 +2728,7 @@ static int check_path_shared(struct btrfs_root *root,
 		if (refs > 1)
 			return 1;
 	}
-	return ret; /* XXX callers? */
+	return 0;
 }
 
 /*
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] Btrfs: do not release more reserved bytes to the global_block_rsv than we need
  2011-01-24 21:43 ENOSPC fixes Josef Bacik
  2011-01-24 21:43 ` [PATCH 1/3] Btrfs: fix check_path_shared so it returns the right value Josef Bacik
@ 2011-01-24 21:43 ` Josef Bacik
  2011-01-24 21:43 ` [PATCH 3/3] Btrfs: use the global block reserve if we cannot reserve space Josef Bacik
  2 siblings, 0 replies; 4+ messages in thread
From: Josef Bacik @ 2011-01-24 21:43 UTC (permalink / raw)
  To: linux-btrfs

When we do btrfs_block_rsv_release, if global_block_rsv is not full we will
release all the extra bytes to global_block_rsv, even if it's only a little
short of the amount of space that we need to reserve.  This causes us to starve
ourselves of reservable space during the transaction which will force us to
shrink delalloc bytes and commit the transaction more often than we should.  So
instead just add the amount of bytes we need to add to the global reserve so
reserved == size, and then add the rest back into the space_info for general
use.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
---
 fs/btrfs/extent-tree.c |   16 ++++++++++++++--
 1 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 7ad7bf2..7aed7bf 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -3599,8 +3599,20 @@ void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv,
 
 	if (num_bytes > 0) {
 		if (dest) {
-			block_rsv_add_bytes(dest, num_bytes, 0);
-		} else {
+			spin_lock(&dest->lock);
+			if (!dest->full) {
+				u64 bytes_to_add;
+
+				bytes_to_add = dest->size - dest->reserved;
+				bytes_to_add = min(num_bytes, bytes_to_add);
+				dest->reserved += bytes_to_add;
+				if (dest->reserved >= dest->size)
+					dest->full = 1;
+				num_bytes -= bytes_to_add;
+			}
+			spin_unlock(&dest->lock);
+		}
+		if (num_bytes) {
 			spin_lock(&space_info->lock);
 			space_info->bytes_reserved -= num_bytes;
 			spin_unlock(&space_info->lock);
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] Btrfs: use the global block reserve if we cannot reserve space
  2011-01-24 21:43 ENOSPC fixes Josef Bacik
  2011-01-24 21:43 ` [PATCH 1/3] Btrfs: fix check_path_shared so it returns the right value Josef Bacik
  2011-01-24 21:43 ` [PATCH 2/3] Btrfs: do not release more reserved bytes to the global_block_rsv than we need Josef Bacik
@ 2011-01-24 21:43 ` Josef Bacik
  2 siblings, 0 replies; 4+ messages in thread
From: Josef Bacik @ 2011-01-24 21:43 UTC (permalink / raw)
  To: linux-btrfs

We call use_block_rsv right before we make an allocation in order to make sure
we have enough space.  Now normally people have called btrfs_start_transaction()
with the appropriate amount of space that we need, so we just use some of that
pre-reserved space and move along happily.  The problem is where people use
btrfs_join_transaction(), which doesn't actually reserve any space.  So we try
and reserve space here, but we cannot flush delalloc, so this forces us to
return -ENOSPC when in reality we have plenty of space.  The most common symptom
is seeing a bunch of "couldn't dirty inode" messages in syslog.  With
xfstests 224 we end up falling back to start_transaction and then doing all the
flush delalloc stuff which causes to hang for a very long time.

So instead steal from the global reserve, which is what this is meant for
anyway.  With this patch and the other 2 I have sent xfstests 224 now passes
successfully.  Thanks,

Signed-off-by: Josef Bacik <josef@redhat.com>
---
 fs/btrfs/extent-tree.c |   28 +++++++++++++++++++++++++++-
 1 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 7aed7bf..355665b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -5656,6 +5656,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
 	      struct btrfs_root *root, u32 blocksize)
 {
 	struct btrfs_block_rsv *block_rsv;
+	struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
 	int ret;
 
 	block_rsv = get_block_rsv(trans, root);
@@ -5663,14 +5664,39 @@ use_block_rsv(struct btrfs_trans_handle *trans,
 	if (block_rsv->size == 0) {
 		ret = reserve_metadata_bytes(trans, root, block_rsv,
 					     blocksize, 0);
-		if (ret)
+		/*
+		 * If we couldn't reserve metadata bytes try and use some from
+		 * the global reserve.
+		 */
+		if (ret && block_rsv != global_rsv) {
+			ret = block_rsv_use_bytes(global_rsv, blocksize);
+			if (!ret)
+				return global_rsv;
+			return ERR_PTR(ret);
+		} else if (ret) {
 			return ERR_PTR(ret);
+		}
 		return block_rsv;
 	}
 
 	ret = block_rsv_use_bytes(block_rsv, blocksize);
 	if (!ret)
 		return block_rsv;
+	if (ret) {
+		WARN_ON(1);
+		ret = reserve_metadata_bytes(trans, root, block_rsv, blocksize,
+					     0);
+		if (!ret) {
+			spin_lock(&block_rsv->lock);
+			block_rsv->size += blocksize;
+			spin_unlock(&block_rsv->lock);
+			return block_rsv;
+		} else if (ret && block_rsv != global_rsv) {
+			ret = block_rsv_use_bytes(global_rsv, blocksize);
+			if (!ret)
+				return global_rsv;
+		}
+	}
 
 	return ERR_PTR(-ENOSPC);
 }
-- 
1.6.6.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-01-24 21:43 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-01-24 21:43 ENOSPC fixes Josef Bacik
2011-01-24 21:43 ` [PATCH 1/3] Btrfs: fix check_path_shared so it returns the right value Josef Bacik
2011-01-24 21:43 ` [PATCH 2/3] Btrfs: do not release more reserved bytes to the global_block_rsv than we need Josef Bacik
2011-01-24 21:43 ` [PATCH 3/3] Btrfs: use the global block reserve if we cannot reserve space Josef Bacik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).