diff options
| -rw-r--r-- | fs/btrfs/compression.c | 15 | ||||
| -rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 38 | ||||
| -rw-r--r-- | fs/btrfs/export.c | 76 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 2 | ||||
| -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 | 7 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 294 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 31 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.c | 67 | ||||
| -rw-r--r-- | fs/btrfs/ordered-data.h | 3 | ||||
| -rw-r--r-- | fs/btrfs/super.c | 41 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 21 |
15 files changed, 572 insertions, 114 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..c547cca26a26 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,29 @@ 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 | static int btree_migratepage(struct address_space *mapping, | ||
| 700 | struct page *newpage, struct page *page) | ||
| 701 | { | ||
| 702 | /* | ||
| 703 | * we can't safely write a btree page from here, | ||
| 704 | * we haven't done the locking hook | ||
| 705 | */ | ||
| 706 | if (PageDirty(page)) | ||
| 707 | return -EAGAIN; | ||
| 708 | /* | ||
| 709 | * Buffers may be managed in a filesystem specific way. | ||
| 710 | * We must have no buffers or drop them. | ||
| 711 | */ | ||
| 712 | if (page_has_private(page) && | ||
| 713 | !try_to_release_page(page, GFP_KERNEL)) | ||
| 714 | return -EAGAIN; | ||
| 715 | #ifdef CONFIG_MIGRATION | ||
| 716 | return migrate_page(mapping, newpage, page); | ||
| 717 | #else | ||
| 718 | return -ENOSYS; | ||
| 719 | #endif | ||
| 720 | } | ||
| 721 | |||
| 696 | static int btree_writepage(struct page *page, struct writeback_control *wbc) | 722 | static int btree_writepage(struct page *page, struct writeback_control *wbc) |
| 697 | { | 723 | { |
| 698 | struct extent_io_tree *tree; | 724 | struct extent_io_tree *tree; |
| @@ -707,8 +733,7 @@ static int btree_writepage(struct page *page, struct writeback_control *wbc) | |||
| 707 | } | 733 | } |
| 708 | 734 | ||
| 709 | redirty_page_for_writepage(wbc, page); | 735 | redirty_page_for_writepage(wbc, page); |
| 710 | eb = btrfs_find_tree_block(root, page_offset(page), | 736 | eb = btrfs_find_tree_block(root, page_offset(page), PAGE_CACHE_SIZE); |
| 711 | PAGE_CACHE_SIZE); | ||
| 712 | WARN_ON(!eb); | 737 | WARN_ON(!eb); |
| 713 | 738 | ||
| 714 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); | 739 | was_dirty = test_and_set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); |
| @@ -799,6 +824,9 @@ static const struct address_space_operations btree_aops = { | |||
| 799 | .releasepage = btree_releasepage, | 824 | .releasepage = btree_releasepage, |
| 800 | .invalidatepage = btree_invalidatepage, | 825 | .invalidatepage = btree_invalidatepage, |
| 801 | .sync_page = block_sync_page, | 826 | .sync_page = block_sync_page, |
| 827 | #ifdef CONFIG_MIGRATION | ||
| 828 | .migratepage = btree_migratepage, | ||
| 829 | #endif | ||
| 802 | }; | 830 | }; |
| 803 | 831 | ||
| 804 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, | 832 | int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, |
| @@ -1538,10 +1566,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1538 | GFP_NOFS); | 1566 | GFP_NOFS); |
| 1539 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), | 1567 | struct btrfs_root *csum_root = kzalloc(sizeof(struct btrfs_root), |
| 1540 | GFP_NOFS); | 1568 | GFP_NOFS); |
| 1541 | struct btrfs_root *tree_root = kzalloc(sizeof(struct btrfs_root), | 1569 | struct btrfs_root *tree_root = btrfs_sb(sb); |
| 1542 | GFP_NOFS); | 1570 | 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), | 1571 | struct btrfs_root *chunk_root = kzalloc(sizeof(struct btrfs_root), |
| 1546 | GFP_NOFS); | 1572 | GFP_NOFS); |
| 1547 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), | 1573 | struct btrfs_root *dev_root = kzalloc(sizeof(struct btrfs_root), |
diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 951ef09b82f4..6f0444473594 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c | |||
| @@ -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..bcd59c7dfb57 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -3412,7 +3412,7 @@ again: | |||
| 3412 | * our reservation. | 3412 | * our reservation. |
| 3413 | */ | 3413 | */ |
| 3414 | if (unused <= space_info->total_bytes) { | 3414 | if (unused <= space_info->total_bytes) { |
| 3415 | unused -= space_info->total_bytes; | 3415 | unused = space_info->total_bytes - unused; |
| 3416 | if (unused >= num_bytes) { | 3416 | if (unused >= num_bytes) { |
| 3417 | if (!reserved) | 3417 | if (!reserved) |
| 3418 | space_info->bytes_reserved += orig_bytes; | 3418 | space_info->bytes_reserved += orig_bytes; |
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..c1faded5fca0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -1047,8 +1047,14 @@ out: | |||
| 1047 | 1047 | ||
| 1048 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { | 1048 | if ((file->f_flags & O_DSYNC) || IS_SYNC(inode)) { |
| 1049 | trans = btrfs_start_transaction(root, 0); | 1049 | trans = btrfs_start_transaction(root, 0); |
| 1050 | if (IS_ERR(trans)) { | ||
| 1051 | num_written = PTR_ERR(trans); | ||
| 1052 | goto done; | ||
| 1053 | } | ||
| 1054 | mutex_lock(&inode->i_mutex); | ||
| 1050 | ret = btrfs_log_dentry_safe(trans, root, | 1055 | ret = btrfs_log_dentry_safe(trans, root, |
| 1051 | file->f_dentry); | 1056 | file->f_dentry); |
| 1057 | mutex_unlock(&inode->i_mutex); | ||
| 1052 | if (ret == 0) { | 1058 | if (ret == 0) { |
| 1053 | ret = btrfs_sync_log(trans, root); | 1059 | ret = btrfs_sync_log(trans, root); |
| 1054 | if (ret == 0) | 1060 | if (ret == 0) |
| @@ -1067,6 +1073,7 @@ out: | |||
| 1067 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); | 1073 | (start_pos + num_written - 1) >> PAGE_CACHE_SHIFT); |
| 1068 | } | 1074 | } |
| 1069 | } | 1075 | } |
| 1076 | done: | ||
| 1070 | current->backing_dev_info = NULL; | 1077 | current->backing_dev_info = NULL; |
| 1071 | return num_written ? num_written : err; | 1078 | return num_written ? num_written : err; |
| 1072 | } | 1079 | } |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 558cac2dfa54..8039390bd6a6 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -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 | "disk_bytenr %lu len %u err no %d\n", | ||
| 5716 | dip->inode->i_ino, bio->bi_rw, bio->bi_sector, | ||
| 5717 | 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 |
| @@ -6607,8 +6781,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 6607 | BUG_ON(ret); | 6781 | BUG_ON(ret); |
| 6608 | 6782 | ||
| 6609 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { | 6783 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { |
| 6610 | btrfs_log_new_name(trans, old_inode, old_dir, | 6784 | struct dentry *parent = dget_parent(new_dentry); |
| 6611 | new_dentry->d_parent); | 6785 | btrfs_log_new_name(trans, old_inode, old_dir, parent); |
| 6786 | dput(parent); | ||
| 6612 | btrfs_end_log_trans(root); | 6787 | btrfs_end_log_trans(root); |
| 6613 | } | 6788 | } |
| 6614 | out_fail: | 6789 | out_fail: |
| @@ -6758,8 +6933,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 6758 | btrfs_set_trans_block_group(trans, dir); | 6933 | btrfs_set_trans_block_group(trans, dir); |
| 6759 | 6934 | ||
| 6760 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, | 6935 | inode = btrfs_new_inode(trans, root, dir, dentry->d_name.name, |
| 6761 | dentry->d_name.len, | 6936 | 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, | 6937 | BTRFS_I(dir)->block_group, S_IFLNK|S_IRWXUGO, |
| 6764 | &index); | 6938 | &index); |
| 6765 | err = PTR_ERR(inode); | 6939 | err = PTR_ERR(inode); |
| @@ -6773,7 +6947,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry, | |||
| 6773 | } | 6947 | } |
| 6774 | 6948 | ||
| 6775 | btrfs_set_trans_block_group(trans, inode); | 6949 | btrfs_set_trans_block_group(trans, inode); |
| 6776 | err = btrfs_add_nondir(trans, dentry, inode, 0, index); | 6950 | err = btrfs_add_nondir(trans, dir, dentry, inode, 0, index); |
| 6777 | if (err) | 6951 | if (err) |
| 6778 | drop_inode = 1; | 6952 | drop_inode = 1; |
| 6779 | else { | 6953 | else { |
| @@ -6844,6 +7018,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 6844 | struct btrfs_root *root = BTRFS_I(inode)->root; | 7018 | struct btrfs_root *root = BTRFS_I(inode)->root; |
| 6845 | struct btrfs_key ins; | 7019 | struct btrfs_key ins; |
| 6846 | u64 cur_offset = start; | 7020 | u64 cur_offset = start; |
| 7021 | u64 i_size; | ||
| 6847 | int ret = 0; | 7022 | int ret = 0; |
| 6848 | bool own_trans = true; | 7023 | bool own_trans = true; |
| 6849 | 7024 | ||
| @@ -6885,11 +7060,11 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, | |||
| 6885 | (actual_len > inode->i_size) && | 7060 | (actual_len > inode->i_size) && |
| 6886 | (cur_offset > inode->i_size)) { | 7061 | (cur_offset > inode->i_size)) { |
| 6887 | if (cur_offset > actual_len) | 7062 | if (cur_offset > actual_len) |
| 6888 | i_size_write(inode, actual_len); | 7063 | i_size = actual_len; |
| 6889 | else | 7064 | else |
| 6890 | i_size_write(inode, cur_offset); | 7065 | i_size = cur_offset; |
| 6891 | i_size_write(inode, cur_offset); | 7066 | i_size_write(inode, i_size); |
| 6892 | btrfs_ordered_update_i_size(inode, cur_offset, NULL); | 7067 | btrfs_ordered_update_i_size(inode, i_size, NULL); |
| 6893 | } | 7068 | } |
| 6894 | 7069 | ||
| 6895 | ret = btrfs_update_inode(trans, root, inode); | 7070 | ret = btrfs_update_inode(trans, root, inode); |
| @@ -6943,6 +7118,10 @@ static long btrfs_fallocate(struct inode *inode, int mode, | |||
| 6943 | btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start); | 7118 | btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start); |
| 6944 | 7119 | ||
| 6945 | mutex_lock(&inode->i_mutex); | 7120 | mutex_lock(&inode->i_mutex); |
| 7121 | ret = inode_newsize_ok(inode, alloc_end); | ||
| 7122 | if (ret) | ||
| 7123 | goto out; | ||
| 7124 | |||
| 6946 | if (alloc_start > inode->i_size) { | 7125 | if (alloc_start > inode->i_size) { |
| 6947 | ret = btrfs_cont_expand(inode, alloc_start); | 7126 | ret = btrfs_cont_expand(inode, alloc_start); |
| 6948 | if (ret) | 7127 | if (ret) |
| @@ -7139,6 +7318,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
| 7139 | .readlink = generic_readlink, | 7318 | .readlink = generic_readlink, |
| 7140 | .follow_link = page_follow_link_light, | 7319 | .follow_link = page_follow_link_light, |
| 7141 | .put_link = page_put_link, | 7320 | .put_link = page_put_link, |
| 7321 | .getattr = btrfs_getattr, | ||
| 7142 | .permission = btrfs_permission, | 7322 | .permission = btrfs_permission, |
| 7143 | .setxattr = btrfs_setxattr, | 7323 | .setxattr = btrfs_setxattr, |
| 7144 | .getxattr = btrfs_getxattr, | 7324 | .getxattr = btrfs_getxattr, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 463d91b4dd3a..f1c9bb4079ed 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; |
| @@ -1669,12 +1681,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1669 | olen = len = src->i_size - off; | 1681 | olen = len = src->i_size - off; |
| 1670 | /* if we extend to eof, continue to block boundary */ | 1682 | /* if we extend to eof, continue to block boundary */ |
| 1671 | if (off + len == src->i_size) | 1683 | if (off + len == src->i_size) |
| 1672 | len = ((src->i_size + bs-1) & ~(bs-1)) | 1684 | len = ALIGN(src->i_size, bs) - off; |
| 1673 | - off; | ||
| 1674 | 1685 | ||
| 1675 | /* verify the end result is block aligned */ | 1686 | /* verify the end result is block aligned */ |
| 1676 | if ((off & (bs-1)) || | 1687 | if (!IS_ALIGNED(off, bs) || !IS_ALIGNED(off + len, bs) || |
| 1677 | ((off + len) & (bs-1))) | 1688 | !IS_ALIGNED(destoff, bs)) |
| 1678 | goto out_unlock; | 1689 | goto out_unlock; |
| 1679 | 1690 | ||
| 1680 | /* do any pending delalloc/csum calc on src, one way or | 1691 | /* do any pending delalloc/csum calc on src, one way or |
| @@ -1874,8 +1885,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
| 1874 | * but shouldn't round up the file size | 1885 | * but shouldn't round up the file size |
| 1875 | */ | 1886 | */ |
| 1876 | endoff = new_key.offset + datal; | 1887 | endoff = new_key.offset + datal; |
| 1877 | if (endoff > off+olen) | 1888 | if (endoff > destoff+olen) |
| 1878 | endoff = off+olen; | 1889 | endoff = destoff+olen; |
| 1879 | if (endoff > inode->i_size) | 1890 | if (endoff > inode->i_size) |
| 1880 | btrfs_i_size_write(inode, endoff); | 1891 | btrfs_i_size_write(inode, endoff); |
| 1881 | 1892 | ||
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/super.c b/fs/btrfs/super.c index 8299a25ffc8f..dbb51ea7a13c 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 | ||
| @@ -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 | /* |
