diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 46 |
1 files changed, 30 insertions, 16 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 6d0cd9a7a615..6d6e1ac0a9a0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -135,6 +135,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end) | |||
135 | alloc_hint = ins.objectid + ins.offset; | 135 | alloc_hint = ins.objectid + ins.offset; |
136 | start += cur_alloc_size; | 136 | start += cur_alloc_size; |
137 | } | 137 | } |
138 | btrfs_add_ordered_inode(inode); | ||
138 | out: | 139 | out: |
139 | btrfs_end_transaction(trans, root); | 140 | btrfs_end_transaction(trans, root); |
140 | return ret; | 141 | return ret; |
@@ -367,8 +368,8 @@ void btrfs_read_locked_inode(struct inode *inode) | |||
367 | path = btrfs_alloc_path(); | 368 | path = btrfs_alloc_path(); |
368 | BUG_ON(!path); | 369 | BUG_ON(!path); |
369 | mutex_lock(&root->fs_info->fs_mutex); | 370 | mutex_lock(&root->fs_info->fs_mutex); |
370 | |||
371 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); | 371 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); |
372 | |||
372 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); | 373 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); |
373 | if (ret) | 374 | if (ret) |
374 | goto make_bad; | 375 | goto make_bad; |
@@ -898,7 +899,6 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
898 | if ((offset & (blocksize - 1)) == 0) | 899 | if ((offset & (blocksize - 1)) == 0) |
899 | goto out; | 900 | goto out; |
900 | 901 | ||
901 | down_read(&root->snap_sem); | ||
902 | ret = -ENOMEM; | 902 | ret = -ENOMEM; |
903 | page = grab_cache_page(mapping, index); | 903 | page = grab_cache_page(mapping, index); |
904 | if (!page) | 904 | if (!page) |
@@ -917,7 +917,6 @@ static int btrfs_truncate_page(struct address_space *mapping, loff_t from) | |||
917 | 917 | ||
918 | unlock_page(page); | 918 | unlock_page(page); |
919 | page_cache_release(page); | 919 | page_cache_release(page); |
920 | up_read(&BTRFS_I(inode)->root->snap_sem); | ||
921 | out: | 920 | out: |
922 | return ret; | 921 | return ret; |
923 | } | 922 | } |
@@ -1146,6 +1145,19 @@ static int btrfs_find_actor(struct inode *inode, void *opaque) | |||
1146 | args->root == BTRFS_I(inode)->root); | 1145 | args->root == BTRFS_I(inode)->root); |
1147 | } | 1146 | } |
1148 | 1147 | ||
1148 | struct inode *btrfs_ilookup(struct super_block *s, u64 objectid, | ||
1149 | u64 root_objectid) | ||
1150 | { | ||
1151 | struct btrfs_iget_args args; | ||
1152 | args.ino = objectid; | ||
1153 | args.root = btrfs_lookup_fs_root(btrfs_sb(s)->fs_info, root_objectid); | ||
1154 | |||
1155 | if (!args.root) | ||
1156 | return NULL; | ||
1157 | |||
1158 | return ilookup5(s, objectid, btrfs_find_actor, (void *)&args); | ||
1159 | } | ||
1160 | |||
1149 | struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, | 1161 | struct inode *btrfs_iget_locked(struct super_block *s, u64 objectid, |
1150 | struct btrfs_root *root) | 1162 | struct btrfs_root *root) |
1151 | { | 1163 | { |
@@ -1336,7 +1348,6 @@ read_dir_items: | |||
1336 | 1348 | ||
1337 | d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; | 1349 | d_type = btrfs_filetype_table[btrfs_dir_type(leaf, di)]; |
1338 | btrfs_dir_item_key_to_cpu(leaf, di, &location); | 1350 | btrfs_dir_item_key_to_cpu(leaf, di, &location); |
1339 | |||
1340 | over = filldir(dirent, name_ptr, name_len, | 1351 | over = filldir(dirent, name_ptr, name_len, |
1341 | found_key.offset, | 1352 | found_key.offset, |
1342 | location.objectid, | 1353 | location.objectid, |
@@ -2054,7 +2065,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
2054 | 2065 | ||
2055 | ret = -EINVAL; | 2066 | ret = -EINVAL; |
2056 | 2067 | ||
2057 | down_read(&BTRFS_I(inode)->root->snap_sem); | ||
2058 | lock_page(page); | 2068 | lock_page(page); |
2059 | wait_on_page_writeback(page); | 2069 | wait_on_page_writeback(page); |
2060 | size = i_size_read(inode); | 2070 | size = i_size_read(inode); |
@@ -2075,7 +2085,6 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page) | |||
2075 | ret = btrfs_cow_one_page(inode, page, end); | 2085 | ret = btrfs_cow_one_page(inode, page, end); |
2076 | 2086 | ||
2077 | out_unlock: | 2087 | out_unlock: |
2078 | up_read(&BTRFS_I(inode)->root->snap_sem); | ||
2079 | unlock_page(page); | 2088 | unlock_page(page); |
2080 | out: | 2089 | out: |
2081 | return ret; | 2090 | return ret; |
@@ -2118,7 +2127,7 @@ static int noinline create_subvol(struct btrfs_root *root, char *name, | |||
2118 | struct btrfs_root_item root_item; | 2127 | struct btrfs_root_item root_item; |
2119 | struct btrfs_inode_item *inode_item; | 2128 | struct btrfs_inode_item *inode_item; |
2120 | struct extent_buffer *leaf; | 2129 | struct extent_buffer *leaf; |
2121 | struct btrfs_root *new_root; | 2130 | struct btrfs_root *new_root = root; |
2122 | struct inode *inode; | 2131 | struct inode *inode; |
2123 | struct inode *dir; | 2132 | struct inode *dir; |
2124 | int ret; | 2133 | int ret; |
@@ -2230,7 +2239,7 @@ static int noinline create_subvol(struct btrfs_root *root, char *name, | |||
2230 | goto fail; | 2239 | goto fail; |
2231 | fail: | 2240 | fail: |
2232 | nr = trans->blocks_used; | 2241 | nr = trans->blocks_used; |
2233 | err = btrfs_commit_transaction(trans, root); | 2242 | err = btrfs_commit_transaction(trans, new_root); |
2234 | if (err && !ret) | 2243 | if (err && !ret) |
2235 | ret = err; | 2244 | ret = err; |
2236 | fail_commit: | 2245 | fail_commit: |
@@ -2253,10 +2262,6 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2253 | if (!root->ref_cows) | 2262 | if (!root->ref_cows) |
2254 | return -EINVAL; | 2263 | return -EINVAL; |
2255 | 2264 | ||
2256 | down_write(&root->snap_sem); | ||
2257 | freeze_bdev(root->fs_info->sb->s_bdev); | ||
2258 | thaw_bdev(root->fs_info->sb->s_bdev, root->fs_info->sb); | ||
2259 | |||
2260 | mutex_lock(&root->fs_info->fs_mutex); | 2265 | mutex_lock(&root->fs_info->fs_mutex); |
2261 | ret = btrfs_check_free_space(root, 1, 0); | 2266 | ret = btrfs_check_free_space(root, 1, 0); |
2262 | if (ret) | 2267 | if (ret) |
@@ -2264,6 +2269,9 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2264 | 2269 | ||
2265 | trans = btrfs_start_transaction(root, 1); | 2270 | trans = btrfs_start_transaction(root, 1); |
2266 | BUG_ON(!trans); | 2271 | BUG_ON(!trans); |
2272 | err = btrfs_commit_transaction(trans, root); | ||
2273 | |||
2274 | trans = btrfs_start_transaction(root, 1); | ||
2267 | 2275 | ||
2268 | ret = btrfs_update_inode(trans, root, root->inode); | 2276 | ret = btrfs_update_inode(trans, root, root->inode); |
2269 | if (ret) | 2277 | if (ret) |
@@ -2272,9 +2280,7 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2272 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, | 2280 | ret = btrfs_find_free_objectid(trans, root->fs_info->tree_root, |
2273 | 0, &objectid); | 2281 | 0, &objectid); |
2274 | if (ret) | 2282 | if (ret) |
2275 | goto fail; | 2283 | goto fail; memcpy(&new_root_item, &root->root_item, |
2276 | |||
2277 | memcpy(&new_root_item, &root->root_item, | ||
2278 | sizeof(new_root_item)); | 2284 | sizeof(new_root_item)); |
2279 | 2285 | ||
2280 | key.objectid = objectid; | 2286 | key.objectid = objectid; |
@@ -2285,12 +2291,20 @@ static int create_snapshot(struct btrfs_root *root, char *name, int namelen) | |||
2285 | btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); | 2291 | btrfs_cow_block(trans, root, root->node, NULL, 0, &tmp); |
2286 | free_extent_buffer(tmp); | 2292 | free_extent_buffer(tmp); |
2287 | 2293 | ||
2294 | /* write the ordered inodes to force all delayed allocations to | ||
2295 | * be filled. Once this is done, we can copy the root | ||
2296 | */ | ||
2297 | mutex_lock(&root->fs_info->trans_mutex); | ||
2298 | btrfs_write_ordered_inodes(trans, root); | ||
2299 | mutex_unlock(&root->fs_info->trans_mutex); | ||
2300 | |||
2288 | btrfs_copy_root(trans, root, root->node, &tmp, objectid); | 2301 | btrfs_copy_root(trans, root, root->node, &tmp, objectid); |
2289 | 2302 | ||
2290 | btrfs_set_root_bytenr(&new_root_item, tmp->start); | 2303 | btrfs_set_root_bytenr(&new_root_item, tmp->start); |
2291 | btrfs_set_root_level(&new_root_item, btrfs_header_level(tmp)); | 2304 | btrfs_set_root_level(&new_root_item, btrfs_header_level(tmp)); |
2292 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, | 2305 | ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key, |
2293 | &new_root_item); | 2306 | &new_root_item); |
2307 | printk("new root %Lu node %Lu\n", objectid, tmp->start); | ||
2294 | free_extent_buffer(tmp); | 2308 | free_extent_buffer(tmp); |
2295 | if (ret) | 2309 | if (ret) |
2296 | goto fail; | 2310 | goto fail; |
@@ -2321,7 +2335,6 @@ fail: | |||
2321 | ret = err; | 2335 | ret = err; |
2322 | fail_unlock: | 2336 | fail_unlock: |
2323 | mutex_unlock(&root->fs_info->fs_mutex); | 2337 | mutex_unlock(&root->fs_info->fs_mutex); |
2324 | up_write(&root->snap_sem); | ||
2325 | btrfs_btree_balance_dirty(root, nr); | 2338 | btrfs_btree_balance_dirty(root, nr); |
2326 | return ret; | 2339 | return ret; |
2327 | } | 2340 | } |
@@ -2608,6 +2621,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) | |||
2608 | if (!ei) | 2621 | if (!ei) |
2609 | return NULL; | 2622 | return NULL; |
2610 | ei->last_trans = 0; | 2623 | ei->last_trans = 0; |
2624 | ei->ordered_trans = 0; | ||
2611 | return &ei->vfs_inode; | 2625 | return &ei->vfs_inode; |
2612 | } | 2626 | } |
2613 | 2627 | ||