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:
 "We've queued up a few fixes in my for-linus branch"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix crash when starting transaction
  Btrfs: fix btrfs_print_leaf for skinny metadata
  Btrfs: fix race of using total_bytes_pinned
  btrfs: use E2BIG instead of EIO if compression does not help
  btrfs: remove stale comment from btrfs_flush_all_pending_stuffs
  Btrfs: fix use-after-free when cloning a trailing file hole
  btrfs: fix null pointer dereference in btrfs_show_devname when name is null
  btrfs: fix null pointer dereference in clone_fs_devices when name is null
  btrfs: fix nossd and ssd_spread mount option regression
  Btrfs: fix race between balance recovery and root deletion
  Btrfs: atomically set inode->i_flags in btrfs_update_iflags
  btrfs: only unlock block in verify_parent_transid if we locked it
  Btrfs: assert send doesn't attempt to start transactions
  btrfs compression: reuse recently used workspace
  Btrfs: fix crash when mounting raid5 btrfs with missing disks
  btrfs: create sprout should rename fsid on the sysfs as well
  btrfs: dev replace should replace the sysfs entry
  btrfs: dev add should add its sysfs entry
  btrfs: dev delete should remove sysfs entry
  btrfs: rename add_device_membership to btrfs_kobj_add_device
  • Loading branch information
Linus Torvalds committed Jul 4, 2014
2 parents 034a0f6 + abdd2e8 commit b82207b
Show file tree
Hide file tree
Showing 14 changed files with 109 additions and 47 deletions.
2 changes: 1 addition & 1 deletion fs/btrfs/compression.c
Original file line number Diff line number Diff line change
Expand Up @@ -821,7 +821,7 @@ static void free_workspace(int type, struct list_head *workspace)

spin_lock(workspace_lock);
if (*num_workspace < num_online_cpus()) {
list_add_tail(workspace, idle_workspace);
list_add(workspace, idle_workspace);
(*num_workspace)++;
spin_unlock(workspace_lock);
goto wake;
Expand Down
5 changes: 5 additions & 0 deletions fs/btrfs/dev-replace.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "check-integrity.h"
#include "rcu-string.h"
#include "dev-replace.h"
#include "sysfs.h"

static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
int scrub_ret);
Expand Down Expand Up @@ -562,6 +563,10 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
fs_info->fs_devices->latest_bdev = tgt_device->bdev;
list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);

/* replace the sysfs entry */
btrfs_kobj_rm_device(fs_info, src_device);
btrfs_kobj_add_device(fs_info, tgt_device);

btrfs_rm_dev_replace_blocked(fs_info);

btrfs_rm_dev_replace_srcdev(fs_info, src_device);
Expand Down
5 changes: 4 additions & 1 deletion fs/btrfs/disk-io.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
out:
unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1,
&cached_state, GFP_NOFS);
btrfs_tree_read_unlock_blocking(eb);
if (need_lock)
btrfs_tree_read_unlock_blocking(eb);
return ret;
}

