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

Commit cb5520f0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (33 commits)
  Btrfs: Fix page count calculation
  btrfs: Drop __exit attribute on btrfs_exit_compress
  btrfs: cleanup error handling in btrfs_unlink_inode()
  Btrfs: exclude super blocks when we read in block groups
  Btrfs: make sure search_bitmap finds something in remove_from_bitmap
  btrfs: fix return value check of btrfs_start_transaction()
  btrfs: checking NULL or not in some functions
  Btrfs: avoid uninit variable warnings in ordered-data.c
  Btrfs: catch errors from btrfs_sync_log
  Btrfs: make shrink_delalloc a little friendlier
  Btrfs: handle no memory properly in prepare_pages
  Btrfs: do error checking in btrfs_del_csums
  Btrfs: use the global block reserve if we cannot reserve space
  Btrfs: do not release more reserved bytes to the global_block_rsv than we need
  Btrfs: fix check_path_shared so it returns the right value
  btrfs: check return value of btrfs_start_ioctl_transaction() properly
  btrfs: fix return value check of btrfs_join_transaction()
  fs/btrfs/inode.c: Add missing IS_ERR test
  btrfs: fix missing break in switch phrase
  btrfs: fix several uncheck memory allocations
  ...
parents eee4da2c 3a90983d
Loading
Loading
Loading
Loading
+6 −0
Original line number Original line Diff line number Diff line
@@ -37,6 +37,9 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
	char *value = NULL;
	char *value = NULL;
	struct posix_acl *acl;
	struct posix_acl *acl;


	if (!IS_POSIXACL(inode))
		return NULL;

	acl = get_cached_acl(inode, type);
	acl = get_cached_acl(inode, type);
	if (acl != ACL_NOT_CACHED)
	if (acl != ACL_NOT_CACHED)
		return acl;
		return acl;
@@ -84,6 +87,9 @@ static int btrfs_xattr_acl_get(struct dentry *dentry, const char *name,
	struct posix_acl *acl;
	struct posix_acl *acl;
	int ret = 0;
	int ret = 0;


	if (!IS_POSIXACL(dentry->d_inode))
		return -EOPNOTSUPP;

	acl = btrfs_get_acl(dentry->d_inode, type);
	acl = btrfs_get_acl(dentry->d_inode, type);


	if (IS_ERR(acl))
	if (IS_ERR(acl))
+24 −3
Original line number Original line Diff line number Diff line
@@ -562,7 +562,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
	u64 em_len;
	u64 em_len;
	u64 em_start;
	u64 em_start;
	struct extent_map *em;
	struct extent_map *em;
	int ret;
	int ret = -ENOMEM;
	u32 *sums;
	u32 *sums;


	tree = &BTRFS_I(inode)->io_tree;
	tree = &BTRFS_I(inode)->io_tree;
@@ -577,6 +577,9 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,


	compressed_len = em->block_len;
	compressed_len = em->block_len;
	cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS);
	cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS);
	if (!cb)
		goto out;

	atomic_set(&cb->pending_bios, 0);
	atomic_set(&cb->pending_bios, 0);
	cb->errors = 0;
	cb->errors = 0;
	cb->inode = inode;
	cb->inode = inode;
@@ -597,13 +600,18 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,


	nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) /
	nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) /
				 PAGE_CACHE_SIZE;
				 PAGE_CACHE_SIZE;
	cb->compressed_pages = kmalloc(sizeof(struct page *) * nr_pages,
	cb->compressed_pages = kzalloc(sizeof(struct page *) * nr_pages,
				       GFP_NOFS);
				       GFP_NOFS);
	if (!cb->compressed_pages)
		goto fail1;

	bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;
	bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;


	for (page_index = 0; page_index < nr_pages; page_index++) {
	for (page_index = 0; page_index < nr_pages; page_index++) {
		cb->compressed_pages[page_index] = alloc_page(GFP_NOFS |
		cb->compressed_pages[page_index] = alloc_page(GFP_NOFS |
							      __GFP_HIGHMEM);
							      __GFP_HIGHMEM);
		if (!cb->compressed_pages[page_index])
			goto fail2;
	}
	}
	cb->nr_pages = nr_pages;
	cb->nr_pages = nr_pages;


