Skip to content

Commit b82207b

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/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
2 parents 034a0f6 + abdd2e8 commit b82207b

File tree

14 files changed

+109
-47
lines changed

14 files changed

+109
-47
lines changed

fs/btrfs/compression.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -821,7 +821,7 @@ static void free_workspace(int type, struct list_head *workspace)
821821

822822
spin_lock(workspace_lock);
823823
if (*num_workspace < num_online_cpus()) {
824-
list_add_tail(workspace, idle_workspace);
824+
list_add(workspace, idle_workspace);
825825
(*num_workspace)++;
826826
spin_unlock(workspace_lock);
827827
goto wake;

fs/btrfs/dev-replace.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "check-integrity.h"
3737
#include "rcu-string.h"
3838
#include "dev-replace.h"
39+
#include "sysfs.h"
3940

4041
static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
4142
int scrub_ret);
@@ -562,6 +563,10 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info,
562563
fs_info->fs_devices->latest_bdev = tgt_device->bdev;
563564
list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list);
564565

566+
/* replace the sysfs entry */
567+
btrfs_kobj_rm_device(fs_info, src_device);
568+
btrfs_kobj_add_device(fs_info, tgt_device);
569+
565570
btrfs_rm_dev_replace_blocked(fs_info);
566571

567572
btrfs_rm_dev_replace_srcdev(fs_info, src_device);

fs/btrfs/disk-io.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ static int verify_parent_transid(struct extent_io_tree *io_tree,
369369
out:
370370
unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1,
371371
&cached_state, GFP_NOFS);
372-
btrfs_tree_read_unlock_blocking(eb);
372+
if (need_lock)
373+
btrfs_tree_read_unlock_blocking(eb);
373374
return ret;
374375
}
375376

@@ -2904,7 +2905,9 @@ int open_ctree(struct super_block *sb,
29042905
if (ret)
29052906
goto fail_qgroup;
29062907

2908+
mutex_lock(&fs_info->cleaner_mutex);
29072909
ret = btrfs_recover_relocation(tree_root);
2910+
mutex_unlock(&fs_info->cleaner_mutex);
29082911
if (ret < 0) {
29092912
printk(KERN_WARNING
29102913
"BTRFS: failed to recover relocation\n");

fs/btrfs/extent-tree.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5678,7 +5678,6 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans,
56785678
struct btrfs_caching_control *next;
56795679
struct btrfs_caching_control *caching_ctl;
56805680
struct btrfs_block_group_cache *cache;
5681-
struct btrfs_space_info *space_info;
56825681

56835682
down_write(&fs_info->commit_root_sem);
56845683

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

57025701
up_write(&fs_info->commit_root_sem);
57035702

5704-
list_for_each_entry_rcu(space_info, &fs_info->space_info, list)
5705-
percpu_counter_set(&space_info->total_bytes_pinned, 0);
5706-
57075703
update_global_block_rsv(fs_info);
57085704
}
57095705

@@ -5741,6 +5737,7 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end)
57415737
spin_lock(&cache->lock);
57425738
cache->pinned -= len;
57435739
space_info->bytes_pinned -= len;
5740+
percpu_counter_add(&space_info->total_bytes_pinned, -len);
57445741
if (cache->ro) {
57455742
space_info->bytes_readonly += len;
57465743
readonly = true;

fs/btrfs/ioctl.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -136,19 +136,22 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags)
136136
void btrfs_update_iflags(struct inode *inode)
137137
{
138138
struct btrfs_inode *ip = BTRFS_I(inode);
139-
140-
inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC);
139+
unsigned int new_fl = 0;
141140

142141
if (ip->flags & BTRFS_INODE_SYNC)
143-
inode->i_flags |= S_SYNC;
142+
new_fl |= S_SYNC;
144143
if (ip->flags & BTRFS_INODE_IMMUTABLE)
145-
inode->i_flags |= S_IMMUTABLE;
144+
new_fl |= S_IMMUTABLE;
146145
if (ip->flags & BTRFS_INODE_APPEND)
147-
inode->i_flags |= S_APPEND;
146+
new_fl |= S_APPEND;
148147
if (ip->flags & BTRFS_INODE_NOATIME)
149-
inode->i_flags |= S_NOATIME;
148+
new_fl |= S_NOATIME;
150149
if (ip->flags & BTRFS_INODE_DIRSYNC)
151-
inode->i_flags |= S_DIRSYNC;
150+
new_fl |= S_DIRSYNC;
151+
152+
set_mask_bits(&inode->i_flags,
153+
S_SYNC | S_APPEND | S_IMMUTABLE | S_NOATIME | S_DIRSYNC,
154+
new_fl);
152155
}
153156

