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:
  Btrfs: look for acls during btrfs_read_locked_inode
  Btrfs: fix acl caching
  Btrfs: Fix a bunch of printk() warnings.
  Btrfs: Fix a trivial warning using max() of u64 vs ULL.
  Btrfs: remove unused btrfs_bit_radix slab
  Btrfs: ratelimit IO error printks
  Btrfs: remove #if 0 code
  Btrfs: When shrinking, only update disk size on success
  Btrfs: fix deadlocks and stalls on dead root removal
  Btrfs: fix fallocate deadlock on inode extent lock
  Btrfs: kill btrfs_cache_create
  Btrfs: don't export symbols
  Btrfs: simplify makefile
  Btrfs: try to keep a healthy ratio of metadata vs data block groups
  • Loading branch information
Linus Torvalds committed Apr 27, 2009
2 parents 14b6084 + 46a53cc commit 4ebf662
Show file tree
Hide file tree
Showing 17 changed files with 281 additions and 337 deletions.
19 changes: 2 additions & 17 deletions fs/btrfs/Makefile
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
ifneq ($(KERNELRELEASE),)
# kbuild part of makefile

obj-$(CONFIG_BTRFS_FS) := btrfs.o
btrfs-y := super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \

btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
file-item.o inode-item.o inode-map.o disk-io.o \
transaction.o inode.o file.o tree-defrag.o \
extent_map.o sysfs.o struct-funcs.o xattr.o ordered-data.o \
extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \
ref-cache.o export.o tree-log.o acl.o free-space-cache.o zlib.o \
compression.o delayed-ref.o
else

# Normal Makefile

KERNELDIR := /lib/modules/`uname -r`/build
all:
$(MAKE) -C $(KERNELDIR) M=`pwd` CONFIG_BTRFS_FS=m modules

modules_install:
$(MAKE) -C $(KERNELDIR) M=`pwd` modules_install
clean:
$(MAKE) -C $(KERNELDIR) M=`pwd` clean

endif
18 changes: 13 additions & 5 deletions fs/btrfs/acl.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,20 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
return ERR_PTR(-EINVAL);
}

/* Handle the cached NULL acl case without locking */
acl = ACCESS_ONCE(*p_acl);
if (!acl)
return acl;

spin_lock(&inode->i_lock);
if (*p_acl != BTRFS_ACL_NOT_CACHED)
acl = posix_acl_dup(*p_acl);
acl = *p_acl;
if (acl != BTRFS_ACL_NOT_CACHED)
acl = posix_acl_dup(acl);
spin_unlock(&inode->i_lock);

if (acl)
if (acl != BTRFS_ACL_NOT_CACHED)
return acl;


size = __btrfs_getxattr(inode, name, "", 0);
if (size > 0) {
value = kzalloc(size, GFP_NOFS);
Expand All @@ -80,9 +85,12 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
btrfs_update_cached_acl(inode, p_acl, acl);
}
kfree(value);
} else if (size == -ENOENT) {
} else if (size == -ENOENT || size == -ENODATA || size == 0) {
/* FIXME, who returns -ENOENT? I think nobody */
acl = NULL;
btrfs_update_cached_acl(inode, p_acl, acl);
} else {
acl = ERR_PTR(-EIO);
}

return acl;
Expand Down
6 changes: 5 additions & 1 deletion fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -881,6 +881,9 @@ struct btrfs_fs_info {
u64 metadata_alloc_profile;
u64 system_alloc_profile;

unsigned data_chunk_allocations;
unsigned metadata_ratio;

void *bdev_holder;
};

Expand Down Expand Up @@ -2174,7 +2177,8 @@ int btrfs_check_file(struct btrfs_root *root, struct inode *inode);
extern struct file_operations btrfs_file_operations;
int btrfs_drop_extents(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct inode *inode,
u64 start, u64 end, u64 inline_limit, u64 *hint_block);
u64 start, u64 end, u64 locked_end,
u64 inline_limit, u64 *hint_block);
int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct inode *inode, u64 start, u64 end);
Expand Down
93 changes: 30 additions & 63 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,10 +232,14 @@ static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
memcpy(&found, result, csum_size);