@@ -614,6 +622,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
	cb->len = uncompressed_len;
	cb->len = uncompressed_len;


	comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS);
	comp_bio = compressed_bio_alloc(bdev, cur_disk_byte, GFP_NOFS);
	if (!comp_bio)
		goto fail2;
	comp_bio->bi_private = cb;
	comp_bio->bi_private = cb;
	comp_bio->bi_end_io = end_compressed_bio_read;
	comp_bio->bi_end_io = end_compressed_bio_read;
	atomic_inc(&cb->pending_bios);
	atomic_inc(&cb->pending_bios);
@@ -681,6 +691,17 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,


	bio_put(comp_bio);
	bio_put(comp_bio);
	return 0;
	return 0;

fail2:
	for (page_index = 0; page_index < nr_pages; page_index++)
		free_page((unsigned long)cb->compressed_pages[page_index]);

	kfree(cb->compressed_pages);
fail1:
	kfree(cb);
out:
	free_extent_map(em);
	return ret;
}
}


static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES];
static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES];
@@ -900,7 +921,7 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page,
	return ret;
	return ret;
}
}


void __exit btrfs_exit_compress(void)
void btrfs_exit_compress(void)
{
{
	free_workspaces();
	free_workspaces();
}
}
+7 −0
Original line number Original line Diff line number Diff line
@@ -1550,6 +1550,7 @@ static int transaction_kthread(void *arg)
		spin_unlock(&root->fs_info->new_trans_lock);
		spin_unlock(&root->fs_info->new_trans_lock);


		trans = btrfs_join_transaction(root, 1);
		trans = btrfs_join_transaction(root, 1);
		BUG_ON(IS_ERR(trans));
		if (transid == trans->transid) {
		if (transid == trans->transid) {
			ret = btrfs_commit_transaction(trans, root);
			ret = btrfs_commit_transaction(trans, root);
			BUG_ON(ret);
			BUG_ON(ret);
@@ -2453,10 +2454,14 @@ int btrfs_commit_super(struct btrfs_root *root)
	up_write(&root->fs_info->cleanup_work_sem);
	up_write(&root->fs_info->cleanup_work_sem);


	trans = btrfs_join_transaction(root, 1);
	trans = btrfs_join_transaction(root, 1);
	if (IS_ERR(trans))
		return PTR_ERR(trans);
	ret = btrfs_commit_transaction(trans, root);
	ret = btrfs_commit_transaction(trans, root);
	BUG_ON(ret);
	BUG_ON(ret);
	/* run commit again to drop the original snapshot */
	/* run commit again to drop the original snapshot */
	trans = btrfs_join_transaction(root, 1);
	trans = btrfs_join_transaction(root, 1);
	if (IS_ERR(trans))
		return PTR_ERR(trans);
	btrfs_commit_transaction(trans, root);
	btrfs_commit_transaction(trans, root);
	ret = btrfs_write_and_wait_transaction(NULL, root);
	ret = btrfs_write_and_wait_transaction(NULL, root);
	BUG_ON(ret);
	BUG_ON(ret);
@@ -2554,6 +2559,8 @@ int close_ctree(struct btrfs_root *root)
	kfree(fs_info->chunk_root);
	kfree(fs_info->chunk_root);
	kfree(fs_info->dev_root);
	kfree(fs_info->dev_root);
	kfree(fs_info->csum_root);
	kfree(fs_info->csum_root);
	kfree(fs_info);

	return 0;
	return 0;
}
}


+2 −0
Original line number Original line Diff line number Diff line
@@ -171,6 +171,8 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
	int ret;
	int ret;


	path = btrfs_alloc_path();
	path = btrfs_alloc_path();
	if (!path)
		return ERR_PTR(-ENOMEM);


	if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
	if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
		key.objectid = root->root_key.objectid;
		key.objectid = root->root_key.objectid;