Expand Down Expand Up @@ -2904,7 +2905,9 @@ int open_ctree(struct super_block *sb,
if (ret)
goto fail_qgroup;

mutex_lock(&fs_info->cleaner_mutex);
ret = btrfs_recover_relocation(tree_root);
mutex_unlock(&fs_info->cleaner_mutex);
if (ret < 0) {
printk(KERN_WARNING
"BTRFS: failed to recover relocation\n");
Expand Down
5 changes: 1 addition & 4 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -5678,7 +5678,6 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
struct btrfs_caching_control *next;
struct btrfs_caching_control *caching_ctl;
struct btrfs_block_group_cache *cache;
struct btrfs_space_info *space_info;

down_write(&fs_info->commit_root_sem);

Expand All @@ -5701,9 +5700,6 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,

up_write(&fs_info->commit_root_sem);

list_for_each_entry_rcu(space_info, &fs_info->space_info, list)
percpu_counter_set(&space_info->total_bytes_pinned, 0);

update_global_block_rsv(fs_info);
}

Expand Down Expand Up @@ -5741,6 +5737,7 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
spin_lock(&cache->lock);
cache->pinned -= len;
space_info->bytes_pinned -= len;
percpu_counter_add(&space_info->total_bytes_pinned, -len);
if (cache->ro) {
space_info->bytes_readonly += len;
readonly = true;
Expand Down
37 changes: 19 additions & 18 deletions fs/btrfs/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -136,19 +136,22 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags)
void btrfs_update_iflags(struct inode *inode)
{
struct btrfs_inode *ip = BTRFS_I(inode);

inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
unsigned int new_fl = 0;

if (ip->flags & BTRFS_INODE_SYNC)
inode->i_flags |= S_SYNC;
new_fl |= S_SYNC;
if (ip->flags & BTRFS_INODE_IMMUTABLE)
inode->i_flags |= S_IMMUTABLE;
new_fl |= S_IMMUTABLE;
if (ip->flags & BTRFS_INODE_APPEND)
inode->i_flags |= S_APPEND;
new_fl |= S_APPEND;
if (ip->flags & BTRFS_INODE_NOATIME)
inode->i_flags |= S_NOATIME;
new_fl |= S_NOATIME;
if (ip->flags & BTRFS_INODE_DIRSYNC)
inode->i_flags |= S_DIRSYNC;
new_fl |= S_DIRSYNC;

set_mask_bits(&inode->i_flags,
S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
new_fl);
}

/*
Expand Down Expand Up @@ -3139,7 +3142,6 @@ static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
static void clone_update_extent_map(struct inode *inode,
const struct btrfs_trans_handle *trans,
const struct btrfs_path *path,
struct btrfs_file_extent_item *fi,
const u64 hole_offset,
const u64 hole_len)
{
Expand All @@ -3154,7 +3156,11 @@ static void clone_update_extent_map(struct inode *inode,
return;
}

if (fi) {
if (path) {
struct btrfs_file_extent_item *fi;

fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
struct btrfs_file_extent_item);
btrfs_extent_item_to_extent_map(inode, path, fi, false, em);
em->generation = -1;
if (btrfs_file_extent_type(path->nodes[0], fi) ==
Expand Down Expand Up @@ -3508,18 +3514,15 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
btrfs_item_ptr_offset(leaf, slot),
size);
inode_add_bytes(inode, datal);
extent = btrfs_item_ptr(leaf, slot,
struct btrfs_file_extent_item);
}

/* If we have an implicit hole (NO_HOLES feature). */
if (drop_start < new_key.offset)
clone_update_extent_map(inode, trans,
path, NULL, drop_start,
NULL, drop_start,
new_key.offset - drop_start);

clone_update_extent_map(inode, trans, path,
extent, 0, 0);
clone_update_extent_map(inode, trans, path, 0, 0);

btrfs_mark_buffer_dirty(leaf);
btrfs_release_path(path);
Expand Down Expand Up @@ -3562,12 +3565,10 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
btrfs_end_transaction(trans, root);
goto out;
}
clone_update_extent_map(inode, trans, NULL, last_dest_end,
destoff + len - last_dest_end);
ret = clone_finish_inode_update(trans, inode, destoff + len,
destoff, olen);
if (ret)
goto out;
clone_update_extent_map(inode, trans, path, NULL, last_dest_end,
destoff + len - last_dest_end);
}

out:
Expand Down
9 changes: 5 additions & 4 deletions fs/btrfs/print-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static void print_extent_data_ref(struct extent_buffer *eb,
btrfs_extent_data_ref_count(eb, ref));
}

static void print_extent_item(struct extent_buffer *eb, int slot)
static void print_extent_item(struct extent_buffer *eb, int slot, int type)
{
struct btrfs_extent_item *ei;
struct btrfs_extent_inline_ref *iref;
Expand All @@ -63,7 +63,6 @@ static void print_extent_item(struct extent_buffer *eb, int slot)
struct btrfs_disk_key key;
unsigned long end;
unsigned long ptr;
int type;
u32 item_size = btrfs_item_size_nr(eb, slot);
u64 flags;
u64 offset;
Expand All @@ -88,7 +87,8 @@ static void print_extent_item(struct extent_buffer *eb, int slot)
btrfs_extent_refs(eb, ei), btrfs_extent_generation(eb, ei),
flags);

