Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/mason/linux-btrfs

Pull btrfs fixes from Chris Mason:
 "These are mostly bug fixes and a two small performance fixes.  The
  most important of the bunch are Josef's fix for a snapshotting
  regression and Mark's update to fix compile problems on arm"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (25 commits)
  Btrfs: create the uuid tree on remount rw
  btrfs: change extent-same to copy entire argument struct
  Btrfs: dir_inode_operations should use btrfs_update_time also
  btrfs: Add btrfs: prefix to kernel log output
  btrfs: refuse to remount read-write after abort
  Btrfs: btrfs_ioctl_default_subvol: Revert back to toplevel subvolume when arg is 0
  Btrfs: don't leak transaction in btrfs_sync_file()
  Btrfs: add the missing mutex unlock in write_all_supers()
  Btrfs: iput inode on allocation failure
  Btrfs: remove space_info->reservation_progress
  Btrfs: kill delay_iput arg to the wait_ordered functions
  Btrfs: fix worst case calculator for space usage
  Revert "Btrfs: rework the overcommit logic to be based on the total size"
  Btrfs: improve replacing nocow extents
  Btrfs: drop dir i_size when adding new names on replay
  Btrfs: replay dir_index items before other items
  Btrfs: check roots last log commit when checking if an inode has been logged
  Btrfs: actually log directory we are fsync()'ing
  Btrfs: actually limit the size of delalloc range
  Btrfs: allocate the free space by the existed max extent size when ENOSPC
  ...
  • Loading branch information
Linus Torvalds committed Sep 22, 2013
2 parents c43a385 + 94aebfb commit 0fbf2cc
Show file tree
Hide file tree
Showing 21 changed files with 364 additions and 175 deletions.
5 changes: 4 additions & 1 deletion fs/btrfs/btrfs_inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,10 @@ static inline bool btrfs_is_free_space_inode(struct inode *inode)
static inline int btrfs_inode_in_log(struct inode *inode, u64 generation)
{
if (BTRFS_I(inode)->logged_trans == generation &&
BTRFS_I(inode)->last_sub_trans <= BTRFS_I(inode)->last_log_commit)
BTRFS_I(inode)->last_sub_trans <=
BTRFS_I(inode)->last_log_commit &&
BTRFS_I(inode)->last_sub_trans <=
BTRFS_I(inode)->root->last_log_commit)
return 1;
return 0;
}
Expand Down
7 changes: 5 additions & 2 deletions fs/btrfs/ctree.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,8 +1005,11 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans,
return ret;
}

if (root->ref_cows)
btrfs_reloc_cow_block(trans, root, buf, cow);
if (root->ref_cows) {
ret = btrfs_reloc_cow_block(trans, root, buf, cow);
if (ret)
return ret;
}

if (buf == root->node) {
WARN_ON(parent && parent != buf);
Expand Down
17 changes: 4 additions & 13 deletions fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1118,15 +1118,6 @@ struct btrfs_space_info {
*/
struct percpu_counter total_bytes_pinned;

/*
* we bump reservation progress every time we decrement
* bytes_reserved. This way people waiting for reservations
* know something good has happened and they can check
* for progress. The number here isn't to be trusted, it
* just shows reclaim activity
*/
unsigned long reservation_progress;

unsigned int full:1; /* indicates that we cannot allocate any more
chunks for this space */
unsigned int chunk_alloc:1; /* set if we are allocating a chunk */
Expand Down Expand Up @@ -3135,7 +3126,7 @@ static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_root *root,
unsigned num_items)
{
return (root->leafsize + root->nodesize * (BTRFS_MAX_LEVEL - 1)) *
3 * num_items;
2 * num_items;
}

/*
Expand Down Expand Up @@ -3939,9 +3930,9 @@ int btrfs_update_reloc_root(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_recover_relocation(struct btrfs_root *root);
int btrfs_reloc_clone_csums(struct inode *inode, u64 file_pos, u64 len);
void btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *buf,
struct extent_buffer *cow);
int btrfs_reloc_cow_block(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct extent_buffer *buf,
struct extent_buffer *cow);
void btrfs_reloc_pre_snapshot(struct btrfs_trans_handle *trans,
struct btrfs_pending_snapshot *pending,
u64 *bytes_to_reserve);
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/dev-replace.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,7 +400,7 @@ int btrfs_dev_replace_start(struct btrfs_root *root,
args->result = BTRFS_IOCTL_DEV_REPLACE_RESULT_NO_ERROR;
btrfs_dev_replace_unlock(dev_replace);

btrfs_wait_all_ordered_extents(root->fs_info, 0);
btrfs_wait_all_ordered_extents(root->fs_info);

/* force writing the updated state information to disk */
trans = btrfs_start_transaction(root, 0);
Expand Down Expand Up @@ -475,7 +475,7 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
mutex_unlock(&dev_replace->lock_finishing_cancel_unmount);
return ret;
}
btrfs_wait_all_ordered_extents(root->fs_info, 0);
btrfs_wait_all_ordered_extents(root->fs_info);