+81 −17
Original line number Original line Diff line number Diff line
@@ -320,11 +320,6 @@ static int caching_kthread(void *data)
	if (!path)
	if (!path)
		return -ENOMEM;
		return -ENOMEM;


	exclude_super_stripes(extent_root, block_group);
	spin_lock(&block_group->space_info->lock);
	block_group->space_info->bytes_readonly += block_group->bytes_super;
	spin_unlock(&block_group->space_info->lock);

	last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);
	last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);


	/*
	/*
@@ -467,9 +462,11 @@ static int cache_block_group(struct btrfs_block_group_cache *cache,
			cache->cached = BTRFS_CACHE_NO;
			cache->cached = BTRFS_CACHE_NO;
		}
		}
		spin_unlock(&cache->lock);
		spin_unlock(&cache->lock);
		if (ret == 1)
		if (ret == 1) {
			free_excluded_extents(fs_info->extent_root, cache);
			return 0;
			return 0;
		}
		}
	}


	if (load_cache_only)
	if (load_cache_only)
		return 0;
		return 0;
@@ -3344,8 +3341,10 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
	u64 reserved;
	u64 reserved;
	u64 max_reclaim;
	u64 max_reclaim;
	u64 reclaimed = 0;
	u64 reclaimed = 0;
	long time_left;
	int pause = 1;
	int pause = 1;
	int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
	int nr_pages = (2 * 1024 * 1024) >> PAGE_CACHE_SHIFT;
	int loops = 0;


	block_rsv = &root->fs_info->delalloc_block_rsv;
	block_rsv = &root->fs_info->delalloc_block_rsv;
	space_info = block_rsv->space_info;
	space_info = block_rsv->space_info;
@@ -3358,7 +3357,7 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,


	max_reclaim = min(reserved, to_reclaim);
	max_reclaim = min(reserved, to_reclaim);


	while (1) {
	while (loops < 1024) {
		/* have the flusher threads jump in and do some IO */
		/* have the flusher threads jump in and do some IO */
		smp_mb();
		smp_mb();
		nr_pages = min_t(unsigned long, nr_pages,
		nr_pages = min_t(unsigned long, nr_pages,
@@ -3366,8 +3365,12 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
		writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);
		writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);


		spin_lock(&space_info->lock);
		spin_lock(&space_info->lock);
		if (reserved > space_info->bytes_reserved)
		if (reserved > space_info->bytes_reserved) {
			loops = 0;
			reclaimed += reserved - space_info->bytes_reserved;
			reclaimed += reserved - space_info->bytes_reserved;
		} else {
			loops++;
		}
		reserved = space_info->bytes_reserved;
		reserved = space_info->bytes_reserved;
		spin_unlock(&space_info->lock);
		spin_unlock(&space_info->lock);


@@ -3378,7 +3381,12 @@ static int shrink_delalloc(struct btrfs_trans_handle *trans,
			return -EAGAIN;
			return -EAGAIN;


		__set_current_state(TASK_INTERRUPTIBLE);
		__set_current_state(TASK_INTERRUPTIBLE);
		schedule_timeout(pause);
		time_left = schedule_timeout(pause);

		/* We were interrupted, exit */
		if (time_left)
			break;

		pause <<= 1;
		pause <<= 1;
		if (pause > HZ / 10)
		if (pause > HZ / 10)
			pause = HZ / 10;
			pause = HZ / 10;
@@ -3588,8 +3596,20 @@ void block_rsv_release_bytes(struct btrfs_block_rsv *block_rsv,


	if (num_bytes > 0) {
	if (num_bytes > 0) {
		if (dest) {
		if (dest) {
			block_rsv_add_bytes(dest, num_bytes, 0);
			spin_lock(&dest->lock);
		} else {
			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);
			spin_lock(&space_info->lock);
			space_info->bytes_reserved -= num_bytes;
			space_info->bytes_reserved -= num_bytes;
			spin_unlock(&space_info->lock);
			spin_unlock(&space_info->lock);
@@ -4012,6 +4032,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)


	num_bytes = ALIGN(num_bytes, root->sectorsize);
	num_bytes = ALIGN(num_bytes, root->sectorsize);
	atomic_dec(&BTRFS_I(inode)->outstanding_extents);
	atomic_dec(&BTRFS_I(inode)->outstanding_extents);
	WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents) < 0);


	spin_lock(&BTRFS_I(inode)->accounting_lock);
	spin_lock(&BTRFS_I(inode)->accounting_lock);
	nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents);
	nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents);
