diff options
| -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 | ||||
| -rw-r--r-- | include/uapi/linux/btrfs.h | 1 |
14 files changed, 109 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 |
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h index 6f9c38ce45c7..2f47824e7a36 100644 --- a/include/uapi/linux/btrfs.h +++ b/include/uapi/linux/btrfs.h | |||
| @@ -38,6 +38,7 @@ struct btrfs_ioctl_vol_args { | |||
| 38 | #define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2) | 38 | #define BTRFS_SUBVOL_QGROUP_INHERIT (1ULL << 2) |
| 39 | #define BTRFS_FSID_SIZE 16 | 39 | #define BTRFS_FSID_SIZE 16 |
| 40 | #define BTRFS_UUID_SIZE 16 | 40 | #define BTRFS_UUID_SIZE 16 |
| 41 | #define BTRFS_UUID_UNPARSED_SIZE 37 | ||
| 41 | 42 | ||
| 42 | #define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0) | 43 | #define BTRFS_QGROUP_INHERIT_SET_LIMITS (1ULL << 0) |
| 43 | 44 | ||
