diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-29 17:11:08 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-11-29 17:11:08 -0500 |
commit | aa3fc52546b847f590d86a093afd863ff9081628 (patch) | |
tree | 9d8b35a700287ae19fb3baa0e9f2c93462795d11 /fs | |
parent | 555bdaefd52c386e79f98591810ceb8bab780398 (diff) | |
parent | 5a92bc88cef279261d3f138e25850c122df67045 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (24 commits)
Btrfs: don't use migrate page without CONFIG_MIGRATION
Btrfs: deal with DIO bios that span more than one ordered extent
Btrfs: setup blank root and fs_info for mount time
Btrfs: fix fiemap
Btrfs - fix race between btrfs_get_sb() and umount
Btrfs: update inode ctime when using links
Btrfs: make sure new inode size is ok in fallocate
Btrfs: fix typo in fallocate to make it honor actual size
Btrfs: avoid NULL pointer deref in try_release_extent_buffer
Btrfs: make btrfs_add_nondir take parent inode as an argument
Btrfs: hold i_mutex when calling btrfs_log_dentry_safe
Btrfs: use dget_parent where we can UPDATED
Btrfs: fix more ESTALE problems with NFS
Btrfs: handle NFS lookups properly
btrfs: make 1-bit signed fileds unsigned
btrfs: Show device attr correctly for symlinks
btrfs: Set file size correctly in file clone
btrfs: Check if dest_offset is block-size aligned before cloning file
Btrfs: handle the space_cache option properly
btrfs: Fix early enospc because 'unused' calculated with wrong sign.
...
Diffstat (limited to 'fs')
-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 | /* |