diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents_status.c | 50 |
1 files changed, 24 insertions, 26 deletions
diff --git a/fs/ext4/extents_status.c b/fs/ext4/extents_status.c index eeb893122d8d..cce152c3c8dc 100644 --- a/fs/ext4/extents_status.c +++ b/fs/ext4/extents_status.c | |||
@@ -142,9 +142,8 @@ | |||
142 | 142 | ||
143 | static struct kmem_cache *ext4_es_cachep; | 143 | static struct kmem_cache *ext4_es_cachep; |
144 | 144 | ||
145 | static int __es_insert_extent(struct ext4_es_tree *tree, | 145 | static int __es_insert_extent(struct inode *inode, struct extent_status *newes); |
146 | struct extent_status *newes); | 146 | static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, |
147 | static int __es_remove_extent(struct ext4_es_tree *tree, ext4_lblk_t lblk, | ||
148 | ext4_lblk_t end); | 147 | ext4_lblk_t end); |
149 | 148 | ||
150 | int __init ext4_init_es(void) | 149 | int __init ext4_init_es(void) |
@@ -285,7 +284,8 @@ out: | |||
285 | } | 284 | } |
286 | 285 | ||
287 | static struct extent_status * | 286 | static struct extent_status * |
288 | ext4_es_alloc_extent(ext4_lblk_t lblk, ext4_lblk_t len, ext4_fsblk_t pblk) | 287 | ext4_es_alloc_extent(struct inode *inode, ext4_lblk_t lblk, ext4_lblk_t len, |
288 | ext4_fsblk_t pblk) | ||
289 | { | 289 | { |
290 | struct extent_status *es; | 290 | struct extent_status *es; |
291 | es = kmem_cache_alloc(ext4_es_cachep, GFP_ATOMIC); | 291 | es = kmem_cache_alloc(ext4_es_cachep, GFP_ATOMIC); |
@@ -297,7 +297,7 @@ ext4_es_alloc_extent(ext4_lblk_t lblk, ext4_lblk_t len, ext4_fsblk_t pblk) | |||
297 | return es; | 297 | return es; |
298 | } | 298 | } |
299 | 299 | ||
300 | static void ext4_es_free_extent(struct extent_status *es) | 300 | static void ext4_es_free_extent(struct inode *inode, struct extent_status *es) |
301 | { | 301 | { |
302 | kmem_cache_free(ext4_es_cachep, es); | 302 | kmem_cache_free(ext4_es_cachep, es); |
303 | } | 303 | } |
@@ -326,8 +326,9 @@ static int ext4_es_can_be_merged(struct extent_status *es1, | |||
326 | } | 326 | } |
327 | 327 | ||
328 | static struct extent_status * | 328 | static struct extent_status * |
329 | ext4_es_try_to_merge_left(struct ext4_es_tree *tree, struct extent_status *es) | 329 | ext4_es_try_to_merge_left(struct inode *inode, struct extent_status *es) |
330 | { | 330 | { |
331 | struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; | ||
331 | struct extent_status *es1; | 332 | struct extent_status *es1; |
332 | struct rb_node *node; | 333 | struct rb_node *node; |
333 | 334 | ||
@@ -339,7 +340,7 @@ ext4_es_try_to_merge_left(struct ext4_es_tree *tree, struct extent_status *es) | |||
339 | if (ext4_es_can_be_merged(es1, es)) { | 340 | if (ext4_es_can_be_merged(es1, es)) { |
340 | es1->es_len += es->es_len; | 341 | es1->es_len += es->es_len; |
341 | rb_erase(&es->rb_node, &tree->root); | 342 | rb_erase(&es->rb_node, &tree->root); |
342 | ext4_es_free_extent(es); | 343 | ext4_es_free_extent(inode, es); |
343 | es = es1; | 344 | es = es1; |
344 | } | 345 | } |
345 | 346 | ||
@@ -347,8 +348,9 @@ ext4_es_try_to_merge_left(struct ext4_es_tree *tree, struct extent_status *es) | |||
347 | } | 348 | } |
348 | 349 | ||
349 | static struct extent_status * | 350 | static struct extent_status * |
350 | ext4_es_try_to_merge_right(struct ext4_es_tree *tree, struct extent_status *es) | 351 | ext4_es_try_to_merge_right(struct inode *inode, struct extent_status *es) |
351 | { | 352 | { |
353 | struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; | ||
352 | struct extent_status *es1; | 354 | struct extent_status *es1; |
353 | struct rb_node *node; | 355 | struct rb_node *node; |
354 | 356 | ||
@@ -360,15 +362,15 @@ ext4_es_try_to_merge_right(struct ext4_es_tree *tree, struct extent_status *es) | |||
360 | if (ext4_es_can_be_merged(es, es1)) { | 362 | if (ext4_es_can_be_merged(es, es1)) { |
361 | es->es_len += es1->es_len; | 363 | es->es_len += es1->es_len; |
362 | rb_erase(node, &tree->root); | 364 | rb_erase(node, &tree->root); |
363 | ext4_es_free_extent(es1); | 365 | ext4_es_free_extent(inode, es1); |
364 | } | 366 | } |
365 | 367 | ||
366 | return es; | 368 | return es; |
367 | } | 369 | } |
368 | 370 | ||
369 | static int __es_insert_extent(struct ext4_es_tree *tree, | 371 | static int __es_insert_extent(struct inode *inode, struct extent_status *newes) |
370 | struct extent_status *newes) | ||
371 | { | 372 | { |
373 | struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; | ||
372 | struct rb_node **p = &tree->root.rb_node; | 374 | struct rb_node **p = &tree->root.rb_node; |
373 | struct rb_node *parent = NULL; | 375 | struct rb_node *parent = NULL; |
374 | struct extent_status *es; | 376 | struct extent_status *es; |
@@ -389,14 +391,14 @@ static int __es_insert_extent(struct ext4_es_tree *tree, | |||
389 | ext4_es_is_unwritten(es)) | 391 | ext4_es_is_unwritten(es)) |
390 | ext4_es_store_pblock(es, | 392 | ext4_es_store_pblock(es, |
391 | newes->es_pblk); | 393 | newes->es_pblk); |
392 | es = ext4_es_try_to_merge_left(tree, es); | 394 | es = ext4_es_try_to_merge_left(inode, es); |
393 | goto out; | 395 | goto out; |
394 | } | 396 | } |
395 | p = &(*p)->rb_left; | 397 | p = &(*p)->rb_left; |
396 | } else if (newes->es_lblk > ext4_es_end(es)) { | 398 | } else if (newes->es_lblk > ext4_es_end(es)) { |
397 | if (ext4_es_can_be_merged(es, newes)) { | 399 | if (ext4_es_can_be_merged(es, newes)) { |
398 | es->es_len += newes->es_len; | 400 | es->es_len += newes->es_len; |
399 | es = ext4_es_try_to_merge_right(tree, es); | 401 | es = ext4_es_try_to_merge_right(inode, es); |
400 | goto out; | 402 | goto out; |
401 | } | 403 | } |
402 | p = &(*p)->rb_right; | 404 | p = &(*p)->rb_right; |
@@ -406,7 +408,7 @@ static int __es_insert_extent(struct ext4_es_tree *tree, | |||
406 | } | 408 | } |
407 | } | 409 | } |
408 | 410 | ||
409 | es = ext4_es_alloc_extent(newes->es_lblk, newes->es_len, | 411 | es = ext4_es_alloc_extent(inode, newes->es_lblk, newes->es_len, |
410 | newes->es_pblk); | 412 | newes->es_pblk); |
411 | if (!es) | 413 | if (!es) |
412 | return -ENOMEM; | 414 | return -ENOMEM; |
@@ -430,7 +432,6 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, | |||
430 | ext4_lblk_t len, ext4_fsblk_t pblk, | 432 | ext4_lblk_t len, ext4_fsblk_t pblk, |
431 | unsigned long long status) | 433 | unsigned long long status) |
432 | { | 434 | { |
433 | struct ext4_es_tree *tree; | ||
434 | struct extent_status newes; | 435 | struct extent_status newes; |
435 | ext4_lblk_t end = lblk + len - 1; | 436 | ext4_lblk_t end = lblk + len - 1; |
436 | int err = 0; | 437 | int err = 0; |
@@ -447,11 +448,10 @@ int ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, | |||
447 | trace_ext4_es_insert_extent(inode, &newes); | 448 | trace_ext4_es_insert_extent(inode, &newes); |
448 | 449 | ||
449 | write_lock(&EXT4_I(inode)->i_es_lock); | 450 | write_lock(&EXT4_I(inode)->i_es_lock); |
450 | tree = &EXT4_I(inode)->i_es_tree; | 451 | err = __es_remove_extent(inode, lblk, end); |
451 | err = __es_remove_extent(tree, lblk, end); | ||
452 | if (err != 0) | 452 | if (err != 0) |
453 | goto error; | 453 | goto error; |
454 | err = __es_insert_extent(tree, &newes); | 454 | err = __es_insert_extent(inode, &newes); |
455 | 455 | ||
456 | error: | 456 | error: |
457 | write_unlock(&EXT4_I(inode)->i_es_lock); | 457 | write_unlock(&EXT4_I(inode)->i_es_lock); |
@@ -521,9 +521,10 @@ out: | |||
521 | return found; | 521 | return found; |
522 | } | 522 | } |
523 | 523 | ||
524 | static int __es_remove_extent(struct ext4_es_tree *tree, ext4_lblk_t lblk, | 524 | static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk, |
525 | ext4_lblk_t end) | 525 | ext4_lblk_t end) |
526 | { | 526 | { |
527 | struct ext4_es_tree *tree = &EXT4_I(inode)->i_es_tree; | ||
527 | struct rb_node *node; | 528 | struct rb_node *node; |
528 | struct extent_status *es; | 529 | struct extent_status *es; |
529 | struct extent_status orig_es; | 530 | struct extent_status orig_es; |
@@ -561,7 +562,7 @@ static int __es_remove_extent(struct ext4_es_tree *tree, ext4_lblk_t lblk, | |||
561 | ext4_es_store_pblock(&newes, block); | 562 | ext4_es_store_pblock(&newes, block); |
562 | } | 563 | } |
563 | ext4_es_store_status(&newes, ext4_es_status(&orig_es)); | 564 | ext4_es_store_status(&newes, ext4_es_status(&orig_es)); |
564 | err = __es_insert_extent(tree, &newes); | 565 | err = __es_insert_extent(inode, &newes); |
565 | if (err) { | 566 | if (err) { |
566 | es->es_lblk = orig_es.es_lblk; | 567 | es->es_lblk = orig_es.es_lblk; |
567 | es->es_len = orig_es.es_len; | 568 | es->es_len = orig_es.es_len; |
@@ -590,7 +591,7 @@ static int __es_remove_extent(struct ext4_es_tree *tree, ext4_lblk_t lblk, | |||
590 | while (es && ext4_es_end(es) <= end) { | 591 | while (es && ext4_es_end(es) <= end) { |
591 | node = rb_next(&es->rb_node); | 592 | node = rb_next(&es->rb_node); |
592 | rb_erase(&es->rb_node, &tree->root); | 593 | rb_erase(&es->rb_node, &tree->root); |
593 | ext4_es_free_extent(es); | 594 | ext4_es_free_extent(inode, es); |
594 | if (!node) { | 595 | if (!node) { |
595 | es = NULL; | 596 | es = NULL; |
596 | break; | 597 | break; |
@@ -622,7 +623,6 @@ out: | |||
622 | int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, | 623 | int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, |
623 | ext4_lblk_t len) | 624 | ext4_lblk_t len) |
624 | { | 625 | { |
625 | struct ext4_es_tree *tree; | ||
626 | ext4_lblk_t end; | 626 | ext4_lblk_t end; |
627 | int err = 0; | 627 | int err = 0; |
628 | 628 | ||
@@ -633,10 +633,8 @@ int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, | |||
633 | end = lblk + len - 1; | 633 | end = lblk + len - 1; |
634 | BUG_ON(end < lblk); | 634 | BUG_ON(end < lblk); |
635 | 635 | ||
636 | tree = &EXT4_I(inode)->i_es_tree; | ||
637 | |||
638 | write_lock(&EXT4_I(inode)->i_es_lock); | 636 | write_lock(&EXT4_I(inode)->i_es_lock); |
639 | err = __es_remove_extent(tree, lblk, end); | 637 | err = __es_remove_extent(inode, lblk, end); |
640 | write_unlock(&EXT4_I(inode)->i_es_lock); | 638 | write_unlock(&EXT4_I(inode)->i_es_lock); |
641 | ext4_es_print_tree(inode); | 639 | ext4_es_print_tree(inode); |
642 | return err; | 640 | return err; |