Skip to content

Commit

Permalink
Merge git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-next.…
Browse files Browse the repository at this point in the history
…git for-chris into for-linus
  • Loading branch information
Chris Mason committed Feb 6, 2013
2 parents 3c91160 + 59fe4f4 commit 24f8ebe
Show file tree
Hide file tree
Showing 16 changed files with 370 additions and 119 deletions.
6 changes: 4 additions & 2 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3997,7 +3997,7 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
* We make the other tasks wait for the flush only when we can flush
* all things.
*/
if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) {
if (ret && flush != BTRFS_RESERVE_NO_FLUSH) {
flushing = true;
space_info->flush = 1;
}
Expand Down Expand Up @@ -5560,7 +5560,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
int empty_cluster = 2 * 1024 * 1024;
struct btrfs_space_info *space_info;
int loop = 0;
int index = 0;
int index = __get_raid_index(data);
int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ?
RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC;
bool found_uncached_bg = false;
Expand Down Expand Up @@ -6788,11 +6788,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
&wc->flags[level]);
if (ret < 0) {
btrfs_tree_unlock_rw(eb, path->locks[level]);
path->locks[level] = 0;
return ret;
}
BUG_ON(wc->refs[level] == 0);
if (wc->refs[level] == 1) {
btrfs_tree_unlock_rw(eb, path->locks[level]);
path->locks[level] = 0;
return 1;
}
}
Expand Down
14 changes: 13 additions & 1 deletion fs/btrfs/extent_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,10 @@ static int mergable_maps(struct extent_map *prev, struct extent_map *next)
if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags))
return 0;

if (test_bit(EXTENT_FLAG_LOGGING, &prev->flags) ||
test_bit(EXTENT_FLAG_LOGGING, &next->flags))
return 0;

if (extent_map_end(prev) == next->start &&
prev->flags == next->flags &&
prev->bdev == next->bdev &&
Expand Down Expand Up @@ -256,7 +260,8 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,
if (!em)
goto out;

list_move(&em->list, &tree->modified_extents);
if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags))
list_move(&em->list, &tree->modified_extents);
em->generation = gen;
clear_bit(EXTENT_FLAG_PINNED, &em->flags);
em->mod_start = em->start;
Expand All @@ -281,6 +286,13 @@ int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,

}

void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em)
{
clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
if (em->in_tree)
try_merge_map(tree, em);
}

/**
* add_extent_mapping - add new extent map to the extent tree
* @tree: tree to insert new map in
Expand Down
1 change: 1 addition & 0 deletions fs/btrfs/extent_map.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void free_extent_map(struct extent_map *em);
int __init extent_map_init(void);
void extent_map_exit(void);
int unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len, u64 gen);
void clear_em_logging(struct extent_map_tree *tree, struct extent_map *em);
struct extent_map *search_extent_mapping(struct extent_map_tree *tree,
u64 start, u64 len);
#endif
4 changes: 2 additions & 2 deletions fs/btrfs/file-item.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
if (!contig)
offset = page_offset(bvec->bv_page) + bvec->bv_offset;

if (!contig && (offset >= ordered->file_offset + ordered->len ||
offset < ordered->file_offset)) {
if (offset >= ordered->file_offset + ordered->len ||
offset < ordered->file_offset) {
unsigned long bytes_left;
sums->len = this_sum_bytes;
this_sum_bytes = 0;
Expand Down
35 changes: 27 additions & 8 deletions fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,25 +293,35 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,
struct btrfs_key key;
struct btrfs_ioctl_defrag_range_args range;
int num_defrag;
int index;
int ret;

/* get the inode */
key.objectid = defrag->root;
btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);
key.offset = (u64)-1;

index = srcu_read_lock(&fs_info->subvol_srcu);

inode_root = btrfs_read_fs_root_no_name(fs_info, &key);
if (IS_ERR(inode_root)) {
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
return PTR_ERR(inode_root);
ret = PTR_ERR(inode_root);
goto cleanup;
}
if (btrfs_root_refs(&inode_root->root_item) == 0) {
ret = -ENOENT;
goto cleanup;
}

key.objectid = defrag->ino;
btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
key.offset = 0;
inode = btrfs_iget(fs_info->sb, &key, inode_root, NULL);
if (IS_ERR(inode)) {
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
return PTR_ERR(inode);
ret = PTR_ERR(inode);
goto cleanup;
}
srcu_read_unlock(&fs_info->subvol_srcu, index);

/* do a chunk of defrag */
clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
Expand Down Expand Up @@ -346,6 +356,10 @@ static int __btrfs_run_defrag_inode(struct btrfs_fs_info *fs_info,

iput(inode);
return 0;
cleanup:
srcu_read_unlock(&fs_info->subvol_srcu, index);
kmem_cache_free(btrfs_inode_defrag_cachep, defrag);
return ret;
}

/*
Expand Down Expand Up @@ -1595,9 +1609,10 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
if (err < 0 && num_written > 0)
num_written = err;
}
out:

if (sync)
atomic_dec(&BTRFS_I(inode)->sync_writers);
out:
sb_end_write(inode->i_sb);
current->backing_dev_info = NULL;
return num_written ? num_written : err;
Expand Down Expand Up @@ -2242,6 +2257,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
if (lockend <= lockstart)
lockend = lockstart + root->sectorsize;

lockend--;
len = lockend - lockstart + 1;

len = max_t(u64, len, root->sectorsize);
Expand Down Expand Up @@ -2308,9 +2324,12 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
}
}

*offset = start;
free_extent_map(em);
break;
if (!test_bit(EXTENT_FLAG_PREALLOC,
&em->flags)) {
*offset = start;
free_extent_map(em);
break;
}
}
}

Expand Down
20 changes: 12 additions & 8 deletions fs/btrfs/free-space-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1862,11 +1862,13 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
{
struct btrfs_free_space_ctl *ctl = block_group->free_space_ctl;
struct btrfs_free_space *info;
int ret = 0;
int ret;
bool re_search = false;

spin_lock(&ctl->tree_lock);

again:
ret = 0;
if (!bytes)
goto out_lock;

Expand All @@ -1879,17 +1881,17 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
info = tree_search_offset(ctl, offset_to_bitmap(ctl, offset),
1, 0);
if (!info) {
/* the tree logging code might be calling us before we
* have fully loaded the free space rbtree for this
* block group. So it is possible the entry won't
* be in the rbtree yet at all. The caching code
* will make sure not to put it in the rbtree if
* the logging code has pinned it.
/*
* If we found a partial bit of our free space in a
* bitmap but then couldn't find the other part this may
* be a problem, so WARN about it.
*/
WARN_ON(re_search);
goto out_lock;
}
}

re_search = false;
if (!info->bitmap) {
unlink_free_space(ctl, info);
if (offset == info->offset) {
Expand Down Expand Up @@ -1935,8 +1937,10 @@ int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
}

ret = remove_from_bitmap(ctl, info, &offset, &bytes);
if (ret == -EAGAIN)
if (ret == -EAGAIN) {
re_search = true;
goto again;
}
BUG_ON(ret); /* logic error */
out_lock:
spin_unlock(&ctl->tree_lock);
Expand Down
Loading

0 comments on commit 24f8ebe

Please sign in to comment.