read_extent_buffer(buf, &val, 0, csum_size);
printk(KERN_INFO "btrfs: %s checksum verify failed "
"on %llu wanted %X found %X level %d\n",
root->fs_info->sb->s_id,
buf->start, val, found, btrfs_header_level(buf));
if (printk_ratelimit()) {
printk(KERN_INFO "btrfs: %s checksum verify "
"failed on %llu wanted %X found %X "
"level %d\n",
root->fs_info->sb->s_id,
(unsigned long long)buf->start, val, found,
btrfs_header_level(buf));
}
if (result != (char *)&inline_result)
kfree(result);
return 1;
Expand Down Expand Up @@ -268,10 +272,13 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
ret = 0;
goto out;
}
printk("parent transid verify failed on %llu wanted %llu found %llu\n",
(unsigned long long)eb->start,
(unsigned long long)parent_transid,
(unsigned long long)btrfs_header_generation(eb));
if (printk_ratelimit()) {
printk("parent transid verify failed on %llu wanted %llu "
"found %llu\n",
(unsigned long long)eb->start,
(unsigned long long)parent_transid,
(unsigned long long)btrfs_header_generation(eb));
}
ret = 1;
clear_extent_buffer_uptodate(io_tree, eb);
out:
Expand Down Expand Up @@ -415,9 +422,12 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,

found_start = btrfs_header_bytenr(eb);
if (found_start != start) {
printk(KERN_INFO "btrfs bad tree block start %llu %llu\n",
(unsigned long long)found_start,
(unsigned long long)eb->start);
if (printk_ratelimit()) {
printk(KERN_INFO "btrfs bad tree block start "
"%llu %llu\n",
(unsigned long long)found_start,
(unsigned long long)eb->start);
}
ret = -EIO;
goto err;
}
Expand All @@ -429,8 +439,10 @@ static int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end,
goto err;
}
if (check_tree_block_fsid(root, eb)) {
printk(KERN_INFO "btrfs bad fsid on block %llu\n",
(unsigned long long)eb->start);
if (printk_ratelimit()) {
printk(KERN_INFO "btrfs bad fsid on block %llu\n",
(unsigned long long)eb->start);
}
ret = -EIO;
goto err;
}
Expand Down Expand Up @@ -584,18 +596,7 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
btrfs_set_work_high_prio(&async->work);

btrfs_queue_worker(&fs_info->workers, &async->work);
#if 0
int limit = btrfs_async_submit_limit(fs_info);
if (atomic_read(&fs_info->nr_async_submits) > limit) {
wait_event_timeout(fs_info->async_submit_wait,
(atomic_read(&fs_info->nr_async_submits) < limit),
HZ/10);

wait_event_timeout(fs_info->async_submit_wait,
(atomic_read(&fs_info->nr_async_bios) < limit),
HZ/10);
}
#endif
while (atomic_read(&fs_info->async_submit_draining) &&
atomic_read(&fs_info->nr_async_submits)) {
wait_event(fs_info->async_submit_wait,
Expand Down Expand Up @@ -770,27 +771,6 @@ static void btree_invalidatepage(struct page *page, unsigned long offset)
}
}

#if 0
static int btree_writepage(struct page *page, struct writeback_control *wbc)
{
struct buffer_head *bh;
struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
struct buffer_head *head;
if (!page_has_buffers(page)) {
create_empty_buffers(page, root->fs_info->sb->s_blocksize,
(1 << BH_Dirty)|(1 << BH_Uptodate));
}
head = page_buffers(page);
bh = head;
do {
if (buffer_dirty(bh))
csum_tree_block(root, bh, 0);
bh = bh->b_this_page;
} while (bh != head);
return block_write_full_page(page, btree_get_block, wbc);
}
#endif

static struct address_space_operations btree_aops = {
.readpage = btree_readpage,
.writepage = btree_writepage,
Expand Down Expand Up @@ -1278,11 +1258,7 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
int ret = 0;
struct btrfs_device *device;
struct backing_dev_info *bdi;
#if 0
if ((bdi_bits & (1 << BDI_write_congested)) &&
btrfs_congested_async(info, 0))
return 1;
#endif

list_for_each_entry(device, &info->fs_devices->devices, dev_list) {
if (!device->bdev)
continue;
Expand Down Expand Up @@ -1604,6 +1580,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
fs_info->btree_inode = new_inode(sb);
fs_info->btree_inode->i_ino = 1;
fs_info->btree_inode->i_nlink = 1;
fs_info->metadata_ratio = 8;

fs_info->thread_pool_size = min_t(unsigned long,
num_online_cpus() + 2, 8);
Expand Down Expand Up @@ -1694,7 +1671,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
if (features) {
printk(KERN_ERR "BTRFS: couldn't mount because of "
"unsupported optional features (%Lx).\n",
features);
(unsigned long long)features);
err = -EINVAL;
goto fail_iput;
}
Expand All @@ -1704,7 +1681,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
if (!(sb->s_flags & MS_RDONLY) && features) {
printk(KERN_ERR "BTRFS: couldn't mount RDWR because of "
"unsupported option features (%Lx).\n",
features);
(unsigned long long)features);
err = -EINVAL;
goto fail_iput;
}
Expand Down Expand Up @@ -2296,7 +2273,7 @@ int close_ctree(struct btrfs_root *root)

