Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
Browse files Browse the repository at this point in the history
* 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
  ...
  • Loading branch information
torvalds committed Feb 7, 2011
2 parents eee4da2 + 3a90983 commit cb5520f
Show file tree
Hide file tree
Showing 18 changed files with 371 additions and 116 deletions.
6 changes: 6 additions & 0 deletions fs/btrfs/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
char *value = NULL;
struct posix_acl *acl;

if (!IS_POSIXACL(inode))
return NULL;

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

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

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

if (IS_ERR(acl))
Expand Down
27 changes: 24 additions & 3 deletions fs/btrfs/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
u64 em_len;
u64 em_start;
struct extent_map *em;
int ret;
int ret = -ENOMEM;
u32 *sums;

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

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

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

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

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

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

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

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

bio_put(comp_bio);
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];
Expand Down Expand Up @@ -900,7 +921,7 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page,
return ret;
}

void __exit btrfs_exit_compress(void)
void btrfs_exit_compress(void)
{
free_workspaces();
}
Expand Down
7 changes: 7 additions & 0 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1550,6 +1550,7 @@ static int transaction_kthread(void *arg)
spin_unlock(&root->fs_info->new_trans_lock);

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

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

return 0;
}

Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/export.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ static struct dentry *btrfs_get_parent(struct dentry *child)
int ret;

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

if (dir->i_ino == BTRFS_FIRST_FREE_OBJECTID) {
key.objectid = root->root_key.objectid;
Expand Down
98 changes: 81 additions & 17 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,11 +320,6 @@ static int caching_kthread(void *data)
if (!path)
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);

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

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

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

max_reclaim = min(reserved, to_reclaim);

while (1) {
while (loops < 1024) {
/* have the flusher threads jump in and do some IO */
smp_mb();
nr_pages = min_t(unsigned long, nr_pages,
root->fs_info->delalloc_bytes >> PAGE_CACHE_SHIFT);
writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);

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;
} else {
loops++;
}
reserved = space_info->bytes_reserved;
spin_unlock(&space_info->lock);

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

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

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

pause <<= 1;
if (pause > HZ / 10)
pause = HZ / 10;
Expand Down Expand Up @@ -3588,8 +3596,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);
Expand Down Expand Up @@ -4012,6 +4032,7 @@ void btrfs_delalloc_release_metadata(struct inode *inode, u64 num_bytes)

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

spin_lock(&BTRFS_I(inode)->accounting_lock);
nr_extents = atomic_read(&BTRFS_I(inode)->outstanding_extents);
Expand Down Expand Up @@ -5633,21 +5654,47 @@ 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);

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);
}
Expand Down Expand Up @@ -6221,6 +6268,8 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
BUG_ON(!wc);

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

if (block_rsv)
trans->block_rsv = block_rsv;

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

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

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

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

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

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


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

if (extent_key->objectid == 0) {
ret = del_extent_zero(trans, extent_root, path, extent_key);
Expand Down Expand Up @@ -8270,6 +8322,13 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
if (block_group->cached == BTRFS_CACHE_STARTED)
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_put_block_group(block_group);

Expand Down Expand Up @@ -8384,6 +8443,13 @@ int btrfs_read_block_groups(struct btrfs_root *root)
cache->flags = btrfs_block_group_flags(&cache->item);
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
* don't need to bother with the caching work since we won't
Expand All @@ -8392,12 +8458,10 @@ int btrfs_read_block_groups(struct btrfs_root *root)
* time, particularly in the full case.
*/
if (found_key.offset == btrfs_block_group_used(&cache->item)) {
exclude_super_stripes(root, cache);
cache->last_byte_to_unpin = (u64)-1;
cache->cached = BTRFS_CACHE_FINISHED;
free_excluded_extents(root, cache);
} else if (btrfs_block_group_used(&cache->item) == 0) {
exclude_super_stripes(root, cache);
cache->last_byte_to_unpin = (u64)-1;
cache->cached = BTRFS_CACHE_FINISHED;
add_new_free_space(cache, root->fs_info,
Expand Down
Loading

0 comments on commit cb5520f

Please sign in to comment.