trans = btrfs_start_transaction(root, 0);
if (IS_ERR(trans)) {
Expand Down
2 changes: 2 additions & 0 deletions fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ static struct btrfs_lockdep_keyset {
{ .id = BTRFS_TREE_LOG_OBJECTID, .name_stem = "log" },
{ .id = BTRFS_TREE_RELOC_OBJECTID, .name_stem = "treloc" },
{ .id = BTRFS_DATA_RELOC_TREE_OBJECTID, .name_stem = "dreloc" },
{ .id = BTRFS_UUID_TREE_OBJECTID, .name_stem = "uuid" },
{ .id = 0, .name_stem = "tree" },
};

Expand Down Expand Up @@ -3415,6 +3416,7 @@ static int write_all_supers(struct btrfs_root *root, int max_mirrors)
if (total_errors > max_errors) {
printk(KERN_ERR "btrfs: %d errors while writing supers\n",
total_errors);
mutex_unlock(&root->fs_info->fs_devices->device_list_mutex);

/* FUA is masked off if unsupported and can't be the reason */
btrfs_error(root->fs_info, -EIO,
Expand Down
57 changes: 30 additions & 27 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3925,7 +3925,6 @@ static int can_overcommit(struct btrfs_root *root,
u64 space_size;
u64 avail;
u64 used;
u64 to_add;

used = space_info->bytes_used + space_info->bytes_reserved +
space_info->bytes_pinned + space_info->bytes_readonly;
Expand Down Expand Up @@ -3959,25 +3958,17 @@ static int can_overcommit(struct btrfs_root *root,
BTRFS_BLOCK_GROUP_RAID10))
avail >>= 1;

to_add = space_info->total_bytes;

/*
* If we aren't flushing all things, let us overcommit up to
* 1/2th of the space. If we can flush, don't let us overcommit
* too much, let it overcommit up to 1/8 of the space.
*/
if (flush == BTRFS_RESERVE_FLUSH_ALL)
to_add >>= 3;
avail >>= 3;
else
to_add >>= 1;

/*
* Limit the overcommit to the amount of free space we could possibly
* allocate for chunks.
*/
to_add = min(avail, to_add);
avail >>= 1;

if (used + bytes < space_info->total_bytes + to_add)
if (used + bytes < space_info->total_bytes + avail)
return 1;
return 0;
}
Expand All @@ -4000,7 +3991,7 @@ static void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,
*/
btrfs_start_all_delalloc_inodes(root->fs_info, 0);
if (!current->journal_info)
btrfs_wait_all_ordered_extents(root->fs_info, 0);
btrfs_wait_all_ordered_extents(root->fs_info);
}
}

Expand Down Expand Up @@ -4030,7 +4021,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,
if (delalloc_bytes == 0) {
if (trans)
return;
btrfs_wait_all_ordered_extents(root->fs_info, 0);
btrfs_wait_all_ordered_extents(root->fs_info);
return;
}