154157
/*
@@ -3139,7 +3142,6 @@ static int clone_finish_inode_update(struct btrfs_trans_handle *trans,
31393142
static void clone_update_extent_map(struct inode *inode,
31403143
const struct btrfs_trans_handle *trans,
31413144
const struct btrfs_path *path,
3142-
struct btrfs_file_extent_item *fi,
31433145
const u64 hole_offset,
31443146
const u64 hole_len)
31453147
{
@@ -3154,7 +3156,11 @@ static void clone_update_extent_map(struct inode *inode,
31543156
return;
31553157
}
31563158

3157-
if (fi) {
3159+
if (path) {
3160+
struct btrfs_file_extent_item *fi;
3161+
3162+
fi = btrfs_item_ptr(path->nodes[0], path->slots[0],
3163+
struct btrfs_file_extent_item);
31583164
btrfs_extent_item_to_extent_map(inode, path, fi, false, em);
31593165
em->generation = -1;
31603166
if (btrfs_file_extent_type(path->nodes[0], fi) ==
@@ -3508,18 +3514,15 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
35083514
btrfs_item_ptr_offset(leaf, slot),
35093515
size);
35103516
inode_add_bytes(inode, datal);
3511-
extent = btrfs_item_ptr(leaf, slot,
3512-
struct btrfs_file_extent_item);
35133517
}
35143518

35153519
/* If we have an implicit hole (NO_HOLES feature). */
35163520
if (drop_start < new_key.offset)
35173521
clone_update_extent_map(inode, trans,
3518-
path, NULL, drop_start,
3522+
NULL, drop_start,
35193523
new_key.offset - drop_start);
35203524

3521-
clone_update_extent_map(inode, trans, path,
3522-
extent, 0, 0);
3525+
clone_update_extent_map(inode, trans, path, 0, 0);
35233526

35243527
btrfs_mark_buffer_dirty(leaf);
35253528
btrfs_release_path(path);
@@ -3562,12 +3565,10 @@ static int btrfs_clone(struct inode *src, struct inode *inode,
35623565
btrfs_end_transaction(trans, root);
35633566
goto out;
35643567
}
3568+
clone_update_extent_map(inode, trans, NULL, last_dest_end,
3569+
destoff + len - last_dest_end);
35653570
ret = clone_finish_inode_update(trans, inode, destoff + len,
35663571
destoff, olen);
3567-
if (ret)
3568-
goto out;
3569-
clone_update_extent_map(inode, trans, path, NULL, last_dest_end,
3570-
destoff + len - last_dest_end);
35713572
}
35723573

35733574
out:

fs/btrfs/print-tree.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ static void print_extent_data_ref(struct extent_buffer *eb,
5454
btrfs_extent_data_ref_count(eb, ref));
5555
}
5656

57-
static void print_extent_item(struct extent_buffer *eb, int slot)
57+
static void print_extent_item(struct extent_buffer *eb, int slot, int type)
5858
{
5959
struct btrfs_extent_item *ei;
6060
struct btrfs_extent_inline_ref *iref;
@@ -63,7 +63,6 @@ static void print_extent_item(struct extent_buffer *eb, int slot)
6363
struct btrfs_disk_key key;
6464
unsigned long end;
6565
unsigned long ptr;
66-
int type;
6766
u32 item_size = btrfs_item_size_nr(eb, slot);
6867
u64 flags;
6968
u64 offset;
@@ -88,7 +87,8 @@ static void print_extent_item(struct extent_buffer *eb, int slot)
8887
btrfs_extent_refs(eb, ei), btrfs_extent_generation(eb, ei),
8988
flags);
9089

91-
if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
90+
if ((type == BTRFS_EXTENT_ITEM_KEY) &&
91+
flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
9292
struct btrfs_tree_block_info *info;
9393
info = (struct btrfs_tree_block_info *)(ei + 1);
9494
btrfs_tree_block_key(eb, info, &key);
@@ -223,7 +223,8 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
223223
btrfs_disk_root_refs(l, ri));
224224
break;
225225
case BTRFS_EXTENT_ITEM_KEY:
226-
print_extent_item(l, i);
226+
case BTRFS_METADATA_ITEM_KEY:
227+
print_extent_item(l, i, type);
227228
break;
228229
case BTRFS_TREE_BLOCK_REF_KEY:
229230
printk(KERN_INFO "\t\ttree block backref\n");

