diff options
| author | Ingo Molnar <mingo@elte.hu> | 2009-10-01 05:20:33 -0400 | 
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-10-01 05:20:48 -0400 | 
| commit | 0aa73ba1c4e1ad1d51a29e0df95ccd9f746918b6 (patch) | |
| tree | f0714ddcd02812b4fbe3b5405df9e4068f5587e2 /fs/btrfs/disk-io.c | |
| parent | 925936ebf35a95c290e010b784c962164e6728f3 (diff) | |
| parent | 33974093c024f08caadd2fc71a83bd811ed1831d (diff) | |
Merge branch 'tracing/urgent' into tracing/core
Merge reason: Pick up latest fixes and update to latest upstream.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/btrfs/disk-io.c')
| -rw-r--r-- | fs/btrfs/disk-io.c | 237 | 
1 files changed, 155 insertions, 82 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8b8192790011..644e796fd643 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c  | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | 41 | ||
| 42 | static struct extent_io_ops btree_extent_io_ops; | 42 | static struct extent_io_ops btree_extent_io_ops; | 
| 43 | static void end_workqueue_fn(struct btrfs_work *work); | 43 | static void end_workqueue_fn(struct btrfs_work *work); | 
| 44 | static void free_fs_root(struct btrfs_root *root); | ||
| 44 | 45 | ||
| 45 | static atomic_t btrfs_bdi_num = ATOMIC_INIT(0); | 46 | static atomic_t btrfs_bdi_num = ATOMIC_INIT(0); | 
| 46 | 47 | ||
| @@ -123,15 +124,15 @@ static struct extent_map *btree_get_extent(struct inode *inode, | |||
| 123 | struct extent_map *em; | 124 | struct extent_map *em; | 
| 124 | int ret; | 125 | int ret; | 
| 125 | 126 | ||
| 126 | spin_lock(&em_tree->lock); | 127 | read_lock(&em_tree->lock); | 
| 127 | em = lookup_extent_mapping(em_tree, start, len); | 128 | em = lookup_extent_mapping(em_tree, start, len); | 
| 128 | if (em) { | 129 | if (em) { | 
| 129 | em->bdev = | 130 | em->bdev = | 
| 130 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; | 131 | BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; | 
| 131 | spin_unlock(&em_tree->lock); | 132 | read_unlock(&em_tree->lock); | 
| 132 | goto out; | 133 | goto out; | 
| 133 | } | 134 | } | 
| 134 | spin_unlock(&em_tree->lock); | 135 | read_unlock(&em_tree->lock); | 
| 135 | 136 | ||
| 136 | em = alloc_extent_map(GFP_NOFS); | 137 | em = alloc_extent_map(GFP_NOFS); | 
| 137 | if (!em) { | 138 | if (!em) { | 
| @@ -144,7 +145,7 @@ static struct extent_map *btree_get_extent(struct inode *inode, | |||
| 144 | em->block_start = 0; | 145 | em->block_start = 0; | 
| 145 | em->bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; | 146 | em->bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev; | 
| 146 | 147 | ||
| 147 | spin_lock(&em_tree->lock); | 148 | write_lock(&em_tree->lock); | 
| 148 | ret = add_extent_mapping(em_tree, em); | 149 | ret = add_extent_mapping(em_tree, em); | 
| 149 | if (ret == -EEXIST) { | 150 | if (ret == -EEXIST) { | 
| 150 | u64 failed_start = em->start; | 151 | u64 failed_start = em->start; | 
| @@ -163,7 +164,7 @@ static struct extent_map *btree_get_extent(struct inode *inode, | |||
| 163 | free_extent_map(em); | 164 | free_extent_map(em); | 
| 164 | em = NULL; | 165 | em = NULL; | 
| 165 | } | 166 | } | 
| 166 | spin_unlock(&em_tree->lock); | 167 | write_unlock(&em_tree->lock); | 
| 167 | 168 | ||
| 168 | if (ret) | 169 | if (ret) | 
| 169 | em = ERR_PTR(ret); | 170 | em = ERR_PTR(ret); | 
| @@ -772,7 +773,7 @@ static void btree_invalidatepage(struct page *page, unsigned long offset) | |||
| 772 | } | 773 | } | 
| 773 | } | 774 | } | 
| 774 | 775 | ||
| 775 | static struct address_space_operations btree_aops = { | 776 | static const struct address_space_operations btree_aops = { | 
| 776 | .readpage = btree_readpage, | 777 | .readpage = btree_readpage, | 
| 777 | .writepage = btree_writepage, | 778 | .writepage = btree_writepage, | 
| 778 | .writepages = btree_writepages, | 779 | .writepages = btree_writepages, | 
| @@ -895,8 +896,7 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize, | |||
| 895 | root->fs_info = fs_info; | 896 | root->fs_info = fs_info; | 
| 896 | root->objectid = objectid; | 897 | root->objectid = objectid; | 
| 897 | root->last_trans = 0; | 898 | root->last_trans = 0; | 
| 898 | root->highest_inode = 0; | 899 | root->highest_objectid = 0; | 
| 899 | root->last_inode_alloc = 0; | ||
| 900 | root->name = NULL; | 900 | root->name = NULL; | 
| 901 | root->in_sysfs = 0; | 901 | root->in_sysfs = 0; | 
| 902 | root->inode_tree.rb_node = NULL; | 902 | root->inode_tree.rb_node = NULL; | 
| @@ -952,14 +952,16 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
| 952 | root, fs_info, objectid); | 952 | root, fs_info, objectid); | 
| 953 | ret = btrfs_find_last_root(tree_root, objectid, | 953 | ret = btrfs_find_last_root(tree_root, objectid, | 
| 954 | &root->root_item, &root->root_key); | 954 | &root->root_item, &root->root_key); | 
| 955 | if (ret > 0) | ||
| 956 | return -ENOENT; | ||
| 955 | BUG_ON(ret); | 957 | BUG_ON(ret); | 
| 956 | 958 | ||
| 957 | generation = btrfs_root_generation(&root->root_item); | 959 | generation = btrfs_root_generation(&root->root_item); | 
| 958 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 960 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 
| 959 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 961 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 
| 960 | blocksize, generation); | 962 | blocksize, generation); | 
| 961 | root->commit_root = btrfs_root_node(root); | ||
| 962 | BUG_ON(!root->node); | 963 | BUG_ON(!root->node); | 
| 964 | root->commit_root = btrfs_root_node(root); | ||
| 963 | return 0; | 965 | return 0; | 
| 964 | } | 966 | } | 
| 965 | 967 | ||
| @@ -1095,7 +1097,6 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
| 1095 | struct btrfs_fs_info *fs_info = tree_root->fs_info; | 1097 | struct btrfs_fs_info *fs_info = tree_root->fs_info; | 
| 1096 | struct btrfs_path *path; | 1098 | struct btrfs_path *path; | 
| 1097 | struct extent_buffer *l; | 1099 | struct extent_buffer *l; | 
| 1098 | u64 highest_inode; | ||
| 1099 | u64 generation; | 1100 | u64 generation; | 
| 1100 | u32 blocksize; | 1101 | u32 blocksize; | 
| 1101 | int ret = 0; | 1102 | int ret = 0; | 
| @@ -1110,7 +1111,7 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
| 1110 | kfree(root); | 1111 | kfree(root); | 
| 1111 | return ERR_PTR(ret); | 1112 | return ERR_PTR(ret); | 
| 1112 | } | 1113 | } | 
| 1113 | goto insert; | 1114 | goto out; | 
| 1114 | } | 1115 | } | 
| 1115 | 1116 | ||
| 1116 | __setup_root(tree_root->nodesize, tree_root->leafsize, | 1117 | __setup_root(tree_root->nodesize, tree_root->leafsize, | 
| @@ -1120,39 +1121,30 @@ struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_root *tree_root, | |||
| 1120 | path = btrfs_alloc_path(); | 1121 | path = btrfs_alloc_path(); | 
| 1121 | BUG_ON(!path); | 1122 | BUG_ON(!path); | 
| 1122 | ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); | 1123 | ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0); | 
| 1123 | if (ret != 0) { | 1124 | if (ret == 0) { | 
| 1124 | if (ret > 0) | 1125 | l = path->nodes[0]; | 
| 1125 | ret = -ENOENT; | 1126 | read_extent_buffer(l, &root->root_item, | 
| 1126 | goto out; | 1127 | btrfs_item_ptr_offset(l, path->slots[0]), | 
| 1128 | sizeof(root->root_item)); | ||
| 1129 | memcpy(&root->root_key, location, sizeof(*location)); | ||
| 1127 | } | 1130 | } | 
| 1128 | l = path->nodes[0]; | ||
| 1129 | read_extent_buffer(l, &root->root_item, | ||
| 1130 | btrfs_item_ptr_offset(l, path->slots[0]), | ||
| 1131 | sizeof(root->root_item)); | ||
| 1132 | memcpy(&root->root_key, location, sizeof(*location)); | ||
| 1133 | ret = 0; | ||
| 1134 | out: | ||
| 1135 | btrfs_release_path(root, path); | ||
| 1136 | btrfs_free_path(path); | 1131 | btrfs_free_path(path); | 
| 1137 | if (ret) { | 1132 | if (ret) { | 
| 1138 | kfree(root); | 1133 | if (ret > 0) | 
| 1134 | ret = -ENOENT; | ||
| 1139 | return ERR_PTR(ret); | 1135 | return ERR_PTR(ret); | 
| 1140 | } | 1136 | } | 
| 1137 | |||
| 1141 | generation = btrfs_root_generation(&root->root_item); | 1138 | generation = btrfs_root_generation(&root->root_item); | 
| 1142 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 1139 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 
| 1143 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 1140 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 
| 1144 | blocksize, generation); | 1141 | blocksize, generation); | 
| 1145 | root->commit_root = btrfs_root_node(root); | 1142 | root->commit_root = btrfs_root_node(root); | 
| 1146 | BUG_ON(!root->node); | 1143 | BUG_ON(!root->node); | 
| 1147 | insert: | 1144 | out: | 
| 1148 | if (location->objectid != BTRFS_TREE_LOG_OBJECTID) { | 1145 | if (location->objectid != BTRFS_TREE_LOG_OBJECTID) | 
| 1149 | root->ref_cows = 1; | 1146 | root->ref_cows = 1; | 
| 1150 | ret = btrfs_find_highest_inode(root, &highest_inode); | 1147 | |
| 1151 | if (ret == 0) { | ||
| 1152 | root->highest_inode = highest_inode; | ||
| 1153 | root->last_inode_alloc = highest_inode; | ||
| 1154 | } | ||
| 1155 | } | ||
| 1156 | return root; | 1148 | return root; | 
| 1157 | } | 1149 | } | 
| 1158 | 1150 | ||
| @@ -1187,39 +1179,66 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, | |||
| 1187 | return fs_info->dev_root; | 1179 | return fs_info->dev_root; | 
| 1188 | if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) | 1180 | if (location->objectid == BTRFS_CSUM_TREE_OBJECTID) | 
| 1189 | return fs_info->csum_root; | 1181 | return fs_info->csum_root; | 
| 1190 | 1182 | again: | |
| 1183 | spin_lock(&fs_info->fs_roots_radix_lock); | ||
| 1191 | root = radix_tree_lookup(&fs_info->fs_roots_radix, | 1184 | root = radix_tree_lookup(&fs_info->fs_roots_radix, | 
| 1192 | (unsigned long)location->objectid); | 1185 | (unsigned long)location->objectid); | 
| 1186 | spin_unlock(&fs_info->fs_roots_radix_lock); | ||
| 1193 | if (root) | 1187 | if (root) | 
| 1194 | return root; | 1188 | return root; | 
| 1195 | 1189 | ||
| 1190 | ret = btrfs_find_orphan_item(fs_info->tree_root, location->objectid); | ||
| 1191 | if (ret == 0) | ||
| 1192 | ret = -ENOENT; | ||
| 1193 | if (ret < 0) | ||
| 1194 | return ERR_PTR(ret); | ||
| 1195 | |||
| 1196 | root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); | 1196 | root = btrfs_read_fs_root_no_radix(fs_info->tree_root, location); | 
| 1197 | if (IS_ERR(root)) | 1197 | if (IS_ERR(root)) | 
| 1198 | return root; | 1198 | return root; | 
| 1199 | 1199 | ||
| 1200 | WARN_ON(btrfs_root_refs(&root->root_item) == 0); | ||
| 1200 | set_anon_super(&root->anon_super, NULL); | 1201 | set_anon_super(&root->anon_super, NULL); | 
| 1201 | 1202 | ||
| 1203 | ret = radix_tree_preload(GFP_NOFS & ~__GFP_HIGHMEM); | ||
| 1204 | if (ret) | ||
| 1205 | goto fail; | ||
| 1206 | |||
| 1207 | spin_lock(&fs_info->fs_roots_radix_lock); | ||
| 1202 | ret = radix_tree_insert(&fs_info->fs_roots_radix, | 1208 | ret = radix_tree_insert(&fs_info->fs_roots_radix, | 
| 1203 | (unsigned long)root->root_key.objectid, | 1209 | (unsigned long)root->root_key.objectid, | 
| 1204 | root); | 1210 | root); | 
| 1211 | if (ret == 0) | ||
| 1212 | root->in_radix = 1; | ||
| 1213 | spin_unlock(&fs_info->fs_roots_radix_lock); | ||
| 1214 | radix_tree_preload_end(); | ||
| 1205 | if (ret) { | 1215 | if (ret) { | 
| 1206 | free_extent_buffer(root->node); | 1216 | if (ret == -EEXIST) { | 
| 1207 | kfree(root); | 1217 | free_fs_root(root); | 
| 1208 | return ERR_PTR(ret); | 1218 | goto again; | 
| 1219 | } | ||
| 1220 | goto fail; | ||
| 1209 | } | 1221 | } | 
| 1210 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { | 1222 | |
| 1211 | ret = btrfs_find_dead_roots(fs_info->tree_root, | 1223 | ret = btrfs_find_dead_roots(fs_info->tree_root, | 
| 1212 | root->root_key.objectid); | 1224 | root->root_key.objectid); | 
| 1213 | BUG_ON(ret); | 1225 | WARN_ON(ret); | 
| 1226 | |||
| 1227 | if (!(fs_info->sb->s_flags & MS_RDONLY)) | ||
| 1214 | btrfs_orphan_cleanup(root); | 1228 | btrfs_orphan_cleanup(root); | 
| 1215 | } | 1229 | |
| 1216 | return root; | 1230 | return root; | 
| 1231 | fail: | ||
| 1232 | free_fs_root(root); | ||
| 1233 | return ERR_PTR(ret); | ||
| 1217 | } | 1234 | } | 
| 1218 | 1235 | ||
| 1219 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | 1236 | struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | 
| 1220 | struct btrfs_key *location, | 1237 | struct btrfs_key *location, | 
| 1221 | const char *name, int namelen) | 1238 | const char *name, int namelen) | 
| 1222 | { | 1239 | { | 
| 1240 | return btrfs_read_fs_root_no_name(fs_info, location); | ||
| 1241 | #if 0 | ||
| 1223 | struct btrfs_root *root; | 1242 | struct btrfs_root *root; | 
| 1224 | int ret; | 1243 | int ret; | 
| 1225 | 1244 | ||
| @@ -1236,7 +1255,7 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | |||
| 1236 | kfree(root); | 1255 | kfree(root); | 
| 1237 | return ERR_PTR(ret); | 1256 | return ERR_PTR(ret); | 
| 1238 | } | 1257 | } | 
| 1239 | #if 0 | 1258 | |
| 1240 | ret = btrfs_sysfs_add_root(root); | 1259 | ret = btrfs_sysfs_add_root(root); | 
| 1241 | if (ret) { | 1260 | if (ret) { | 
| 1242 | free_extent_buffer(root->node); | 1261 | free_extent_buffer(root->node); | 
| @@ -1244,9 +1263,9 @@ struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info, | |||
| 1244 | kfree(root); | 1263 | kfree(root); | 
| 1245 | return ERR_PTR(ret); | 1264 | return ERR_PTR(ret); | 
| 1246 | } | 1265 | } | 
| 1247 | #endif | ||
| 1248 | root->in_sysfs = 1; | 1266 | root->in_sysfs = 1; | 
| 1249 | return root; | 1267 | return root; | 
| 1268 | #endif | ||
| 1250 | } | 1269 | } | 
| 1251 | 1270 | ||
| 1252 | static int btrfs_congested_fn(void *congested_data, int bdi_bits) | 1271 | static int btrfs_congested_fn(void *congested_data, int bdi_bits) | 
| @@ -1325,9 +1344,9 @@ static void btrfs_unplug_io_fn(struct backing_dev_info *bdi, struct page *page) | |||
| 1325 | offset = page_offset(page); | 1344 | offset = page_offset(page); | 
| 1326 | 1345 | ||
| 1327 | em_tree = &BTRFS_I(inode)->extent_tree; | 1346 | em_tree = &BTRFS_I(inode)->extent_tree; | 
| 1328 | spin_lock(&em_tree->lock); | 1347 | read_lock(&em_tree->lock); | 
| 1329 | em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE); | 1348 | em = lookup_extent_mapping(em_tree, offset, PAGE_CACHE_SIZE); | 
| 1330 | spin_unlock(&em_tree->lock); | 1349 | read_unlock(&em_tree->lock); | 
| 1331 | if (!em) { | 1350 | if (!em) { | 
| 1332 | __unplug_io_fn(bdi, page); | 1351 | __unplug_io_fn(bdi, page); | 
| 1333 | return; | 1352 | return; | 
| @@ -1360,8 +1379,10 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi) | |||
| 1360 | 1379 | ||
| 1361 | err = bdi_register(bdi, NULL, "btrfs-%d", | 1380 | err = bdi_register(bdi, NULL, "btrfs-%d", | 
| 1362 | atomic_inc_return(&btrfs_bdi_num)); | 1381 | atomic_inc_return(&btrfs_bdi_num)); | 
| 1363 | if (err) | 1382 | if (err) { | 
| 1383 | bdi_destroy(bdi); | ||
| 1364 | return err; | 1384 | return err; | 
| 1385 | } | ||
| 1365 | 1386 | ||
| 1366 | bdi->ra_pages = default_backing_dev_info.ra_pages; | 1387 | bdi->ra_pages = default_backing_dev_info.ra_pages; | 
| 1367 | bdi->unplug_io_fn = btrfs_unplug_io_fn; | 1388 | bdi->unplug_io_fn = btrfs_unplug_io_fn; | 
| @@ -1451,9 +1472,12 @@ static int cleaner_kthread(void *arg) | |||
| 1451 | break; | 1472 | break; | 
| 1452 | 1473 | ||
| 1453 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | 1474 | vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); | 
| 1454 | mutex_lock(&root->fs_info->cleaner_mutex); | 1475 | |
| 1455 | btrfs_clean_old_snapshots(root); | 1476 | if (!(root->fs_info->sb->s_flags & MS_RDONLY) && | 
| 1456 | mutex_unlock(&root->fs_info->cleaner_mutex); | 1477 | mutex_trylock(&root->fs_info->cleaner_mutex)) { | 
| 1478 | btrfs_clean_old_snapshots(root); | ||
| 1479 | mutex_unlock(&root->fs_info->cleaner_mutex); | ||
| 1480 | } | ||
| 1457 | 1481 | ||
| 1458 | if (freezing(current)) { | 1482 | if (freezing(current)) { | 
| 1459 | refrigerator(); | 1483 | refrigerator(); | 
| @@ -1558,15 +1582,36 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1558 | err = -ENOMEM; | 1582 | err = -ENOMEM; | 
| 1559 | goto fail; | 1583 | goto fail; | 
| 1560 | } | 1584 | } | 
| 1561 | INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS); | 1585 | |
| 1586 | ret = init_srcu_struct(&fs_info->subvol_srcu); | ||
| 1587 | if (ret) { | ||
| 1588 | err = ret; | ||
| 1589 | goto fail; | ||
| 1590 | } | ||
| 1591 | |||
| 1592 | ret = setup_bdi(fs_info, &fs_info->bdi); | ||
| 1593 | if (ret) { | ||
| 1594 | err = ret; | ||
| 1595 | goto fail_srcu; | ||
| 1596 | } | ||
| 1597 | |||
| 1598 | fs_info->btree_inode = new_inode(sb); | ||
| 1599 | if (!fs_info->btree_inode) { | ||
| 1600 | err = -ENOMEM; | ||
| 1601 | goto fail_bdi; | ||
| 1602 | } | ||
| 1603 | |||
| 1604 | INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); | ||
| 1562 | INIT_LIST_HEAD(&fs_info->trans_list); | 1605 | INIT_LIST_HEAD(&fs_info->trans_list); | 
| 1563 | INIT_LIST_HEAD(&fs_info->dead_roots); | 1606 | INIT_LIST_HEAD(&fs_info->dead_roots); | 
| 1564 | INIT_LIST_HEAD(&fs_info->hashers); | 1607 | INIT_LIST_HEAD(&fs_info->hashers); | 
| 1565 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); | 1608 | INIT_LIST_HEAD(&fs_info->delalloc_inodes); | 
| 1566 | INIT_LIST_HEAD(&fs_info->ordered_operations); | 1609 | INIT_LIST_HEAD(&fs_info->ordered_operations); | 
| 1610 | INIT_LIST_HEAD(&fs_info->caching_block_groups); | ||
| 1567 | spin_lock_init(&fs_info->delalloc_lock); | 1611 | spin_lock_init(&fs_info->delalloc_lock); | 
| 1568 | spin_lock_init(&fs_info->new_trans_lock); | 1612 | spin_lock_init(&fs_info->new_trans_lock); | 
| 1569 | spin_lock_init(&fs_info->ref_cache_lock); | 1613 | spin_lock_init(&fs_info->ref_cache_lock); | 
| 1614 | spin_lock_init(&fs_info->fs_roots_radix_lock); | ||
| 1570 | 1615 | ||
| 1571 | init_completion(&fs_info->kobj_unregister); | 1616 | init_completion(&fs_info->kobj_unregister); | 
| 1572 | fs_info->tree_root = tree_root; | 1617 | fs_info->tree_root = tree_root; | 
| @@ -1585,11 +1630,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1585 | fs_info->sb = sb; | 1630 | fs_info->sb = sb; | 
| 1586 | fs_info->max_extent = (u64)-1; | 1631 | fs_info->max_extent = (u64)-1; | 
| 1587 | fs_info->max_inline = 8192 * 1024; | 1632 | fs_info->max_inline = 8192 * 1024; | 
| 1588 | if (setup_bdi(fs_info, &fs_info->bdi)) | ||
| 1589 | goto fail_bdi; | ||
| 1590 | fs_info->btree_inode = new_inode(sb); | ||
| 1591 | fs_info->btree_inode->i_ino = 1; | ||
| 1592 | fs_info->btree_inode->i_nlink = 1; | ||
| 1593 | fs_info->metadata_ratio = 8; | 1633 | fs_info->metadata_ratio = 8; | 
| 1594 | 1634 | ||
| 1595 | fs_info->thread_pool_size = min_t(unsigned long, | 1635 | fs_info->thread_pool_size = min_t(unsigned long, | 
| @@ -1602,6 +1642,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1602 | sb->s_blocksize_bits = blksize_bits(4096); | 1642 | sb->s_blocksize_bits = blksize_bits(4096); | 
| 1603 | sb->s_bdi = &fs_info->bdi; | 1643 | sb->s_bdi = &fs_info->bdi; | 
| 1604 | 1644 | ||
| 1645 | fs_info->btree_inode->i_ino = BTRFS_BTREE_INODE_OBJECTID; | ||
| 1646 | fs_info->btree_inode->i_nlink = 1; | ||
| 1605 | /* | 1647 | /* | 
| 1606 | * we set the i_size on the btree inode to the max possible int. | 1648 | * we set the i_size on the btree inode to the max possible int. | 
| 1607 | * the real end of the address space is determined by all of | 1649 | * the real end of the address space is determined by all of | 
| @@ -1620,28 +1662,32 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1620 | 1662 | ||
| 1621 | BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops; | 1663 | BTRFS_I(fs_info->btree_inode)->io_tree.ops = &btree_extent_io_ops; | 
| 1622 | 1664 | ||
| 1665 | BTRFS_I(fs_info->btree_inode)->root = tree_root; | ||
| 1666 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, | ||
| 1667 | sizeof(struct btrfs_key)); | ||
| 1668 | BTRFS_I(fs_info->btree_inode)->dummy_inode = 1; | ||
| 1669 | insert_inode_hash(fs_info->btree_inode); | ||
| 1670 | |||
| 1623 | spin_lock_init(&fs_info->block_group_cache_lock); | 1671 | spin_lock_init(&fs_info->block_group_cache_lock); | 
| 1624 | fs_info->block_group_cache_tree.rb_node = NULL; | 1672 | fs_info->block_group_cache_tree.rb_node = NULL; | 
| 1625 | 1673 | ||
| 1626 | extent_io_tree_init(&fs_info->pinned_extents, | 1674 | extent_io_tree_init(&fs_info->freed_extents[0], | 
| 1627 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 1675 | fs_info->btree_inode->i_mapping, GFP_NOFS); | 
| 1676 | extent_io_tree_init(&fs_info->freed_extents[1], | ||
| 1677 | fs_info->btree_inode->i_mapping, GFP_NOFS); | ||
| 1678 | fs_info->pinned_extents = &fs_info->freed_extents[0]; | ||
| 1628 | fs_info->do_barriers = 1; | 1679 | fs_info->do_barriers = 1; | 
| 1629 | 1680 | ||
| 1630 | BTRFS_I(fs_info->btree_inode)->root = tree_root; | ||
| 1631 | memset(&BTRFS_I(fs_info->btree_inode)->location, 0, | ||
| 1632 | sizeof(struct btrfs_key)); | ||
| 1633 | insert_inode_hash(fs_info->btree_inode); | ||
| 1634 | 1681 | ||
| 1635 | mutex_init(&fs_info->trans_mutex); | 1682 | mutex_init(&fs_info->trans_mutex); | 
| 1636 | mutex_init(&fs_info->ordered_operations_mutex); | 1683 | mutex_init(&fs_info->ordered_operations_mutex); | 
| 1637 | mutex_init(&fs_info->tree_log_mutex); | 1684 | mutex_init(&fs_info->tree_log_mutex); | 
| 1638 | mutex_init(&fs_info->drop_mutex); | ||
| 1639 | mutex_init(&fs_info->chunk_mutex); | 1685 | mutex_init(&fs_info->chunk_mutex); | 
| 1640 | mutex_init(&fs_info->transaction_kthread_mutex); | 1686 | mutex_init(&fs_info->transaction_kthread_mutex); | 
| 1641 | mutex_init(&fs_info->cleaner_mutex); | 1687 | mutex_init(&fs_info->cleaner_mutex); | 
| 1642 | mutex_init(&fs_info->volume_mutex); | 1688 | mutex_init(&fs_info->volume_mutex); | 
| 1643 | mutex_init(&fs_info->tree_reloc_mutex); | ||
| 1644 | init_rwsem(&fs_info->extent_commit_sem); | 1689 | init_rwsem(&fs_info->extent_commit_sem); | 
| 1690 | init_rwsem(&fs_info->subvol_sem); | ||
| 1645 | 1691 | ||
| 1646 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); | 1692 | btrfs_init_free_cluster(&fs_info->meta_alloc_cluster); | 
| 1647 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); | 1693 | btrfs_init_free_cluster(&fs_info->data_alloc_cluster); | 
| @@ -1700,7 +1746,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1700 | err = -EINVAL; | 1746 | err = -EINVAL; | 
| 1701 | goto fail_iput; | 1747 | goto fail_iput; | 
| 1702 | } | 1748 | } | 
| 1703 | 1749 | printk("thread pool is %d\n", fs_info->thread_pool_size); | |
| 1704 | /* | 1750 | /* | 
| 1705 | * we need to start all the end_io workers up front because the | 1751 | * we need to start all the end_io workers up front because the | 
| 1706 | * queue work function gets called at interrupt time, and so it | 1752 | * queue work function gets called at interrupt time, and so it | 
| @@ -1745,20 +1791,22 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1745 | fs_info->endio_workers.idle_thresh = 4; | 1791 | fs_info->endio_workers.idle_thresh = 4; | 
| 1746 | fs_info->endio_meta_workers.idle_thresh = 4; | 1792 | fs_info->endio_meta_workers.idle_thresh = 4; | 
| 1747 | 1793 | ||
| 1748 | fs_info->endio_write_workers.idle_thresh = 64; | 1794 | fs_info->endio_write_workers.idle_thresh = 2; | 
| 1749 | fs_info->endio_meta_write_workers.idle_thresh = 64; | 1795 | fs_info->endio_meta_write_workers.idle_thresh = 2; | 
| 1796 | |||
| 1797 | fs_info->endio_workers.atomic_worker_start = 1; | ||
| 1798 | fs_info->endio_meta_workers.atomic_worker_start = 1; | ||
| 1799 | fs_info->endio_write_workers.atomic_worker_start = 1; | ||
| 1800 | fs_info->endio_meta_write_workers.atomic_worker_start = 1; | ||
| 1750 | 1801 | ||
| 1751 | btrfs_start_workers(&fs_info->workers, 1); | 1802 | btrfs_start_workers(&fs_info->workers, 1); | 
| 1752 | btrfs_start_workers(&fs_info->submit_workers, 1); | 1803 | btrfs_start_workers(&fs_info->submit_workers, 1); | 
| 1753 | btrfs_start_workers(&fs_info->delalloc_workers, 1); | 1804 | btrfs_start_workers(&fs_info->delalloc_workers, 1); | 
| 1754 | btrfs_start_workers(&fs_info->fixup_workers, 1); | 1805 | btrfs_start_workers(&fs_info->fixup_workers, 1); | 
| 1755 | btrfs_start_workers(&fs_info->endio_workers, fs_info->thread_pool_size); | 1806 | btrfs_start_workers(&fs_info->endio_workers, 1); | 
| 1756 | btrfs_start_workers(&fs_info->endio_meta_workers, | 1807 | btrfs_start_workers(&fs_info->endio_meta_workers, 1); | 
| 1757 | fs_info->thread_pool_size); | 1808 | btrfs_start_workers(&fs_info->endio_meta_write_workers, 1); | 
| 1758 | btrfs_start_workers(&fs_info->endio_meta_write_workers, | 1809 | btrfs_start_workers(&fs_info->endio_write_workers, 1); | 
| 1759 | fs_info->thread_pool_size); | ||
| 1760 | btrfs_start_workers(&fs_info->endio_write_workers, | ||
| 1761 | fs_info->thread_pool_size); | ||
| 1762 | 1810 | ||
| 1763 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); | 1811 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); | 
| 1764 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, | 1812 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, | 
| @@ -1918,6 +1966,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1918 | } | 1966 | } | 
| 1919 | } | 1967 | } | 
| 1920 | 1968 | ||
| 1969 | ret = btrfs_find_orphan_roots(tree_root); | ||
| 1970 | BUG_ON(ret); | ||
| 1971 | |||
| 1921 | if (!(sb->s_flags & MS_RDONLY)) { | 1972 | if (!(sb->s_flags & MS_RDONLY)) { | 
| 1922 | ret = btrfs_recover_relocation(tree_root); | 1973 | ret = btrfs_recover_relocation(tree_root); | 
| 1923 | BUG_ON(ret); | 1974 | BUG_ON(ret); | 
| @@ -1977,6 +2028,8 @@ fail_iput: | |||
| 1977 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 2028 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 
| 1978 | fail_bdi: | 2029 | fail_bdi: | 
| 1979 | bdi_destroy(&fs_info->bdi); | 2030 | bdi_destroy(&fs_info->bdi); | 
| 2031 | fail_srcu: | ||
| 2032 | cleanup_srcu_struct(&fs_info->subvol_srcu); | ||
| 1980 | fail: | 2033 | fail: | 
| 1981 | kfree(extent_root); | 2034 | kfree(extent_root); | 
| 1982 | kfree(tree_root); | 2035 | kfree(tree_root); | 
| @@ -2236,20 +2289,29 @@ int write_ctree_super(struct btrfs_trans_handle *trans, | |||
| 2236 | 2289 | ||
| 2237 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | 2290 | int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root) | 
| 2238 | { | 2291 | { | 
| 2239 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); | 2292 | spin_lock(&fs_info->fs_roots_radix_lock); | 
| 2240 | radix_tree_delete(&fs_info->fs_roots_radix, | 2293 | radix_tree_delete(&fs_info->fs_roots_radix, | 
| 2241 | (unsigned long)root->root_key.objectid); | 2294 | (unsigned long)root->root_key.objectid); | 
| 2295 | spin_unlock(&fs_info->fs_roots_radix_lock); | ||
| 2296 | |||
| 2297 | if (btrfs_root_refs(&root->root_item) == 0) | ||
| 2298 | synchronize_srcu(&fs_info->subvol_srcu); | ||
| 2299 | |||
| 2300 | free_fs_root(root); | ||
| 2301 | return 0; | ||
| 2302 | } | ||
| 2303 | |||
| 2304 | static void free_fs_root(struct btrfs_root *root) | ||
| 2305 | { | ||
| 2306 | WARN_ON(!RB_EMPTY_ROOT(&root->inode_tree)); | ||
| 2242 | if (root->anon_super.s_dev) { | 2307 | if (root->anon_super.s_dev) { | 
| 2243 | down_write(&root->anon_super.s_umount); | 2308 | down_write(&root->anon_super.s_umount); | 
| 2244 | kill_anon_super(&root->anon_super); | 2309 | kill_anon_super(&root->anon_super); | 
| 2245 | } | 2310 | } | 
| 2246 | if (root->node) | 2311 | free_extent_buffer(root->node); | 
| 2247 | free_extent_buffer(root->node); | 2312 | free_extent_buffer(root->commit_root); | 
| 2248 | if (root->commit_root) | ||
| 2249 | free_extent_buffer(root->commit_root); | ||
| 2250 | kfree(root->name); | 2313 | kfree(root->name); | 
| 2251 | kfree(root); | 2314 | kfree(root); | 
| 2252 | return 0; | ||
| 2253 | } | 2315 | } | 
| 2254 | 2316 | ||
| 2255 | static int del_fs_roots(struct btrfs_fs_info *fs_info) | 2317 | static int del_fs_roots(struct btrfs_fs_info *fs_info) | 
| @@ -2258,6 +2320,20 @@ static int del_fs_roots(struct btrfs_fs_info *fs_info) | |||
| 2258 | struct btrfs_root *gang[8]; | 2320 | struct btrfs_root *gang[8]; | 
| 2259 | int i; | 2321 | int i; | 
| 2260 | 2322 | ||
| 2323 | while (!list_empty(&fs_info->dead_roots)) { | ||
| 2324 | gang[0] = list_entry(fs_info->dead_roots.next, | ||
| 2325 | struct btrfs_root, root_list); | ||
| 2326 | list_del(&gang[0]->root_list); | ||
| 2327 | |||
| 2328 | if (gang[0]->in_radix) { | ||
| 2329 | btrfs_free_fs_root(fs_info, gang[0]); | ||
| 2330 | } else { | ||
| 2331 | free_extent_buffer(gang[0]->node); | ||
| 2332 | free_extent_buffer(gang[0]->commit_root); | ||
| 2333 | kfree(gang[0]); | ||
| 2334 | } | ||
| 2335 | } | ||
| 2336 | |||
| 2261 | while (1) { | 2337 | while (1) { | 
| 2262 | ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, | 2338 | ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, | 
| 2263 | (void **)gang, 0, | 2339 | (void **)gang, 0, | 
| @@ -2287,9 +2363,6 @@ int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) | |||
| 2287 | root_objectid = gang[ret - 1]->root_key.objectid + 1; | 2363 | root_objectid = gang[ret - 1]->root_key.objectid + 1; | 
| 2288 | for (i = 0; i < ret; i++) { | 2364 | for (i = 0; i < ret; i++) { | 
| 2289 | root_objectid = gang[i]->root_key.objectid; | 2365 | root_objectid = gang[i]->root_key.objectid; | 
| 2290 | ret = btrfs_find_dead_roots(fs_info->tree_root, | ||
| 2291 | root_objectid); | ||
| 2292 | BUG_ON(ret); | ||
| 2293 | btrfs_orphan_cleanup(gang[i]); | 2366 | btrfs_orphan_cleanup(gang[i]); | 
| 2294 | } | 2367 | } | 
| 2295 | root_objectid++; | 2368 | root_objectid++; | 
| @@ -2359,7 +2432,6 @@ int close_ctree(struct btrfs_root *root) | |||
| 2359 | free_extent_buffer(root->fs_info->csum_root->commit_root); | 2432 | free_extent_buffer(root->fs_info->csum_root->commit_root); | 
| 2360 | 2433 | ||
| 2361 | btrfs_free_block_groups(root->fs_info); | 2434 | btrfs_free_block_groups(root->fs_info); | 
| 2362 | btrfs_free_pinned_extents(root->fs_info); | ||
| 2363 | 2435 | ||
| 2364 | del_fs_roots(fs_info); | 2436 | del_fs_roots(fs_info); | 
| 2365 | 2437 | ||
| @@ -2378,6 +2450,7 @@ int close_ctree(struct btrfs_root *root) | |||
| 2378 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 2450 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 
| 2379 | 2451 | ||
| 2380 | bdi_destroy(&fs_info->bdi); | 2452 | bdi_destroy(&fs_info->bdi); | 
| 2453 | cleanup_srcu_struct(&fs_info->subvol_srcu); | ||
| 2381 | 2454 | ||
| 2382 | kfree(fs_info->extent_root); | 2455 | kfree(fs_info->extent_root); | 
| 2383 | kfree(fs_info->tree_root); | 2456 | kfree(fs_info->tree_root); | 