@@ -5633,6 +5654,7 @@ use_block_rsv(struct btrfs_trans_handle *trans,
	      struct btrfs_root *root, u32 blocksize)
	      struct btrfs_root *root, u32 blocksize)
{
{
	struct btrfs_block_rsv *block_rsv;
	struct btrfs_block_rsv *block_rsv;
	struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;
	int ret;
	int ret;


	block_rsv = get_block_rsv(trans, root);
	block_rsv = get_block_rsv(trans, root);
@@ -5640,14 +5662,39 @@ use_block_rsv(struct btrfs_trans_handle *trans,
	if (block_rsv->size == 0) {
	if (block_rsv->size == 0) {
		ret = reserve_metadata_bytes(trans, root, block_rsv,
		ret = reserve_metadata_bytes(trans, root, block_rsv,
					     blocksize, 0);
					     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 ERR_PTR(ret);
		}
		return block_rsv;
		return block_rsv;
	}
	}


	ret = block_rsv_use_bytes(block_rsv, blocksize);
	ret = block_rsv_use_bytes(block_rsv, blocksize);
	if (!ret)
	if (!ret)
		return block_rsv;
		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);
	return ERR_PTR(-ENOSPC);
}
}
@@ -6221,6 +6268,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
	BUG_ON(!wc);
	BUG_ON(!wc);


	trans = btrfs_start_transaction(tree_root, 0);
	trans = btrfs_start_transaction(tree_root, 0);
	BUG_ON(IS_ERR(trans));

	if (block_rsv)
	if (block_rsv)
		trans->block_rsv = block_rsv;
		trans->block_rsv = block_rsv;


@@ -6318,6 +6367,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,


			btrfs_end_transaction_throttle(trans, tree_root);
			btrfs_end_transaction_throttle(trans, tree_root);
			trans = btrfs_start_transaction(tree_root, 0);
			trans = btrfs_start_transaction(tree_root, 0);
			BUG_ON(IS_ERR(trans));
			if (block_rsv)
			if (block_rsv)
				trans->block_rsv = block_rsv;
				trans->block_rsv = block_rsv;
		}
		}
