diff options
author | David Sterba <dsterba@suse.cz> | 2011-10-24 08:47:58 -0400 |
---|---|---|
committer | David Sterba <dsterba@suse.cz> | 2011-10-24 08:47:58 -0400 |
commit | a81d3b1ba2f5faae28ba7a092c7598673fa02ac2 (patch) | |
tree | 8301fefcd9f3d45be9d0030456a86bca5b9ff061 /fs/btrfs | |
parent | afd582ac8f10382002a72b4d17d9c2db328ed8b8 (diff) | |
parent | f9d9ef62cd3ecbd6cbb7957a253c1e81f69d5586 (diff) |
Merge branch 'hotfixes-20111024/josef/for-chris' into btrfs-next-stable
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/acl.c | 17 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 10 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 9 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 2 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 9 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 58 | ||||
-rw-r--r-- | fs/btrfs/print-tree.c | 8 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 5 | ||||
-rw-r--r-- | fs/btrfs/super.c | 31 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 6 |
10 files changed, 107 insertions, 48 deletions
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c index eb159aaa5a11..89b156d85d63 100644 --- a/fs/btrfs/acl.c +++ b/fs/btrfs/acl.c | |||
@@ -59,22 +59,19 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type) | |||
59 | if (!value) | 59 | if (!value) |
60 | return ERR_PTR(-ENOMEM); | 60 | return ERR_PTR(-ENOMEM); |
61 | size = __btrfs_getxattr(inode, name, value, size); | 61 | size = __btrfs_getxattr(inode, name, value, size); |
62 | if (size > 0) { | 62 | } |
63 | acl = posix_acl_from_xattr(value, size); | 63 | if (size > 0) { |
64 | if (IS_ERR(acl)) { | 64 | acl = posix_acl_from_xattr(value, size); |
65 | kfree(value); | ||
66 | return acl; | ||
67 | } | ||
68 | set_cached_acl(inode, type, acl); | ||
69 | } | ||
70 | kfree(value); | ||
71 | } else if (size == -ENOENT || size == -ENODATA || size == 0) { | 65 | } else if (size == -ENOENT || size == -ENODATA || size == 0) { |
72 | /* FIXME, who returns -ENOENT? I think nobody */ | 66 | /* FIXME, who returns -ENOENT? I think nobody */ |
73 | acl = NULL; | 67 | acl = NULL; |
74 | set_cached_acl(inode, type, acl); | ||
75 | } else { | 68 | } else { |
76 | acl = ERR_PTR(-EIO); | 69 | acl = ERR_PTR(-EIO); |
77 | } | 70 | } |
71 | kfree(value); | ||
72 | |||
73 | if (!IS_ERR(acl)) | ||
74 | set_cached_acl(inode, type, acl); | ||
78 | 75 | ||
79 | return acl; | 76 | return acl; |
80 | } | 77 | } |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 011cab3aca8d..0fe615e4ea38 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -902,9 +902,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
902 | 902 | ||
903 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); | 903 | orig_ptr = btrfs_node_blockptr(mid, orig_slot); |
904 | 904 | ||
905 | if (level < BTRFS_MAX_LEVEL - 1) | 905 | if (level < BTRFS_MAX_LEVEL - 1) { |
906 | parent = path->nodes[level + 1]; | 906 | parent = path->nodes[level + 1]; |
907 | pslot = path->slots[level + 1]; | 907 | pslot = path->slots[level + 1]; |
908 | } | ||
908 | 909 | ||
909 | /* | 910 | /* |
910 | * deal with the case where there is only one pointer in the root | 911 | * deal with the case where there is only one pointer in the root |
@@ -1107,9 +1108,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, | |||
1107 | mid = path->nodes[level]; | 1108 | mid = path->nodes[level]; |
1108 | WARN_ON(btrfs_header_generation(mid) != trans->transid); | 1109 | WARN_ON(btrfs_header_generation(mid) != trans->transid); |
1109 | 1110 | ||
1110 | if (level < BTRFS_MAX_LEVEL - 1) | 1111 | if (level < BTRFS_MAX_LEVEL - 1) { |
1111 | parent = path->nodes[level + 1]; | 1112 | parent = path->nodes[level + 1]; |
1112 | pslot = path->slots[level + 1]; | 1113 | pslot = path->slots[level + 1]; |
1114 | } | ||
1113 | 1115 | ||
1114 | if (!parent) | 1116 | if (!parent) |
1115 | return 1; | 1117 | return 1; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 4eb7d2ba38f8..cef355f1328a 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -4954,6 +4954,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
4954 | bool failed_cluster_refill = false; | 4954 | bool failed_cluster_refill = false; |
4955 | bool failed_alloc = false; | 4955 | bool failed_alloc = false; |
4956 | bool use_cluster = true; | 4956 | bool use_cluster = true; |
4957 | bool have_caching_bg = false; | ||
4957 | u64 ideal_cache_percent = 0; | 4958 | u64 ideal_cache_percent = 0; |
4958 | u64 ideal_cache_offset = 0; | 4959 | u64 ideal_cache_offset = 0; |
4959 | 4960 | ||
@@ -5036,6 +5037,7 @@ ideal_cache: | |||
5036 | } | 5037 | } |
5037 | } | 5038 | } |
5038 | search: | 5039 | search: |
5040 | have_caching_bg = false; | ||
5039 | down_read(&space_info->groups_sem); | 5041 | down_read(&space_info->groups_sem); |
5040 | list_for_each_entry(block_group, &space_info->block_groups[index], | 5042 | list_for_each_entry(block_group, &space_info->block_groups[index], |
5041 | list) { | 5043 | list) { |
@@ -5244,6 +5246,8 @@ refill_cluster: | |||
5244 | failed_alloc = true; | 5246 | failed_alloc = true; |
5245 | goto have_block_group; | 5247 | goto have_block_group; |
5246 | } else if (!offset) { | 5248 | } else if (!offset) { |
5249 | if (!cached) | ||
5250 | have_caching_bg = true; | ||
5247 | goto loop; | 5251 | goto loop; |
5248 | } | 5252 | } |
5249 | checks: | 5253 | checks: |
@@ -5294,6 +5298,9 @@ loop: | |||
5294 | } | 5298 | } |
5295 | up_read(&space_info->groups_sem); | 5299 | up_read(&space_info->groups_sem); |
5296 | 5300 | ||
5301 | if (!ins->objectid && loop >= LOOP_CACHING_WAIT && have_caching_bg) | ||
5302 | goto search; | ||
5303 | |||
5297 | if (!ins->objectid && ++index < BTRFS_NR_RAID_TYPES) | 5304 | if (!ins->objectid && ++index < BTRFS_NR_RAID_TYPES) |
5298 | goto search; | 5305 | goto search; |
5299 | 5306 | ||
@@ -7312,7 +7319,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans, | |||
7312 | goto out; | 7319 | goto out; |
7313 | } | 7320 | } |
7314 | 7321 | ||
7315 | inode = lookup_free_space_inode(root, block_group, path); | 7322 | inode = lookup_free_space_inode(tree_root, block_group, path); |
7316 | if (!IS_ERR(inode)) { | 7323 | if (!IS_ERR(inode)) { |
7317 | ret = btrfs_orphan_add(trans, inode); | 7324 | ret = btrfs_orphan_add(trans, inode); |
7318 | BUG_ON(ret); | 7325 | BUG_ON(ret); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 0ada0b700b44..f284d4e5f447 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1107,7 +1107,7 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, | |||
1107 | struct extent_state **cached_state, gfp_t mask) | 1107 | struct extent_state **cached_state, gfp_t mask) |
1108 | { | 1108 | { |
1109 | return set_extent_bit(tree, start, end, | 1109 | return set_extent_bit(tree, start, end, |
1110 | EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE, | 1110 | EXTENT_DELALLOC | EXTENT_UPTODATE, |
1111 | 0, NULL, cached_state, mask); | 1111 | 0, NULL, cached_state, mask); |
1112 | } | 1112 | } |
1113 | 1113 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index f12747c9447b..65474d95f26f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -393,7 +393,10 @@ again: | |||
393 | (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))) { | 393 | (BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))) { |
394 | WARN_ON(pages); | 394 | WARN_ON(pages); |
395 | pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); | 395 | pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); |
396 | BUG_ON(!pages); | 396 | if (!pages) { |
397 | /* just bail out to the uncompressed code */ | ||
398 | goto cont; | ||
399 | } | ||
397 | 400 | ||
398 | if (BTRFS_I(inode)->force_compress) | 401 | if (BTRFS_I(inode)->force_compress) |
399 | compress_type = BTRFS_I(inode)->force_compress; | 402 | compress_type = BTRFS_I(inode)->force_compress; |
@@ -424,6 +427,7 @@ again: | |||
424 | will_compress = 1; | 427 | will_compress = 1; |
425 | } | 428 | } |
426 | } | 429 | } |
430 | cont: | ||
427 | if (start == 0) { | 431 | if (start == 0) { |
428 | trans = btrfs_join_transaction(root); | 432 | trans = btrfs_join_transaction(root); |
429 | BUG_ON(IS_ERR(trans)); | 433 | BUG_ON(IS_ERR(trans)); |
@@ -5773,8 +5777,7 @@ again: | |||
5773 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) { | 5777 | if (test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) { |
5774 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); | 5778 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
5775 | if (!ret) | 5779 | if (!ret) |
5776 | ret = btrfs_update_inode(trans, root, inode); | 5780 | err = btrfs_update_inode(trans, root, inode); |
5777 | err = ret; | ||
5778 | goto out; | 5781 | goto out; |
5779 | } | 5782 | } |
5780 | 5783 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 877727b28d88..33aae13cc74b 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -282,6 +282,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
282 | struct fstrim_range range; | 282 | struct fstrim_range range; |
283 | u64 minlen = ULLONG_MAX; | 283 | u64 minlen = ULLONG_MAX; |
284 | u64 num_devices = 0; | 284 | u64 num_devices = 0; |
285 | u64 total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy); | ||
285 | int ret; | 286 | int ret; |
286 | 287 | ||
287 | if (!capable(CAP_SYS_ADMIN)) | 288 | if (!capable(CAP_SYS_ADMIN)) |
@@ -300,12 +301,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg) | |||
300 | } | 301 | } |
301 | } | 302 | } |
302 | rcu_read_unlock(); | 303 | rcu_read_unlock(); |
304 | |||
303 | if (!num_devices) | 305 | if (!num_devices) |
304 | return -EOPNOTSUPP; | 306 | return -EOPNOTSUPP; |
305 | |||
306 | if (copy_from_user(&range, arg, sizeof(range))) | 307 | if (copy_from_user(&range, arg, sizeof(range))) |
307 | return -EFAULT; | 308 | return -EFAULT; |
309 | if (range.start > total_bytes) | ||
310 | return -EINVAL; | ||
308 | 311 | ||
312 | range.len = min(range.len, total_bytes - range.start); | ||
309 | range.minlen = max(range.minlen, minlen); | 313 | range.minlen = max(range.minlen, minlen); |
310 | ret = btrfs_trim_fs(root, &range); | 314 | ret = btrfs_trim_fs(root, &range); |
311 | if (ret < 0) | 315 | if (ret < 0) |
@@ -765,7 +769,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len, | |||
765 | int ret = 1; | 769 | int ret = 1; |
766 | 770 | ||
767 | /* | 771 | /* |
768 | * make sure that once we start defragging and extent, we keep on | 772 | * make sure that once we start defragging an extent, we keep on |
769 | * defragging it | 773 | * defragging it |
770 | */ | 774 | */ |
771 | if (start < *defrag_end) | 775 | if (start < *defrag_end) |
@@ -810,7 +814,6 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len, | |||
810 | * extent will force at least part of that big extent to be defragged. | 814 | * extent will force at least part of that big extent to be defragged. |
811 | */ | 815 | */ |
812 | if (ret) { | 816 | if (ret) { |
813 | *last_len += len; | ||
814 | *defrag_end = extent_map_end(em); | 817 | *defrag_end = extent_map_end(em); |
815 | } else { | 818 | } else { |
816 | *last_len = 0; | 819 | *last_len = 0; |
@@ -978,18 +981,20 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
978 | struct btrfs_super_block *disk_super; | 981 | struct btrfs_super_block *disk_super; |
979 | struct file_ra_state *ra = NULL; | 982 | struct file_ra_state *ra = NULL; |
980 | unsigned long last_index; | 983 | unsigned long last_index; |
984 | u64 isize = i_size_read(inode); | ||
981 | u64 features; | 985 | u64 features; |
982 | u64 last_len = 0; | 986 | u64 last_len = 0; |
983 | u64 skip = 0; | 987 | u64 skip = 0; |
984 | u64 defrag_end = 0; | 988 | u64 defrag_end = 0; |
985 | u64 newer_off = range->start; | 989 | u64 newer_off = range->start; |
986 | int newer_left = 0; | ||
987 | unsigned long i; | 990 | unsigned long i; |
991 | unsigned long ra_index = 0; | ||
988 | int ret; | 992 | int ret; |
989 | int defrag_count = 0; | 993 | int defrag_count = 0; |
990 | int compress_type = BTRFS_COMPRESS_ZLIB; | 994 | int compress_type = BTRFS_COMPRESS_ZLIB; |
991 | int extent_thresh = range->extent_thresh; | 995 | int extent_thresh = range->extent_thresh; |
992 | int newer_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT; | 996 | int max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT; |
997 | int cluster = max_cluster; | ||
993 | u64 new_align = ~((u64)128 * 1024 - 1); | 998 | u64 new_align = ~((u64)128 * 1024 - 1); |
994 | struct page **pages = NULL; | 999 | struct page **pages = NULL; |
995 | 1000 | ||
@@ -1003,7 +1008,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1003 | compress_type = range->compress_type; | 1008 | compress_type = range->compress_type; |
1004 | } | 1009 | } |
1005 | 1010 | ||
1006 | if (inode->i_size == 0) | 1011 | if (isize == 0) |
1007 | return 0; | 1012 | return 0; |
1008 | 1013 | ||
1009 | /* | 1014 | /* |
@@ -1019,7 +1024,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1019 | ra = &file->f_ra; | 1024 | ra = &file->f_ra; |
1020 | } | 1025 | } |
1021 | 1026 | ||
1022 | pages = kmalloc(sizeof(struct page *) * newer_cluster, | 1027 | pages = kmalloc(sizeof(struct page *) * max_cluster, |
1023 | GFP_NOFS); | 1028 | GFP_NOFS); |
1024 | if (!pages) { | 1029 | if (!pages) { |
1025 | ret = -ENOMEM; | 1030 | ret = -ENOMEM; |
@@ -1028,10 +1033,10 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1028 | 1033 | ||
1029 | /* find the last page to defrag */ | 1034 | /* find the last page to defrag */ |
1030 | if (range->start + range->len > range->start) { | 1035 | if (range->start + range->len > range->start) { |
1031 | last_index = min_t(u64, inode->i_size - 1, | 1036 | last_index = min_t(u64, isize - 1, |
1032 | range->start + range->len - 1) >> PAGE_CACHE_SHIFT; | 1037 | range->start + range->len - 1) >> PAGE_CACHE_SHIFT; |
1033 | } else { | 1038 | } else { |
1034 | last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT; | 1039 | last_index = (isize - 1) >> PAGE_CACHE_SHIFT; |
1035 | } | 1040 | } |
1036 | 1041 | ||
1037 | if (newer_than) { | 1042 | if (newer_than) { |
@@ -1044,14 +1049,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1044 | * the extents in the file evenly spaced | 1049 | * the extents in the file evenly spaced |
1045 | */ | 1050 | */ |
1046 | i = (newer_off & new_align) >> PAGE_CACHE_SHIFT; | 1051 | i = (newer_off & new_align) >> PAGE_CACHE_SHIFT; |
1047 | newer_left = newer_cluster; | ||
1048 | } else | 1052 | } else |
1049 | goto out_ra; | 1053 | goto out_ra; |
1050 | } else { | 1054 | } else { |
1051 | i = range->start >> PAGE_CACHE_SHIFT; | 1055 | i = range->start >> PAGE_CACHE_SHIFT; |
1052 | } | 1056 | } |
1053 | if (!max_to_defrag) | 1057 | if (!max_to_defrag) |
1054 | max_to_defrag = last_index - 1; | 1058 | max_to_defrag = last_index; |
1055 | 1059 | ||
1056 | /* | 1060 | /* |
1057 | * make writeback starts from i, so the defrag range can be | 1061 | * make writeback starts from i, so the defrag range can be |
@@ -1085,18 +1089,31 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1085 | i = max(i + 1, next); | 1089 | i = max(i + 1, next); |
1086 | continue; | 1090 | continue; |
1087 | } | 1091 | } |
1092 | |||
1093 | if (!newer_than) { | ||
1094 | cluster = (PAGE_CACHE_ALIGN(defrag_end) >> | ||
1095 | PAGE_CACHE_SHIFT) - i; | ||
1096 | cluster = min(cluster, max_cluster); | ||
1097 | } else { | ||
1098 | cluster = max_cluster; | ||
1099 | } | ||
1100 | |||
1088 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) | 1101 | if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) |
1089 | BTRFS_I(inode)->force_compress = compress_type; | 1102 | BTRFS_I(inode)->force_compress = compress_type; |
1090 | 1103 | ||
1091 | btrfs_force_ra(inode->i_mapping, ra, file, i, newer_cluster); | 1104 | if (i + cluster > ra_index) { |
1105 | ra_index = max(i, ra_index); | ||
1106 | btrfs_force_ra(inode->i_mapping, ra, file, ra_index, | ||
1107 | cluster); | ||
1108 | ra_index += max_cluster; | ||
1109 | } | ||
1092 | 1110 | ||
1093 | ret = cluster_pages_for_defrag(inode, pages, i, newer_cluster); | 1111 | ret = cluster_pages_for_defrag(inode, pages, i, cluster); |
1094 | if (ret < 0) | 1112 | if (ret < 0) |
1095 | goto out_ra; | 1113 | goto out_ra; |
1096 | 1114 | ||
1097 | defrag_count += ret; | 1115 | defrag_count += ret; |
1098 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret); | 1116 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret); |
1099 | i += ret; | ||
1100 | 1117 | ||
1101 | if (newer_than) { | 1118 | if (newer_than) { |
1102 | if (newer_off == (u64)-1) | 1119 | if (newer_off == (u64)-1) |
@@ -1111,12 +1128,17 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1111 | if (!ret) { | 1128 | if (!ret) { |
1112 | range->start = newer_off; | 1129 | range->start = newer_off; |
1113 | i = (newer_off & new_align) >> PAGE_CACHE_SHIFT; | 1130 | i = (newer_off & new_align) >> PAGE_CACHE_SHIFT; |
1114 | newer_left = newer_cluster; | ||
1115 | } else { | 1131 | } else { |
1116 | break; | 1132 | break; |
1117 | } | 1133 | } |
1118 | } else { | 1134 | } else { |
1119 | i++; | 1135 | if (ret > 0) { |
1136 | i += ret; | ||
1137 | last_len += ret << PAGE_CACHE_SHIFT; | ||
1138 | } else { | ||
1139 | i++; | ||
1140 | last_len = 0; | ||
1141 | } | ||
1120 | } | 1142 | } |
1121 | } | 1143 | } |
1122 | 1144 | ||
@@ -1149,9 +1171,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file, | |||
1149 | btrfs_set_super_incompat_flags(disk_super, features); | 1171 | btrfs_set_super_incompat_flags(disk_super, features); |
1150 | } | 1172 | } |
1151 | 1173 | ||
1152 | if (!file) | 1174 | ret = defrag_count; |
1153 | kfree(ra); | ||
1154 | return defrag_count; | ||
1155 | 1175 | ||
1156 | out_ra: | 1176 | out_ra: |
1157 | if (!file) | 1177 | if (!file) |
diff --git a/fs/btrfs/print-tree.c b/fs/btrfs/print-tree.c index fb2605d998e9..f38e452486b8 100644 --- a/fs/btrfs/print-tree.c +++ b/fs/btrfs/print-tree.c | |||
@@ -158,8 +158,7 @@ static void print_extent_ref_v0(struct extent_buffer *eb, int slot) | |||
158 | void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | 158 | void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) |
159 | { | 159 | { |
160 | int i; | 160 | int i; |
161 | u32 type; | 161 | u32 type, nr; |
162 | u32 nr = btrfs_header_nritems(l); | ||
163 | struct btrfs_item *item; | 162 | struct btrfs_item *item; |
164 | struct btrfs_root_item *ri; | 163 | struct btrfs_root_item *ri; |
165 | struct btrfs_dir_item *di; | 164 | struct btrfs_dir_item *di; |
@@ -172,6 +171,11 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) | |||
172 | struct btrfs_key key; | 171 | struct btrfs_key key; |
173 | struct btrfs_key found_key; | 172 | struct btrfs_key found_key; |
174 | 173 | ||
174 | if (!l) | ||
175 | return; | ||
176 | |||
177 | nr = btrfs_header_nritems(l); | ||
178 | |||
175 | printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n", | 179 | printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n", |
176 | (unsigned long long)btrfs_header_bytenr(l), nr, | 180 | (unsigned long long)btrfs_header_bytenr(l), nr, |
177 | btrfs_leaf_free_space(root, l)); | 181 | btrfs_leaf_free_space(root, l)); |
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index 10af6a0e0865..24d654ce7a06 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -3322,8 +3322,11 @@ static int find_data_references(struct reloc_control *rc, | |||
3322 | } | 3322 | } |
3323 | 3323 | ||
3324 | key.objectid = ref_objectid; | 3324 | key.objectid = ref_objectid; |
3325 | key.offset = ref_offset; | ||
3326 | key.type = BTRFS_EXTENT_DATA_KEY; | 3325 | key.type = BTRFS_EXTENT_DATA_KEY; |
3326 | if (ref_offset > ((u64)-1 << 32)) | ||
3327 | key.offset = 0; | ||
3328 | else | ||
3329 | key.offset = ref_offset; | ||
3327 | 3330 | ||
3328 | path->search_commit_root = 1; | 3331 | path->search_commit_root = 1; |
3329 | path->skip_locking = 1; | 3332 | path->skip_locking = 1; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 266d1f35465d..5429b1fa0bfc 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -419,7 +419,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
419 | u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices) | 419 | u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices) |
420 | { | 420 | { |
421 | substring_t args[MAX_OPT_ARGS]; | 421 | substring_t args[MAX_OPT_ARGS]; |
422 | char *opts, *orig, *p; | 422 | char *device_name, *opts, *orig, *p; |
423 | int error = 0; | 423 | int error = 0; |
424 | int intarg; | 424 | int intarg; |
425 | 425 | ||
@@ -470,8 +470,14 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags, | |||
470 | } | 470 | } |
471 | break; | 471 | break; |
472 | case Opt_device: | 472 | case Opt_device: |
473 | error = btrfs_scan_one_device(match_strdup(&args[0]), | 473 | device_name = match_strdup(&args[0]); |
474 | if (!device_name) { | ||
475 | error = -ENOMEM; | ||
476 | goto out; | ||
477 | } | ||
478 | error = btrfs_scan_one_device(device_name, | ||
474 | flags, holder, fs_devices); | 479 | flags, holder, fs_devices); |
480 | kfree(device_name); | ||
475 | if (error) | 481 | if (error) |
476 | goto out; | 482 | goto out; |
477 | break; | 483 | break; |
@@ -735,6 +741,16 @@ static int btrfs_set_super(struct super_block *s, void *data) | |||
735 | } | 741 | } |
736 | 742 | ||
737 | /* | 743 | /* |
744 | * subvolumes are identified by ino 256 | ||
745 | */ | ||
746 | static inline int is_subvolume_inode(struct inode *inode) | ||
747 | { | ||
748 | if (inode && inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | ||
749 | return 1; | ||
750 | return 0; | ||
751 | } | ||
752 | |||
753 | /* | ||
738 | * This will strip out the subvol=%s argument for an argument string and add | 754 | * This will strip out the subvol=%s argument for an argument string and add |
739 | * subvolid=0 to make sure we get the actual tree root for path walking to the | 755 | * subvolid=0 to make sure we get the actual tree root for path walking to the |
740 | * subvol we want. | 756 | * subvol we want. |
@@ -837,6 +853,15 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags, | |||
837 | if (error) | 853 | if (error) |
838 | return ERR_PTR(error); | 854 | return ERR_PTR(error); |
839 | 855 | ||
856 | if (!is_subvolume_inode(path.dentry->d_inode)) { | ||
857 | path_put(&path); | ||
858 | mntput(mnt); | ||
859 | error = -EINVAL; | ||
860 | printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n", | ||
861 | subvol_name); | ||
862 | return ERR_PTR(-EINVAL); | ||
863 | } | ||
864 | |||
840 | /* Get a ref to the sb and the dentry we found and return it */ | 865 | /* Get a ref to the sb and the dentry we found and return it */ |
841 | s = path.mnt->mnt_sb; | 866 | s = path.mnt->mnt_sb; |
842 | atomic_inc(&s->s_active); | 867 | atomic_inc(&s->s_active); |
@@ -933,6 +958,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
933 | 958 | ||
934 | s->s_flags = flags | MS_NOSEC; | 959 | s->s_flags = flags | MS_NOSEC; |
935 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 960 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
961 | btrfs_sb(s)->fs_info->bdev_holder = fs_type; | ||
936 | error = btrfs_fill_super(s, fs_devices, data, | 962 | error = btrfs_fill_super(s, fs_devices, data, |
937 | flags & MS_SILENT ? 1 : 0); | 963 | flags & MS_SILENT ? 1 : 0); |
938 | if (error) { | 964 | if (error) { |
@@ -940,7 +966,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
940 | return ERR_PTR(error); | 966 | return ERR_PTR(error); |
941 | } | 967 | } |
942 | 968 | ||
943 | btrfs_sb(s)->fs_info->bdev_holder = fs_type; | ||
944 | s->s_flags |= MS_ACTIVE; | 969 | s->s_flags |= MS_ACTIVE; |
945 | } | 970 | } |
946 | 971 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index e138af710de2..c6938b45e0fd 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -597,10 +597,8 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
597 | set_blocksize(bdev, 4096); | 597 | set_blocksize(bdev, 4096); |
598 | 598 | ||
599 | bh = btrfs_read_dev_super(bdev); | 599 | bh = btrfs_read_dev_super(bdev); |
600 | if (!bh) { | 600 | if (!bh) |
601 | ret = -EINVAL; | ||
602 | goto error_close; | 601 | goto error_close; |
603 | } | ||
604 | 602 | ||
605 | disk_super = (struct btrfs_super_block *)bh->b_data; | 603 | disk_super = (struct btrfs_super_block *)bh->b_data; |
606 | devid = btrfs_stack_device_id(&disk_super->dev_item); | 604 | devid = btrfs_stack_device_id(&disk_super->dev_item); |
@@ -655,7 +653,7 @@ error: | |||
655 | continue; | 653 | continue; |
656 | } | 654 | } |
657 | if (fs_devices->open_devices == 0) { | 655 | if (fs_devices->open_devices == 0) { |
658 | ret = -EIO; | 656 | ret = -EINVAL; |
659 | goto out; | 657 | goto out; |
660 | } | 658 | } |
661 | fs_devices->seeding = seeding; | 659 | fs_devices->seeding = seeding; |