diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-04 11:53:53 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-07-04 11:53:53 -0400 |
commit | b82207b8e8bffae5b2df8c054a35b0994cbb9896 (patch) | |
tree | 6bd07ce01442201cd01a8a95d00fb5367065f2f7 /fs/btrfs | |
parent | 034a0f6b7db78f2324ba903a41c7ffd119c0e171 (diff) | |
parent | abdd2e80a57e5f7278f47913315065f0a3d78d20 (diff) |
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
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/compression.c | 2 | ||||
-rw-r--r-- | fs/btrfs/dev-replace.c | 5 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 5 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 5 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 37 | ||||
-rw-r--r-- | fs/btrfs/print-tree.c | 9 | ||||
-rw-r--r-- | fs/btrfs/raid56.c | 5 | ||||
-rw-r--r-- | fs/btrfs/super.c | 7 | ||||
-rw-r--r-- | fs/btrfs/sysfs.c | 32 | ||||
-rw-r--r-- | fs/btrfs/sysfs.h | 4 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 12 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 30 | ||||
-rw-r--r-- | fs/btrfs/zlib.c | 2 |
13 files changed, 108 insertions, 47 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 92371c414228..1daea0b47187 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -821,7 +821,7 @@ static void free_workspace(int type, struct list_head *workspace) | |||
821 | 821 | ||
822 | spin_lock(workspace_lock); | 822 | spin_lock(workspace_lock); |
823 | if (*num_workspace < num_online_cpus()) { | 823 | if (*num_workspace < num_online_cpus()) { |
824 | list_add_tail(workspace, idle_workspace); | 824 | list_add(workspace, idle_workspace); |
825 | (*num_workspace)++; | 825 | (*num_workspace)++; |
826 | spin_unlock(workspace_lock); | 826 | spin_unlock(workspace_lock); |
827 | goto wake; | 827 | goto wake; |
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c index 2af6e66fe788..eea26e1b2fda 100644 --- a/fs/btrfs/dev-replace.c +++ b/fs/btrfs/dev-replace.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include "check-integrity.h" | 36 | #include "check-integrity.h" |
37 | #include "rcu-string.h" | 37 | #include "rcu-string.h" |
38 | #include "dev-replace.h" | 38 | #include "dev-replace.h" |
39 | #include "sysfs.h" | ||
39 | 40 | ||
40 | static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | 41 | static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, |
41 | int scrub_ret); | 42 | int scrub_ret); |
@@ -562,6 +563,10 @@ static int btrfs_dev_replace_finishing(struct btrfs_fs_info *fs_info, | |||
562 | fs_info->fs_devices->latest_bdev = tgt_device->bdev; | 563 | fs_info->fs_devices->latest_bdev = tgt_device->bdev; |
563 | list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); | 564 | list_add(&tgt_device->dev_alloc_list, &fs_info->fs_devices->alloc_list); |
564 | 565 | ||
566 | /* replace the sysfs entry */ | ||
567 | btrfs_kobj_rm_device(fs_info, src_device); | ||
568 | btrfs_kobj_add_device(fs_info, tgt_device); | ||
569 | |||
565 | btrfs_rm_dev_replace_blocked(fs_info); | 570 | btrfs_rm_dev_replace_blocked(fs_info); |
566 | 571 | ||
567 | btrfs_rm_dev_replace_srcdev(fs_info, src_device); | 572 | btrfs_rm_dev_replace_srcdev(fs_info, src_device); |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8bb4aa19898f..08e65e9cf2aa 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -369,7 +369,8 @@ static int verify_parent_transid(struct extent_io_tree *io_tree, | |||
369 | out: | 369 | out: |
370 | unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1, | 370 | unlock_extent_cached(io_tree, eb->start, eb->start + eb->len - 1, |
371 | &cached_state, GFP_NOFS); | 371 | &cached_state, GFP_NOFS); |
372 | btrfs_tree_read_unlock_blocking(eb); | 372 | if (need_lock) |
373 | btrfs_tree_read_unlock_blocking(eb); | ||
373 | return ret; | 374 | return ret; |
374 | } | 375 | } |
375 | 376 | ||
@@ -2904,7 +2905,9 @@ retry_root_backup: | |||
2904 | if (ret) | 2905 | if (ret) |
2905 | goto fail_qgroup; | 2906 | goto fail_qgroup; |
2906 | 2907 | ||
2908 | mutex_lock(&fs_info->cleaner_mutex); | ||
2907 | ret = btrfs_recover_relocation(tree_root); | 2909 | ret = btrfs_recover_relocation(tree_root); |
2910 | mutex_unlock(&fs_info->cleaner_mutex); | ||
2908 | if (ret < 0) { | 2911 | if (ret < 0) { |
2909 | printk(KERN_WARNING | 2912 | printk(KERN_WARNING |
2910 | "BTRFS: failed to recover relocation\n"); | 2913 | "BTRFS: failed to recover relocation\n"); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 99c253918208..813537f362f9 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -5678,7 +5678,6 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | |||
5678 | struct btrfs_caching_control *next; | 5678 | struct btrfs_caching_control *next; |
5679 | struct btrfs_caching_control *caching_ctl; | 5679 | struct btrfs_caching_control *caching_ctl; |
5680 | struct btrfs_block_group_cache *cache; | 5680 | struct btrfs_block_group_cache *cache; |
5681 | struct btrfs_space_info *space_info; | ||
5682 | 5681 | ||
5683 | down_write(&fs_info->commit_root_sem); | 5682 | down_write(&fs_info->commit_root_sem); |
5684 | 5683 | ||
@@ -5701,9 +5700,6 @@ void btrfs_prepare_extent_commit(struct btrfs_trans_handle *trans, | |||
5701 | 5700 | ||
5702 | up_write(&fs_info->commit_root_sem); | 5701 | up_write(&fs_info->commit_root_sem); |
5703 | 5702 | ||
5704 | list_for_each_entry_rcu(space_info, &fs_info->space_info, list) | ||
5705 | percpu_counter_set(&space_info->total_bytes_pinned, 0); | ||
5706 | |||
5707 | update_global_block_rsv(fs_info); | 5703 | update_global_block_rsv(fs_info); |
5708 | } | 5704 | } |
5709 | 5705 | ||
@@ -5741,6 +5737,7 @@ static int unpin_extent_range(struct btrfs_root *root, u64 start, u64 end) | |||
5741 | spin_lock(&cache->lock); | 5737 | spin_lock(&cache->lock); |
5742 | cache->pinned -= len; | 5738 | cache->pinned -= len; |
5743 | space_info->bytes_pinned -= len; | 5739 | space_info->bytes_pinned -= len; |
5740 | percpu_counter_add(&space_info->total_bytes_pinned, -len); | ||
5744 | if (cache->ro) { | 5741 | if (cache->ro) { |
5745 | space_info->bytes_readonly += len; | 5742 | space_info->bytes_readonly += len; |
5746 | readonly = true; | 5743 | readonly = true; |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 0d321c23069a..47aceb494d1d 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -136,19 +136,22 @@ static unsigned int btrfs_flags_to_ioctl(unsigned int flags) | |||
136 | void btrfs_update_iflags(struct inode *inode) | 136 | void btrfs_update_iflags(struct inode *inode) |
137 | { | 137 | { |
138 | struct btrfs_inode *ip = BTRFS_I(inode); | 138 | struct btrfs_inode *ip = BTRFS_I(inode); |
139 | 139 | unsigned int new_fl = 0; | |
140 | inode->i_flags &= ~(S_SYNC|S_APPEND|S_IMMUTABLE|S_NOATIME|S_DIRSYNC); | ||
141 | 140 | ||
142 | if (ip->flags & BTRFS_INODE_SYNC) | 141 | if (ip->flags & BTRFS_INODE_SYNC) |
143 | inode->i_flags |= S_SYNC; | 142 | new_fl |= S_SYNC; |
144 | if (ip->flags & BTRFS_INODE_IMMUTABLE) | 143 | if (ip->flags & BTRFS_INODE_IMMUTABLE) |
145 | inode->i_flags |= S_IMMUTABLE; | 144 | new_fl |= S_IMMUTABLE; |
146 | if (ip->flags & BTRFS_INODE_APPEND) | 145 | if (ip->flags & BTRFS_INODE_APPEND) |
147 | inode->i_flags |= S_APPEND; | 146 | new_fl |= S_APPEND; |
148 | if (ip->flags & BTRFS_INODE_NOATIME) | 147 | if (ip->flags & BTRFS_INODE_NOATIME) |
149 | inode->i_flags |= S_NOATIME; | 148 | new_fl |= S_NOATIME; |
150 | if (ip->flags & BTRFS_INODE_DIRSYNC) | 149 | 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); | ||
152 | } | 155 | } |
153 | 156 | ||
154 | /* | 157 | /* |
@@ -3139,7 +3142,6 @@ out: | |||
3139 | static void clone_update_extent_map(struct inode *inode, | 3142 | static void clone_update_extent_map(struct inode *inode, |
3140 | const struct btrfs_trans_handle *trans, | 3143 | const struct btrfs_trans_handle *trans, |
3141 | const struct btrfs_path *path, | 3144 | const struct btrfs_path *path, |
3142 | struct btrfs_file_extent_item *fi, | ||
3143 | const u64 hole_offset, | 3145 | const u64 hole_offset, |
3144 | const u64 hole_len) | 3146 | const u64 hole_len) |
3145 | { | 3147 | { |
@@ -3154,7 +3156,11 @@ static void clone_update_extent_map(struct inode *inode, | |||
3154 | return; | 3156 | return; |
3155 | } | 3157 | } |
3156 | 3158 | ||
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); | ||
3158 | btrfs_extent_item_to_extent_map(inode, path, fi, false, em); | 3164 | btrfs_extent_item_to_extent_map(inode, path, fi, false, em); |
3159 | em->generation = -1; | 3165 | em->generation = -1; |
3160 | if (btrfs_file_extent_type(path->nodes[0], fi) == | 3166 | if (btrfs_file_extent_type(path->nodes[0], fi) == |
@@ -3508,18 +3514,15 @@ process_slot: | |||
3508 | btrfs_item_ptr_offset(leaf, slot), | 3514 | btrfs_item_ptr_offset(leaf, slot), |
3509 | size); | 3515 | size); |
3510 | inode_add_bytes(inode, datal); | 3516 | inode_add_bytes(inode, datal); |
3511 | extent = btrfs_item_ptr(leaf, slot, | ||
3512 | struct btrfs_file_extent_item); | ||
3513 | } | 3517 | } |
3514 | 3518 | ||
3515 | /* If we have an implicit hole (NO_HOLES feature). */ | 3519 | /* If we have an implicit hole (NO_HOLES feature). */ |
3516 | if (drop_start < new_key.offset) | 3520 | if (drop_start < new_key.offset) |
3517 | clone_update_extent_map(inode, trans, | 3521 | clone_update_extent_map(inode, trans, |
3518 | path, NULL, drop_start, | 3522 | NULL, drop_start, |
3519 | new_key.offset - drop_start); | 3523 | new_key.offset - drop_start); |
3520 | 3524 | ||
3521 | clone_update_extent_map(inode, trans, path, | 3525 | clone_update_extent_map(inode, trans, path, 0, 0); |
3522 | extent, 0, 0); | ||
3523 | 3526 | ||
3524 | btrfs_mark_buffer_dirty(leaf); | 3527 | btrfs_mark_buffer_dirty(leaf); |
3525 | btrfs_release_path(path); | 3528 | btrfs_release_path(path); |
@@ -3562,12 +3565,10 @@ process_slot: | |||
3562 | btrfs_end_transaction(trans, root); | 3565 | btrfs_end_transaction(trans, root); |
3563 | goto out; | 3566 | goto out; |
3564 | } | 3567 | } |
3568 | clone_update_extent_map(inode, trans, NULL, last_dest_end, | ||
3569 | destoff + len - last_dest_end); | ||
3565 | ret = clone_finish_inode_update(trans, inode, destoff + len, | 3570 | ret = clone_finish_inode_update(trans, inode, destoff + len, |
3566 | destoff, olen); | 3571 | 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); | ||
3571 | } | 3572 | } |
3572 | 3573 | ||
3573 | out: | 3574 | out: |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index 6efd70d3b64f..9626b4ad3b9a 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -54,7 +54,7 @@ static void print_extent_data_ref(struct extent_buffer *eb, | |||
54 | btrfs_extent_data_ref_count(eb, ref)); | 54 | btrfs_extent_data_ref_count(eb, ref)); |
55 | } | 55 | } |
56 | 56 | ||
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) |
58 | { | 58 | { |
59 | struct btrfs_extent_item *ei; | 59 | struct btrfs_extent_item *ei; |
60 | struct btrfs_extent_inline_ref *iref; | 60 | struct btrfs_extent_inline_ref *iref; |
@@ -63,7 +63,6 @@ static void print_extent_item(struct extent_buffer *eb, int slot) | |||
63 | struct btrfs_disk_key key; | 63 | struct btrfs_disk_key key; |
64 | unsigned long end; | 64 | unsigned long end; |
65 | unsigned long ptr; | 65 | unsigned long ptr; |
66 | int type; | ||
67 | u32 item_size = btrfs_item_size_nr(eb, slot); | 66 | u32 item_size = btrfs_item_size_nr(eb, slot); |
68 | u64 flags; | 67 | u64 flags; |
69 | u64 offset; | 68 | u64 offset; |
@@ -88,7 +87,8 @@ static void print_extent_item(struct extent_buffer *eb, int slot) | |||
88 | btrfs_extent_refs(eb, ei), btrfs_extent_generation(eb, ei), | 87 | btrfs_extent_refs(eb, ei), btrfs_extent_generation(eb, ei), |
89 | flags); | 88 | flags); |
90 | 89 | ||
91 | if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { | 90 | if ((type == BTRFS_EXTENT_ITEM_KEY) && |
91 | flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { | ||
92 | struct btrfs_tree_block_info *info; | 92 | struct btrfs_tree_block_info *info; |
93 | info = (struct btrfs_tree_block_info *)(ei + 1); | 93 | info = (struct btrfs_tree_block_info *)(ei + 1); |
94 | btrfs_tree_block_key(eb, info, &key); | 94 | btrfs_tree_block_key(eb, info, &key); |
@@ -223,7 +223,8 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
223 | btrfs_disk_root_refs(l, ri)); | 223 | btrfs_disk_root_refs(l, ri)); |
224 | break; | 224 | break; |
225 | case BTRFS_EXTENT_ITEM_KEY: | 225 | case BTRFS_EXTENT_ITEM_KEY: |
226 | print_extent_item(l, i); | 226 | case BTRFS_METADATA_ITEM_KEY: |
227 | print_extent_item(l, i, type); | ||
227 | break; | 228 | break; |
228 | case BTRFS_TREE_BLOCK_REF_KEY: | 229 | case BTRFS_TREE_BLOCK_REF_KEY: |
229 | printk(KERN_INFO "\t\ttree block backref\n"); | 230 | printk(KERN_INFO "\t\ttree block backref\n"); |
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c index 4055291a523e..4a88f073fdd7 100644 --- a/fs/btrfs/raid56.c +++ b/fs/btrfs/raid56.c | |||
@@ -1956,9 +1956,10 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio) | |||
1956 | * pages are going to be uptodate. | 1956 | * pages are going to be uptodate. |
1957 | */ | 1957 | */ |
1958 | for (stripe = 0; stripe < bbio->num_stripes; stripe++) { | 1958 | for (stripe = 0; stripe < bbio->num_stripes; stripe++) { |
1959 | if (rbio->faila == stripe || | 1959 | if (rbio->faila == stripe || rbio->failb == stripe) { |
1960 | rbio->failb == stripe) | 1960 | atomic_inc(&rbio->bbio->error); |
1961 | continue; | 1961 | continue; |
1962 | } | ||
1962 | 1963 | ||
1963 | for (pagenr = 0; pagenr < nr_pages; pagenr++) { | 1964 | for (pagenr = 0; pagenr < nr_pages; pagenr++) { |
1964 | struct page *p; | 1965 | struct page *p; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 4662d92a4b73..8e16bca69c56 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -522,9 +522,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
522 | case Opt_ssd_spread: | 522 | case Opt_ssd_spread: |
523 | btrfs_set_and_info(root, SSD_SPREAD, | 523 | btrfs_set_and_info(root, SSD_SPREAD, |
524 | "use spread ssd allocation scheme"); | 524 | "use spread ssd allocation scheme"); |
525 | btrfs_set_opt(info->mount_opt, SSD); | ||
525 | break; | 526 | break; |
526 | case Opt_nossd: | 527 | case Opt_nossd: |
527 | btrfs_clear_and_info(root, NOSSD, | 528 | btrfs_set_and_info(root, NOSSD, |
528 | "not using ssd allocation scheme"); | 529 | "not using ssd allocation scheme"); |
529 | btrfs_clear_opt(info->mount_opt, SSD); | 530 | btrfs_clear_opt(info->mount_opt, SSD); |
530 | break; | 531 | break; |
@@ -1467,7 +1468,9 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1467 | goto restore; | 1468 | goto restore; |
1468 | 1469 | ||
1469 | /* recover relocation */ | 1470 | /* recover relocation */ |
1471 | mutex_lock(&fs_info->cleaner_mutex); | ||
1470 | ret = btrfs_recover_relocation(root); | 1472 | ret = btrfs_recover_relocation(root); |
1473 | mutex_unlock(&fs_info->cleaner_mutex); | ||
1471 | if (ret) | 1474 | if (ret) |
1472 | goto restore; | 1475 | goto restore; |
1473 | 1476 | ||
@@ -1808,6 +1811,8 @@ static int btrfs_show_devname(struct seq_file *m, struct dentry *root) | |||
1808 | list_for_each_entry(dev, head, dev_list) { | 1811 | list_for_each_entry(dev, head, dev_list) { |
1809 | if (dev->missing) | 1812 | if (dev->missing) |
1810 | continue; | 1813 | continue; |
1814 | if (!dev->name) | ||
1815 | continue; | ||
1811 | if (!first_dev || dev->devid < first_dev->devid) | 1816 | if (!first_dev || dev->devid < first_dev->devid) |
1812 | first_dev = dev; | 1817 | first_dev = dev; |
1813 | } | 1818 | } |
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c index df39458f1487..78699364f537 100644 --- a/fs/btrfs/sysfs.c +++ b/fs/btrfs/sysfs.c | |||
@@ -605,14 +605,37 @@ static void init_feature_attrs(void) | |||
605 | } | 605 | } |
606 | } | 606 | } |
607 | 607 | ||
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) | ||
609 | { | 630 | { |
610 | int error = 0; | 631 | int error = 0; |
611 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; | 632 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; |
612 | struct btrfs_device *dev; | 633 | struct btrfs_device *dev; |
613 | 634 | ||
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", | ||
615 | &fs_info->super_kobj); | 637 | &fs_info->super_kobj); |
638 | |||
616 | if (!fs_info->device_dir_kobj) | 639 | if (!fs_info->device_dir_kobj) |
617 | return -ENOMEM; | 640 | return -ENOMEM; |
618 | 641 | ||
@@ -623,6 +646,9 @@ static int add_device_membership(struct btrfs_fs_info *fs_info) | |||
623 | if (!dev->bdev) | 646 | if (!dev->bdev) |
624 | continue; | 647 | continue; |
625 | 648 | ||
649 | if (one_device && one_device != dev) | ||
650 | continue; | ||
651 | |||
626 | disk = dev->bdev->bd_part; | 652 | disk = dev->bdev->bd_part; |
627 | disk_kobj = &part_to_dev(disk)->kobj; | 653 | disk_kobj = &part_to_dev(disk)->kobj; |
628 | 654 | ||
@@ -666,7 +692,7 @@ int btrfs_sysfs_add_one(struct btrfs_fs_info *fs_info) | |||
666 | if (error) | 692 | if (error) |
667 | goto failure; | 693 | goto failure; |
668 | 694 | ||
669 | error = add_device_membership(fs_info); | 695 | error = btrfs_kobj_add_device(fs_info, NULL); |
670 | if (error) | 696 | if (error) |
671 | goto failure; | 697 | goto failure; |
672 | 698 | ||
diff --git a/fs/btrfs/sysfs.h b/fs/btrfs/sysfs.h index 9ab576318a84..ac46df37504c 100644 --- a/fs/btrfs/sysfs.h +++ b/fs/btrfs/sysfs.h | |||
@@ -66,4 +66,8 @@ char *btrfs_printable_features(enum btrfs_feature_set set, u64 flags); | |||
66 | extern const char * const btrfs_feature_set_names[3]; | 66 | extern const char * const btrfs_feature_set_names[3]; |
67 | extern struct kobj_type space_info_ktype; | 67 | extern struct kobj_type space_info_ktype; |
68 | extern struct kobj_type btrfs_raid_ktype; | 68 | 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); | ||
69 | #endif /* _BTRFS_SYSFS_H_ */ | 73 | #endif /* _BTRFS_SYSFS_H_ */ |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 511839c04f11..5f379affdf23 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -386,11 +386,13 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type, | |||
386 | bool reloc_reserved = false; | 386 | bool reloc_reserved = false; |
387 | int ret; | 387 | int ret; |
388 | 388 | ||
389 | /* Send isn't supposed to start transactions. */ | ||
390 | ASSERT(current->journal_info != (void *)BTRFS_SEND_TRANS_STUB); | ||
391 | |||
389 | if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) | 392 | if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) |
390 | return ERR_PTR(-EROFS); | 393 | return ERR_PTR(-EROFS); |
391 | 394 | ||
392 | if (current->journal_info && | 395 | if (current->journal_info) { |
393 | current->journal_info != (void *)BTRFS_SEND_TRANS_STUB) { | ||
394 | WARN_ON(type & TRANS_EXTWRITERS); | 396 | WARN_ON(type & TRANS_EXTWRITERS); |
395 | h = current->journal_info; | 397 | h = current->journal_info; |
396 | h->use_count++; | 398 | h->use_count++; |
@@ -491,6 +493,7 @@ again: | |||
491 | smp_mb(); | 493 | smp_mb(); |
492 | if (cur_trans->state >= TRANS_STATE_BLOCKED && | 494 | if (cur_trans->state >= TRANS_STATE_BLOCKED && |
493 | may_wait_transaction(root, type)) { | 495 | may_wait_transaction(root, type)) { |
496 | current->journal_info = h; | ||
494 | btrfs_commit_transaction(h, root); | 497 | btrfs_commit_transaction(h, root); |
495 | goto again; | 498 | goto again; |
496 | } | 499 | } |
@@ -1615,11 +1618,6 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
1615 | int ret; | 1618 | int ret; |
1616 | 1619 | ||
1617 | ret = btrfs_run_delayed_items(trans, root); | 1620 | 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 | */ | ||
1623 | if (ret) | 1621 | if (ret) |
1624 | return ret; | 1622 | return ret; |
1625 | 1623 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index c83b24251e53..6104676857f5 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "rcu-string.h" | 40 | #include "rcu-string.h" |
41 | #include "math.h" | 41 | #include "math.h" |
42 | #include "dev-replace.h" | 42 | #include "dev-replace.h" |
43 | #include "sysfs.h" | ||
43 | 44 | ||
44 | static int init_first_rw_device(struct btrfs_trans_handle *trans, | 45 | static int init_first_rw_device(struct btrfs_trans_handle *trans, |
45 | struct btrfs_root *root, | 46 | struct btrfs_root *root, |
@@ -554,12 +555,14 @@ static struct btrfs_fs_devices *clone_fs_devices(struct btrfs_fs_devices *orig) | |||
554 | * This is ok to do without rcu read locked because we hold the | 555 | * This is ok to do without rcu read locked because we hold the |
555 | * uuid mutex so nothing we touch in here is going to disappear. | 556 | * uuid mutex so nothing we touch in here is going to disappear. |
556 | */ | 557 | */ |
557 | name = rcu_string_strdup(orig_dev->name->str, GFP_NOFS); | 558 | if (orig_dev->name) { |
558 | if (!name) { | 559 | name = rcu_string_strdup(orig_dev->name->str, GFP_NOFS); |
559 | kfree(device); | 560 | if (!name) { |
560 | goto error; | 561 | kfree(device); |
562 | goto error; | ||
563 | } | ||
564 | rcu_assign_pointer(device->name, name); | ||
561 | } | 565 | } |
562 | rcu_assign_pointer(device->name, name); | ||
563 | 566 | ||
564 | list_add(&device->dev_list, &fs_devices->devices); | 567 | list_add(&device->dev_list, &fs_devices->devices); |
565 | device->fs_devices = fs_devices; | 568 | device->fs_devices = fs_devices; |
@@ -1680,6 +1683,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1680 | if (device->bdev) | 1683 | if (device->bdev) |
1681 | device->fs_devices->open_devices--; | 1684 | device->fs_devices->open_devices--; |
1682 | 1685 | ||
1686 | /* remove sysfs entry */ | ||
1687 | btrfs_kobj_rm_device(root->fs_info, device); | ||
1688 | |||
1683 | call_rcu(&device->rcu, free_device); | 1689 | call_rcu(&device->rcu, free_device); |
1684 | 1690 | ||
1685 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; | 1691 | num_devices = btrfs_super_num_devices(root->fs_info->super_copy) - 1; |
@@ -2143,9 +2149,14 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
2143 | total_bytes = btrfs_super_num_devices(root->fs_info->super_copy); | 2149 | total_bytes = btrfs_super_num_devices(root->fs_info->super_copy); |
2144 | btrfs_set_super_num_devices(root->fs_info->super_copy, | 2150 | btrfs_set_super_num_devices(root->fs_info->super_copy, |
2145 | total_bytes + 1); | 2151 | total_bytes + 1); |
2152 | |||
2153 | /* add sysfs device entry */ | ||
2154 | btrfs_kobj_add_device(root->fs_info, device); | ||
2155 | |||
2146 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); | 2156 | mutex_unlock(&root->fs_info->fs_devices->device_list_mutex); |
2147 | 2157 | ||
2148 | if (seeding_dev) { | 2158 | if (seeding_dev) { |
2159 | char fsid_buf[BTRFS_UUID_UNPARSED_SIZE]; | ||
2149 | ret = init_first_rw_device(trans, root, device); | 2160 | ret = init_first_rw_device(trans, root, device); |
2150 | if (ret) { | 2161 | if (ret) { |
2151 | btrfs_abort_transaction(trans, root, ret); | 2162 | btrfs_abort_transaction(trans, root, ret); |
@@ -2156,6 +2167,14 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
2156 | btrfs_abort_transaction(trans, root, ret); | 2167 | btrfs_abort_transaction(trans, root, ret); |
2157 | goto error_trans; | 2168 | goto error_trans; |
2158 | } | 2169 | } |
2170 | |||
2171 | /* Sprouting would change fsid of the mounted root, | ||
2172 | * so rename the fsid on the sysfs | ||
2173 | */ | ||
2174 | snprintf(fsid_buf, BTRFS_UUID_UNPARSED_SIZE, "%pU", | ||
2175 | root->fs_info->fsid); | ||
2176 | if (kobject_rename(&root->fs_info->super_kobj, fsid_buf)) | ||
2177 | goto error_trans; | ||
2159 | } else { | 2178 | } else { |
2160 | ret = btrfs_add_device(trans, root, device); | 2179 | ret = btrfs_add_device(trans, root, device); |
2161 | if (ret) { | 2180 | if (ret) { |
@@ -2205,6 +2224,7 @@ error_trans: | |||
2205 | unlock_chunks(root); | 2224 | unlock_chunks(root); |
2206 | btrfs_end_transaction(trans, root); | 2225 | btrfs_end_transaction(trans, root); |
2207 | rcu_string_free(device->name); | 2226 | rcu_string_free(device->name); |
2227 | btrfs_kobj_rm_device(root->fs_info, device); | ||
2208 | kfree(device); | 2228 | kfree(device); |
2209 | error: | 2229 | error: |
2210 | blkdev_put(bdev, FMODE_EXCL); | 2230 | blkdev_put(bdev, FMODE_EXCL); |
diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 4f196314c0c1..b67d8fc81277 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c | |||
@@ -136,7 +136,7 @@ static int zlib_compress_pages(struct list_head *ws, | |||
136 | if (workspace->def_strm.total_in > 8192 && | 136 | if (workspace->def_strm.total_in > 8192 && |
137 | workspace->def_strm.total_in < | 137 | workspace->def_strm.total_in < |
138 | workspace->def_strm.total_out) { | 138 | workspace->def_strm.total_out) { |
139 | ret = -EIO; | 139 | ret = -E2BIG; |
140 | goto out; | 140 | goto out; |
141 | } | 141 | } |
142 | /* we need another page for writing out. Test this | 142 | /* we need another page for writing out. Test this |