aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.cz>2011-10-24 08:47:58 -0400
committerDavid Sterba <dsterba@suse.cz>2011-10-24 08:47:58 -0400
commita81d3b1ba2f5faae28ba7a092c7598673fa02ac2 (patch)
tree8301fefcd9f3d45be9d0030456a86bca5b9ff061 /fs/btrfs
parentafd582ac8f10382002a72b4d17d9c2db328ed8b8 (diff)
parentf9d9ef62cd3ecbd6cbb7957a253c1e81f69d5586 (diff)
Merge branch 'hotfixes-20111024/josef/for-chris' into btrfs-next-stable
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/acl.c17
-rw-r--r--fs/btrfs/ctree.c10
-rw-r--r--fs/btrfs/extent-tree.c9
-rw-r--r--fs/btrfs/extent_io.c2
-rw-r--r--fs/btrfs/inode.c9
-rw-r--r--fs/btrfs/ioctl.c58
-rw-r--r--fs/btrfs/print-tree.c8
-rw-r--r--fs/btrfs/relocation.c5
-rw-r--r--fs/btrfs/super.c31
-rw-r--r--fs/btrfs/volumes.c6
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 }
5038search: 5039search:
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 }
5249checks: 5253checks:
@@ -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 }
430cont:
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
1156out_ra: 1176out_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)
158void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) 158void 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 */
746static 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;