diff options
Diffstat (limited to 'fs/btrfs')
| -rw-r--r-- | fs/btrfs/compression.c | 15 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 41 | ||||
| -rw-r--r-- | fs/btrfs/export.c | 78 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 77 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.c | 77 | ||||
| -rw-r--r-- | fs/btrfs/extent_io.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/file.c | 99 | ||||
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 12 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 299 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 87 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.h | 14 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.c | 67 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/orphan.c | 6 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 43 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 21 | ||||
| -rw-r--r-- | fs/btrfs/volumes.c | 20 | ||||
| -rw-r--r-- | fs/btrfs/volumes.h | 2 |
20 files changed, 773 insertions, 202 deletions
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 7845d1f7d1d9..b50bc4bd5c56 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -91,23 +91,10 @@ static inline int compressed_bio_size(struct btrfs_root *root, | |||
| 91 | static struct bio *compressed_bio_alloc(struct block_device *bdev, | 91 | static struct bio *compressed_bio_alloc(struct block_device *bdev, |
| 92 | u64 first_byte, gfp_t gfp_flags) | 92 | u64 first_byte, gfp_t gfp_flags) |
| 93 | { | 93 | { |
| 94 | struct bio *bio; | ||
| 95 | int nr_vecs; | 94 | int nr_vecs; |
| 96 | 95 | ||
| 97 | nr_vecs = bio_get_nr_vecs(bdev); | 96 | nr_vecs = bio_get_nr_vecs(bdev); |
| 98 | bio = bio_alloc(gfp_flags, nr_vecs); | 97 | return btrfs_bio_alloc(bdev, first_byte >> 9, nr_vecs, gfp_flags); |
| 99 | |||
| 100 | if (bio == NULL && (current->flags & PF_MEMALLOC)) { | ||
| 101 | while (!bio && (nr_vecs /= 2)) | ||
| 102 | bio = bio_alloc(gfp_flags, nr_vecs); | ||
| 103 | } | ||
| 104 | |||
| 105 | if (bio) { | ||
| 106 | bio->bi_size = 0; | ||
| 107 | bio->bi_bdev = bdev; | ||
| 108 | bio->bi_sector = first_byte >> 9; | ||
| 109 | } | ||
| 110 | return bio; | ||
| 111 | } | 98 | } |
| 112 | 99 | ||
| 113 | static int check_compressed_csum(struct inode *inode, | 100 | static int check_compressed_csum(struct inode *inode, |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 8db9234f6b41..af52f6d7a4d8 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -808,9 +808,9 @@ struct btrfs_block_group_cache { | |||
| 808 | int extents_thresh; | 808 | int extents_thresh; |
| 809 | int free_extents; | 809 | int free_extents; |
| 810 | int total_bitmaps; | 810 | int total_bitmaps; |
| 811 | int ro:1; | 811 | unsigned int ro:1; |
| 812 | int dirty:1; | 812 | unsigned int dirty:1; |
| 813 | int iref:1; | 813 | unsigned int iref:1; |
| 814 | 814 | ||
| 815 | int disk_cache_state; | 815 | int disk_cache_state; |
| 816 | 816 | ||
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index fb827d0d7181..51d2e4de34eb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/freezer.h> | 28 | #include <linux/freezer.h> |
| 29 | #include <linux/crc32c.h> | 29 | #include <linux/crc32c.h> |
| 30 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
| 31 | #include <linux/migrate.h> | ||
| 31 | #include "compat.h" | 32 | #include "compat.h" |
| 32 | #include "ctree.h" | 33 | #include "ctree.h" |
| 33 | #include "disk-io.h" | 34 | #include "disk-io.h" |
| @@ -355,6 +356,8 @@ static int csum_dirty_buffer(struct btrfs_root *root, struct page *page) | |||
| 355 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, | 356 | ret = btree_read_extent_buffer_pages(root, eb, start + PAGE_CACHE_SIZE, |
| 356 | btrfs_header_generation(eb)); | 357 | btrfs_header_generation(eb)); |
| 357 | BUG_ON(ret); | 358 | BUG_ON(ret); |
| 359 | WARN_ON(!btrfs_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN)); | ||
| 360 | |||
| 358 | found_start = btrfs_header_bytenr(eb); | 361 | found_start = btrfs_header_bytenr(eb); |
| 359 | if (found_start != start) { | 362 | if (found_start != start) { |
| 360 | WARN_ON(1); | 363 | WARN_ON(1); |
| @@ -693,6 +696,27 @@ static int btree_submit_bio_hook(struct inode *inode, int rw, struct bio *bio, | |||
| 693 | __btree_submit_bio_done); | 696 | __btree_submit_bio_done); |
| 694 | } | 697 | } |
| 695 | 698 | ||
| 699 | #ifdef CONFIG_MIGRATION | ||
| 700 | static int btree_migratepage(struct address_space *mapping, | ||
| 701 | struct page *newpage, struct page *page) | ||
| 702 | { | ||
| 703 | /* | ||
| 704 | * we can't safely write a btree page from here, | ||
| 705 | * we haven't done the locking hook | ||
| 706 | */ | ||
| 707 | if (PageDirty(page)) | ||
| 708 | return -EAGAIN; | ||
| 709 | /* | ||
| 710 | * Buffers may be managed in a filesystem specific way. | ||
| 711 | * We must have no buffers or drop them. | ||
| 712 | */ | ||
| 713 | if (page_has_private(page) && | ||
| 714 | !try_to_release_page(page, GFP_KERNEL)) | ||
| 715 | return -EAGAIN; | ||
| 716 | return migrate_page(mapping, newpage, page); | ||
| 717 | } | ||
| 718 | #endif | ||
| 719 | |||
| 696 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 720 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
| 697 | { | 721 | { |
| 698 | struct extent_io_tree *tree; | 722 | struct extent_io_tree *tree; |
| @@ -707,8 +731,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc) | |||
| 707 | } | 731 | } |
| 708 | 732 | ||
| 709 | redirty_page_for_writepage(wbc, page); | 733 | redirty_page_for_writepage(wbc, page); |
| 710 | eb = btrfs_find_tree_block(root, page_offset(page), | 734 | eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE); |
| 711 | PAGE_CACHE_SIZE); | ||
| 712 | WARN_ON(!eb); | 735 | WARN_ON(!eb); |
| 713 | 736 | ||
| 714 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); | 737 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); |
| @@ -799,6 +822,9 @@ static const struct address_space_operations btree_aops = { | |||
| 799 | .releasepage = btree_releasepage, | 822 | .releasepage = btree_releasepage, |
| 800 | .invalidatepage = btree_invalidatepage, | 823 | .invalidatepage = btree_invalidatepage, |
| 801 | .sync_page = block_sync_page, | 824 | .sync_page = block_sync_page, |
| 825 | #ifdef CONFIG_MIGRATION | ||
| 826 | .migratepage = btree_migratepage, | ||
| 827 | #endif | ||
| 802 | }; | 828 | }; |
| 803 | 829 | ||
| 804 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, | 830 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, |
| @@ -981,7 +1007,10 @@ static int find_and_setup_root(struct btrfs_root *tree_root, | |||
| 981 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); | 1007 | blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item)); |
| 982 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), | 1008 | root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item), |
| 983 | blocksize, generation); | 1009 | blocksize, generation); |
| 984 | BUG_ON(!root->node); | 1010 | if (!root->node || !btrfs_buffer_uptodate(root->node, generation)) { |
| 1011 | free_extent_buffer(root->node); | ||
| 1012 | return -EIO; | ||
| 1013 | } | ||
| 985 | root->commit_root = btrfs_root_node(root); | 1014 | root->commit_root = btrfs_root_node(root); |
| 986 | return 0; | 1015 | return 0; |
| 987 | } | 1016 | } |
| @@ -1538,10 +1567,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1538 | GFP_NOFS); | 1567 | GFP_NOFS); |
| 1539 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), | 1568 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), |
| 1540 | GFP_NOFS); | 1569 | GFP_NOFS); |
| 1541 | struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root), | 1570 | struct btrfs_root *tree_root = btrfs_sb(sb); |
| 1542 | GFP_NOFS); | 1571 | struct btrfs_fs_info *fs_info = tree_root->fs_info; |
| 1543 | struct btrfs_fs_info *fs_info = kzalloc(sizeof(*fs_info), | ||
| 1544 | GFP_NOFS); | ||
| 1545 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), | 1572 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), |
| 1546 | GFP_NOFS); | 1573 | GFP_NOFS); |
| 1547 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), | 1574 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 951ef09b82f4..659f532d26a0 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -166,7 +166,7 @@ static struct dentry *btrfs_fh_to_dentry(struct super_block *sb, struct fid *fh, | |||
| 166 | static struct dentry *btrfs_get_parent(struct dentry *child) | 166 | static struct dentry *btrfs_get_parent(struct dentry *child) |
| 167 | { | 167 | { |
| 168 | struct inode *dir = child->d_inode; | 168 | struct inode *dir = child->d_inode; |
| 169 | static struct dentry *dentry; | 169 | struct dentry *dentry; |
| 170 | struct btrfs_root *root = BTRFS_I(dir)->root; | 170 | struct btrfs_root *root = BTRFS_I(dir)->root; |
| 171 | struct btrfs_path *path; | 171 | struct btrfs_path *path; |
| 172 | struct extent_buffer *leaf; | 172 | struct extent_buffer *leaf; |
| @@ -232,9 +232,85 @@ fail: | |||
| 232 | return ERR_PTR(ret); | 232 | return ERR_PTR(ret); |
| 233 | } | 233 | } |
| 234 | 234 | ||
| 235 | static int btrfs_get_name(struct dentry *parent, char *name, | ||
| 236 | struct dentry *child) | ||
| 237 | { | ||
| 238 | struct inode *inode = child->d_inode; | ||
| 239 | struct inode *dir = parent->d_inode; | ||
| 240 | struct btrfs_path *path; | ||
| 241 | struct btrfs_root *root = BTRFS_I(dir)->root; | ||
| 242 | struct btrfs_inode_ref *iref; | ||
| 243 | struct btrfs_root_ref *rref; | ||
| 244 | struct extent_buffer *leaf; | ||
| 245 | unsigned long name_ptr; | ||
| 246 | struct btrfs_key key; | ||
| 247 | int name_len; | ||
| 248 | int ret; | ||
| 249 | |||
| 250 | if (!dir || !inode) | ||
| 251 | return -EINVAL; | ||
| 252 | |||
| 253 | if (!S_ISDIR(dir->i_mode)) | ||
| 254 | return -EINVAL; | ||
| 255 | |||
| 256 | path = btrfs_alloc_path(); | ||
| 257 | if (!path) | ||
| 258 | return -ENOMEM; | ||
| 259 | path->leave_spinning = 1; | ||
| 260 | |||
| 261 | if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | ||
| 262 | key.objectid = BTRFS_I(inode)->root->root_key.objectid; | ||
| 263 | key.type = BTRFS_ROOT_BACKREF_KEY; | ||
| 264 | key.offset = (u64)-1; | ||
| 265 | root = root->fs_info->tree_root; | ||
| 266 | } else { | ||
| 267 | key.objectid = inode->i_ino; | ||
| 268 | key.offset = dir->i_ino; | ||
| 269 | key.type = BTRFS_INODE_REF_KEY; | ||
| 270 | } | ||
| 271 | |||
| 272 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | ||
| 273 | if (ret < 0) { | ||
| 274 | btrfs_free_path(path); | ||
| 275 | return ret; | ||
| 276 | } else if (ret > 0) { | ||
| 277 | if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | ||
| 278 | path->slots[0]--; | ||
| 279 | } else { | ||
| 280 | btrfs_free_path(path); | ||
| 281 | return -ENOENT; | ||
| 282 | } | ||
| 283 | } | ||
| 284 | leaf = path->nodes[0]; | ||
| 285 | |||
| 286 | if (inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | ||
| 287 | rref = btrfs_item_ptr(leaf, path->slots[0], | ||
| 288 | struct btrfs_root_ref); | ||
| 289 | name_ptr = (unsigned long)(rref + 1); | ||
| 290 | name_len = btrfs_root_ref_name_len(leaf, rref); | ||
| 291 | } else { | ||
| 292 | iref = btrfs_item_ptr(leaf, path->slots[0], | ||
| 293 | struct btrfs_inode_ref); | ||
| 294 | name_ptr = (unsigned long)(iref + 1); | ||
| 295 | name_len = btrfs_inode_ref_name_len(leaf, iref); | ||
| 296 | } | ||
| 297 | |||
| 298 | read_extent_buffer(leaf, name, name_ptr, name_len); | ||
| 299 | btrfs_free_path(path); | ||
| 300 | |||
| 301 | /* | ||
| 302 | * have to add the null termination to make sure that reconnect_path | ||
| 303 | * gets the right len for strlen | ||
| 304 | */ | ||
| 305 | name[name_len] = '\0'; | ||
| 306 | |||
| 307 | return 0; | ||
| 308 | } | ||
| 309 | |||
| 235 | const struct export_operations btrfs_export_ops = { | 310 | const struct export_operations btrfs_export_ops = { |
| 236 | .encode_fh = btrfs_encode_fh, | 311 | .encode_fh = btrfs_encode_fh, |
| 237 | .fh_to_dentry = btrfs_fh_to_dentry, | 312 | .fh_to_dentry = btrfs_fh_to_dentry, |
| 238 | .fh_to_parent = btrfs_fh_to_parent, | 313 | .fh_to_parent = btrfs_fh_to_parent, |
| 239 | .get_parent = btrfs_get_parent, | 314 | .get_parent = btrfs_get_parent, |
| 315 | .get_name = btrfs_get_name, | ||
| 240 | }; | 316 | }; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 0c097f3aec41..227e5815d838 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -429,6 +429,7 @@ err: | |||
| 429 | 429 | ||
| 430 | static int cache_block_group(struct btrfs_block_group_cache *cache, | 430 | static int cache_block_group(struct btrfs_block_group_cache *cache, |
| 431 | struct btrfs_trans_handle *trans, | 431 | struct btrfs_trans_handle *trans, |
| 432 | struct btrfs_root *root, | ||
| 432 | int load_cache_only) | 433 | int load_cache_only) |
| 433 | { | 434 | { |
| 434 | struct btrfs_fs_info *fs_info = cache->fs_info; | 435 | struct btrfs_fs_info *fs_info = cache->fs_info; |
| @@ -442,9 +443,12 @@ static int cache_block_group(struct btrfs_block_group_cache *cache, | |||
| 442 | 443 | ||
| 443 | /* | 444 | /* |
| 444 | * We can't do the read from on-disk cache during a commit since we need | 445 | * We can't do the read from on-disk cache during a commit since we need |
| 445 | * to have the normal tree locking. | 446 | * to have the normal tree locking. Also if we are currently trying to |
| 447 | * allocate blocks for the tree root we can't do the fast caching since | ||
| 448 | * we likely hold important locks. | ||
| 446 | */ | 449 | */ |
| 447 | if (!trans->transaction->in_commit) { | 450 | if (!trans->transaction->in_commit && |
| 451 | (root && root != root->fs_info->tree_root)) { | ||
| 448 | spin_lock(&cache->lock); | 452 | spin_lock(&cache->lock); |
| 449 | if (cache->cached != BTRFS_CACHE_NO) { | 453 | if (cache->cached != BTRFS_CACHE_NO) { |
| 450 | spin_unlock(&cache->lock); | 454 | spin_unlock(&cache->lock); |
| @@ -2741,6 +2745,7 @@ static int cache_save_setup(struct btrfs_block_group_cache *block_group, | |||
| 2741 | struct btrfs_root *root = block_group->fs_info->tree_root; | 2745 | struct btrfs_root *root = block_group->fs_info->tree_root; |
| 2742 | struct inode *inode = NULL; | 2746 | struct inode *inode = NULL; |
| 2743 | u64 alloc_hint = 0; | 2747 | u64 alloc_hint = 0; |
| 2748 | int dcs = BTRFS_DC_ERROR; | ||
| 2744 | int num_pages = 0; | 2749 | int num_pages = 0; |
| 2745 | int retries = 0; | 2750 | int retries = 0; |
| 2746 | int ret = 0; | 2751 | int ret = 0; |
| @@ -2795,6 +2800,8 @@ again: | |||
| 2795 | 2800 | ||
| 2796 | spin_lock(&block_group->lock); | 2801 | spin_lock(&block_group->lock); |
| 2797 | if (block_group->cached != BTRFS_CACHE_FINISHED) { | 2802 | if (block_group->cached != BTRFS_CACHE_FINISHED) { |
| 2803 | /* We're not cached, don't bother trying to write stuff out */ | ||
| 2804 | dcs = BTRFS_DC_WRITTEN; | ||
| 2798 | spin_unlock(&block_group->lock); | 2805 | spin_unlock(&block_group->lock); |
| 2799 | goto out_put; | 2806 | goto out_put; |
| 2800 | } | 2807 | } |
| @@ -2821,6 +2828,8 @@ again: | |||
| 2821 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, | 2828 | ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, num_pages, |
| 2822 | num_pages, num_pages, | 2829 | num_pages, num_pages, |
| 2823 | &alloc_hint); | 2830 | &alloc_hint); |
| 2831 | if (!ret) | ||
| 2832 | dcs = BTRFS_DC_SETUP; | ||
| 2824 | btrfs_free_reserved_data_space(inode, num_pages); | 2833 | btrfs_free_reserved_data_space(inode, num_pages); |
| 2825 | out_put: | 2834 | out_put: |
| 2826 | iput(inode); | 2835 | iput(inode); |
| @@ -2828,10 +2837,7 @@ out_free: | |||
| 2828 | btrfs_release_path(root, path); | 2837 | btrfs_release_path(root, path); |
| 2829 | out: | 2838 | out: |
| 2830 | spin_lock(&block_group->lock); | 2839 | spin_lock(&block_group->lock); |
| 2831 | if (ret) | 2840 | block_group->disk_cache_state = dcs; |
| 2832 | block_group->disk_cache_state = BTRFS_DC_ERROR; | ||
| 2833 | else | ||
| 2834 | block_group->disk_cache_state = BTRFS_DC_SETUP; | ||
| 2835 | spin_unlock(&block_group->lock); | 2841 | spin_unlock(&block_group->lock); |
| 2836 | 2842 | ||
| 2837 | return ret; | 2843 | return ret; |
| @@ -3037,7 +3043,13 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags) | |||
| 3037 | 3043 | ||
| 3038 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) | 3044 | u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags) |
| 3039 | { | 3045 | { |
| 3040 | u64 num_devices = root->fs_info->fs_devices->rw_devices; | 3046 | /* |
| 3047 | * we add in the count of missing devices because we want | ||
| 3048 | * to make sure that any RAID levels on a degraded FS | ||
| 3049 | * continue to be honored. | ||
| 3050 | */ | ||
| 3051 | u64 num_devices = root->fs_info->fs_devices->rw_devices + | ||
| 3052 | root->fs_info->fs_devices->missing_devices; | ||
| 3041 | 3053 | ||
| 3042 | if (num_devices == 1) | 3054 | if (num_devices == 1) |
| 3043 | flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); | 3055 | flags &= ~(BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID0); |
| @@ -3412,7 +3424,7 @@ again: | |||
| 3412 | * our reservation. | 3424 | * our reservation. |
| 3413 | */ | 3425 | */ |
| 3414 | if (unused <= space_info->total_bytes) { | 3426 | if (unused <= space_info->total_bytes) { |
| 3415 | unused -= space_info->total_bytes; | 3427 | unused = space_info->total_bytes - unused; |
| 3416 | if (unused >= num_bytes) { | 3428 | if (unused >= num_bytes) { |
| 3417 | if (!reserved) | 3429 | if (!reserved) |
| 3418 | space_info->bytes_reserved += orig_bytes; | 3430 | space_info->bytes_reserved += orig_bytes; |
| @@ -4080,7 +4092,7 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
| 4080 | * space back to the block group, otherwise we will leak space. | 4092 | * space back to the block group, otherwise we will leak space. |
| 4081 | */ | 4093 | */ |
| 4082 | if (!alloc && cache->cached == BTRFS_CACHE_NO) | 4094 | if (!alloc && cache->cached == BTRFS_CACHE_NO) |
| 4083 | cache_block_group(cache, trans, 1); | 4095 | cache_block_group(cache, trans, NULL, 1); |
| 4084 | 4096 | ||
| 4085 | byte_in_group = bytenr - cache->key.objectid; | 4097 | byte_in_group = bytenr - cache->key.objectid; |
| 4086 | WARN_ON(byte_in_group > cache->key.offset); | 4098 | WARN_ON(byte_in_group > cache->key.offset); |
| @@ -4930,11 +4942,31 @@ search: | |||
| 4930 | btrfs_get_block_group(block_group); | 4942 | btrfs_get_block_group(block_group); |
| 4931 | search_start = block_group->key.objectid; | 4943 | search_start = block_group->key.objectid; |
| 4932 | 4944 | ||
| 4945 | /* | ||
| 4946 | * this can happen if we end up cycling through all the | ||
| 4947 | * raid types, but we want to make sure we only allocate | ||
| 4948 | * for the proper type. | ||
| 4949 | */ | ||
| 4950 | if (!block_group_bits(block_group, data)) { | ||
| 4951 | u64 extra = BTRFS_BLOCK_GROUP_DUP | | ||
| 4952 | BTRFS_BLOCK_GROUP_RAID1 | | ||
| 4953 | BTRFS_BLOCK_GROUP_RAID10; | ||
| 4954 | |||
| 4955 | /* | ||
| 4956 | * if they asked for extra copies and this block group | ||
| 4957 | * doesn't provide them, bail. This does allow us to | ||
| 4958 | * fill raid0 from raid1. | ||
| 4959 | */ | ||
| 4960 | if ((data & extra) && !(block_group->flags & extra)) | ||
| 4961 | goto loop; | ||
| 4962 | } | ||
| 4963 | |||
| 4933 | have_block_group: | 4964 | have_block_group: |
| 4934 | if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { | 4965 | if (unlikely(block_group->cached == BTRFS_CACHE_NO)) { |
| 4935 | u64 free_percent; | 4966 | u64 free_percent; |
| 4936 | 4967 | ||
| 4937 | ret = cache_block_group(block_group, trans, 1); | 4968 | ret = cache_block_group(block_group, trans, |
| 4969 | orig_root, 1); | ||
| 4938 | if (block_group->cached == BTRFS_CACHE_FINISHED) | 4970 | if (block_group->cached == BTRFS_CACHE_FINISHED) |
| 4939 | goto have_block_group; | 4971 | goto have_block_group; |
| 4940 | 4972 | ||
| @@ -4958,7 +4990,8 @@ have_block_group: | |||
| 4958 | if (loop > LOOP_CACHING_NOWAIT || | 4990 | if (loop > LOOP_CACHING_NOWAIT || |
| 4959 | (loop > LOOP_FIND_IDEAL && | 4991 | (loop > LOOP_FIND_IDEAL && |
| 4960 | atomic_read(&space_info->caching_threads) < 2)) { | 4992 | atomic_read(&space_info->caching_threads) < 2)) { |
| 4961 | ret = cache_block_group(block_group, trans, 0); | 4993 | ret = cache_block_group(block_group, trans, |
| 4994 | orig_root, 0); | ||
| 4962 | BUG_ON(ret); | 4995 | BUG_ON(ret); |
| 4963 | } | 4996 | } |
| 4964 | found_uncached_bg = true; | 4997 | found_uncached_bg = true; |
| @@ -5515,7 +5548,7 @@ int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans, | |||
| 5515 | u64 num_bytes = ins->offset; | 5548 | u64 num_bytes = ins->offset; |
| 5516 | 5549 | ||
| 5517 | block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); | 5550 | block_group = btrfs_lookup_block_group(root->fs_info, ins->objectid); |
| 5518 | cache_block_group(block_group, trans, 0); | 5551 | cache_block_group(block_group, trans, NULL, 0); |
| 5519 | caching_ctl = get_caching_control(block_group); | 5552 | caching_ctl = get_caching_control(block_group); |
| 5520 | 5553 | ||
| 5521 | if (!caching_ctl) { | 5554 | if (!caching_ctl) { |
| @@ -6300,9 +6333,13 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
| 6300 | NULL, NULL); | 6333 | NULL, NULL); |
| 6301 | BUG_ON(ret < 0); | 6334 | BUG_ON(ret < 0); |
| 6302 | if (ret > 0) { | 6335 | if (ret > 0) { |
| 6303 | ret = btrfs_del_orphan_item(trans, tree_root, | 6336 | /* if we fail to delete the orphan item this time |
| 6304 | root->root_key.objectid); | 6337 | * around, it'll get picked up the next time. |
| 6305 | BUG_ON(ret); | 6338 | * |
| 6339 | * The most common failure here is just -ENOENT. | ||
| 6340 | */ | ||
| 6341 | btrfs_del_orphan_item(trans, tree_root, | ||
| 6342 | root->root_key.objectid); | ||
| 6306 | } | 6343 | } |
| 6307 | } | 6344 | } |
| 6308 | 6345 | ||
| @@ -7878,7 +7915,14 @@ static u64 update_block_group_flags(struct btrfs_root *root, u64 flags) | |||
| 7878 | u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | | 7915 | u64 stripped = BTRFS_BLOCK_GROUP_RAID0 | |
| 7879 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; | 7916 | BTRFS_BLOCK_GROUP_RAID1 | BTRFS_BLOCK_GROUP_RAID10; |
| 7880 | 7917 | ||
| 7881 | num_devices = root->fs_info->fs_devices->rw_devices; | 7918 | /* |
| 7919 | * we add in the count of missing devices because we want | ||
| 7920 | * to make sure that any RAID levels on a degraded FS | ||
| 7921 | * continue to be honored. | ||
| 7922 | */ | ||
| 7923 | num_devices = root->fs_info->fs_devices->rw_devices + | ||
| 7924 | root->fs_info->fs_devices->missing_devices; | ||
| 7925 | |||
| 7882 | if (num_devices == 1) { | 7926 | if (num_devices == 1) { |
| 7883 | stripped |= BTRFS_BLOCK_GROUP_DUP; | 7927 | stripped |= BTRFS_BLOCK_GROUP_DUP; |
| 7884 | stripped = flags & ~stripped; | 7928 | stripped = flags & ~stripped; |
| @@ -8247,7 +8291,6 @@ int btrfs_read_block_groups(struct btrfs_root *root) | |||
| 8247 | break; | 8291 | break; |
| 8248 | if (ret != 0) | 8292 | if (ret != 0) |
| 8249 | goto error; | 8293 | goto error; |
| 8250 | |||
| 8251 | leaf = path->nodes[0]; | 8294 | leaf = path->nodes[0]; |
| 8252 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); | 8295 | btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]); |
| 8253 | cache = kzalloc(sizeof(*cache), GFP_NOFS); | 8296 | cache = kzalloc(sizeof(*cache), GFP_NOFS); |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index eac10e3260a9..3e86b9f36507 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
| @@ -1828,9 +1828,9 @@ static void end_bio_extent_preparewrite(struct bio *bio, int err) | |||
| 1828 | bio_put(bio); | 1828 | bio_put(bio); |
| 1829 | } | 1829 | } |
| 1830 | 1830 | ||
| 1831 | static struct bio * | 1831 | struct bio * |
| 1832 | extent_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | 1832 | btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, |
| 1833 | gfp_t gfp_flags) | 1833 | gfp_t gfp_flags) |
| 1834 | { | 1834 | { |
| 1835 | struct bio *bio; | 1835 | struct bio *bio; |
| 1836 | 1836 | ||
| @@ -1919,7 +1919,7 @@ static int submit_extent_page(int rw, struct extent_io_tree *tree, | |||
| 1919 | else | 1919 | else |
| 1920 | nr = bio_get_nr_vecs(bdev); | 1920 | nr = bio_get_nr_vecs(bdev); |
| 1921 | 1921 | ||
| 1922 | bio = extent_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH); | 1922 | bio = btrfs_bio_alloc(bdev, sector, nr, GFP_NOFS | __GFP_HIGH); |
| 1923 | 1923 | ||
| 1924 | bio_add_page(bio, page, page_size, offset); | 1924 | bio_add_page(bio, page, page_size, offset); |
| 1925 | bio->bi_end_io = end_io_func; | 1925 | bio->bi_end_io = end_io_func; |
| @@ -2901,21 +2901,53 @@ out: | |||
| 2901 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | 2901 | int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, |
| 2902 | __u64 start, __u64 len, get_extent_t *get_extent) | 2902 | __u64 start, __u64 len, get_extent_t *get_extent) |
| 2903 | { | 2903 | { |
| 2904 | int ret; | 2904 | int ret = 0; |
| 2905 | u64 off = start; | 2905 | u64 off = start; |
| 2906 | u64 max = start + len; | 2906 | u64 max = start + len; |
| 2907 | u32 flags = 0; | 2907 | u32 flags = 0; |
| 2908 | u32 found_type; | ||
| 2909 | u64 last; | ||
| 2908 | u64 disko = 0; | 2910 | u64 disko = 0; |
| 2911 | struct btrfs_key found_key; | ||
| 2909 | struct extent_map *em = NULL; | 2912 | struct extent_map *em = NULL; |
| 2910 | struct extent_state *cached_state = NULL; | 2913 | struct extent_state *cached_state = NULL; |
| 2914 | struct btrfs_path *path; | ||
| 2915 | struct btrfs_file_extent_item *item; | ||
| 2911 | int end = 0; | 2916 | int end = 0; |
| 2912 | u64 em_start = 0, em_len = 0; | 2917 | u64 em_start = 0, em_len = 0; |
| 2913 | unsigned long emflags; | 2918 | unsigned long emflags; |
| 2914 | ret = 0; | 2919 | int hole = 0; |
| 2915 | 2920 | ||
| 2916 | if (len == 0) | 2921 | if (len == 0) |
| 2917 | return -EINVAL; | 2922 | return -EINVAL; |
| 2918 | 2923 | ||
| 2924 | path = btrfs_alloc_path(); | ||
| 2925 | if (!path) | ||
| 2926 | return -ENOMEM; | ||
| 2927 | path->leave_spinning = 1; | ||
| 2928 | |||
| 2929 | ret = btrfs_lookup_file_extent(NULL, BTRFS_I(inode)->root, | ||
| 2930 | path, inode->i_ino, -1, 0); | ||
| 2931 | if (ret < 0) { | ||
| 2932 | btrfs_free_path(path); | ||
| 2933 | return ret; | ||
| 2934 | } | ||
| 2935 | WARN_ON(!ret); | ||
| 2936 | path->slots[0]--; | ||
| 2937 | item = btrfs_item_ptr(path->nodes[0], path->slots[0], | ||
| 2938 | struct btrfs_file_extent_item); | ||
| 2939 | btrfs_item_key_to_cpu(path->nodes[0], &found_key, path->slots[0]); | ||
| 2940 | found_type = btrfs_key_type(&found_key); | ||
| 2941 | |||
| 2942 | /* No extents, just return */ | ||
| 2943 | if (found_key.objectid != inode->i_ino || | ||
| 2944 | found_type != BTRFS_EXTENT_DATA_KEY) { | ||
| 2945 | btrfs_free_path(path); | ||
| 2946 | return 0; | ||
| 2947 | } | ||
| 2948 | last = found_key.offset; | ||
| 2949 | btrfs_free_path(path); | ||
| 2950 | |||
| 2919 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, | 2951 | lock_extent_bits(&BTRFS_I(inode)->io_tree, start, start + len, 0, |
| 2920 | &cached_state, GFP_NOFS); | 2952 | &cached_state, GFP_NOFS); |
| 2921 | em = get_extent(inode, NULL, 0, off, max - off, 0); | 2953 | em = get_extent(inode, NULL, 0, off, max - off, 0); |
| @@ -2925,11 +2957,18 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2925 | ret = PTR_ERR(em); | 2957 | ret = PTR_ERR(em); |
| 2926 | goto out; | 2958 | goto out; |
| 2927 | } | 2959 | } |
| 2960 | |||
| 2928 | while (!end) { | 2961 | while (!end) { |
| 2962 | hole = 0; | ||
| 2929 | off = em->start + em->len; | 2963 | off = em->start + em->len; |
| 2930 | if (off >= max) | 2964 | if (off >= max) |
| 2931 | end = 1; | 2965 | end = 1; |
| 2932 | 2966 | ||
| 2967 | if (em->block_start == EXTENT_MAP_HOLE) { | ||
| 2968 | hole = 1; | ||
| 2969 | goto next; | ||
| 2970 | } | ||
| 2971 | |||
| 2933 | em_start = em->start; | 2972 | em_start = em->start; |
| 2934 | em_len = em->len; | 2973 | em_len = em->len; |
| 2935 | 2974 | ||
| @@ -2939,8 +2978,6 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2939 | if (em->block_start == EXTENT_MAP_LAST_BYTE) { | 2978 | if (em->block_start == EXTENT_MAP_LAST_BYTE) { |
| 2940 | end = 1; | 2979 | end = 1; |
| 2941 | flags |= FIEMAP_EXTENT_LAST; | 2980 | flags |= FIEMAP_EXTENT_LAST; |
| 2942 | } else if (em->block_start == EXTENT_MAP_HOLE) { | ||
| 2943 | flags |= FIEMAP_EXTENT_UNWRITTEN; | ||
| 2944 | } else if (em->block_start == EXTENT_MAP_INLINE) { | 2981 | } else if (em->block_start == EXTENT_MAP_INLINE) { |
| 2945 | flags |= (FIEMAP_EXTENT_DATA_INLINE | | 2982 | flags |= (FIEMAP_EXTENT_DATA_INLINE | |
| 2946 | FIEMAP_EXTENT_NOT_ALIGNED); | 2983 | FIEMAP_EXTENT_NOT_ALIGNED); |
| @@ -2953,10 +2990,10 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2953 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) | 2990 | if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) |
| 2954 | flags |= FIEMAP_EXTENT_ENCODED; | 2991 | flags |= FIEMAP_EXTENT_ENCODED; |
| 2955 | 2992 | ||
| 2993 | next: | ||
| 2956 | emflags = em->flags; | 2994 | emflags = em->flags; |
| 2957 | free_extent_map(em); | 2995 | free_extent_map(em); |
| 2958 | em = NULL; | 2996 | em = NULL; |
| 2959 | |||
| 2960 | if (!end) { | 2997 | if (!end) { |
| 2961 | em = get_extent(inode, NULL, 0, off, max - off, 0); | 2998 | em = get_extent(inode, NULL, 0, off, max - off, 0); |
| 2962 | if (!em) | 2999 | if (!em) |
| @@ -2967,15 +3004,23 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, | |||
| 2967 | } | 3004 | } |
| 2968 | emflags = em->flags; | 3005 | emflags = em->flags; |
| 2969 | } | 3006 | } |
| 3007 | |||
| 2970 | if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { | 3008 | if (test_bit(EXTENT_FLAG_VACANCY, &emflags)) { |
| 2971 | flags |= FIEMAP_EXTENT_LAST; | 3009 | flags |= FIEMAP_EXTENT_LAST; |
| 2972 | end = 1; | 3010 | end = 1; |
| 2973 | } | 3011 | } |
| 2974 | 3012 | ||
| 2975 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | 3013 | if (em_start == last) { |
| 2976 | em_len, flags); | 3014 | flags |= FIEMAP_EXTENT_LAST; |
| 2977 | if (ret) | 3015 | end = 1; |
| 2978 | goto out_free; | 3016 | } |
| 3017 | |||
| 3018 | if (!hole) { | ||
| 3019 | ret = fiemap_fill_next_extent(fieinfo, em_start, disko, | ||
| 3020 | em_len, flags); | ||
| 3021 | if (ret) | ||
| 3022 | goto out_free; | ||
| 3023 | } | ||
| 2979 | } | 3024 | } |
| 2980 | out_free: | 3025 | out_free: |
| 2981 | free_extent_map(em); | 3026 | free_extent_map(em); |
| @@ -3836,8 +3881,10 @@ int try_release_extent_buffer(struct extent_io_tree *tree, struct page *page) | |||
| 3836 | 3881 | ||
| 3837 | spin_lock(&tree->buffer_lock); | 3882 | spin_lock(&tree->buffer_lock); |
| 3838 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); | 3883 | eb = radix_tree_lookup(&tree->buffer, start >> PAGE_CACHE_SHIFT); |
| 3839 | if (!eb) | 3884 | if (!eb) { |
| 3840 | goto out; | 3885 | spin_unlock(&tree->buffer_lock); |
| 3886 | return ret; | ||
| 3887 | } | ||
| 3841 | 3888 | ||
| 3842 | if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { | 3889 | if (test_bit(EXTENT_BUFFER_DIRTY, &eb->bflags)) { |
| 3843 | ret = 0; | 3890 | ret = 0; |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 1c6d4f342ef7..4183c8178f01 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
| @@ -310,4 +310,7 @@ int extent_clear_unlock_delalloc(struct inode *inode, | |||
| 310 | struct extent_io_tree *tree, | 310 | struct extent_io_tree *tree, |
| 311 | u64 start, u64 end, struct page *locked_page, | 311 | u64 start, u64 end, struct page *locked_page, |
| 312 | unsigned long op); | 312 | unsigned long op); |
| 313 | struct bio * | ||
| 314 | btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, | ||
| 315 | gfp_t gfp_flags); | ||
| 313 | #endif | 316 | #endif |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index e354c33df082..66836d85763b 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -48,30 +48,34 @@ static noinline int btrfs_copy_from_user(loff_t pos, int num_pages, | |||
| 48 | struct page **prepared_pages, | 48 | struct page **prepared_pages, |
| 49 | struct iov_iter *i) | 49 | struct iov_iter *i) |
| 50 | { | 50 | { |
| 51 | size_t copied; | 51 | size_t copied = 0; |
| 52 | int pg = 0; | 52 | int pg = 0; |
| 53 | int offset = pos & (PAGE_CACHE_SIZE - 1); | 53 | int offset = pos & (PAGE_CACHE_SIZE - 1); |
| 54 | int total_copied = 0; | ||
| 54 | 55 | ||
| 55 | while (write_bytes > 0) { | 56 | while (write_bytes > 0) { |
| 56 | size_t count = min_t(size_t, | 57 | size_t count = min_t(size_t, |
| 57 | PAGE_CACHE_SIZE - offset, write_bytes); | 58 | PAGE_CACHE_SIZE - offset, write_bytes); |
| 58 | struct page *page = prepared_pages[pg]; | 59 | struct page *page = prepared_pages[pg]; |
| 59 | again: | 60 | /* |
| 60 | if (unlikely(iov_iter_fault_in_readable(i, count))) | 61 | * Copy data from userspace to the current page |
| 61 | return -EFAULT; | 62 | * |
| 62 | 63 | * Disable pagefault to avoid recursive lock since | |
| 63 | /* Copy data from userspace to the current page */ | 64 | * the pages are already locked |
| 64 | copied = iov_iter_copy_from_user(page, i, offset, count); | 65 | */ |
| 66 | pagefault_disable(); | ||
| 67 | copied = iov_iter_copy_from_user_atomic(page, i, offset, count); | ||
| 68 | pagefault_enable(); | ||
| 65 | 69 | ||
| 66 | /* Flush processor's dcache for this page */ | 70 | /* Flush processor's dcache for this page */ |
| 67 | flush_dcache_page(page); | 71 | flush_dcache_page(page); |
| 68 | iov_iter_advance(i, copied); | 72 | iov_iter_advance(i, copied); |
| 69 | write_bytes -= copied; | 73 | write_bytes -= copied; |
| 74 | total_copied += copied; | ||
| 70 | 75 | ||
| 76 | /* Return to btrfs_file_aio_write to fault page */ | ||
| 71 | if (unlikely(copied == 0)) { | 77 | if (unlikely(copied == 0)) { |
| 72 | count = min_t(size_t, PAGE_CACHE_SIZE - offset, | 78 | break; |
| 73 | iov_iter_single_seg_count(i)); | ||
| 74 | goto again; | ||
| 75 | } | 79 | } |
| 76 | 80 | ||
| 77 | if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { | 81 | if (unlikely(copied < PAGE_CACHE_SIZE - offset)) { |
| @@ -81,7 +85,7 @@ again: | |||
| 81 | offset = 0; | 85 | offset = 0; |
| 82 | } | 86 | } |
| 83 | } | 87 | } |
| 84 | return 0; | 88 | return total_copied; |
| 85 | } | 89 | } |
| 86 | 90 | ||
| 87 | /* | 91 | /* |
| @@ -854,6 +858,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 854 | unsigned long last_index; | 858 | unsigned long last_index; |
| 855 | int will_write; | 859 | int will_write; |
| 856 | int buffered = 0; | 860 | int buffered = 0; |
| 861 | int copied = 0; | ||
| 862 | int dirty_pages = 0; | ||
| 857 | 863 | ||
| 858 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || | 864 | will_write = ((file->f_flags & O_DSYNC) || IS_SYNC(inode) || |
| 859 | (file->f_flags & O_DIRECT)); | 865 | (file->f_flags & O_DIRECT)); |
| @@ -970,7 +976,17 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 970 | WARN_ON(num_pages > nrptrs); | 976 | WARN_ON(num_pages > nrptrs); |
| 971 | memset(pages, 0, sizeof(struct page *) * nrptrs); | 977 | memset(pages, 0, sizeof(struct page *) * nrptrs); |
| 972 | 978 | ||
| 973 | ret = btrfs_delalloc_reserve_space(inode, write_bytes); | 979 | /* |
| 980 | * Fault pages before locking them in prepare_pages | ||
| 981 | * to avoid recursive lock | ||
| 982 | */ | ||
| 983 | if (unlikely(iov_iter_fault_in_readable(&i, write_bytes))) { | ||
| 984 | ret = -EFAULT; | ||
| 985 | goto out; | ||
| 986 | } | ||
| 987 | |||
| 988 | ret = btrfs_delalloc_reserve_space(inode, | ||
| 989 | num_pages << PAGE_CACHE_SHIFT); | ||
| 974 | if (ret) | 990 | if (ret) |
| 975 | goto out; | 991 | goto out; |
| 976 | 992 | ||
| @@ -978,37 +994,49 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb, | |||
| 978 | pos, first_index, last_index, | 994 | pos, first_index, last_index, |
| 979 | write_bytes); | 995 | write_bytes); |
| 980 | if (ret) { | 996 | if (ret) { |
| 981 | btrfs_delalloc_release_space(inode, write_bytes); | 997 | btrfs_delalloc_release_space(inode, |
| 998 | num_pages << PAGE_CACHE_SHIFT); | ||
| 982 | goto out; | 999 | goto out; |
| 983 | } | 1000 | } |
| 984 | 1001 | ||
| 985 | ret = btrfs_copy_from_user(pos, num_pages, | 1002 | copied = btrfs_copy_from_user(pos, num_pages, |
| 986 | write_bytes, pages, &i); | 1003 | write_bytes, pages, &i); |
| 987 | if (ret == 0) { | 1004 | dirty_pages = (copied + PAGE_CACHE_SIZE - 1) >> |
| 1005 | PAGE_CACHE_SHIFT; | ||
| 1006 | |||
| 1007 | if (num_pages > dirty_pages) { | ||
| 1008 | if (copied > 0) | ||
| 1009 | atomic_inc( | ||
| 1010 | &BTRFS_I(inode)->outstanding_extents); | ||
| 1011 | btrfs_delalloc_release_space(inode, | ||
| 1012 | (num_pages - dirty_pages) << | ||
| 1013 | PAGE_CACHE_SHIFT); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | if (copied > 0) { | ||
| 988 | dirty_and_release_pages(NULL, root, file, pages, | 1017 | dirty_and_release_pages(NULL, root, file, pages, |
| 989 | num_pages, pos, write_bytes); | 1018 | dirty_pages, pos, copied); |
| 990 | } | 1019 | } |
| 991 | 1020 | ||
| 992 | btrfs_drop_pages(pages, num_pages); | 1021 | btrfs_drop_pages(pages, num_pages); |
| 993 | if (ret) { | ||
| 994 | btrfs_delalloc_release_space(inode, write_bytes); | ||
| 995 | goto out; | ||
| 996 | } | ||
| 997 | 1022 | ||
| 998 | if (will_write) { | 1023 | if (copied > 0) { |
| 999 | filemap_fdatawrite_range(inode->i_mapping, pos, | 1024 | if (will_write) { |
| 1000 | pos + write_bytes - 1); | 1025 | filemap_fdatawrite_range(inode->i_mapping, pos, |
| 1001 | } else { | 1026 | pos + copied - 1); |
| 1002 | balance_dirty_pages_ratelimited_nr(inode->i_mapping, | 1027 | } else { |
| 1003 | num_pages); | 1028 | balance_dirty_pages_ratelimited_nr( |
| 1004 | if (num_pages < | 1029 | inode->i_mapping, |
| 1005 | (root->leafsize >> PAGE_CACHE_SHIFT) + 1) | 1030 | dirty_pages); |
| 1006 | btrfs_btree_balance_dirty(root, 1); | 1031 | if (dirty_pages < |
| 1007 | btrfs_throttle(root); | 1032 | (root->leafsize >> PAGE_CACHE_SHIFT) + 1) |
| 1033 | btrfs_btree_balance_dirty(root, 1); | ||
| 1034 | btrfs_throttle(root); | ||
| 1035 | } | ||
| 1008 | } | 1036 | } |
| 1009 | 1037 | ||
| 1010 | pos += write_bytes; | 1038 | pos += copied; |
| 1011 | num_written += write_bytes; | 1039 | num_written += copied; |
| 1012 | 1040 | ||
| 1013 | cond_resched(); | 1041 | cond_resched(); |
| 1014 | } | 1042 | } |
| @@ -1047,8 +1075,14 @@ out: | |||
| 1047 | 1075 | ||
| 1048 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { | 1076 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { |
| 1049 | trans = btrfs_start_transaction(root, 0); | 1077 | trans = btrfs_start_transaction(root, 0); |
| 1078 | if (IS_ERR(trans)) { | ||
| 1079 | num_written = PTR_ERR(trans); | ||
| 1080 | goto done; | ||
| 1081 | } | ||
| 1082 | mutex_lock(&inode->i_mutex); | ||
| 1050 | ret = btrfs_log_dentry_safe(trans, root, | 1083 | ret = btrfs_log_dentry_safe(trans, root, |
| 1051 | file->f_dentry); | 1084 | file->f_dentry); |
| 1085 | mutex_unlock(&inode->i_mutex); | ||
| 1052 | if (ret == 0) { | 1086 | if (ret == 0) { |
| 1053 | ret = btrfs_sync_log(trans, root); | 1087 | ret = btrfs_sync_log(trans, root); |
| 1054 | if (ret == 0) | 1088 | if (ret == 0) |
| @@ -1067,6 +1101,7 @@ out: | |||
| 1067 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); | 1101 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); |
| 1068 | } | 1102 | } |
| 1069 | } | 1103 | } |
| 1104 | done: | ||
| 1070 | current->backing_dev_info = NULL; | 1105 | current->backing_dev_info = NULL; |
| 1071 | return num_written ? num_written : err; | 1106 | return num_written ? num_written : err; |
| 1072 | } | 1107 | } |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 22ee0dc2e6b8..60d684266959 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -290,7 +290,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
| 290 | (unsigned long long)BTRFS_I(inode)->generation, | 290 | (unsigned long long)BTRFS_I(inode)->generation, |
| 291 | (unsigned long long)generation, | 291 | (unsigned long long)generation, |
| 292 | (unsigned long long)block_group->key.objectid); | 292 | (unsigned long long)block_group->key.objectid); |
| 293 | goto out; | 293 | goto free_cache; |
| 294 | } | 294 | } |
| 295 | 295 | ||
| 296 | if (!num_entries) | 296 | if (!num_entries) |
| @@ -524,6 +524,12 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 524 | return 0; | 524 | return 0; |
| 525 | } | 525 | } |
| 526 | 526 | ||
| 527 | node = rb_first(&block_group->free_space_offset); | ||
| 528 | if (!node) { | ||
| 529 | iput(inode); | ||
| 530 | return 0; | ||
| 531 | } | ||
| 532 | |||
| 527 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; | 533 | last_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT; |
| 528 | filemap_write_and_wait(inode->i_mapping); | 534 | filemap_write_and_wait(inode->i_mapping); |
| 529 | btrfs_wait_ordered_range(inode, inode->i_size & | 535 | btrfs_wait_ordered_range(inode, inode->i_size & |
| @@ -543,10 +549,6 @@ int btrfs_write_out_cache(struct btrfs_root *root, | |||
| 543 | */ | 549 | */ |
| 544 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); | 550 | first_page_offset = (sizeof(u32) * num_checksums) + sizeof(u64); |
| 545 | 551 | ||
| 546 | node = rb_first(&block_group->free_space_offset); | ||
| 547 | if (!node) | ||
| 548 | goto out_free; | ||
| 549 | |||
| 550 | /* | 552 | /* |
| 551 | * Lock all pages first so we can lock the extent safely. | 553 | * Lock all pages first so we can lock the extent safely. |
| 552 | * | 554 | * |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 558cac2dfa54..72f31ecb5c90 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -495,7 +495,7 @@ again: | |||
| 495 | add_async_extent(async_cow, start, num_bytes, | 495 | add_async_extent(async_cow, start, num_bytes, |
| 496 | total_compressed, pages, nr_pages_ret); | 496 | total_compressed, pages, nr_pages_ret); |
| 497 | 497 | ||
| 498 | if (start + num_bytes < end && start + num_bytes < actual_end) { | 498 | if (start + num_bytes < end) { |
| 499 | start += num_bytes; | 499 | start += num_bytes; |
| 500 | pages = NULL; | 500 | pages = NULL; |
| 501 | cond_resched(); | 501 | cond_resched(); |
| @@ -4501,6 +4501,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
| 4501 | BTRFS_I(inode)->index_cnt = 2; | 4501 | BTRFS_I(inode)->index_cnt = 2; |
| 4502 | BTRFS_I(inode)->root = root; | 4502 | BTRFS_I(inode)->root = root; |
| 4503 | BTRFS_I(inode)->generation = trans->transid; | 4503 | BTRFS_I(inode)->generation = trans->transid; |
| 4504 | inode->i_generation = BTRFS_I(inode)->generation; | ||
| 4504 | btrfs_set_inode_space_info(root, inode); | 4505 | btrfs_set_inode_space_info(root, inode); |
| 4505 | 4506 | ||
| 4506 | if (mode & S_IFDIR) | 4507 | if (mode & S_IFDIR) |
| @@ -4622,12 +4623,12 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
| 4622 | } | 4623 | } |
| 4623 | 4624 | ||
| 4624 | static int btrfs_add_nondir(struct btrfs_trans_handle *trans, | 4625 | static int btrfs_add_nondir(struct btrfs_trans_handle *trans, |
| 4625 | struct dentry *dentry, struct inode *inode, | 4626 | struct inode *dir, struct dentry *dentry, |
| 4626 | int backref, u64 index) | 4627 | struct inode *inode, int backref, u64 index) |
| 4627 | { | 4628 | { |
| 4628 | int err = btrfs_add_link(trans, dentry->d_parent->d_inode, | 4629 | int err = btrfs_add_link(trans, dir, inode, |
| 4629 | inode, dentry->d_name.name, | 4630 | dentry->d_name.name, dentry->d_name.len, |
| 4630 | dentry->d_name.len, backref, index); | 4631 | backref, index); |
| 4631 | if (!err) { | 4632 | if (!err) { |
| 4632 | d_instantiate(dentry, inode); | 4633 | d_instantiate(dentry, inode); |
| 4633 | return 0; | 4634 | return 0; |
| @@ -4668,8 +4669,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 4668 | btrfs_set_trans_block_group(trans, dir); | 4669 | btrfs_set_trans_block_group(trans, dir); |
| 4669 | 4670 | ||
| 4670 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4671 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4671 | dentry->d_name.len, | 4672 | dentry->d_name.len, dir->i_ino, objectid, |
| 4672 | dentry->d_parent->d_inode->i_ino, objectid, | ||
| 4673 | BTRFS_I(dir)->block_group, mode, &index); | 4673 | BTRFS_I(dir)->block_group, mode, &index); |
| 4674 | err = PTR_ERR(inode); | 4674 | err = PTR_ERR(inode); |
| 4675 | if (IS_ERR(inode)) | 4675 | if (IS_ERR(inode)) |
| @@ -4682,7 +4682,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry, | |||
| 4682 | } | 4682 | } |
| 4683 | 4683 | ||
| 4684 | btrfs_set_trans_block_group(trans, inode); | 4684 | btrfs_set_trans_block_group(trans, inode); |
| 4685 | err = btrfs_add_nondir(trans, dentry, inode, 0, index); | 4685 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 4686 | if (err) | 4686 | if (err) |
| 4687 | drop_inode = 1; | 4687 | drop_inode = 1; |
| 4688 | else { | 4688 | else { |
| @@ -4730,10 +4730,8 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 4730 | btrfs_set_trans_block_group(trans, dir); | 4730 | btrfs_set_trans_block_group(trans, dir); |
| 4731 | 4731 | ||
| 4732 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4732 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4733 | dentry->d_name.len, | 4733 | dentry->d_name.len, dir->i_ino, objectid, |
| 4734 | dentry->d_parent->d_inode->i_ino, | 4734 | BTRFS_I(dir)->block_group, mode, &index); |
| 4735 | objectid, BTRFS_I(dir)->block_group, mode, | ||
| 4736 | &index); | ||
| 4737 | err = PTR_ERR(inode); | 4735 | err = PTR_ERR(inode); |
| 4738 | if (IS_ERR(inode)) | 4736 | if (IS_ERR(inode)) |
| 4739 | goto out_unlock; | 4737 | goto out_unlock; |
| @@ -4745,7 +4743,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry, | |||
| 4745 | } | 4743 | } |
| 4746 | 4744 | ||
| 4747 | btrfs_set_trans_block_group(trans, inode); | 4745 | btrfs_set_trans_block_group(trans, inode); |
| 4748 | err = btrfs_add_nondir(trans, dentry, inode, 0, index); | 4746 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 4749 | if (err) | 4747 | if (err) |
| 4750 | drop_inode = 1; | 4748 | drop_inode = 1; |
| 4751 | else { | 4749 | else { |
| @@ -4787,6 +4785,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 4787 | return -EPERM; | 4785 | return -EPERM; |
| 4788 | 4786 | ||
| 4789 | btrfs_inc_nlink(inode); | 4787 | btrfs_inc_nlink(inode); |
| 4788 | inode->i_ctime = CURRENT_TIME; | ||
| 4790 | 4789 | ||
| 4791 | err = btrfs_set_inode_index(dir, &index); | 4790 | err = btrfs_set_inode_index(dir, &index); |
| 4792 | if (err) | 4791 | if (err) |
| @@ -4805,15 +4804,17 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
| 4805 | btrfs_set_trans_block_group(trans, dir); | 4804 | btrfs_set_trans_block_group(trans, dir); |
| 4806 | ihold(inode); | 4805 | ihold(inode); |
| 4807 | 4806 | ||
| 4808 | err = btrfs_add_nondir(trans, dentry, inode, 1, index); | 4807 | err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index); |
| 4809 | 4808 | ||
| 4810 | if (err) { | 4809 | if (err) { |
| 4811 | drop_inode = 1; | 4810 | drop_inode = 1; |
| 4812 | } else { | 4811 | } else { |
| 4812 | struct dentry *parent = dget_parent(dentry); | ||
| 4813 | btrfs_update_inode_block_group(trans, dir); | 4813 | btrfs_update_inode_block_group(trans, dir); |
| 4814 | err = btrfs_update_inode(trans, root, inode); | 4814 | err = btrfs_update_inode(trans, root, inode); |
| 4815 | BUG_ON(err); | 4815 | BUG_ON(err); |
| 4816 | btrfs_log_new_name(trans, inode, NULL, dentry->d_parent); | 4816 | btrfs_log_new_name(trans, inode, NULL, parent); |
| 4817 | dput(parent); | ||
| 4817 | } | 4818 | } |
| 4818 | 4819 | ||
| 4819 | nr = trans->blocks_used; | 4820 | nr = trans->blocks_used; |
| @@ -4853,8 +4854,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 4853 | btrfs_set_trans_block_group(trans, dir); | 4854 | btrfs_set_trans_block_group(trans, dir); |
| 4854 | 4855 | ||
| 4855 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 4856 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 4856 | dentry->d_name.len, | 4857 | dentry->d_name.len, dir->i_ino, objectid, |
| 4857 | dentry->d_parent->d_inode->i_ino, objectid, | ||
| 4858 | BTRFS_I(dir)->block_group, S_IFDIR | mode, | 4858 | BTRFS_I(dir)->block_group, S_IFDIR | mode, |
| 4859 | &index); | 4859 | &index); |
| 4860 | if (IS_ERR(inode)) { | 4860 | if (IS_ERR(inode)) { |
| @@ -4877,9 +4877,8 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
| 4877 | if (err) | 4877 | if (err) |
| 4878 | goto out_fail; | 4878 | goto out_fail; |
| 4879 | 4879 | ||
| 4880 | err = btrfs_add_link(trans, dentry->d_parent->d_inode, | 4880 | err = btrfs_add_link(trans, dir, inode, dentry->d_name.name, |
| 4881 | inode, dentry->d_name.name, | 4881 | dentry->d_name.len, 0, index); |
| 4882 | dentry->d_name.len, 0, index); | ||
| 4883 | if (err) | 4882 | if (err) |
| 4884 | goto out_fail; | 4883 | goto out_fail; |
| 4885 | 4884 | ||
| @@ -5535,13 +5534,21 @@ struct btrfs_dio_private { | |||
| 5535 | u64 bytes; | 5534 | u64 bytes; |
| 5536 | u32 *csums; | 5535 | u32 *csums; |
| 5537 | void *private; | 5536 | void *private; |
| 5537 | |||
| 5538 | /* number of bios pending for this dio */ | ||
| 5539 | atomic_t pending_bios; | ||
| 5540 | |||
| 5541 | /* IO errors */ | ||
| 5542 | int errors; | ||
| 5543 | |||
| 5544 | struct bio *orig_bio; | ||
| 5538 | }; | 5545 | }; |
| 5539 | 5546 | ||
| 5540 | static void btrfs_endio_direct_read(struct bio *bio, int err) | 5547 | static void btrfs_endio_direct_read(struct bio *bio, int err) |
| 5541 | { | 5548 | { |
| 5549 | struct btrfs_dio_private *dip = bio->bi_private; | ||
| 5542 | struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; | 5550 | struct bio_vec *bvec_end = bio->bi_io_vec + bio->bi_vcnt - 1; |
| 5543 | struct bio_vec *bvec = bio->bi_io_vec; | 5551 | struct bio_vec *bvec = bio->bi_io_vec; |
| 5544 | struct btrfs_dio_private *dip = bio->bi_private; | ||
| 5545 | struct inode *inode = dip->inode; | 5552 | struct inode *inode = dip->inode; |
| 5546 | struct btrfs_root *root = BTRFS_I(inode)->root; | 5553 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 5547 | u64 start; | 5554 | u64 start; |
| @@ -5595,15 +5602,18 @@ static void btrfs_endio_direct_write(struct bio *bio, int err) | |||
| 5595 | struct btrfs_trans_handle *trans; | 5602 | struct btrfs_trans_handle *trans; |
| 5596 | struct btrfs_ordered_extent *ordered = NULL; | 5603 | struct btrfs_ordered_extent *ordered = NULL; |
| 5597 | struct extent_state *cached_state = NULL; | 5604 | struct extent_state *cached_state = NULL; |
| 5605 | u64 ordered_offset = dip->logical_offset; | ||
| 5606 | u64 ordered_bytes = dip->bytes; | ||
| 5598 | int ret; | 5607 | int ret; |
| 5599 | 5608 | ||
| 5600 | if (err) | 5609 | if (err) |
| 5601 | goto out_done; | 5610 | goto out_done; |
| 5602 | 5611 | again: | |
| 5603 | ret = btrfs_dec_test_ordered_pending(inode, &ordered, | 5612 | ret = btrfs_dec_test_first_ordered_pending(inode, &ordered, |
| 5604 | dip->logical_offset, dip->bytes); | 5613 | &ordered_offset, |
| 5614 | ordered_bytes); | ||
| 5605 | if (!ret) | 5615 | if (!ret) |
| 5606 | goto out_done; | 5616 | goto out_test; |
| 5607 | 5617 | ||
| 5608 | BUG_ON(!ordered); | 5618 | BUG_ON(!ordered); |
| 5609 | 5619 | ||
| @@ -5663,8 +5673,20 @@ out_unlock: | |||
| 5663 | out: | 5673 | out: |
| 5664 | btrfs_delalloc_release_metadata(inode, ordered->len); | 5674 | btrfs_delalloc_release_metadata(inode, ordered->len); |
| 5665 | btrfs_end_transaction(trans, root); | 5675 | btrfs_end_transaction(trans, root); |
| 5676 | ordered_offset = ordered->file_offset + ordered->len; | ||
| 5666 | btrfs_put_ordered_extent(ordered); | 5677 | btrfs_put_ordered_extent(ordered); |
| 5667 | btrfs_put_ordered_extent(ordered); | 5678 | btrfs_put_ordered_extent(ordered); |
| 5679 | |||
| 5680 | out_test: | ||
| 5681 | /* | ||
| 5682 | * our bio might span multiple ordered extents. If we haven't | ||
| 5683 | * completed the accounting for the whole dio, go back and try again | ||
| 5684 | */ | ||
| 5685 | if (ordered_offset < dip->logical_offset + dip->bytes) { | ||
| 5686 | ordered_bytes = dip->logical_offset + dip->bytes - | ||
| 5687 | ordered_offset; | ||
| 5688 | goto again; | ||
| 5689 | } | ||
| 5668 | out_done: | 5690 | out_done: |
| 5669 | bio->bi_private = dip->private; | 5691 | bio->bi_private = dip->private; |
| 5670 | 5692 | ||
| @@ -5684,6 +5706,176 @@ static int __btrfs_submit_bio_start_direct_io(struct inode *inode, int rw, | |||
| 5684 | return 0; | 5706 | return 0; |
| 5685 | } | 5707 | } |
| 5686 | 5708 | ||
| 5709 | static void btrfs_end_dio_bio(struct bio *bio, int err) | ||
| 5710 | { | ||
| 5711 | struct btrfs_dio_private *dip = bio->bi_private; | ||
| 5712 | |||
| 5713 | if (err) { | ||
| 5714 | printk(KERN_ERR "btrfs direct IO failed ino %lu rw %lu " | ||
| 5715 | "sector %#Lx len %u err no %d\n", | ||
| 5716 | dip->inode->i_ino, bio->bi_rw, | ||
| 5717 | (unsigned long long)bio->bi_sector, bio->bi_size, err); | ||
| 5718 | dip->errors = 1; | ||
| 5719 | |||
| 5720 | /* | ||
| 5721 | * before atomic variable goto zero, we must make sure | ||
| 5722 | * dip->errors is perceived to be set. | ||
| 5723 | */ | ||
| 5724 | smp_mb__before_atomic_dec(); | ||
| 5725 | } | ||
| 5726 | |||
| 5727 | /* if there are more bios still pending for this dio, just exit */ | ||
| 5728 | if (!atomic_dec_and_test(&dip->pending_bios)) | ||
| 5729 | goto out; | ||
| 5730 | |||
| 5731 | if (dip->errors) | ||
| 5732 | bio_io_error(dip->orig_bio); | ||
| 5733 | else { | ||
| 5734 | set_bit(BIO_UPTODATE, &dip->orig_bio->bi_flags); | ||
| 5735 | bio_endio(dip->orig_bio, 0); | ||
| 5736 | } | ||
| 5737 | out: | ||
| 5738 | bio_put(bio); | ||
| 5739 | } | ||
| 5740 | |||
| 5741 | static struct bio *btrfs_dio_bio_alloc(struct block_device *bdev, | ||
| 5742 | u64 first_sector, gfp_t gfp_flags) | ||
| 5743 | { | ||
| 5744 | int nr_vecs = bio_get_nr_vecs(bdev); | ||
| 5745 | return btrfs_bio_alloc(bdev, first_sector, nr_vecs, gfp_flags); | ||
| 5746 | } | ||
| 5747 | |||
| 5748 | static inline int __btrfs_submit_dio_bio(struct bio *bio, struct inode *inode, | ||
| 5749 | int rw, u64 file_offset, int skip_sum, | ||
| 5750 | u32 *csums) | ||
| 5751 | { | ||
| 5752 | int write = rw & REQ_WRITE; | ||
| 5753 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 5754 | int ret; | ||
| 5755 | |||
| 5756 | bio_get(bio); | ||
| 5757 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); | ||
| 5758 | if (ret) | ||
| 5759 | goto err; | ||
| 5760 | |||
| 5761 | if (write && !skip_sum) { | ||
| 5762 | ret = btrfs_wq_submit_bio(root->fs_info, | ||
| 5763 | inode, rw, bio, 0, 0, | ||
| 5764 | file_offset, | ||
| 5765 | __btrfs_submit_bio_start_direct_io, | ||
| 5766 | __btrfs_submit_bio_done); | ||
| 5767 | goto err; | ||
| 5768 | } else if (!skip_sum) | ||
| 5769 | btrfs_lookup_bio_sums_dio(root, inode, bio, | ||
| 5770 | file_offset, csums); | ||
| 5771 | |||
| 5772 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | ||
| 5773 | err: | ||
| 5774 | bio_put(bio); | ||
| 5775 | return ret; | ||
| 5776 | } | ||
| 5777 | |||
| 5778 | static int btrfs_submit_direct_hook(int rw, struct btrfs_dio_private *dip, | ||
| 5779 | int skip_sum) | ||
| 5780 | { | ||
| 5781 | struct inode *inode = dip->inode; | ||
| 5782 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
| 5783 | struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; | ||
| 5784 | struct bio *bio; | ||
| 5785 | struct bio *orig_bio = dip->orig_bio; | ||
| 5786 | struct bio_vec *bvec = orig_bio->bi_io_vec; | ||
| 5787 | u64 start_sector = orig_bio->bi_sector; | ||
| 5788 | u64 file_offset = dip->logical_offset; | ||
| 5789 | u64 submit_len = 0; | ||
| 5790 | u64 map_length; | ||
| 5791 | int nr_pages = 0; | ||
| 5792 | u32 *csums = dip->csums; | ||
| 5793 | int ret = 0; | ||
| 5794 | |||
| 5795 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, start_sector, GFP_NOFS); | ||
| 5796 | if (!bio) | ||
| 5797 | return -ENOMEM; | ||
| 5798 | bio->bi_private = dip; | ||
| 5799 | bio->bi_end_io = btrfs_end_dio_bio; | ||
| 5800 | atomic_inc(&dip->pending_bios); | ||
| 5801 | |||
| 5802 | map_length = orig_bio->bi_size; | ||
| 5803 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | ||
| 5804 | &map_length, NULL, 0); | ||
| 5805 | if (ret) { | ||
| 5806 | bio_put(bio); | ||
| 5807 | return -EIO; | ||
| 5808 | } | ||
| 5809 | |||
| 5810 | while (bvec <= (orig_bio->bi_io_vec + orig_bio->bi_vcnt - 1)) { | ||
| 5811 | if (unlikely(map_length < submit_len + bvec->bv_len || | ||
| 5812 | bio_add_page(bio, bvec->bv_page, bvec->bv_len, | ||
| 5813 | bvec->bv_offset) < bvec->bv_len)) { | ||
| 5814 | /* | ||
| 5815 | * inc the count before we submit the bio so | ||
| 5816 | * we know the end IO handler won't happen before | ||
| 5817 | * we inc the count. Otherwise, the dip might get freed | ||
| 5818 | * before we're done setting it up | ||
| 5819 | */ | ||
| 5820 | atomic_inc(&dip->pending_bios); | ||
| 5821 | ret = __btrfs_submit_dio_bio(bio, inode, rw, | ||
| 5822 | file_offset, skip_sum, | ||
| 5823 | csums); | ||
| 5824 | if (ret) { | ||
| 5825 | bio_put(bio); | ||
| 5826 | atomic_dec(&dip->pending_bios); | ||
| 5827 | goto out_err; | ||
| 5828 | } | ||
| 5829 | |||
| 5830 | if (!skip_sum) | ||
| 5831 | csums = csums + nr_pages; | ||
| 5832 | start_sector += submit_len >> 9; | ||
| 5833 | file_offset += submit_len; | ||
| 5834 | |||
| 5835 | submit_len = 0; | ||
| 5836 | nr_pages = 0; | ||
| 5837 | |||
| 5838 | bio = btrfs_dio_bio_alloc(orig_bio->bi_bdev, | ||
| 5839 | start_sector, GFP_NOFS); | ||
| 5840 | if (!bio) | ||
| 5841 | goto out_err; | ||
| 5842 | bio->bi_private = dip; | ||
| 5843 | bio->bi_end_io = btrfs_end_dio_bio; | ||
| 5844 | |||
| 5845 | map_length = orig_bio->bi_size; | ||
| 5846 | ret = btrfs_map_block(map_tree, READ, start_sector << 9, | ||
| 5847 | &map_length, NULL, 0); | ||
| 5848 | if (ret) { | ||
| 5849 | bio_put(bio); | ||
| 5850 | goto out_err; | ||
| 5851 | } | ||
| 5852 | } else { | ||
| 5853 | submit_len += bvec->bv_len; | ||
| 5854 | nr_pages ++; | ||
| 5855 | bvec++; | ||
| 5856 | } | ||
| 5857 | } | ||
| 5858 | |||
| 5859 | ret = __btrfs_submit_dio_bio(bio, inode, rw, file_offset, skip_sum, | ||
| 5860 | csums); | ||
| 5861 | if (!ret) | ||
| 5862 | return 0; | ||
| 5863 | |||
| 5864 | bio_put(bio); | ||
| 5865 | out_err: | ||
| 5866 | dip->errors = 1; | ||
| 5867 | /* | ||
| 5868 | * before atomic variable goto zero, we must | ||
| 5869 | * make sure dip->errors is perceived to be set. | ||
| 5870 | */ | ||
| 5871 | smp_mb__before_atomic_dec(); | ||
| 5872 | if (atomic_dec_and_test(&dip->pending_bios)) | ||
| 5873 | bio_io_error(dip->orig_bio); | ||
| 5874 | |||
| 5875 | /* bio_end_io() will handle error, so we needn't return it */ | ||
| 5876 | return 0; | ||
| 5877 | } | ||
| 5878 | |||
| 5687 | static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, | 5879 | static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, |
| 5688 | loff_t file_offset) | 5880 | loff_t file_offset) |
| 5689 | { | 5881 | { |
| @@ -5723,36 +5915,18 @@ static void btrfs_submit_direct(int rw, struct bio *bio, struct inode *inode, | |||
| 5723 | 5915 | ||
| 5724 | dip->disk_bytenr = (u64)bio->bi_sector << 9; | 5916 | dip->disk_bytenr = (u64)bio->bi_sector << 9; |
| 5725 | bio->bi_private = dip; | 5917 | bio->bi_private = dip; |
| 5918 | dip->errors = 0; | ||
| 5919 | dip->orig_bio = bio; | ||
| 5920 | atomic_set(&dip->pending_bios, 0); | ||
| 5726 | 5921 | ||
| 5727 | if (write) | 5922 | if (write) |
| 5728 | bio->bi_end_io = btrfs_endio_direct_write; | 5923 | bio->bi_end_io = btrfs_endio_direct_write; |
| 5729 | else | 5924 | else |
| 5730 | bio->bi_end_io = btrfs_endio_direct_read; | 5925 | bio->bi_end_io = btrfs_endio_direct_read; |
| 5731 | 5926 | ||
| 5732 | ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0); | 5927 | ret = btrfs_submit_direct_hook(rw, dip, skip_sum); |
| 5733 | if (ret) | 5928 | if (!ret) |
| 5734 | goto out_err; | ||
| 5735 | |||
| 5736 | if (write && !skip_sum) { | ||
| 5737 | ret = btrfs_wq_submit_bio(BTRFS_I(inode)->root->fs_info, | ||
| 5738 | inode, rw, bio, 0, 0, | ||
| 5739 | dip->logical_offset, | ||
| 5740 | __btrfs_submit_bio_start_direct_io, | ||
| 5741 | __btrfs_submit_bio_done); | ||
| 5742 | if (ret) | ||
| 5743 | goto out_err; | ||
| 5744 | return; | 5929 | return; |
| 5745 | } else if (!skip_sum) | ||
| 5746 | btrfs_lookup_bio_sums_dio(root, inode, bio, | ||
| 5747 | dip->logical_offset, dip->csums); | ||
| 5748 | |||
| 5749 | ret = btrfs_map_bio(root, rw, bio, 0, 1); | ||
| 5750 | if (ret) | ||
| 5751 | goto out_err; | ||
| 5752 | return; | ||
| 5753 | out_err: | ||
| 5754 | kfree(dip->csums); | ||
| 5755 | kfree(dip); | ||
| 5756 | free_ordered: | 5930 | free_ordered: |
| 5757 | /* | 5931 | /* |
| 5758 | * If this is a write, we need to clean up the reserved space and kill | 5932 | * If this is a write, we need to clean up the reserved space and kill |
| @@ -5760,8 +5934,7 @@ free_ordered: | |||
| 5760 | */ | 5934 | */ |
| 5761 | if (write) { | 5935 | if (write) { |
| 5762 | struct btrfs_ordered_extent *ordered; | 5936 | struct btrfs_ordered_extent *ordered; |
| 5763 | ordered = btrfs_lookup_ordered_extent(inode, | 5937 | ordered = btrfs_lookup_ordered_extent(inode, file_offset); |
| 5764 | dip->logical_offset); | ||
| 5765 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && | 5938 | if (!test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags) && |
| 5766 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) | 5939 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) |
| 5767 | btrfs_free_reserved_extent(root, ordered->start, | 5940 | btrfs_free_reserved_extent(root, ordered->start, |
| @@ -6607,8 +6780,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 6607 | BUG_ON(ret); | 6780 | BUG_ON(ret); |
| 6608 | 6781 | ||
| 6609 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { | 6782 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { |
| 6610 | btrfs_log_new_name(trans, old_inode, old_dir, | 6783 | struct dentry *parent = dget_parent(new_dentry); |
| 6611 | new_dentry->d_parent); | 6784 | btrfs_log_new_name(trans, old_inode, old_dir, parent); |
| 6785 | dput(parent); | ||
| 6612 | btrfs_end_log_trans(root); | 6786 | btrfs_end_log_trans(root); |
| 6613 | } | 6787 | } |
| 6614 | out_fail: | 6788 | out_fail: |
| @@ -6758,8 +6932,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 6758 | btrfs_set_trans_block_group(trans, dir); | 6932 | btrfs_set_trans_block_group(trans, dir); |
| 6759 | 6933 | ||
| 6760 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 6934 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 6761 | dentry->d_name.len, | 6935 | dentry->d_name.len, dir->i_ino, objectid, |
| 6762 | dentry->d_parent->d_inode->i_ino, objectid, | ||
| 6763 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, | 6936 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, |
| 6764 | &index); | 6937 | &index); |
| 6765 | err = PTR_ERR(inode); | 6938 | err = PTR_ERR(inode); |
| @@ -6773,7 +6946,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 6773 | } | 6946 | } |
| 6774 | 6947 | ||
| 6775 | btrfs_set_trans_block_group(trans, inode); | 6948 | btrfs_set_trans_block_group(trans, inode); |
| 6776 | err = btrfs_add_nondir(trans, dentry, inode, 0, index); | 6949 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 6777 | if (err) | 6950 | if (err) |
| 6778 | drop_inode = 1; | 6951 | drop_inode = 1; |
| 6779 | else { | 6952 | else { |
| @@ -6844,6 +7017,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 6844 | struct btrfs_root *root = BTRFS_I(inode)->root; | 7017 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 6845 | struct btrfs_key ins; | 7018 | struct btrfs_key ins; |
| 6846 | u64 cur_offset = start; | 7019 | u64 cur_offset = start; |
| 7020 | u64 i_size; | ||
| 6847 | int ret = 0; | 7021 | int ret = 0; |
| 6848 | bool own_trans = true; | 7022 | bool own_trans = true; |
| 6849 | 7023 | ||
| @@ -6885,11 +7059,11 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 6885 | (actual_len > inode->i_size) && | 7059 | (actual_len > inode->i_size) && |
| 6886 | (cur_offset > inode->i_size)) { | 7060 | (cur_offset > inode->i_size)) { |
| 6887 | if (cur_offset > actual_len) | 7061 | if (cur_offset > actual_len) |
| 6888 | i_size_write(inode, actual_len); | 7062 | i_size = actual_len; |
| 6889 | else | 7063 | else |
| 6890 | i_size_write(inode, cur_offset); | 7064 | i_size = cur_offset; |
| 6891 | i_size_write(inode, cur_offset); | 7065 | i_size_write(inode, i_size); |
| 6892 | btrfs_ordered_update_i_size(inode, cur_offset, NULL); | 7066 | btrfs_ordered_update_i_size(inode, i_size, NULL); |
| 6893 | } | 7067 | } |
| 6894 | 7068 | ||
| 6895 | ret = btrfs_update_inode(trans, root, inode); | 7069 | ret = btrfs_update_inode(trans, root, inode); |
| @@ -6943,6 +7117,10 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
| 6943 | btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start); | 7117 | btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start); |
| 6944 | 7118 | ||
| 6945 | mutex_lock(&inode->i_mutex); | 7119 | mutex_lock(&inode->i_mutex); |
| 7120 | ret = inode_newsize_ok(inode, alloc_end); | ||
| 7121 | if (ret) | ||
| 7122 | goto out; | ||
| 7123 | |||
| 6946 | if (alloc_start > inode->i_size) { | 7124 | if (alloc_start > inode->i_size) { |
| 6947 | ret = btrfs_cont_expand(inode, alloc_start); | 7125 | ret = btrfs_cont_expand(inode, alloc_start); |
| 6948 | if (ret) | 7126 | if (ret) |
| @@ -7139,6 +7317,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
| 7139 | .readlink = generic_readlink, | 7317 | .readlink = generic_readlink, |
| 7140 | .follow_link = page_follow_link_light, | 7318 | .follow_link = page_follow_link_light, |
| 7141 | .put_link = page_put_link, | 7319 | .put_link = page_put_link, |
| 7320 | .getattr = btrfs_getattr, | ||
| 7142 | .permission = btrfs_permission, | 7321 | .permission = btrfs_permission, |
| 7143 | .setxattr = btrfs_setxattr, | 7322 | .setxattr = btrfs_setxattr, |
| 7144 | .getxattr = btrfs_getxattr, | 7323 | .getxattr = btrfs_getxattr, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 463d91b4dd3a..f87552a1d7ea 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -233,7 +233,8 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 233 | struct btrfs_inode_item *inode_item; | 233 | struct btrfs_inode_item *inode_item; |
| 234 | struct extent_buffer *leaf; | 234 | struct extent_buffer *leaf; |
| 235 | struct btrfs_root *new_root; | 235 | struct btrfs_root *new_root; |
| 236 | struct inode *dir = dentry->d_parent->d_inode; | 236 | struct dentry *parent = dget_parent(dentry); |
| 237 | struct inode *dir; | ||
| 237 | int ret; | 238 | int ret; |
| 238 | int err; | 239 | int err; |
| 239 | u64 objectid; | 240 | u64 objectid; |
| @@ -242,8 +243,13 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 242 | 243 | ||
| 243 | ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root, | 244 | ret = btrfs_find_free_objectid(NULL, root->fs_info->tree_root, |
| 244 | 0, &objectid); | 245 | 0, &objectid); |
| 245 | if (ret) | 246 | if (ret) { |
| 247 | dput(parent); | ||
| 246 | return ret; | 248 | return ret; |
| 249 | } | ||
| 250 | |||
| 251 | dir = parent->d_inode; | ||
| 252 | |||
| 247 | /* | 253 | /* |
| 248 | * 1 - inode item | 254 | * 1 - inode item |
| 249 | * 2 - refs | 255 | * 2 - refs |
| @@ -251,8 +257,10 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 251 | * 2 - dir items | 257 | * 2 - dir items |
| 252 | */ | 258 | */ |
| 253 | trans = btrfs_start_transaction(root, 6); | 259 | trans = btrfs_start_transaction(root, 6); |
| 254 | if (IS_ERR(trans)) | 260 | if (IS_ERR(trans)) { |
| 261 | dput(parent); | ||
| 255 | return PTR_ERR(trans); | 262 | return PTR_ERR(trans); |
| 263 | } | ||
| 256 | 264 | ||
| 257 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 265 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
| 258 | 0, objectid, NULL, 0, 0, 0); | 266 | 0, objectid, NULL, 0, 0, 0); |
| @@ -339,6 +347,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
| 339 | 347 | ||
| 340 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); | 348 | d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry)); |
| 341 | fail: | 349 | fail: |
| 350 | dput(parent); | ||
| 342 | if (async_transid) { | 351 | if (async_transid) { |
| 343 | *async_transid = trans->transid; | 352 | *async_transid = trans->transid; |
| 344 | err = btrfs_commit_transaction_async(trans, root, 1); | 353 | err = btrfs_commit_transaction_async(trans, root, 1); |
| @@ -354,6 +363,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
| 354 | char *name, int namelen, u64 *async_transid) | 363 | char *name, int namelen, u64 *async_transid) |
| 355 | { | 364 | { |
| 356 | struct inode *inode; | 365 | struct inode *inode; |
| 366 | struct dentry *parent; | ||
| 357 | struct btrfs_pending_snapshot *pending_snapshot; | 367 | struct btrfs_pending_snapshot *pending_snapshot; |
| 358 | struct btrfs_trans_handle *trans; | 368 | struct btrfs_trans_handle *trans; |
| 359 | int ret; | 369 | int ret; |
| @@ -396,7 +406,9 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, | |||
| 396 | 406 | ||
| 397 | btrfs_orphan_cleanup(pending_snapshot->snap); | 407 | btrfs_orphan_cleanup(pending_snapshot->snap); |
| 398 | 408 | ||
| 399 | inode = btrfs_lookup_dentry(dentry->d_parent->d_inode, dentry); | 409 | parent = dget_parent(dentry); |
| 410 | inode = btrfs_lookup_dentry(parent->d_inode, dentry); | ||
| 411 | dput(parent); | ||
| 400 | if (IS_ERR(inode)) { | 412 | if (IS_ERR(inode)) { |
| 401 | ret = PTR_ERR(inode); | 413 | ret = PTR_ERR(inode); |
| 402 | goto fail; | 414 | goto fail; |
| @@ -935,23 +947,42 @@ out: | |||
| 935 | 947 | ||
| 936 | static noinline int btrfs_ioctl_snap_create(struct file *file, | 948 | static noinline int btrfs_ioctl_snap_create(struct file *file, |
| 937 | void __user *arg, int subvol, | 949 | void __user *arg, int subvol, |
| 938 | int async) | 950 | int v2) |
| 939 | { | 951 | { |
| 940 | struct btrfs_ioctl_vol_args *vol_args = NULL; | 952 | struct btrfs_ioctl_vol_args *vol_args = NULL; |
| 941 | struct btrfs_ioctl_async_vol_args *async_vol_args = NULL; | 953 | struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL; |
| 942 | char *name; | 954 | char *name; |
| 943 | u64 fd; | 955 | u64 fd; |
| 944 | u64 transid = 0; | ||
| 945 | int ret; | 956 | int ret; |
| 946 | 957 | ||
| 947 | if (async) { | 958 | if (v2) { |
| 948 | async_vol_args = memdup_user(arg, sizeof(*async_vol_args)); | 959 | u64 transid = 0; |
| 949 | if (IS_ERR(async_vol_args)) | 960 | u64 *ptr = NULL; |
| 950 | return PTR_ERR(async_vol_args); | 961 | |
| 962 | vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2)); | ||
| 963 | if (IS_ERR(vol_args_v2)) | ||
| 964 | return PTR_ERR(vol_args_v2); | ||
| 965 | |||
| 966 | if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) { | ||
| 967 | ret = -EINVAL; | ||
| 968 | goto out; | ||
| 969 | } | ||
| 970 | |||
| 971 | name = vol_args_v2->name; | ||
| 972 | fd = vol_args_v2->fd; | ||
| 973 | vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; | ||
| 974 | |||
| 975 | if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC) | ||
| 976 | ptr = &transid; | ||
| 977 | |||
| 978 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, | ||
| 979 | subvol, ptr); | ||
| 951 | 980 | ||
| 952 | name = async_vol_args->name; | 981 | if (ret == 0 && ptr && |
| 953 | fd = async_vol_args->fd; | 982 | copy_to_user(arg + |
| 954 | async_vol_args->name[BTRFS_SNAPSHOT_NAME_MAX] = '\0'; | 983 | offsetof(struct btrfs_ioctl_vol_args_v2, |
| 984 | transid), ptr, sizeof(*ptr))) | ||
| 985 | ret = -EFAULT; | ||
| 955 | } else { | 986 | } else { |
| 956 | vol_args = memdup_user(arg, sizeof(*vol_args)); | 987 | vol_args = memdup_user(arg, sizeof(*vol_args)); |
| 957 | if (IS_ERR(vol_args)) | 988 | if (IS_ERR(vol_args)) |
| @@ -959,20 +990,13 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, | |||
| 959 | name = vol_args->name; | 990 | name = vol_args->name; |
| 960 | fd = vol_args->fd; | 991 | fd = vol_args->fd; |
| 961 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; | 992 | vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; |
| 962 | } | ||
| 963 | |||
| 964 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, | ||
| 965 | subvol, &transid); | ||
| 966 | 993 | ||
| 967 | if (!ret && async) { | 994 | ret = btrfs_ioctl_snap_create_transid(file, name, fd, |
| 968 | if (copy_to_user(arg + | 995 | subvol, NULL); |
| 969 | offsetof(struct btrfs_ioctl_async_vol_args, | ||
| 970 | transid), &transid, sizeof(transid))) | ||
| 971 | return -EFAULT; | ||
| 972 | } | 996 | } |
| 973 | 997 | out: | |
| 974 | kfree(vol_args); | 998 | kfree(vol_args); |
| 975 | kfree(async_vol_args); | 999 | kfree(vol_args_v2); |
| 976 | 1000 | ||
| 977 | return ret; | 1001 | return ret; |
| 978 | } | 1002 | } |
| @@ -1669,12 +1693,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1669 | olen = len = src->i_size - off; | 1693 | olen = len = src->i_size - off; |
| 1670 | /* if we extend to eof, continue to block boundary */ | 1694 | /* if we extend to eof, continue to block boundary */ |
| 1671 | if (off + len == src->i_size) | 1695 | if (off + len == src->i_size) |
| 1672 | len = ((src->i_size + bs-1) & ~(bs-1)) | 1696 | len = ALIGN(src->i_size, bs) - off; |
| 1673 | - off; | ||
| 1674 | 1697 | ||
| 1675 | /* verify the end result is block aligned */ | 1698 | /* verify the end result is block aligned */ |
| 1676 | if ((off & (bs-1)) || | 1699 | if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) || |
| 1677 | ((off + len) & (bs-1))) | 1700 | !IS_ALIGNED(destoff, bs)) |
| 1678 | goto out_unlock; | 1701 | goto out_unlock; |
| 1679 | 1702 | ||
| 1680 | /* do any pending delalloc/csum calc on src, one way or | 1703 | /* do any pending delalloc/csum calc on src, one way or |
| @@ -1874,8 +1897,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1874 | * but shouldn't round up the file size | 1897 | * but shouldn't round up the file size |
| 1875 | */ | 1898 | */ |
| 1876 | endoff = new_key.offset + datal; | 1899 | endoff = new_key.offset + datal; |
| 1877 | if (endoff > off+olen) | 1900 | if (endoff > destoff+olen) |
| 1878 | endoff = off+olen; | 1901 | endoff = destoff+olen; |
| 1879 | if (endoff > inode->i_size) | 1902 | if (endoff > inode->i_size) |
| 1880 | btrfs_i_size_write(inode, endoff); | 1903 | btrfs_i_size_write(inode, endoff); |
| 1881 | 1904 | ||
| @@ -2235,7 +2258,7 @@ long btrfs_ioctl(struct file *file, unsigned int | |||
| 2235 | return btrfs_ioctl_getversion(file, argp); | 2258 | return btrfs_ioctl_getversion(file, argp); |
| 2236 | case BTRFS_IOC_SNAP_CREATE: | 2259 | case BTRFS_IOC_SNAP_CREATE: |
| 2237 | return btrfs_ioctl_snap_create(file, argp, 0, 0); | 2260 | return btrfs_ioctl_snap_create(file, argp, 0, 0); |
| 2238 | case BTRFS_IOC_SNAP_CREATE_ASYNC: | 2261 | case BTRFS_IOC_SNAP_CREATE_V2: |
| 2239 | return btrfs_ioctl_snap_create(file, argp, 0, 1); | 2262 | return btrfs_ioctl_snap_create(file, argp, 0, 1); |
| 2240 | case BTRFS_IOC_SUBVOL_CREATE: | 2263 | case BTRFS_IOC_SUBVOL_CREATE: |
| 2241 | return btrfs_ioctl_snap_create(file, argp, 1, 0); | 2264 | return btrfs_ioctl_snap_create(file, argp, 1, 0); |
diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 17c99ebdf960..c344d12c646b 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h | |||
| @@ -30,11 +30,15 @@ struct btrfs_ioctl_vol_args { | |||
| 30 | char name[BTRFS_PATH_NAME_MAX + 1]; | 30 | char name[BTRFS_PATH_NAME_MAX + 1]; |
| 31 | }; | 31 | }; |
| 32 | 32 | ||
| 33 | #define BTRFS_SNAPSHOT_NAME_MAX 4079 | 33 | #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) |
| 34 | struct btrfs_ioctl_async_vol_args { | 34 | |
| 35 | #define BTRFS_SUBVOL_NAME_MAX 4039 | ||
| 36 | struct btrfs_ioctl_vol_args_v2 { | ||
| 35 | __s64 fd; | 37 | __s64 fd; |
| 36 | __u64 transid; | 38 | __u64 transid; |
| 37 | char name[BTRFS_SNAPSHOT_NAME_MAX + 1]; | 39 | __u64 flags; |
| 40 | __u64 unused[4]; | ||
| 41 | char name[BTRFS_SUBVOL_NAME_MAX + 1]; | ||
| 38 | }; | 42 | }; |
| 39 | 43 | ||
| 40 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 | 44 | #define BTRFS_INO_LOOKUP_PATH_MAX 4080 |
| @@ -187,6 +191,6 @@ struct btrfs_ioctl_space_args { | |||
| 187 | struct btrfs_ioctl_space_args) | 191 | struct btrfs_ioctl_space_args) |
| 188 | #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) | 192 | #define BTRFS_IOC_START_SYNC _IOR(BTRFS_IOCTL_MAGIC, 24, __u64) |
| 189 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) | 193 | #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) |
| 190 | #define BTRFS_IOC_SNAP_CREATE_ASYNC _IOW(BTRFS_IOCTL_MAGIC, 23, \ | 194 | #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ |
| 191 | struct btrfs_ioctl_async_vol_args) | 195 | struct btrfs_ioctl_vol_args_v2) |
| 192 | #endif | 196 | #endif |
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index f4621f6deca1..ae7737e352c9 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
| @@ -250,6 +250,73 @@ int btrfs_add_ordered_sum(struct inode *inode, | |||
| 250 | 250 | ||
| 251 | /* | 251 | /* |
| 252 | * this is used to account for finished IO across a given range | 252 | * this is used to account for finished IO across a given range |
| 253 | * of the file. The IO may span ordered extents. If | ||
| 254 | * a given ordered_extent is completely done, 1 is returned, otherwise | ||
| 255 | * 0. | ||
| 256 | * | ||
| 257 | * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used | ||
| 258 | * to make sure this function only returns 1 once for a given ordered extent. | ||
| 259 | * | ||
| 260 | * file_offset is updated to one byte past the range that is recorded as | ||
| 261 | * complete. This allows you to walk forward in the file. | ||
| 262 | */ | ||
| 263 | int btrfs_dec_test_first_ordered_pending(struct inode *inode, | ||
| 264 | struct btrfs_ordered_extent **cached, | ||
| 265 | u64 *file_offset, u64 io_size) | ||
| 266 | { | ||
| 267 | struct btrfs_ordered_inode_tree *tree; | ||
| 268 | struct rb_node *node; | ||
| 269 | struct btrfs_ordered_extent *entry = NULL; | ||
| 270 | int ret; | ||
| 271 | u64 dec_end; | ||
| 272 | u64 dec_start; | ||
| 273 | u64 to_dec; | ||
| 274 | |||
| 275 | tree = &BTRFS_I(inode)->ordered_tree; | ||
| 276 | spin_lock(&tree->lock); | ||
| 277 | node = tree_search(tree, *file_offset); | ||
| 278 | if (!node) { | ||
| 279 | ret = 1; | ||
| 280 | goto out; | ||
| 281 | } | ||
| 282 | |||
| 283 | entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); | ||
| 284 | if (!offset_in_entry(entry, *file_offset)) { | ||
| 285 | ret = 1; | ||
| 286 | goto out; | ||
| 287 | } | ||
| 288 | |||
| 289 | dec_start = max(*file_offset, entry->file_offset); | ||
| 290 | dec_end = min(*file_offset + io_size, entry->file_offset + | ||
| 291 | entry->len); | ||
| 292 | *file_offset = dec_end; | ||
| 293 | if (dec_start > dec_end) { | ||
| 294 | printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n", | ||
| 295 | (unsigned long long)dec_start, | ||
| 296 | (unsigned long long)dec_end); | ||
| 297 | } | ||
| 298 | to_dec = dec_end - dec_start; | ||
| 299 | if (to_dec > entry->bytes_left) { | ||
| 300 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", | ||
| 301 | (unsigned long long)entry->bytes_left, | ||
| 302 | (unsigned long long)to_dec); | ||
| 303 | } | ||
| 304 | entry->bytes_left -= to_dec; | ||
| 305 | if (entry->bytes_left == 0) | ||
| 306 | ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); | ||
| 307 | else | ||
| 308 | ret = 1; | ||
| 309 | out: | ||
| 310 | if (!ret && cached && entry) { | ||
| 311 | *cached = entry; | ||
| 312 | atomic_inc(&entry->refs); | ||
| 313 | } | ||
| 314 | spin_unlock(&tree->lock); | ||
| 315 | return ret == 0; | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 319 | * this is used to account for finished IO across a given range | ||
| 253 | * of the file. The IO should not span ordered extents. If | 320 | * of the file. The IO should not span ordered extents. If |
| 254 | * a given ordered_extent is completely done, 1 is returned, otherwise | 321 | * a given ordered_extent is completely done, 1 is returned, otherwise |
| 255 | * 0. | 322 | * 0. |
diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 8ac365492a3f..61dca83119dd 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h | |||
| @@ -141,6 +141,9 @@ int btrfs_remove_ordered_extent(struct inode *inode, | |||
| 141 | int btrfs_dec_test_ordered_pending(struct inode *inode, | 141 | int btrfs_dec_test_ordered_pending(struct inode *inode, |
| 142 | struct btrfs_ordered_extent **cached, | 142 | struct btrfs_ordered_extent **cached, |
| 143 | u64 file_offset, u64 io_size); | 143 | u64 file_offset, u64 io_size); |
| 144 | int btrfs_dec_test_first_ordered_pending(struct inode *inode, | ||
| 145 | struct btrfs_ordered_extent **cached, | ||
| 146 | u64 *file_offset, u64 io_size); | ||
| 144 | int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | 147 | int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, |
| 145 | u64 start, u64 len, u64 disk_len, int type); | 148 | u64 start, u64 len, u64 disk_len, int type); |
| 146 | int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, | 149 | int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, |
diff --git a/fs/btrfs/orphan.c b/fs/btrfs/orphan.c index 79cba5fbc28e..f8be250963a0 100644 --- a/fs/btrfs/orphan.c +++ b/fs/btrfs/orphan.c | |||
| @@ -56,8 +56,12 @@ int btrfs_del_orphan_item(struct btrfs_trans_handle *trans, | |||
| 56 | return -ENOMEM; | 56 | return -ENOMEM; |
| 57 | 57 | ||
| 58 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); | 58 | ret = btrfs_search_slot(trans, root, &key, path, -1, 1); |
| 59 | if (ret) | 59 | if (ret < 0) |
| 60 | goto out; | 60 | goto out; |
| 61 | if (ret) { | ||
| 62 | ret = -ENOENT; | ||
| 63 | goto out; | ||
| 64 | } | ||
| 61 | 65 | ||
| 62 | ret = btrfs_del_item(trans, root, path); | 66 | ret = btrfs_del_item(trans, root, path); |
| 63 | 67 | ||
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8299a25ffc8f..883c6fa1367e 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -244,6 +244,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
| 244 | case Opt_space_cache: | 244 | case Opt_space_cache: |
| 245 | printk(KERN_INFO "btrfs: enabling disk space caching\n"); | 245 | printk(KERN_INFO "btrfs: enabling disk space caching\n"); |
| 246 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); | 246 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); |
| 247 | break; | ||
| 247 | case Opt_clear_cache: | 248 | case Opt_clear_cache: |
| 248 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); | 249 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); |
| 249 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); | 250 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); |
| @@ -562,12 +563,26 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
| 562 | 563 | ||
| 563 | static int btrfs_test_super(struct super_block *s, void *data) | 564 | static int btrfs_test_super(struct super_block *s, void *data) |
| 564 | { | 565 | { |
| 565 | struct btrfs_fs_devices *test_fs_devices = data; | 566 | struct btrfs_root *test_root = data; |
| 566 | struct btrfs_root *root = btrfs_sb(s); | 567 | struct btrfs_root *root = btrfs_sb(s); |
| 567 | 568 | ||
| 568 | return root->fs_info->fs_devices == test_fs_devices; | 569 | /* |
| 570 | * If this super block is going away, return false as it | ||
| 571 | * can't match as an existing super block. | ||
| 572 | */ | ||
| 573 | if (!atomic_read(&s->s_active)) | ||
| 574 | return 0; | ||
| 575 | return root->fs_info->fs_devices == test_root->fs_info->fs_devices; | ||
| 576 | } | ||
| 577 | |||
| 578 | static int btrfs_set_super(struct super_block *s, void *data) | ||
| 579 | { | ||
| 580 | s->s_fs_info = data; | ||
| 581 | |||
| 582 | return set_anon_super(s, data); | ||
| 569 | } | 583 | } |
| 570 | 584 | ||
| 585 | |||
| 571 | /* | 586 | /* |
| 572 | * Find a superblock for the given device / mount point. | 587 | * Find a superblock for the given device / mount point. |
| 573 | * | 588 | * |
| @@ -581,6 +596,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 581 | struct super_block *s; | 596 | struct super_block *s; |
| 582 | struct dentry *root; | 597 | struct dentry *root; |
| 583 | struct btrfs_fs_devices *fs_devices = NULL; | 598 | struct btrfs_fs_devices *fs_devices = NULL; |
| 599 | struct btrfs_root *tree_root = NULL; | ||
| 600 | struct btrfs_fs_info *fs_info = NULL; | ||
| 584 | fmode_t mode = FMODE_READ; | 601 | fmode_t mode = FMODE_READ; |
| 585 | char *subvol_name = NULL; | 602 | char *subvol_name = NULL; |
| 586 | u64 subvol_objectid = 0; | 603 | u64 subvol_objectid = 0; |
| @@ -608,8 +625,24 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 608 | goto error_close_devices; | 625 | goto error_close_devices; |
| 609 | } | 626 | } |
| 610 | 627 | ||
| 628 | /* | ||
| 629 | * Setup a dummy root and fs_info for test/set super. This is because | ||
| 630 | * we don't actually fill this stuff out until open_ctree, but we need | ||
| 631 | * it for searching for existing supers, so this lets us do that and | ||
| 632 | * then open_ctree will properly initialize everything later. | ||
| 633 | */ | ||
| 634 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); | ||
| 635 | tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | ||
| 636 | if (!fs_info || !tree_root) { | ||
| 637 | error = -ENOMEM; | ||
| 638 | goto error_close_devices; | ||
| 639 | } | ||
| 640 | fs_info->tree_root = tree_root; | ||
| 641 | fs_info->fs_devices = fs_devices; | ||
| 642 | tree_root->fs_info = fs_info; | ||
| 643 | |||
| 611 | bdev = fs_devices->latest_bdev; | 644 | bdev = fs_devices->latest_bdev; |
| 612 | s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices); | 645 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); |
| 613 | if (IS_ERR(s)) | 646 | if (IS_ERR(s)) |
| 614 | goto error_s; | 647 | goto error_s; |
| 615 | 648 | ||
| @@ -652,9 +685,9 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 652 | mutex_unlock(&root->d_inode->i_mutex); | 685 | mutex_unlock(&root->d_inode->i_mutex); |
| 653 | 686 | ||
| 654 | if (IS_ERR(new_root)) { | 687 | if (IS_ERR(new_root)) { |
| 688 | dput(root); | ||
| 655 | deactivate_locked_super(s); | 689 | deactivate_locked_super(s); |
| 656 | error = PTR_ERR(new_root); | 690 | error = PTR_ERR(new_root); |
| 657 | dput(root); | ||
| 658 | goto error_free_subvol_name; | 691 | goto error_free_subvol_name; |
| 659 | } | 692 | } |
| 660 | if (!new_root->d_inode) { | 693 | if (!new_root->d_inode) { |
| @@ -675,6 +708,8 @@ error_s: | |||
| 675 | error = PTR_ERR(s); | 708 | error = PTR_ERR(s); |
| 676 | error_close_devices: | 709 | error_close_devices: |
| 677 | btrfs_close_devices(fs_devices); | 710 | btrfs_close_devices(fs_devices); |
| 711 | kfree(fs_info); | ||
| 712 | kfree(tree_root); | ||
| 678 | error_free_subvol_name: | 713 | error_free_subvol_name: |
| 679 | kfree(subvol_name); | 714 | kfree(subvol_name); |
| 680 | return ERR_PTR(error); | 715 | return ERR_PTR(error); |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 1fffbc017bdf..f50e931fc217 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -902,6 +902,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 902 | struct btrfs_root *root = pending->root; | 902 | struct btrfs_root *root = pending->root; |
| 903 | struct btrfs_root *parent_root; | 903 | struct btrfs_root *parent_root; |
| 904 | struct inode *parent_inode; | 904 | struct inode *parent_inode; |
| 905 | struct dentry *parent; | ||
| 905 | struct dentry *dentry; | 906 | struct dentry *dentry; |
| 906 | struct extent_buffer *tmp; | 907 | struct extent_buffer *tmp; |
| 907 | struct extent_buffer *old; | 908 | struct extent_buffer *old; |
| @@ -941,7 +942,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 941 | trans->block_rsv = &pending->block_rsv; | 942 | trans->block_rsv = &pending->block_rsv; |
| 942 | 943 | ||
| 943 | dentry = pending->dentry; | 944 | dentry = pending->dentry; |
| 944 | parent_inode = dentry->d_parent->d_inode; | 945 | parent = dget_parent(dentry); |
| 946 | parent_inode = parent->d_inode; | ||
| 945 | parent_root = BTRFS_I(parent_inode)->root; | 947 | parent_root = BTRFS_I(parent_inode)->root; |
| 946 | record_root_in_trans(trans, parent_root); | 948 | record_root_in_trans(trans, parent_root); |
| 947 | 949 | ||
| @@ -989,6 +991,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 989 | parent_inode->i_ino, index, | 991 | parent_inode->i_ino, index, |
| 990 | dentry->d_name.name, dentry->d_name.len); | 992 | dentry->d_name.name, dentry->d_name.len); |
| 991 | BUG_ON(ret); | 993 | BUG_ON(ret); |
| 994 | dput(parent); | ||
| 992 | 995 | ||
| 993 | key.offset = (u64)-1; | 996 | key.offset = (u64)-1; |
| 994 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); | 997 | pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index a29f19384a27..054744ac5719 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -2869,6 +2869,7 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
| 2869 | { | 2869 | { |
| 2870 | int ret = 0; | 2870 | int ret = 0; |
| 2871 | struct btrfs_root *root; | 2871 | struct btrfs_root *root; |
| 2872 | struct dentry *old_parent = NULL; | ||
| 2872 | 2873 | ||
| 2873 | /* | 2874 | /* |
| 2874 | * for regular files, if its inode is already on disk, we don't | 2875 | * for regular files, if its inode is already on disk, we don't |
| @@ -2910,10 +2911,13 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
| 2910 | if (IS_ROOT(parent)) | 2911 | if (IS_ROOT(parent)) |
| 2911 | break; | 2912 | break; |
| 2912 | 2913 | ||
| 2913 | parent = parent->d_parent; | 2914 | parent = dget_parent(parent); |
| 2915 | dput(old_parent); | ||
| 2916 | old_parent = parent; | ||
| 2914 | inode = parent->d_inode; | 2917 | inode = parent->d_inode; |
| 2915 | 2918 | ||
| 2916 | } | 2919 | } |
| 2920 | dput(old_parent); | ||
| 2917 | out: | 2921 | out: |
| 2918 | return ret; | 2922 | return ret; |
| 2919 | } | 2923 | } |
| @@ -2945,6 +2949,7 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 2945 | { | 2949 | { |
| 2946 | int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL; | 2950 | int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL; |
| 2947 | struct super_block *sb; | 2951 | struct super_block *sb; |
| 2952 | struct dentry *old_parent = NULL; | ||
| 2948 | int ret = 0; | 2953 | int ret = 0; |
| 2949 | u64 last_committed = root->fs_info->last_trans_committed; | 2954 | u64 last_committed = root->fs_info->last_trans_committed; |
| 2950 | 2955 | ||
| @@ -3016,10 +3021,13 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, | |||
| 3016 | if (IS_ROOT(parent)) | 3021 | if (IS_ROOT(parent)) |
| 3017 | break; | 3022 | break; |
| 3018 | 3023 | ||
| 3019 | parent = parent->d_parent; | 3024 | parent = dget_parent(parent); |
| 3025 | dput(old_parent); | ||
| 3026 | old_parent = parent; | ||
| 3020 | } | 3027 | } |
| 3021 | ret = 0; | 3028 | ret = 0; |
| 3022 | end_trans: | 3029 | end_trans: |
| 3030 | dput(old_parent); | ||
| 3023 | if (ret < 0) { | 3031 | if (ret < 0) { |
| 3024 | BUG_ON(ret != -ENOSPC); | 3032 | BUG_ON(ret != -ENOSPC); |
| 3025 | root->fs_info->last_trans_log_full_commit = trans->transid; | 3033 | root->fs_info->last_trans_log_full_commit = trans->transid; |
| @@ -3039,8 +3047,13 @@ end_no_trans: | |||
| 3039 | int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans, | 3047 | int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans, |
| 3040 | struct btrfs_root *root, struct dentry *dentry) | 3048 | struct btrfs_root *root, struct dentry *dentry) |
| 3041 | { | 3049 | { |
| 3042 | return btrfs_log_inode_parent(trans, root, dentry->d_inode, | 3050 | struct dentry *parent = dget_parent(dentry); |
| 3043 | dentry->d_parent, 0); | 3051 | int ret; |
| 3052 | |||
| 3053 | ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent, 0); | ||
| 3054 | dput(parent); | ||
| 3055 | |||
| 3056 | return ret; | ||
| 3044 | } | 3057 | } |
| 3045 | 3058 | ||
| 3046 | /* | 3059 | /* |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index cc04dc1445d6..6b9884507837 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -412,12 +412,16 @@ static noinline int device_list_add(const char *path, | |||
| 412 | 412 | ||
| 413 | device->fs_devices = fs_devices; | 413 | device->fs_devices = fs_devices; |
| 414 | fs_devices->num_devices++; | 414 | fs_devices->num_devices++; |
| 415 | } else if (strcmp(device->name, path)) { | 415 | } else if (!device->name || strcmp(device->name, path)) { |
| 416 | name = kstrdup(path, GFP_NOFS); | 416 | name = kstrdup(path, GFP_NOFS); |
| 417 | if (!name) | 417 | if (!name) |
| 418 | return -ENOMEM; | 418 | return -ENOMEM; |
| 419 | kfree(device->name); | 419 | kfree(device->name); |
| 420 | device->name = name; | 420 | device->name = name; |
| 421 | if (device->missing) { | ||
| 422 | fs_devices->missing_devices--; | ||
| 423 | device->missing = 0; | ||
| 424 | } | ||
| 421 | } | 425 | } |
| 422 | 426 | ||
| 423 | if (found_transid > fs_devices->latest_trans) { | 427 | if (found_transid > fs_devices->latest_trans) { |
| @@ -1236,6 +1240,9 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
| 1236 | 1240 | ||
| 1237 | device->fs_devices->num_devices--; | 1241 | device->fs_devices->num_devices--; |
| 1238 | 1242 | ||
| 1243 | if (device->missing) | ||
| 1244 | root->fs_info->fs_devices->missing_devices--; | ||
| 1245 | |||
| 1239 | next_device = list_entry(root->fs_info->fs_devices->devices.next, | 1246 | next_device = list_entry(root->fs_info->fs_devices->devices.next, |
| 1240 | struct btrfs_device, dev_list); | 1247 | struct btrfs_device, dev_list); |
| 1241 | if (device->bdev == root->fs_info->sb->s_bdev) | 1248 | if (device->bdev == root->fs_info->sb->s_bdev) |
| @@ -3080,7 +3087,9 @@ static struct btrfs_device *add_missing_dev(struct btrfs_root *root, | |||
| 3080 | device->devid = devid; | 3087 | device->devid = devid; |
| 3081 | device->work.func = pending_bios_fn; | 3088 | device->work.func = pending_bios_fn; |
| 3082 | device->fs_devices = fs_devices; | 3089 | device->fs_devices = fs_devices; |
| 3090 | device->missing = 1; | ||
| 3083 | fs_devices->num_devices++; | 3091 | fs_devices->num_devices++; |
| 3092 | fs_devices->missing_devices++; | ||
| 3084 | spin_lock_init(&device->io_lock); | 3093 | spin_lock_init(&device->io_lock); |
| 3085 | INIT_LIST_HEAD(&device->dev_alloc_list); | 3094 | INIT_LIST_HEAD(&device->dev_alloc_list); |
| 3086 | memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); | 3095 | memcpy(device->uuid, dev_uuid, BTRFS_UUID_SIZE); |
| @@ -3278,6 +3287,15 @@ static int read_one_dev(struct btrfs_root *root, | |||
| 3278 | device = add_missing_dev(root, devid, dev_uuid); | 3287 | device = add_missing_dev(root, devid, dev_uuid); |
| 3279 | if (!device) | 3288 | if (!device) |
| 3280 | return -ENOMEM; | 3289 | return -ENOMEM; |
| 3290 | } else if (!device->missing) { | ||
| 3291 | /* | ||
| 3292 | * this happens when a device that was properly setup | ||
| 3293 | * in the device info lists suddenly goes bad. | ||
| 3294 | * device->bdev is NULL, and so we have to set | ||
| 3295 | * device->missing to one here | ||
| 3296 | */ | ||
| 3297 | root->fs_info->fs_devices->missing_devices++; | ||
| 3298 | device->missing = 1; | ||
| 3281 | } | 3299 | } |
| 3282 | } | 3300 | } |
| 3283 | 3301 | ||
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 2b638b6e4eea..2740db49eb04 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
| @@ -44,6 +44,7 @@ struct btrfs_device { | |||
| 44 | 44 | ||
| 45 | int writeable; | 45 | int writeable; |
| 46 | int in_fs_metadata; | 46 | int in_fs_metadata; |
| 47 | int missing; | ||
| 47 | 48 | ||
| 48 | spinlock_t io_lock; | 49 | spinlock_t io_lock; |
| 49 | 50 | ||
| @@ -93,6 +94,7 @@ struct btrfs_fs_devices { | |||
| 93 | u64 num_devices; | 94 | u64 num_devices; |
| 94 | u64 open_devices; | 95 | u64 open_devices; |
| 95 | u64 rw_devices; | 96 | u64 rw_devices; |
| 97 | u64 missing_devices; | ||
| 96 | u64 total_rw_bytes; | 98 | u64 total_rw_bytes; |
| 97 | struct block_device *latest_bdev; | 99 | struct block_device *latest_bdev; |
| 98 | 100 | ||
