Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 24502ebb authored by Chris Mason's avatar Chris Mason
Browse files

Merge branch 'kdave-part1-enospc' into for-linus-4.8

parents a99cde43 8ca17f0f
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -439,6 +439,8 @@ struct btrfs_space_info {
	struct list_head list;
	/* Protected by the spinlock 'lock'. */
	struct list_head ro_bgs;
	struct list_head priority_tickets;
	struct list_head tickets;

	struct rw_semaphore groups_sem;
	/* for block groups in our same type */
@@ -2624,6 +2626,15 @@ enum btrfs_reserve_flush_enum {
	BTRFS_RESERVE_FLUSH_ALL,
};

enum btrfs_flush_state {
	FLUSH_DELAYED_ITEMS_NR	=	1,
	FLUSH_DELAYED_ITEMS	=	2,
	FLUSH_DELALLOC		=	3,
	FLUSH_DELALLOC_WAIT	=	4,
	ALLOC_CHUNK		=	5,
	COMMIT_TRANS		=	6,
};

int btrfs_check_data_free_space(struct inode *inode, u64 start, u64 len);
int btrfs_alloc_data_chunk_ondemand(struct inode *inode, u64 bytes);
void btrfs_free_reserved_data_space(struct inode *inode, u64 start, u64 len);
@@ -2661,8 +2672,8 @@ int btrfs_block_rsv_refill(struct btrfs_root *root,
			   struct btrfs_block_rsv *block_rsv, u64 min_reserved,
			   enum btrfs_reserve_flush_enum flush);
int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
			    struct btrfs_block_rsv *dst_rsv,
			    u64 num_bytes);
			    struct btrfs_block_rsv *dst_rsv, u64 num_bytes,
			    int update_size);
int btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info,
			     struct btrfs_block_rsv *dest, u64 num_bytes,
			     int min_factor);
+25 −43
Original line number Diff line number Diff line
@@ -553,7 +553,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
	dst_rsv = &root->fs_info->delayed_block_rsv;

	num_bytes = btrfs_calc_trans_metadata_size(root, 1);
	ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
	ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
	if (!ret) {
		trace_btrfs_space_reservation(root->fs_info, "delayed_item",
					      item->key.objectid,
@@ -597,6 +597,29 @@ static int btrfs_delayed_inode_reserve_metadata(

	num_bytes = btrfs_calc_trans_metadata_size(root, 1);

	/*
	 * If our block_rsv is the delalloc block reserve then check and see if
	 * we have our extra reservation for updating the inode.  If not fall
	 * through and try to reserve space quickly.
	 *
	 * We used to try and steal from the delalloc block rsv or the global
	 * reserve, but we'd steal a full reservation, which isn't kind.  We are
	 * here through delalloc which means we've likely just cowed down close
	 * to the leaf that contains the inode, so we would steal less just
	 * doing the fallback inode update, so if we do end up having to steal
	 * from the global block rsv we hopefully only steal one or two blocks
	 * worth which is less likely to hurt us.
	 */
	if (src_rsv && src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) {
		spin_lock(&BTRFS_I(inode)->lock);
		if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
				       &BTRFS_I(inode)->runtime_flags))
			release = true;
		else
			src_rsv = NULL;
		spin_unlock(&BTRFS_I(inode)->lock);
	}

	/*
	 * btrfs_dirty_inode will update the inode under btrfs_join_transaction
	 * which doesn't reserve space for speed.  This is a problem since we
@@ -626,51 +649,10 @@ static int btrfs_delayed_inode_reserve_metadata(
						      num_bytes, 1);
		}
		return ret;
	} else if (src_rsv->type == BTRFS_BLOCK_RSV_DELALLOC) {
		spin_lock(&BTRFS_I(inode)->lock);
		if (test_and_clear_bit(BTRFS_INODE_DELALLOC_META_RESERVED,
				       &BTRFS_I(inode)->runtime_flags)) {
			spin_unlock(&BTRFS_I(inode)->lock);
			release = true;
			goto migrate;
	}
		spin_unlock(&BTRFS_I(inode)->lock);

		/* Ok we didn't have space pre-reserved.  This shouldn't happen
		 * too often but it can happen if we do delalloc to an existing
		 * inode which gets dirtied because of the time update, and then
		 * isn't touched again until after the transaction commits and
		 * then we try to write out the data.  First try to be nice and
		 * reserve something strictly for us.  If not be a pain and try
		 * to steal from the delalloc block rsv.
		 */
		ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes,
					  BTRFS_RESERVE_NO_FLUSH);
		if (!ret)
			goto out;
	ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);

		ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
		if (!ret)
			goto out;

		if (btrfs_test_opt(root, ENOSPC_DEBUG)) {
			btrfs_debug(root->fs_info,
				    "block rsv migrate returned %d", ret);
			WARN_ON(1);
		}
		/*
		 * Ok this is a problem, let's just steal from the global rsv
		 * since this really shouldn't happen that often.
		 */
		ret = btrfs_block_rsv_migrate(&root->fs_info->global_block_rsv,
					      dst_rsv, num_bytes);
		goto out;
	}

migrate:
	ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);

out:
	/*
	 * Migrate only takes a reservation, it doesn't touch the size of the
	 * block_rsv.  This is to simplify people who don't normally have things
+464 −262

File changed.

Preview size limit exceeded, changes collapsed.

+2 −2
Original line number Diff line number Diff line
@@ -2479,7 +2479,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
	}

	ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv,
				      min_size);
				      min_size, 0);
	BUG_ON(ret);
	trans->block_rsv = rsv;

@@ -2522,7 +2522,7 @@ static int btrfs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
		}

		ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv,
					      rsv, min_size);
					      rsv, min_size, 0);
		BUG_ON(ret);	/* shouldn't happen */
		trans->block_rsv = rsv;

+3 −4
Original line number Diff line number Diff line
@@ -5264,7 +5264,7 @@ void btrfs_evict_inode(struct inode *inode)
		if (steal_from_global) {
			if (!btrfs_check_space_for_delayed_refs(trans, root))
				ret = btrfs_block_rsv_migrate(global_rsv, rsv,
							      min_size);
							      min_size, 0);
			else
				ret = -ENOSPC;
		}
@@ -9116,7 +9116,7 @@ static int btrfs_truncate(struct inode *inode)

	/* Migrate the slack space for the truncate to our reserve */
	ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv, rsv,
				      min_size);
				      min_size, 0);
	BUG_ON(ret);

	/*
@@ -9156,7 +9156,7 @@ static int btrfs_truncate(struct inode *inode)
		}

		ret = btrfs_block_rsv_migrate(&root->fs_info->trans_block_rsv,
					      rsv, min_size);
					      rsv, min_size, 0);
		BUG_ON(ret);	/* shouldn't happen */
		trans->block_rsv = rsv;
	}
@@ -9177,7 +9177,6 @@ static int btrfs_truncate(struct inode *inode)
		ret = btrfs_end_transaction(trans, root);
		btrfs_btree_balance_dirty(root);
	}

out:
	btrfs_free_block_rsv(root, rsv);

Loading