aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/extents_status.c
diff options
context:
space:
mode:
authorZheng Liu <wenqing.lz@taobao.com>2013-02-18 00:32:02 -0500
committerTheodore Ts'o <tytso@mit.edu>2013-02-18 00:32:02 -0500
commitbdedbb7b8d5b960e1ff0d116f5d4935febe73183 (patch)
tree4e9a5d708e73bf8bdc39fede73d080b950b921a9 /fs/ext4/extents_status.c
parent69eb33dc24dc44d1128aa5e82d0976c42b440c1a (diff)
ext4: adjust some functions for reclaiming extents from extent status tree
This commit changes some interfaces in extent status tree because we need to use inode to count the cached objects in a extent status tree. Signed-off-by: Zheng Liu <wenqing.lz@taobao.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: Jan kara <jack@suse.cz>
Diffstat (limited to 'fs/ext4/extents_status.c')
-rw-r--r--fs/ext4/extents_status.c50
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
143static struct kmem_cache *ext4_es_cachep; 143static struct kmem_cache *ext4_es_cachep;
144 144
145static int __es_insert_extent(struct ext4_es_tree *tree, 145static int __es_insert_extent(struct inode *inode, struct extent_status *newes);
146 struct extent_status *newes); 146static int __es_remove_extent(struct inode *inode, ext4_lblk_t lblk,
147static 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
150int __init ext4_init_es(void) 149int __init ext4_init_es(void)
@@ -285,7 +284,8 @@ out:
285} 284}
286 285
287static struct extent_status * 286static struct extent_status *
288ext4_es_alloc_extent(ext4_lblk_t lblk, ext4_lblk_t len, ext4_fsblk_t pblk) 287ext4_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
300static void ext4_es_free_extent(struct extent_status *es) 300static 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
328static struct extent_status * 328static struct extent_status *
329ext4_es_try_to_merge_left(struct ext4_es_tree *tree, struct extent_status *es) 329ext4_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
349static struct extent_status * 350static struct extent_status *
350ext4_es_try_to_merge_right(struct ext4_es_tree *tree, struct extent_status *es) 351ext4_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
369static int __es_insert_extent(struct ext4_es_tree *tree, 371static 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
456error: 456error:
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
524static int __es_remove_extent(struct ext4_es_tree *tree, ext4_lblk_t lblk, 524static 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:
622int ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk, 623int 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;