diff options
author | Josef Bacik <jbacik@fusionio.com> | 2013-10-09 12:00:56 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-11-11 21:56:51 -0500 |
commit | 294e30fee35d3151d100cfe59e839c2dbc16a374 (patch) | |
tree | 3906ec3d135ec29dc7700f8e35e494909b210848 /fs/btrfs | |
parent | 857cc2fc29cfaf4ee98fe9967bbf6a3942191136 (diff) |
Btrfs: add tests for find_lock_delalloc_range
So both Liu and I made huge messes of find_lock_delalloc_range trying to fix
stuff, me first by fixing extent size, then him by fixing something I broke and
then me again telling him to fix it a different way. So this is obviously a
candidate for some testing. This patch adds a pseudo fs so we can allocate fake
inodes for tests that need an inode or pages. Then it addes a bunch of tests to
make sure find_lock_delalloc_range is acting the way it is supposed to. With
this patch and all of our previous patches to find_lock_delalloc_range I am sure
it is working as expected now. Thanks,
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/Makefile | 2 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 6 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 9 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 6 | ||||
-rw-r--r-- | fs/btrfs/super.c | 14 | ||||
-rw-r--r-- | fs/btrfs/tests/btrfs-tests.c | 68 | ||||
-rw-r--r-- | fs/btrfs/tests/btrfs-tests.h | 15 | ||||
-rw-r--r-- | fs/btrfs/tests/extent-io-tests.c | 276 |
8 files changed, 388 insertions, 8 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index 4c7dfbfaa3b3..cac4f2d001a3 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
@@ -15,4 +15,4 @@ btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o | |||
15 | btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o | 15 | btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o |
16 | 16 | ||
17 | btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o \ | 17 | btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o \ |
18 | tests/extent-buffer-tests.o | 18 | tests/extent-buffer-tests.o tests/btrfs-tests.o tests/extent-io-tests.o |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 9ca15a84cc5a..2f398062b942 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -47,6 +47,12 @@ extern struct kmem_cache *btrfs_path_cachep; | |||
47 | extern struct kmem_cache *btrfs_free_space_cachep; | 47 | extern struct kmem_cache *btrfs_free_space_cachep; |
48 | struct btrfs_ordered_sum; | 48 | struct btrfs_ordered_sum; |
49 | 49 | ||
50 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
51 | #define STATIC noinline | ||
52 | #else | ||
53 | #define STATIC static noinline | ||
54 | #endif | ||
55 | |||
50 | #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */ | 56 | #define BTRFS_MAGIC 0x4D5F53665248425FULL /* ascii _BHRfS_M, no null */ |
51 | 57 | ||
52 | #define BTRFS_MAX_MIRRORS 3 | 58 | #define BTRFS_MAX_MIRRORS 3 |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 2bf6f46fae44..c10291cc4fd1 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -1598,11 +1598,10 @@ done: | |||
1598 | * | 1598 | * |
1599 | * 1 is returned if we find something, 0 if nothing was in the tree | 1599 | * 1 is returned if we find something, 0 if nothing was in the tree |
1600 | */ | 1600 | */ |
1601 | static noinline u64 find_lock_delalloc_range(struct inode *inode, | 1601 | STATIC u64 find_lock_delalloc_range(struct inode *inode, |
1602 | struct extent_io_tree *tree, | 1602 | struct extent_io_tree *tree, |
1603 | struct page *locked_page, | 1603 | struct page *locked_page, u64 *start, |
1604 | u64 *start, u64 *end, | 1604 | u64 *end, u64 max_bytes) |
1605 | u64 max_bytes) | ||
1606 | { | 1605 | { |
1607 | u64 delalloc_start; | 1606 | u64 delalloc_start; |
1608 | u64 delalloc_end; | 1607 | u64 delalloc_end; |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 6dbc645f1f3d..f98602eac808 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -345,4 +345,10 @@ int repair_io_failure(struct btrfs_fs_info *fs_info, u64 start, | |||
345 | int end_extent_writepage(struct page *page, int err, u64 start, u64 end); | 345 | int end_extent_writepage(struct page *page, int err, u64 start, u64 end); |
346 | int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, | 346 | int repair_eb_io_failure(struct btrfs_root *root, struct extent_buffer *eb, |
347 | int mirror_num); | 347 | int mirror_num); |
348 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | ||
349 | noinline u64 find_lock_delalloc_range(struct inode *inode, | ||
350 | struct extent_io_tree *tree, | ||
351 | struct page *locked_page, u64 *start, | ||
352 | u64 *end, u64 max_bytes); | ||
353 | #endif | ||
348 | #endif | 354 | #endif |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 0e398657d759..78041e34d15a 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1791,10 +1791,20 @@ static int btrfs_run_sanity_tests(void) | |||
1791 | { | 1791 | { |
1792 | int ret; | 1792 | int ret; |
1793 | 1793 | ||
1794 | ret = btrfs_test_free_space_cache(); | 1794 | ret = btrfs_init_test_fs(); |
1795 | if (ret) | 1795 | if (ret) |
1796 | return ret; | 1796 | return ret; |
1797 | return btrfs_test_extent_buffer_operations(); | 1797 | |
1798 | ret = btrfs_test_free_space_cache(); | ||
1799 | if (ret) | ||
1800 | goto out; | ||
1801 | ret = btrfs_test_extent_buffer_operations(); | ||
1802 | if (ret) | ||
1803 | goto out; | ||
1804 | ret = btrfs_test_extent_io(); | ||
1805 | out: | ||
1806 | btrfs_destroy_test_fs(); | ||
1807 | return ret; | ||
1798 | } | 1808 | } |
1799 | 1809 | ||
1800 | static int __init init_btrfs_fs(void) | 1810 | static int __init init_btrfs_fs(void) |
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c new file mode 100644 index 000000000000..697d527377c1 --- /dev/null +++ b/fs/btrfs/tests/btrfs-tests.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Fusion IO. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public | ||
6 | * License v2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public | ||
14 | * License along with this program; if not, write to the | ||
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | * Boston, MA 021110-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/fs.h> | ||
20 | #include <linux/mount.h> | ||
21 | #include <linux/magic.h> | ||
22 | #include "btrfs-tests.h" | ||
23 | #include "../ctree.h" | ||
24 | |||
25 | static struct vfsmount *test_mnt = NULL; | ||
26 | |||
27 | static struct dentry *btrfs_test_mount(struct file_system_type *fs_type, | ||
28 | int flags, const char *dev_name, | ||
29 | void *data) | ||
30 | { | ||
31 | return mount_pseudo(fs_type, "btrfs_test:", NULL, NULL, BTRFS_TEST_MAGIC); | ||
32 | } | ||
33 | |||
34 | static struct file_system_type test_type = { | ||
35 | .name = "btrfs_test_fs", | ||
36 | .mount = btrfs_test_mount, | ||
37 | .kill_sb = kill_anon_super, | ||
38 | }; | ||
39 | |||
40 | struct inode *btrfs_new_test_inode(void) | ||
41 | { | ||
42 | return new_inode(test_mnt->mnt_sb); | ||
43 | } | ||
44 | |||
45 | int btrfs_init_test_fs(void) | ||
46 | { | ||
47 | int ret; | ||
48 | |||
49 | ret = register_filesystem(&test_type); | ||
50 | if (ret) { | ||
51 | printk(KERN_ERR "btrfs: cannot register test file system\n"); | ||
52 | return ret; | ||
53 | } | ||
54 | |||
55 | test_mnt = kern_mount(&test_type); | ||
56 | if (IS_ERR(test_mnt)) { | ||
57 | printk(KERN_ERR "btrfs: cannot mount test file system\n"); | ||
58 | unregister_filesystem(&test_type); | ||
59 | return ret; | ||
60 | } | ||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | void btrfs_destroy_test_fs(void) | ||
65 | { | ||
66 | kern_unmount(test_mnt); | ||
67 | unregister_filesystem(&test_type); | ||
68 | } | ||
diff --git a/fs/btrfs/tests/btrfs-tests.h b/fs/btrfs/tests/btrfs-tests.h index 04f2cd2ca568..e935fe5291e7 100644 --- a/fs/btrfs/tests/btrfs-tests.h +++ b/fs/btrfs/tests/btrfs-tests.h | |||
@@ -25,6 +25,10 @@ | |||
25 | 25 | ||
26 | int btrfs_test_free_space_cache(void); | 26 | int btrfs_test_free_space_cache(void); |
27 | int btrfs_test_extent_buffer_operations(void); | 27 | int btrfs_test_extent_buffer_operations(void); |
28 | int btrfs_test_extent_io(void); | ||
29 | int btrfs_init_test_fs(void); | ||
30 | void btrfs_destroy_test_fs(void); | ||
31 | struct inode *btrfs_new_test_inode(void); | ||
28 | #else | 32 | #else |
29 | static inline int btrfs_test_free_space_cache(void) | 33 | static inline int btrfs_test_free_space_cache(void) |
30 | { | 34 | { |
@@ -34,6 +38,17 @@ static inline int btrfs_test_extent_buffer_operations(void) | |||
34 | { | 38 | { |
35 | return 0; | 39 | return 0; |
36 | } | 40 | } |
41 | static inline int btrfs_init_test_fs(void) | ||
42 | { | ||
43 | return 0; | ||
44 | } | ||
45 | static inline void btrfs_destroy_test_fs(void) | ||
46 | { | ||
47 | } | ||
48 | static inline int btrfs_test_extent_io(void) | ||
49 | { | ||
50 | return 0; | ||
51 | } | ||
37 | #endif | 52 | #endif |
38 | 53 | ||
39 | #endif | 54 | #endif |
diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c new file mode 100644 index 000000000000..7e99c2f98dd0 --- /dev/null +++ b/fs/btrfs/tests/extent-io-tests.c | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Fusion IO. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public | ||
6 | * License v2 as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope that it will be useful, | ||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
11 | * General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public | ||
14 | * License along with this program; if not, write to the | ||
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
16 | * Boston, MA 021110-1307, USA. | ||
17 | */ | ||
18 | |||
19 | #include <linux/pagemap.h> | ||
20 | #include <linux/sched.h> | ||
21 | #include "btrfs-tests.h" | ||
22 | #include "../extent_io.h" | ||
23 | |||
24 | #define PROCESS_UNLOCK (1 << 0) | ||
25 | #define PROCESS_RELEASE (1 << 1) | ||
26 | #define PROCESS_TEST_LOCKED (1 << 2) | ||
27 | |||
28 | static noinline int process_page_range(struct inode *inode, u64 start, u64 end, | ||
29 | unsigned long flags) | ||
30 | { | ||
31 | int ret; | ||
32 | struct page *pages[16]; | ||
33 | unsigned long index = start >> PAGE_CACHE_SHIFT; | ||
34 | unsigned long end_index = end >> PAGE_CACHE_SHIFT; | ||
35 | unsigned long nr_pages = end_index - index + 1; | ||
36 | int i; | ||
37 | int count = 0; | ||
38 | int loops = 0; | ||
39 | |||
40 | while (nr_pages > 0) { | ||
41 | ret = find_get_pages_contig(inode->i_mapping, index, | ||
42 | min_t(unsigned long, nr_pages, | ||
43 | ARRAY_SIZE(pages)), pages); | ||
44 | for (i = 0; i < ret; i++) { | ||
45 | if (flags & PROCESS_TEST_LOCKED && | ||
46 | !PageLocked(pages[i])) | ||
47 | count++; | ||
48 | if (flags & PROCESS_UNLOCK && PageLocked(pages[i])) | ||
49 | unlock_page(pages[i]); | ||
50 | page_cache_release(pages[i]); | ||
51 | if (flags & PROCESS_RELEASE) | ||
52 | page_cache_release(pages[i]); | ||
53 | } | ||
54 | nr_pages -= ret; | ||
55 | index += ret; | ||
56 | cond_resched(); | ||
57 | loops++; | ||
58 | if (loops > 100000) { | ||
59 | printk(KERN_ERR "stuck in a loop, start %Lu, end %Lu, nr_pages %lu, ret %d\n", start, end, nr_pages, ret); | ||
60 | break; | ||
61 | } | ||
62 | } | ||
63 | return count; | ||
64 | } | ||
65 | |||
66 | static int test_find_delalloc(void) | ||
67 | { | ||
68 | struct inode *inode; | ||
69 | struct extent_io_tree tmp; | ||
70 | struct page *page; | ||
71 | struct page *locked_page = NULL; | ||
72 | unsigned long index = 0; | ||
73 | u64 total_dirty = 256 * 1024 * 1024; | ||
74 | u64 max_bytes = 128 * 1024 * 1024; | ||
75 | u64 start, end, test_start; | ||
76 | u64 found; | ||
77 | int ret = -EINVAL; | ||
78 | |||
79 | inode = btrfs_new_test_inode(); | ||
80 | if (!inode) { | ||
81 | test_msg("Failed to allocate test inode\n"); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | |||
85 | extent_io_tree_init(&tmp, &inode->i_data); | ||
86 | |||
87 | /* | ||
88 | * First go through and create and mark all of our pages dirty, we pin | ||
89 | * everything to make sure our pages don't get evicted and screw up our | ||
90 | * test. | ||
91 | */ | ||
92 | for (index = 0; index < (total_dirty >> PAGE_CACHE_SHIFT); index++) { | ||
93 | page = find_or_create_page(inode->i_mapping, index, GFP_NOFS); | ||
94 | if (!page) { | ||
95 | test_msg("Failed to allocate test page\n"); | ||
96 | ret = -ENOMEM; | ||
97 | goto out; | ||
98 | } | ||
99 | SetPageDirty(page); | ||
100 | if (index) { | ||
101 | unlock_page(page); | ||
102 | } else { | ||
103 | page_cache_get(page); | ||
104 | locked_page = page; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | /* Test this scenario | ||
109 | * |--- delalloc ---| | ||
110 | * |--- search ---| | ||
111 | */ | ||
112 | set_extent_delalloc(&tmp, 0, 4095, NULL, GFP_NOFS); | ||
113 | start = 0; | ||
114 | end = 0; | ||
115 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
116 | &end, max_bytes); | ||
117 | if (!found) { | ||
118 | test_msg("Should have found at least one delalloc\n"); | ||
119 | goto out_bits; | ||
120 | } | ||
121 | if (start != 0 || end != 4095) { | ||
122 | test_msg("Expected start 0 end 4095, got start %Lu end %Lu\n", | ||
123 | start, end); | ||
124 | goto out_bits; | ||
125 | } | ||
126 | unlock_extent(&tmp, start, end); | ||
127 | unlock_page(locked_page); | ||
128 | page_cache_release(locked_page); | ||
129 | |||
130 | /* | ||
131 | * Test this scenario | ||
132 | * | ||
133 | * |--- delalloc ---| | ||
134 | * |--- search ---| | ||
135 | */ | ||
136 | test_start = 64 * 1024 * 1024; | ||
137 | locked_page = find_lock_page(inode->i_mapping, | ||
138 | test_start >> PAGE_CACHE_SHIFT); | ||
139 | if (!locked_page) { | ||
140 | test_msg("Couldn't find the locked page\n"); | ||
141 | goto out_bits; | ||
142 | } | ||
143 | set_extent_delalloc(&tmp, 4096, max_bytes - 1, NULL, GFP_NOFS); | ||
144 | start = test_start; | ||
145 | end = 0; | ||
146 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
147 | &end, max_bytes); | ||
148 | if (!found) { | ||
149 | test_msg("Couldn't find delalloc in our range\n"); | ||
150 | goto out_bits; | ||
151 | } | ||
152 | if (start != test_start || end != max_bytes - 1) { | ||
153 | test_msg("Expected start %Lu end %Lu, got start %Lu, end " | ||
154 | "%Lu\n", test_start, max_bytes - 1, start, end); | ||
155 | goto out_bits; | ||
156 | } | ||
157 | if (process_page_range(inode, start, end, | ||
158 | PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) { | ||
159 | test_msg("There were unlocked pages in the range\n"); | ||
160 | goto out_bits; | ||
161 | } | ||
162 | unlock_extent(&tmp, start, end); | ||
163 | /* locked_page was unlocked above */ | ||
164 | page_cache_release(locked_page); | ||
165 | |||
166 | /* | ||
167 | * Test this scenario | ||
168 | * |--- delalloc ---| | ||
169 | * |--- search ---| | ||
170 | */ | ||
171 | test_start = max_bytes + 4096; | ||
172 | locked_page = find_lock_page(inode->i_mapping, test_start >> | ||
173 | PAGE_CACHE_SHIFT); | ||
174 | if (!locked_page) { | ||
175 | test_msg("Could'nt find the locked page\n"); | ||
176 | goto out_bits; | ||
177 | } | ||
178 | start = test_start; | ||
179 | end = 0; | ||
180 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
181 | &end, max_bytes); | ||
182 | if (found) { | ||
183 | test_msg("Found range when we shouldn't have\n"); | ||
184 | goto out_bits; | ||
185 | } | ||
186 | if (end != (u64)-1) { | ||
187 | test_msg("Did not return the proper end offset\n"); | ||
188 | goto out_bits; | ||
189 | } | ||
190 | |||
191 | /* | ||
192 | * Test this scenario | ||
193 | * [------- delalloc -------| | ||
194 | * [max_bytes]|-- search--| | ||
195 | * | ||
196 | * We are re-using our test_start from above since it works out well. | ||
197 | */ | ||
198 | set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, NULL, GFP_NOFS); | ||
199 | start = test_start; | ||
200 | end = 0; | ||
201 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
202 | &end, max_bytes); | ||
203 | if (!found) { | ||
204 | test_msg("Didn't find our range\n"); | ||
205 | goto out_bits; | ||
206 | } | ||
207 | if (start != test_start || end != total_dirty - 1) { | ||
208 | test_msg("Expected start %Lu end %Lu, got start %Lu end %Lu\n", | ||
209 | test_start, total_dirty - 1, start, end); | ||
210 | goto out_bits; | ||
211 | } | ||
212 | if (process_page_range(inode, start, end, | ||
213 | PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) { | ||
214 | test_msg("Pages in range were not all locked\n"); | ||
215 | goto out_bits; | ||
216 | } | ||
217 | unlock_extent(&tmp, start, end); | ||
218 | |||
219 | /* | ||
220 | * Now to test where we run into a page that is no longer dirty in the | ||
221 | * range we want to find. | ||
222 | */ | ||
223 | page = find_get_page(inode->i_mapping, (max_bytes + (1 * 1024 * 1024)) | ||
224 | >> PAGE_CACHE_SHIFT); | ||
225 | if (!page) { | ||
226 | test_msg("Couldn't find our page\n"); | ||
227 | goto out_bits; | ||
228 | } | ||
229 | ClearPageDirty(page); | ||
230 | page_cache_release(page); | ||
231 | |||
232 | /* We unlocked it in the previous test */ | ||
233 | lock_page(locked_page); | ||
234 | start = test_start; | ||
235 | end = 0; | ||
236 | /* | ||
237 | * Currently if we fail to find dirty pages in the delalloc range we | ||
238 | * will adjust max_bytes down to PAGE_CACHE_SIZE and then re-search. If | ||
239 | * this changes at any point in the future we will need to fix this | ||
240 | * tests expected behavior. | ||
241 | */ | ||
242 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | ||
243 | &end, max_bytes); | ||
244 | if (!found) { | ||
245 | test_msg("Didn't find our range\n"); | ||
246 | goto out_bits; | ||
247 | } | ||
248 | if (start != test_start && end != test_start + PAGE_CACHE_SIZE - 1) { | ||
249 | test_msg("Expected start %Lu end %Lu, got start %Lu end %Lu\n", | ||
250 | test_start, test_start + PAGE_CACHE_SIZE - 1, start, | ||
251 | end); | ||
252 | goto out_bits; | ||
253 | } | ||
254 | if (process_page_range(inode, start, end, PROCESS_TEST_LOCKED | | ||
255 | PROCESS_UNLOCK)) { | ||
256 | test_msg("Pages in range were not all locked\n"); | ||
257 | goto out_bits; | ||
258 | } | ||
259 | ret = 0; | ||
260 | out_bits: | ||
261 | clear_extent_bits(&tmp, 0, total_dirty - 1, | ||
262 | (unsigned long)-1, GFP_NOFS); | ||
263 | out: | ||
264 | if (locked_page) | ||
265 | page_cache_release(locked_page); | ||
266 | process_page_range(inode, 0, total_dirty - 1, | ||
267 | PROCESS_UNLOCK | PROCESS_RELEASE); | ||
268 | iput(inode); | ||
269 | return ret; | ||
270 | } | ||
271 | |||
272 | int btrfs_test_extent_io(void) | ||
273 | { | ||
274 | test_msg("Running find delalloc tests\n"); | ||
275 | return test_find_delalloc(); | ||
276 | } | ||