diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
---|---|---|
committer | Glenn Elliott <gelliott@cs.unc.edu> | 2012-03-04 19:47:13 -0500 |
commit | c71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch) | |
tree | ecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /fs/btrfs/ordered-data.c | |
parent | ea53c912f8a86a8567697115b6a0d8152beee5c8 (diff) | |
parent | 6a00f206debf8a5c8899055726ad127dbeeed098 (diff) |
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts:
litmus/sched_cedf.c
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r-- | fs/btrfs/ordered-data.c | 97 |
1 files changed, 91 insertions, 6 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index e56c72bc5add..a1c940425307 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -141,7 +141,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, | |||
141 | u64 file_offset) | 141 | u64 file_offset) |
142 | { | 142 | { |
143 | struct rb_root *root = &tree->tree; | 143 | struct rb_root *root = &tree->tree; |
144 | struct rb_node *prev; | 144 | struct rb_node *prev = NULL; |
145 | struct rb_node *ret; | 145 | struct rb_node *ret; |
146 | struct btrfs_ordered_extent *entry; | 146 | struct btrfs_ordered_extent *entry; |
147 | 147 | ||
@@ -172,7 +172,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, | |||
172 | */ | 172 | */ |
173 | static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | 173 | static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, |
174 | u64 start, u64 len, u64 disk_len, | 174 | u64 start, u64 len, u64 disk_len, |
175 | int type, int dio) | 175 | int type, int dio, int compress_type) |
176 | { | 176 | { |
177 | struct btrfs_ordered_inode_tree *tree; | 177 | struct btrfs_ordered_inode_tree *tree; |
178 | struct rb_node *node; | 178 | struct rb_node *node; |
@@ -189,6 +189,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
189 | entry->disk_len = disk_len; | 189 | entry->disk_len = disk_len; |
190 | entry->bytes_left = len; | 190 | entry->bytes_left = len; |
191 | entry->inode = inode; | 191 | entry->inode = inode; |
192 | entry->compress_type = compress_type; | ||
192 | if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) | 193 | if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) |
193 | set_bit(type, &entry->flags); | 194 | set_bit(type, &entry->flags); |
194 | 195 | ||
@@ -201,6 +202,8 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
201 | INIT_LIST_HEAD(&entry->list); | 202 | INIT_LIST_HEAD(&entry->list); |
202 | INIT_LIST_HEAD(&entry->root_extent_list); | 203 | INIT_LIST_HEAD(&entry->root_extent_list); |
203 | 204 | ||
205 | trace_btrfs_ordered_extent_add(inode, entry); | ||
206 | |||
204 | spin_lock(&tree->lock); | 207 | spin_lock(&tree->lock); |
205 | node = tree_insert(&tree->tree, file_offset, | 208 | node = tree_insert(&tree->tree, file_offset, |
206 | &entry->rb_node); | 209 | &entry->rb_node); |
@@ -220,14 +223,25 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
220 | u64 start, u64 len, u64 disk_len, int type) | 223 | u64 start, u64 len, u64 disk_len, int type) |
221 | { | 224 | { |
222 | return __btrfs_add_ordered_extent(inode, file_offset, start, len, | 225 | return __btrfs_add_ordered_extent(inode, file_offset, start, len, |
223 | disk_len, type, 0); | 226 | disk_len, type, 0, |
227 | BTRFS_COMPRESS_NONE); | ||
224 | } | 228 | } |
225 | 229 | ||
226 | int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, | 230 | int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, |
227 | u64 start, u64 len, u64 disk_len, int type) | 231 | u64 start, u64 len, u64 disk_len, int type) |
228 | { | 232 | { |
229 | return __btrfs_add_ordered_extent(inode, file_offset, start, len, | 233 | return __btrfs_add_ordered_extent(inode, file_offset, start, len, |
230 | disk_len, type, 1); | 234 | disk_len, type, 1, |
235 | BTRFS_COMPRESS_NONE); | ||
236 | } | ||
237 | |||
238 | int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset, | ||
239 | u64 start, u64 len, u64 disk_len, | ||
240 | int type, int compress_type) | ||
241 | { | ||
242 | return __btrfs_add_ordered_extent(inode, file_offset, start, len, | ||
243 | disk_len, type, 0, | ||
244 | compress_type); | ||
231 | } | 245 | } |
232 | 246 | ||
233 | /* | 247 | /* |
@@ -250,6 +264,73 @@ int btrfs_add_ordered_sum(struct inode *inode, | |||
250 | 264 | ||
251 | /* | 265 | /* |
252 | * this is used to account for finished IO across a given range | 266 | * this is used to account for finished IO across a given range |
267 | * of the file. The IO may span ordered extents. If | ||
268 | * a given ordered_extent is completely done, 1 is returned, otherwise | ||
269 | * 0. | ||
270 | * | ||
271 | * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used | ||
272 | * to make sure this function only returns 1 once for a given ordered extent. | ||
273 | * | ||
274 | * file_offset is updated to one byte past the range that is recorded as | ||
275 | * complete. This allows you to walk forward in the file. | ||
276 | */ | ||
277 | int btrfs_dec_test_first_ordered_pending(struct inode *inode, | ||
278 | struct btrfs_ordered_extent **cached, | ||
279 | u64 *file_offset, u64 io_size) | ||
280 | { | ||
281 | struct btrfs_ordered_inode_tree *tree; | ||
282 | struct rb_node *node; | ||
283 | struct btrfs_ordered_extent *entry = NULL; | ||
284 | int ret; | ||
285 | u64 dec_end; | ||
286 | u64 dec_start; | ||
287 | u64 to_dec; | ||
288 | |||
289 | tree = &BTRFS_I(inode)->ordered_tree; | ||
290 | spin_lock(&tree->lock); | ||
291 | node = tree_search(tree, *file_offset); | ||
292 | if (!node) { | ||
293 | ret = 1; | ||
294 | goto out; | ||
295 | } | ||
296 | |||
297 | entry = rb_entry(node, struct btrfs_ordered_extent, rb_node); | ||
298 | if (!offset_in_entry(entry, *file_offset)) { | ||
299 | ret = 1; | ||
300 | goto out; | ||
301 | } | ||
302 | |||
303 | dec_start = max(*file_offset, entry->file_offset); | ||
304 | dec_end = min(*file_offset + io_size, entry->file_offset + | ||
305 | entry->len); | ||
306 | *file_offset = dec_end; | ||
307 | if (dec_start > dec_end) { | ||
308 | printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n", | ||
309 | (unsigned long long)dec_start, | ||
310 | (unsigned long long)dec_end); | ||
311 | } | ||
312 | to_dec = dec_end - dec_start; | ||
313 | if (to_dec > entry->bytes_left) { | ||
314 | printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n", | ||
315 | (unsigned long long)entry->bytes_left, | ||
316 | (unsigned long long)to_dec); | ||
317 | } | ||
318 | entry->bytes_left -= to_dec; | ||
319 | if (entry->bytes_left == 0) | ||
320 | ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags); | ||
321 | else | ||
322 | ret = 1; | ||
323 | out: | ||
324 | if (!ret && cached && entry) { | ||
325 | *cached = entry; | ||
326 | atomic_inc(&entry->refs); | ||
327 | } | ||
328 | spin_unlock(&tree->lock); | ||
329 | return ret == 0; | ||
330 | } | ||
331 | |||
332 | /* | ||
333 | * this is used to account for finished IO across a given range | ||
253 | * of the file. The IO should not span ordered extents. If | 334 | * of the file. The IO should not span ordered extents. If |
254 | * a given ordered_extent is completely done, 1 is returned, otherwise | 335 | * a given ordered_extent is completely done, 1 is returned, otherwise |
255 | * 0. | 336 | * 0. |
@@ -308,6 +389,8 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry) | |||
308 | struct list_head *cur; | 389 | struct list_head *cur; |
309 | struct btrfs_ordered_sum *sum; | 390 | struct btrfs_ordered_sum *sum; |
310 | 391 | ||
392 | trace_btrfs_ordered_extent_put(entry->inode, entry); | ||
393 | |||
311 | if (atomic_dec_and_test(&entry->refs)) { | 394 | if (atomic_dec_and_test(&entry->refs)) { |
312 | while (!list_empty(&entry->list)) { | 395 | while (!list_empty(&entry->list)) { |
313 | cur = entry->list.next; | 396 | cur = entry->list.next; |
@@ -341,6 +424,8 @@ static int __btrfs_remove_ordered_extent(struct inode *inode, | |||
341 | spin_lock(&root->fs_info->ordered_extent_lock); | 424 | spin_lock(&root->fs_info->ordered_extent_lock); |
342 | list_del_init(&entry->root_extent_list); | 425 | list_del_init(&entry->root_extent_list); |
343 | 426 | ||
427 | trace_btrfs_ordered_extent_remove(inode, entry); | ||
428 | |||
344 | /* | 429 | /* |
345 | * we have no more ordered extents for this inode and | 430 | * we have no more ordered extents for this inode and |
346 | * no dirty pages. We can safely remove it from the | 431 | * no dirty pages. We can safely remove it from the |
@@ -506,6 +591,8 @@ void btrfs_start_ordered_extent(struct inode *inode, | |||
506 | u64 start = entry->file_offset; | 591 | u64 start = entry->file_offset; |
507 | u64 end = start + entry->len - 1; | 592 | u64 end = start + entry->len - 1; |
508 | 593 | ||
594 | trace_btrfs_ordered_extent_start(inode, entry); | ||
595 | |||
509 | /* | 596 | /* |
510 | * pages in the range can be dirty, clean or writeback. We | 597 | * pages in the range can be dirty, clean or writeback. We |
511 | * start IO on any dirty ones so the wait doesn't stall waiting | 598 | * start IO on any dirty ones so the wait doesn't stall waiting |
@@ -526,7 +613,6 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
526 | { | 613 | { |
527 | u64 end; | 614 | u64 end; |
528 | u64 orig_end; | 615 | u64 orig_end; |
529 | u64 wait_end; | ||
530 | struct btrfs_ordered_extent *ordered; | 616 | struct btrfs_ordered_extent *ordered; |
531 | int found; | 617 | int found; |
532 | 618 | ||
@@ -537,7 +623,6 @@ int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len) | |||
537 | if (orig_end > INT_LIMIT(loff_t)) | 623 | if (orig_end > INT_LIMIT(loff_t)) |
538 | orig_end = INT_LIMIT(loff_t); | 624 | orig_end = INT_LIMIT(loff_t); |
539 | } | 625 | } |
540 | wait_end = orig_end; | ||
541 | again: | 626 | again: |
542 | /* start IO across the range first to instantiate any delalloc | 627 | /* start IO across the range first to instantiate any delalloc |
543 | * extents | 628 | * extents |