Skip to content

Commit

Permalink
Merge branch 'btrfs-3.0' into for-linus
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Mason committed Aug 18, 2011
2 parents 9a4327c + f1e490a commit 81d86e1
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 35 deletions.
10 changes: 4 additions & 6 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1415,17 +1415,15 @@ void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val);
#define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \
static inline u##bits btrfs_##name(struct extent_buffer *eb) \
{ \
type *p = kmap_atomic(eb->first_page, KM_USER0); \
type *p = page_address(eb->first_page); \
u##bits res = le##bits##_to_cpu(p->member); \
kunmap_atomic(p, KM_USER0); \
return res; \
} \
static inline void btrfs_set_##name(struct extent_buffer *eb, \
u##bits val) \
{ \
type *p = kmap_atomic(eb->first_page, KM_USER0); \
type *p = page_address(eb->first_page); \
p->member = cpu_to_le##bits(val); \
kunmap_atomic(p, KM_USER0); \
}

#define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \
Expand Down Expand Up @@ -2367,8 +2365,8 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans,
int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
int btrfs_drop_snapshot(struct btrfs_root *root,
struct btrfs_block_rsv *block_rsv, int update_ref);
void btrfs_drop_snapshot(struct btrfs_root *root,
struct btrfs_block_rsv *block_rsv, int update_ref);
int btrfs_drop_subtree(struct btrfs_trans_handle *trans,
struct btrfs_root *root,
struct extent_buffer *node,
Expand Down
75 changes: 59 additions & 16 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1782,18 +1782,26 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr,


for (i = 0; i < multi->num_stripes; i++, stripe++) {
if (!stripe->dev->can_discard)
continue;

ret = btrfs_issue_discard(stripe->dev->bdev,
stripe->physical,
stripe->length);
if (!ret)
discarded_bytes += stripe->length;
else if (ret != -EOPNOTSUPP)
break;

/*
* Just in case we get back EOPNOTSUPP for some reason,
* just ignore the return value so we don't screw up
* people calling discard_extent.
*/
ret = 0;
}
kfree(multi);
}
if (discarded_bytes && ret == -EOPNOTSUPP)
ret = 0;

if (actual_bytes)
*actual_bytes = discarded_bytes;
Expand Down Expand Up @@ -6269,8 +6277,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans,
* also make sure backrefs for the shared block and all lower level
* blocks are properly updated.
*/
int btrfs_drop_snapshot(struct btrfs_root *root,
struct btrfs_block_rsv *block_rsv, int update_ref)
void btrfs_drop_snapshot(struct btrfs_root *root,
struct btrfs_block_rsv *block_rsv, int update_ref)
{
struct btrfs_path *path;
struct btrfs_trans_handle *trans;
Expand All @@ -6283,13 +6291,16 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
int level;

path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
if (!path) {
err = -ENOMEM;
goto out;
}

wc = kzalloc(sizeof(*wc), GFP_NOFS);
if (!wc) {
btrfs_free_path(path);
return -ENOMEM;
err = -ENOMEM;
goto out;
}

trans = btrfs_start_transaction(tree_root, 0);
Expand Down Expand Up @@ -6318,7 +6329,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
path->lowest_level = 0;
if (ret < 0) {
err = ret;
goto out;
goto out_free;
}
WARN_ON(ret > 0);

Expand Down Expand Up @@ -6425,11 +6436,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root,
free_extent_buffer(root->commit_root);
kfree(root);
}
out:
out_free:
btrfs_end_transaction_throttle(trans, tree_root);
kfree(wc);
btrfs_free_path(path);
return err;
out:
if (err)
btrfs_std_error(root->fs_info, err);
return;
}

/*
Expand Down Expand Up @@ -6720,6 +6734,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
struct btrfs_space_info *space_info;
struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices;
struct btrfs_device *device;
u64 min_free;
int index;
int dev_nr = 0;
int dev_min = 1;
int full = 0;
int ret = 0;

Expand All @@ -6729,8 +6747,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
if (!block_group)
return -1;

min_free = btrfs_block_group_used(&block_group->item);

/* no bytes used, we're good */
if (!btrfs_block_group_used(&block_group->item))
if (!min_free)
goto out;

space_info = block_group->space_info;
Expand All @@ -6746,10 +6766,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
* all of the extents from this block group. If we can, we're good
*/
if ((space_info->total_bytes != block_group->key.offset) &&
(space_info->bytes_used + space_info->bytes_reserved +
space_info->bytes_pinned + space_info->bytes_readonly +
btrfs_block_group_used(&block_group->item) <
space_info->total_bytes)) {
(space_info->bytes_used + space_info->bytes_reserved +
space_info->bytes_pinned + space_info->bytes_readonly +
min_free < space_info->total_bytes)) {
spin_unlock(&space_info->lock);
goto out;
}
Expand All @@ -6766,9 +6785,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
if (full)
goto out;

/*
* index:
* 0: raid10
* 1: raid1
* 2: dup
* 3: raid0
* 4: single
*/
index = get_block_group_index(block_group);
if (index == 0) {
dev_min = 4;
min_free /= 2;
} else if (index == 1) {
dev_min = 2;
} else if (index == 2) {
min_free *= 2;
} else if (index == 3) {
dev_min = fs_devices->rw_devices;
min_free /= dev_min;
}