fs/btrfs/raid56.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1956,9 +1956,10 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
19561956
* pages are going to be uptodate.
19571957
*/
19581958
for (stripe = 0; stripe < bbio->num_stripes; stripe++) {
1959-
if (rbio->faila == stripe ||
1960-
rbio->failb == stripe)
1959+
if (rbio->faila == stripe || rbio->failb == stripe) {
1960+
atomic_inc(&rbio->bbio->error);
19611961
continue;
1962+
}
19621963

19631964
for (pagenr = 0; pagenr < nr_pages; pagenr++) {
19641965
struct page *p;

fs/btrfs/super.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,9 +522,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
522522
case Opt_ssd_spread:
523523
btrfs_set_and_info(root, SSD_SPREAD,
524524
"use spread ssd allocation scheme");
525+
btrfs_set_opt(info->mount_opt, SSD);
525526
break;
526527
case Opt_nossd:
527-
btrfs_clear_and_info(root, NOSSD,
528+
btrfs_set_and_info(root, NOSSD,
528529
"not using ssd allocation scheme");
529530
btrfs_clear_opt(info->mount_opt, SSD);
530531
break;
@@ -1467,7 +1468,9 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data)
14671468
goto restore;
14681469

14691470
/* recover relocation */
1471+
mutex_lock(&fs_info->cleaner_mutex);
14701472
ret = btrfs_recover_relocation(root);
1473+
mutex_unlock(&fs_info->cleaner_mutex);
14711474
if (ret)
14721475
goto restore;
14731476

@@ -1808,6 +1811,8 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root)
18081811
list_for_each_entry(dev, head, dev_list) {
18091812
if (dev->missing)
18101813
continue;
1814+
if (!dev->name)
1815+
continue;
18111816
if (!first_dev || dev->devid < first_dev->devid)
18121817
first_dev = dev;
18131818
}

fs/btrfs/sysfs.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -605,14 +605,37 @@ static void init_feature_attrs(void)
605605
}
606606
}
607607

608-
static int add_device_membership(struct btrfs_fs_info *fs_info)
608+
int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info,
609+
struct btrfs_device *one_device)
610+
{
611+
struct hd_struct *disk;
612+
struct kobject *disk_kobj;
613+
614+
if (!fs_info->device_dir_kobj)
615+
return -EINVAL;
616+
617+
if (one_device) {
618+
disk = one_device->bdev->bd_part;
619+
disk_kobj = &part_to_dev(disk)->kobj;
620+
621+
sysfs_remove_link(fs_info->device_dir_kobj,
622+
disk_kobj->name);
623+
}
624+
625+
return 0;
626+
}
627+
628+
int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
629+
struct btrfs_device *one_device)
609630
{
610631
int error = 0;
611632
struct btrfs_fs_devices *fs_devices = fs_info->fs_devices;
612633
struct btrfs_device *dev;
613634

614-
fs_info->device_dir_kobj = kobject_create_and_add("devices",
635+
if (!fs_info->device_dir_kobj)
636+
fs_info->device_dir_kobj = kobject_create_and_add("devices",
615637
&fs_info->super_kobj);
638+
616639
if (!fs_info->device_dir_kobj)
617640
return -ENOMEM;
618641

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

649+
if (one_device && one_device != dev)
650+
continue;
651+
626652
disk = dev->bdev->bd_part;
627653
disk_kobj = &part_to_dev(disk)->kobj;
628654

@@ -666,7 +692,7 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info)
666692
if (error)
667693
goto failure;
668694

669-
error = add_device_membership(fs_info);
695+
error = btrfs_kobj_add_device(fs_info, NULL);
670696
if (error)
671697
goto failure;
672698

fs/btrfs/sysfs.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,8 @@ char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags);
6666
extern const char * const btrfs_feature_set_names[3];
6767
extern struct kobj_type space_info_ktype;
6868
extern struct kobj_type btrfs_raid_ktype;
69+
int btrfs_kobj_add_device(struct btrfs_fs_info *fs_info,
70+
struct btrfs_device *one_device);
71+
int btrfs_kobj_rm_device(struct btrfs_fs_info *fs_info,
72+
struct btrfs_device *one_device);
6973
#endif /* _BTRFS_SYSFS_H_ */

fs/btrfs/transaction.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -386,11 +386,13 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
386386
bool reloc_reserved = false;
387387
int ret;
388388

389+
/* Send isn't supposed to start transactions. */
390+
ASSERT(current->journal_info != (void *)BTRFS_SEND_TRANS_STUB);
391+
389392
if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state))
390393
return ERR_PTR(-EROFS);
391394

392-
if (current->journal_info &&
393-
current->journal_info != (void *)BTRFS_SEND_TRANS_STUB) {
395+
if (current->journal_info) {
394396
WARN_ON(type & TRANS_EXTWRITERS);
395397
h = current->journal_info;
396398
h->use_count++;
@@ -491,6 +493,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
491493
smp_mb();
492494
if (cur_trans->state >= TRANS_STATE_BLOCKED &&
493495
may_wait_transaction(root, type)) {
496+
current->journal_info = h;
494497
btrfs_commit_transaction(h, root);
495498
goto again;
496499
}
@@ -1615,11 +1618,6 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans,
16151618
int ret;
16161619

16171620
ret = btrfs_run_delayed_items(trans, root);
1618-
/*
1619-
* running the delayed items may have added new refs. account
1620-
* them now so that they hinder processing of more delayed refs
1621-
* as little as possible.
1622-
*/
16231621
if (ret)
16241622
return ret;
16251623

0 commit comments

Comments
 (0)