diff options
| -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); |