mutex_lock(&root->fs_info->chunk_mutex);
list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
u64 min_free = btrfs_block_group_used(&block_group->item);
u64 dev_offset;

/*
Expand All @@ -6779,7 +6818,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr)
ret = find_free_dev_extent(NULL, device, min_free,
&dev_offset, NULL);
if (!ret)
dev_nr++;

if (dev_nr >= dev_min)
break;

ret = -1;
}
}
Expand Down
16 changes: 16 additions & 0 deletions fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
spin_lock(&root->fs_info->defrag_inodes_lock);
if (!BTRFS_I(inode)->in_defrag)
__btrfs_add_inode_defrag(inode, defrag);
else
kfree(defrag);
spin_unlock(&root->fs_info->defrag_inodes_lock);
return 0;
}
Expand Down Expand Up @@ -1638,11 +1640,15 @@ static long btrfs_fallocate(struct file *file, int mode,

cur_offset = alloc_start;
while (1) {
u64 actual_end;

em = btrfs_get_extent(inode, NULL, 0, cur_offset,
alloc_end - cur_offset, 0);
BUG_ON(IS_ERR_OR_NULL(em));
last_byte = min(extent_map_end(em), alloc_end);
actual_end = min_t(u64, extent_map_end(em), offset + len);
last_byte = (last_byte + mask) & ~mask;

if (em->block_start == EXTENT_MAP_HOLE ||
(cur_offset >= inode->i_size &&
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
Expand All @@ -1655,6 +1661,16 @@ static long btrfs_fallocate(struct file *file, int mode,
free_extent_map(em);
break;
}
} else if (actual_end > inode->i_size &&
!(mode & FALLOC_FL_KEEP_SIZE)) {
/*
* We didn't need to allocate any more space, but we
* still extended the size of the file so we need to
* update i_size.
*/
inode->i_ctime = CURRENT_TIME;
i_size_write(inode, actual_end);
btrfs_ordered_update_i_size(inode, actual_end, NULL);
}
free_extent_map(em);

Expand Down
16 changes: 11 additions & 5 deletions fs/btrfs/free-space-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1168,9 +1168,9 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl)
div64_u64(extent_bytes, (sizeof(struct btrfs_free_space)));
}

static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, u64 offset,
u64 bytes)
static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info,
u64 offset, u64 bytes)
{
unsigned long start, count;

Expand All @@ -1181,6 +1181,13 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
bitmap_clear(info->bitmap, start, count);

info->bytes -= bytes;
}

static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
struct btrfs_free_space *info, u64 offset,
u64 bytes)
{
__bitmap_clear_bits(ctl, info, offset, bytes);
ctl->free_space -= bytes;
}

Expand Down Expand Up @@ -1984,7 +1991,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group,
return 0;

ret = search_start;
bitmap_clear_bits(ctl, entry, ret, bytes);
__bitmap_clear_bits(ctl, entry, ret, bytes);

return ret;
}
Expand Down Expand Up @@ -2039,7 +2046,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
continue;
}
} else {

ret = entry->offset;

entry->offset += bytes;
Expand Down
4 changes: 4 additions & 0 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -2236,6 +2236,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
btrfs_wait_ordered_range(src, off, len);
}

/* truncate page cache pages from target inode range */
truncate_inode_pages_range(&inode->i_data, off,
ALIGN(off + len, PAGE_CACHE_SIZE) - 1);

/* clone data */
key.objectid = btrfs_ino(src);
key.type = BTRFS_EXTENT_DATA_KEY;
Expand Down
28 changes: 24 additions & 4 deletions fs/btrfs/tree-log.c
Original file line number Diff line number Diff line change
Expand Up @@ -799,14 +799,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
struct extent_buffer *eb, int slot,
struct btrfs_key *key)
{
struct inode *dir;
int ret;
struct btrfs_inode_ref *ref;
struct btrfs_dir_item *di;
struct inode *dir;
struct inode *inode;
char *name;
int namelen;
unsigned long ref_ptr;
unsigned long ref_end;
char *name;
int namelen;
int ret;
int search_done = 0;

/*
Expand Down Expand Up @@ -909,6 +910,25 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans,
}
btrfs_release_path(path);

/* look for a conflicting sequence number */
di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir),
btrfs_inode_ref_index(eb, ref),
name, namelen, 0);
if (di && !IS_ERR(di)) {
ret = drop_one_dir_item(trans, root, path, dir, di);
BUG_ON(ret);
}
btrfs_release_path(path);

/* look for a conflicing name */
di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir),
name, namelen, 0);
if (di && !IS_ERR(di)) {
ret = drop_one_dir_item(trans, root, path, dir, di);
BUG_ON(ret);
}
btrfs_release_path(path);

insert:
/* insert our name */
ret = btrfs_add_link(trans, dir, inode, name, namelen, 0,
Expand Down
Loading

0 comments on commit 81d86e1

Please sign in to comment.