@@ -6446,6 +6496,8 @@ static noinline int relocate_inode_pages(struct inode *inode, u64 start,
	int ret = 0;
	int ret = 0;


	ra = kzalloc(sizeof(*ra), GFP_NOFS);
	ra = kzalloc(sizeof(*ra), GFP_NOFS);
	if (!ra)
		return -ENOMEM;


	mutex_lock(&inode->i_mutex);
	mutex_lock(&inode->i_mutex);
	first_index = start >> PAGE_CACHE_SHIFT;
	first_index = start >> PAGE_CACHE_SHIFT;
@@ -7477,7 +7529,7 @@ int btrfs_drop_dead_reloc_roots(struct btrfs_root *root)
		BUG_ON(reloc_root->commit_root != NULL);
		BUG_ON(reloc_root->commit_root != NULL);
		while (1) {
		while (1) {
			trans = btrfs_join_transaction(root, 1);
			trans = btrfs_join_transaction(root, 1);
			BUG_ON(!trans);
			BUG_ON(IS_ERR(trans));


			mutex_lock(&root->fs_info->drop_mutex);
			mutex_lock(&root->fs_info->drop_mutex);
			ret = btrfs_drop_snapshot(trans, reloc_root);
			ret = btrfs_drop_snapshot(trans, reloc_root);
@@ -7535,7 +7587,7 @@ int btrfs_cleanup_reloc_trees(struct btrfs_root *root)


	if (found) {
	if (found) {
		trans = btrfs_start_transaction(root, 1);
		trans = btrfs_start_transaction(root, 1);
		BUG_ON(!trans);
		BUG_ON(IS_ERR(trans));
		ret = btrfs_commit_transaction(trans, root);
		ret = btrfs_commit_transaction(trans, root);
		BUG_ON(ret);
		BUG_ON(ret);
	}
	}
@@ -7779,7 +7831,7 @@ static noinline int relocate_one_extent(struct btrfs_root *extent_root,




	trans = btrfs_start_transaction(extent_root, 1);
	trans = btrfs_start_transaction(extent_root, 1);
	BUG_ON(!trans);
	BUG_ON(IS_ERR(trans));


	if (extent_key->objectid == 0) {
	if (extent_key->objectid == 0) {
		ret = del_extent_zero(trans, extent_root, path, extent_key);
		ret = del_extent_zero(trans, extent_root, path, extent_key);
@@ -8270,6 +8322,13 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
		if (block_group->cached == BTRFS_CACHE_STARTED)
		if (block_group->cached == BTRFS_CACHE_STARTED)
			wait_block_group_cache_done(block_group);
			wait_block_group_cache_done(block_group);


		/*
		 * We haven't cached this block group, which means we could
		 * possibly have excluded extents on this block group.
		 */
		if (block_group->cached == BTRFS_CACHE_NO)
			free_excluded_extents(info->extent_root, block_group);

		btrfs_remove_free_space_cache(block_group);
		btrfs_remove_free_space_cache(block_group);
		btrfs_put_block_group(block_group);
		btrfs_put_block_group(block_group);


@@ -8384,6 +8443,13 @@ int btrfs_read_block_groups(struct btrfs_root *root)
		cache->flags = btrfs_block_group_flags(&cache->item);
		cache->flags = btrfs_block_group_flags(&cache->item);
		cache->sectorsize = root->sectorsize;
		cache->sectorsize = root->sectorsize;


		/*
		 * We need to exclude the super stripes now so that the space
		 * info has super bytes accounted for, otherwise we'll think
		 * we have more space than we actually do.
		 */
		exclude_super_stripes(root, cache);

		/*
		/*
		 * check for two cases, either we are full, and therefore
		 * check for two cases, either we are full, and therefore
		 * don't need to bother with the caching work since we won't
		 * don't need to bother with the caching work since we won't
@@ -8392,12 +8458,10 @@ int btrfs_read_block_groups(struct btrfs_root *root)
		 * time, particularly in the full case.
		 * time, particularly in the full case.
		 */
		 */
		if (found_key.offset == btrfs_block_group_used(&cache->item)) {
		if (found_key.offset == btrfs_block_group_used(&cache->item)) {
			exclude_super_stripes(root, cache);
			cache->last_byte_to_unpin = (u64)-1;
			cache->last_byte_to_unpin = (u64)-1;
			cache->cached = BTRFS_CACHE_FINISHED;
			cache->cached = BTRFS_CACHE_FINISHED;
			free_excluded_extents(root, cache);
			free_excluded_extents(root, cache);
		} else if (btrfs_block_group_used(&cache->item) == 0) {
		} else if (btrfs_block_group_used(&cache->item) == 0) {
			exclude_super_stripes(root, cache);
			cache->last_byte_to_unpin = (u64)-1;
			cache->last_byte_to_unpin = (u64)-1;
			cache->cached = BTRFS_CACHE_FINISHED;
			cache->cached = BTRFS_CACHE_FINISHED;
			add_new_free_space(cache, root->fs_info,
			add_new_free_space(cache, root->fs_info,
Loading