if (fs_info->delalloc_bytes) {
printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n",
fs_info->delalloc_bytes);
(unsigned long long)fs_info->delalloc_bytes);
}
if (fs_info->total_ref_cache_size) {
printk(KERN_INFO "btrfs: at umount reference cache size %llu\n",
Expand Down Expand Up @@ -2333,16 +2310,6 @@ int close_ctree(struct btrfs_root *root)
btrfs_stop_workers(&fs_info->endio_write_workers);
btrfs_stop_workers(&fs_info->submit_workers);

#if 0
while (!list_empty(&fs_info->hashers)) {
struct btrfs_hasher *hasher;
hasher = list_entry(fs_info->hashers.next, struct btrfs_hasher,
hashers);
list_del(&hasher->hashers);
crypto_free_hash(&fs_info->hash_tfm);
kfree(hasher);
}
#endif
btrfs_close_devices(fs_info->fs_devices);
btrfs_mapping_tree_free(&fs_info->mapping_tree);

Expand Down
49 changes: 41 additions & 8 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1844,10 +1844,14 @@ int btrfs_check_data_free_space(struct btrfs_root *root, struct inode *inode,
printk(KERN_ERR "no space left, need %llu, %llu delalloc bytes"
", %llu bytes_used, %llu bytes_reserved, "
"%llu bytes_pinned, %llu bytes_readonly, %llu may use"
"%llu total\n", bytes, data_sinfo->bytes_delalloc,
data_sinfo->bytes_used, data_sinfo->bytes_reserved,
data_sinfo->bytes_pinned, data_sinfo->bytes_readonly,
data_sinfo->bytes_may_use, data_sinfo->total_bytes);
"%llu total\n", (unsigned long long)bytes,
(unsigned long long)data_sinfo->bytes_delalloc,
(unsigned long long)data_sinfo->bytes_used,
(unsigned long long)data_sinfo->bytes_reserved,
(unsigned long long)data_sinfo->bytes_pinned,
(unsigned long long)data_sinfo->bytes_readonly,
(unsigned long long)data_sinfo->bytes_may_use,
(unsigned long long)data_sinfo->total_bytes);
return -ENOSPC;
}
data_sinfo->bytes_may_use += bytes;
Expand Down Expand Up @@ -1918,15 +1922,29 @@ void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode,
spin_unlock(&info->lock);
}

static void force_metadata_allocation(struct btrfs_fs_info *info)
{
struct list_head *head = &info->space_info;
struct btrfs_space_info *found;

rcu_read_lock();
list_for_each_entry_rcu(found, head, list) {
if (found->flags & BTRFS_BLOCK_GROUP_METADATA)
found->force_alloc = 1;
}
rcu_read_unlock();
}

static int do_chunk_alloc(struct btrfs_trans_handle *trans,
struct btrfs_root *extent_root, u64 alloc_bytes,
u64 flags, int force)
{
struct btrfs_space_info *space_info;
struct btrfs_fs_info *fs_info = extent_root->fs_info;
u64 thresh;
int ret = 0;

mutex_lock(&extent_root->fs_info->chunk_mutex);
mutex_lock(&fs_info->chunk_mutex);

flags = btrfs_reduce_alloc_profile(extent_root, flags);

Expand Down Expand Up @@ -1958,6 +1976,18 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
}
spin_unlock(&space_info->lock);

/*
* if we're doing a data chunk, go ahead and make sure that
* we keep a reasonable number of metadata chunks allocated in the
* FS as well.
*/
if (flags & BTRFS_BLOCK_GROUP_DATA) {
fs_info->data_chunk_allocations++;
if (!(fs_info->data_chunk_allocations %
fs_info->metadata_ratio))
force_metadata_allocation(fs_info);
}

ret = btrfs_alloc_chunk(trans, extent_root, flags);
if (ret)
space_info->full = 1;
Expand Down Expand Up @@ -2798,9 +2828,12 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes)
info->bytes_pinned - info->bytes_reserved),
(info->full) ? "" : "not ");
printk(KERN_INFO "space_info total=%llu, pinned=%llu, delalloc=%llu,"
" may_use=%llu, used=%llu\n", info->total_bytes,
info->bytes_pinned, info->bytes_delalloc, info->bytes_may_use,
info->bytes_used);
" may_use=%llu, used=%llu\n",
(unsigned long long)info->total_bytes,
(unsigned long long)info->bytes_pinned,
(unsigned long long)info->bytes_delalloc,
(unsigned long long)info->bytes_may_use,
(unsigned long long)info->bytes_used);

down_read(&info->groups_sem);
list_for_each_entry(cache, &info->block_groups, list) {
Expand Down
Loading

0 comments on commit 4ebf662

Please sign in to comment.