if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
if ((type == BTRFS_EXTENT_ITEM_KEY) &&
flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
struct btrfs_tree_block_info *info;
info = (struct btrfs_tree_block_info *)(ei + 1);
btrfs_tree_block_key(eb, info, &key);
Expand Down Expand Up @@ -223,7 +223,8 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
btrfs_disk_root_refs(l, ri));
break;
case BTRFS_EXTENT_ITEM_KEY:
print_extent_item(l, i);
case BTRFS_METADATA_ITEM_KEY:
print_extent_item(l, i, type);
break;
case BTRFS_TREE_BLOCK_REF_KEY:
printk(KERN_INFO "\t\ttree block backref\n");
Expand Down
5 changes: 3 additions & 2 deletions fs/btrfs/raid56.c
Original file line number Diff line number Diff line change
Expand Up @@ -1956,9 +1956,10 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
* pages are going to be uptodate.
*/
for (stripe = 0; stripe < bbio->num_stripes; stripe++) {
if (rbio->faila == stripe ||
rbio->failb == stripe)
if (rbio->faila == stripe || rbio->failb == stripe) {
atomic_inc(&rbio->bbio->error);
continue;
}

for (pagenr = 0; pagenr < nr_pages; pagenr++) {
struct page *p;
Expand Down
7 changes: 6 additions & 1 deletion fs/btrfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -522,9 +522,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
case Opt_ssd_spread:
btrfs_set_and_info(root, SSD_SPREAD,
"use spread ssd allocation scheme");
btrfs_set_opt(info->mount_opt, SSD);
break;
case Opt_nossd:
btrfs_clear_and_info(root, NOSSD,
btrfs_set_and_info(root, NOSSD,
"not using ssd allocation scheme");
btrfs_clear_opt(info->mount_opt, SSD);
break;
Expand Down Expand Up @@ -1467,7 +1468,9 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
goto restore;

/* recover relocation */
mutex_lock(&fs_info->cleaner_mutex);
ret = btrfs_recover_relocation(root);
mutex_unlock(&fs_info->cleaner_mutex);
if (ret)
goto restore;

Expand Down Expand Up @@ -1808,6 +1811,8 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root)
list_for_each_entry(dev, head, dev_list) {
if (dev->missing)
continue;
if (!dev->name)
continue;
if (!first_dev || dev->devid < first_dev->devid)
first_dev = dev;
}
Expand Down
32 changes: 29 additions & 3 deletions fs/btrfs/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,14 +605,37 @@ static void init_feature_attrs(void)
}
}

static int add_device_membership(struct btrfs_fs_info *fs_info)
int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info,
struct btrfs_device *one_device)
{
struct hd_struct *disk;
struct kobject *disk_kobj;

if (!fs_info->device_dir_kobj)
return -EINVAL;

if (one_device) {
disk = one_device->bdev->bd_part;
disk_kobj = &part_to_dev(disk)->kobj;

sysfs_remove_link(fs_info->device_dir_kobj,
disk_kobj->name);
}

return 0;
}

int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
struct btrfs_device *one_device)
{
int error = 0;
struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
struct btrfs_device *dev;

fs_info->device_dir_kobj = kobject_create_and_add("devices",
if (!fs_info->device_dir_kobj)
fs_info->device_dir_kobj = kobject_create_and_add("devices",
&fs_info->super_kobj);

if (!fs_info->device_dir_kobj)
return -ENOMEM;

Expand All @@ -623,6 +646,9 @@ static int add_device_membership(struct btrfs_fs_info *fs_info)
if (!dev->bdev)
continue;

if (one_device && one_device != dev)
continue;

disk = dev->bdev->bd_part;
disk_kobj = &part_to_dev(disk)->kobj;

Expand Down Expand Up @@ -666,7 +692,7 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
if (error)
goto failure;

error = add_device_membership(fs_info);
error = btrfs_kobj_add_device(fs_info, NULL);
if (error)
goto failure;

Expand Down
4 changes: 4 additions & 0 deletions fs/btrfs/sysfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,8 @@ char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags);
extern const char * const btrfs_feature_set_names[3];
extern struct kobj_type space_info_ktype;
extern struct kobj_type btrfs_raid_ktype;
int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
struct btrfs_device *one_device);
int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info,
struct btrfs_device *one_device);
#endif /* _BTRFS_SYSFS_H_ */
12 changes: 5 additions & 7 deletions fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,11 +386,13 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
bool reloc_reserved = false;
int ret;

/* Send isn't supposed to start transactions. */
ASSERT(current->journal_info != (void *)BTRFS_SEND_TRANS_STUB);

if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state))
return ERR_PTR(-EROFS);

if (current->journal_info &&
current->journal_info != (void *)BTRFS_SEND_TRANS_STUB) {
if (current->journal_info) {
WARN_ON(type & TRANS_EXTWRITERS);
h = current->journal_info;
h->use_count++;
Expand Down Expand Up @@ -491,6 +493,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
smp_mb();
if (cur_trans->state >= TRANS_STATE_BLOCKED &&
may_wait_transaction(root, type)) {
current->journal_info = h;
btrfs_commit_transaction(h, root);
goto again;
}
Expand Down Expand Up @@ -1615,11 +1618,6 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans,
int ret;

ret = btrfs_run_delayed_items(trans, root);
/*
* running the delayed items may have added new refs. account
* them now so that they hinder processing of more delayed refs
* as little as possible.
*/
if (ret)
return ret;

Expand Down
Loading

0 comments on commit b82207b

Please sign in to comment.