Expand Down Expand Up @@ -4058,7 +4049,7 @@ static void shrink_delalloc(struct btrfs_root *root, u64 to_reclaim, u64 orig,

loops++;
if (wait_ordered && !trans) {
btrfs_wait_all_ordered_extents(root->fs_info, 0);
btrfs_wait_all_ordered_extents(root->fs_info);
} else {
time_left = schedule_timeout_killable(1);
if (time_left)
Expand Down Expand Up @@ -4465,7 +4456,6 @@ static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
space_info->bytes_may_use -= num_bytes;
trace_btrfs_space_reservation(fs_info, "space_info",
space_info->flags, num_bytes, 0);
space_info->reservation_progress++;
spin_unlock(&space_info->lock);
}
}
Expand Down Expand Up @@ -4666,7 +4656,6 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info)
sinfo->bytes_may_use -= num_bytes;
trace_btrfs_space_reservation(fs_info, "space_info",
sinfo->flags, num_bytes, 0);
sinfo->reservation_progress++;
block_rsv->reserved = block_rsv->size;
block_rsv->full = 1;
}
Expand Down Expand Up @@ -5446,7 +5435,6 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
space_info->bytes_readonly += num_bytes;
cache->reserved -= num_bytes;
space_info->bytes_reserved -= num_bytes;
space_info->reservation_progress++;
}
spin_unlock(&cache->lock);
spin_unlock(&space_info->lock);
Expand Down Expand Up @@ -6117,10 +6105,13 @@ enum btrfs_loop_type {
/*
* walks the btree of allocated extents and find a hole of a given size.
* The key ins is changed to record the hole:
* ins->objectid == block start
* ins->objectid == start position
* ins->flags = BTRFS_EXTENT_ITEM_KEY
* ins->offset == number of blocks
* ins->offset == the size of the hole.
* Any available blocks before search_start are skipped.
*
* If there is no suitable free space, we will record the max size of
* the free space extent currently.
*/
static noinline int find_free_extent(struct btrfs_root *orig_root,
u64 num_bytes, u64 empty_size,
Expand All @@ -6133,6 +6124,7 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
struct btrfs_block_group_cache *block_group = NULL;
struct btrfs_block_group_cache *used_block_group;
u64 search_start = 0;
u64 max_extent_size = 0;
int empty_cluster = 2 * 1024 * 1024;
struct btrfs_space_info *space_info;
int loop = 0;
Expand Down Expand Up @@ -6292,7 +6284,10 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
btrfs_get_block_group(used_block_group);

offset = btrfs_alloc_from_cluster(used_block_group,
last_ptr, num_bytes, used_block_group->key.objectid);
last_ptr,
num_bytes,
used_block_group->key.objectid,
&max_extent_size);
if (offset) {
/* we have a block, we're done */
spin_unlock(&last_ptr->refill_lock);
Expand Down Expand Up @@ -6355,8 +6350,10 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
* cluster
*/
offset = btrfs_alloc_from_cluster(block_group,
last_ptr, num_bytes,
search_start);
last_ptr,
num_bytes,
search_start,
&max_extent_size);
if (offset) {
/* we found one, proceed */
spin_unlock(&last_ptr->refill_lock);
Expand Down Expand Up @@ -6391,13 +6388,18 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
if (cached &&
block_group->free_space_ctl->free_space <
num_bytes + empty_cluster + empty_size) {
if (block_group->free_space_ctl->free_space >
max_extent_size)
max_extent_size =
block_group->free_space_ctl->free_space;
spin_unlock(&block_group->free_space_ctl->tree_lock);
goto loop;
}
spin_unlock(&block_group->free_space_ctl->tree_lock);

offset = btrfs_find_space_for_alloc(block_group, search_start,
num_bytes, empty_size);
num_bytes, empty_size,
&max_extent_size);
/*
* If we didn't find a chunk, and we haven't failed on this
* block group before, and this block group is in the middle of
Expand Down Expand Up @@ -6515,7 +6517,8 @@ static noinline int find_free_extent(struct btrfs_root *orig_root,
ret = 0;
}
out:

if (ret == -ENOSPC)
ins->offset = max_extent_size;
return ret;
}

Expand Down Expand Up @@ -6573,8 +6576,8 @@ int btrfs_reserve_extent(struct btrfs_root *root,
flags);

if (ret == -ENOSPC) {
if (!final_tried) {
num_bytes = num_bytes >> 1;
if (!final_tried && ins->offset) {
num_bytes = min(num_bytes >> 1, ins->offset);
num_bytes = round_down(num_bytes, root->sectorsize);
num_bytes = max(num_bytes, min_alloc_size);
if (num_bytes == min_alloc_size)
Expand Down
8 changes: 5 additions & 3 deletions fs/btrfs/extent_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1481,10 +1481,12 @@ static noinline u64 find_delalloc_range(struct extent_io_tree *tree,
*end = state->end;
cur_start = state->end + 1;
node = rb_next(node);
if (!node)
break;
total_bytes += state->end - state->start + 1;
if (total_bytes >= max_bytes)
if (total_bytes >= max_bytes) {
*end = *start + max_bytes - 1;
break;
}
if (!node)
break;
}
out:
Expand Down
4 changes: 2 additions & 2 deletions fs/btrfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1859,8 +1859,8 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)

ret = btrfs_log_dentry_safe(trans, root, dentry);
if (ret < 0) {
mutex_unlock(&inode->i_mutex);
goto out;
/* Fallthrough and commit/free transaction. */
ret = 1;
}

/* we've logged all the items and now have a consistent
Expand Down
Loading

0 comments on commit 0fbf2cc

Please sign in to comment.