diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-05-23 14:25:44 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-06-10 10:41:10 -0400 |
commit | d4b961576df2769b936bd967b01e8c607c3c9ad8 (patch) | |
tree | 3d5d31cb7b4ba31a5b8232d0cd0edac2cf368fae /fs/nilfs2/bmap.c | |
parent | 3033342a0b76048e32ce1faebfa85cf8f1aa93b5 (diff) |
nilfs2: remove bmap pointer operations
Previously, the bmap codes of nilfs used three types of function
tables. The abuse of indirect function calls decreased source
readability and suffered many indirect jumps which would confuse
branch prediction of processors.
This eliminates one type of the function tables,
nilfs_bmap_ptr_operations, which was used to dispatch low level
pointer operations of the nilfs bmap.
This adds a new integer variable "b_ptr_type" to nilfs_bmap struct,
and uses the value to select the pointer operations.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/bmap.c')
-rw-r--r-- | fs/nilfs2/bmap.c | 181 |
1 files changed, 52 insertions, 129 deletions
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index de67d2a12515..51824c764294 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
@@ -31,21 +31,26 @@ | |||
31 | #include "dat.h" | 31 | #include "dat.h" |
32 | #include "alloc.h" | 32 | #include "alloc.h" |
33 | 33 | ||
34 | static struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap) | ||
35 | { | ||
36 | return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode)); | ||
37 | } | ||
38 | |||
34 | int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, | 39 | int nilfs_bmap_lookup_at_level(struct nilfs_bmap *bmap, __u64 key, int level, |
35 | __u64 *ptrp) | 40 | __u64 *ptrp) |
36 | { | 41 | { |
37 | __u64 ptr; | 42 | sector_t blocknr; |
38 | int ret; | 43 | int ret; |
39 | 44 | ||
40 | down_read(&bmap->b_sem); | 45 | down_read(&bmap->b_sem); |
41 | ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp); | 46 | ret = bmap->b_ops->bop_lookup(bmap, key, level, ptrp); |
42 | if (ret < 0) | 47 | if (ret < 0) |
43 | goto out; | 48 | goto out; |
44 | if (bmap->b_pops->bpop_translate != NULL) { | 49 | if (NILFS_BMAP_USE_VBN(bmap)) { |
45 | ret = bmap->b_pops->bpop_translate(bmap, *ptrp, &ptr); | 50 | ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), *ptrp, |
46 | if (ret < 0) | 51 | &blocknr); |
47 | goto out; | 52 | if (!ret) |
48 | *ptrp = ptr; | 53 | *ptrp = blocknr; |
49 | } | 54 | } |
50 | 55 | ||
51 | out: | 56 | out: |
@@ -442,11 +447,6 @@ __u64 nilfs_bmap_find_target_seq(const struct nilfs_bmap *bmap, __u64 key) | |||
442 | return NILFS_BMAP_INVALID_PTR; | 447 | return NILFS_BMAP_INVALID_PTR; |
443 | } | 448 | } |
444 | 449 | ||
445 | static struct inode *nilfs_bmap_get_dat(const struct nilfs_bmap *bmap) | ||
446 | { | ||
447 | return nilfs_dat_inode(NILFS_I_NILFS(bmap->b_inode)); | ||
448 | } | ||
449 | |||
450 | #define NILFS_BMAP_GROUP_DIV 8 | 450 | #define NILFS_BMAP_GROUP_DIV 8 |
451 | __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap) | 451 | __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap) |
452 | { | 452 | { |
@@ -459,20 +459,20 @@ __u64 nilfs_bmap_find_target_in_group(const struct nilfs_bmap *bmap) | |||
459 | (entries_per_group / NILFS_BMAP_GROUP_DIV); | 459 | (entries_per_group / NILFS_BMAP_GROUP_DIV); |
460 | } | 460 | } |
461 | 461 | ||
462 | static int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap, | 462 | int nilfs_bmap_prepare_alloc_v(struct nilfs_bmap *bmap, |
463 | union nilfs_bmap_ptr_req *req) | 463 | union nilfs_bmap_ptr_req *req) |
464 | { | 464 | { |
465 | return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); | 465 | return nilfs_dat_prepare_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); |
466 | } | 466 | } |
467 | 467 | ||
468 | static void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap, | 468 | void nilfs_bmap_commit_alloc_v(struct nilfs_bmap *bmap, |
469 | union nilfs_bmap_ptr_req *req) | 469 | union nilfs_bmap_ptr_req *req) |
470 | { | 470 | { |
471 | nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); | 471 | nilfs_dat_commit_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); |
472 | } | 472 | } |
473 | 473 | ||
474 | static void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap, | 474 | void nilfs_bmap_abort_alloc_v(struct nilfs_bmap *bmap, |
475 | union nilfs_bmap_ptr_req *req) | 475 | union nilfs_bmap_ptr_req *req) |
476 | { | 476 | { |
477 | nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); | 477 | nilfs_dat_abort_alloc(nilfs_bmap_get_dat(bmap), &req->bpr_req); |
478 | } | 478 | } |
@@ -489,26 +489,21 @@ int nilfs_bmap_start_v(struct nilfs_bmap *bmap, union nilfs_bmap_ptr_req *req, | |||
489 | return ret; | 489 | return ret; |
490 | } | 490 | } |
491 | 491 | ||
492 | static int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap, | 492 | int nilfs_bmap_prepare_end_v(struct nilfs_bmap *bmap, |
493 | union nilfs_bmap_ptr_req *req) | 493 | union nilfs_bmap_ptr_req *req) |
494 | { | 494 | { |
495 | return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req); | 495 | return nilfs_dat_prepare_end(nilfs_bmap_get_dat(bmap), &req->bpr_req); |
496 | } | 496 | } |
497 | 497 | ||
498 | static void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap, | 498 | void nilfs_bmap_commit_end_v(struct nilfs_bmap *bmap, |
499 | union nilfs_bmap_ptr_req *req) | 499 | union nilfs_bmap_ptr_req *req) |
500 | { | ||
501 | nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 0); | ||
502 | } | ||
503 | |||
504 | static void nilfs_bmap_commit_end_vmdt(struct nilfs_bmap *bmap, | ||
505 | union nilfs_bmap_ptr_req *req) | ||
506 | { | 500 | { |
507 | nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, 1); | 501 | nilfs_dat_commit_end(nilfs_bmap_get_dat(bmap), &req->bpr_req, |
502 | bmap->b_ptr_type == NILFS_BMAP_PTR_VS); | ||
508 | } | 503 | } |
509 | 504 | ||
510 | static void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap, | 505 | void nilfs_bmap_abort_end_v(struct nilfs_bmap *bmap, |
511 | union nilfs_bmap_ptr_req *req) | 506 | union nilfs_bmap_ptr_req *req) |
512 | { | 507 | { |
513 | nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req); | 508 | nilfs_dat_abort_end(nilfs_bmap_get_dat(bmap), &req->bpr_req); |
514 | } | 509 | } |
@@ -524,116 +519,44 @@ int nilfs_bmap_mark_dirty(const struct nilfs_bmap *bmap, __u64 vblocknr) | |||
524 | return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr); | 519 | return nilfs_dat_mark_dirty(nilfs_bmap_get_dat(bmap), vblocknr); |
525 | } | 520 | } |
526 | 521 | ||
527 | int nilfs_bmap_prepare_update(struct nilfs_bmap *bmap, | 522 | int nilfs_bmap_prepare_update_v(struct nilfs_bmap *bmap, |
528 | union nilfs_bmap_ptr_req *oldreq, | 523 | union nilfs_bmap_ptr_req *oldreq, |
529 | union nilfs_bmap_ptr_req *newreq) | 524 | union nilfs_bmap_ptr_req *newreq) |
530 | { | 525 | { |
526 | struct inode *dat = nilfs_bmap_get_dat(bmap); | ||
531 | int ret; | 527 | int ret; |
532 | 528 | ||
533 | ret = bmap->b_pops->bpop_prepare_end_ptr(bmap, oldreq); | 529 | ret = nilfs_dat_prepare_end(dat, &oldreq->bpr_req); |
534 | if (ret < 0) | 530 | if (ret < 0) |
535 | return ret; | 531 | return ret; |
536 | ret = bmap->b_pops->bpop_prepare_alloc_ptr(bmap, newreq); | 532 | ret = nilfs_dat_prepare_alloc(dat, &newreq->bpr_req); |
537 | if (ret < 0) | 533 | if (ret < 0) |
538 | bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq); | 534 | nilfs_dat_abort_end(dat, &oldreq->bpr_req); |
539 | 535 | ||
540 | return ret; | 536 | return ret; |
541 | } | 537 | } |
542 | 538 | ||
543 | void nilfs_bmap_commit_update(struct nilfs_bmap *bmap, | 539 | void nilfs_bmap_commit_update_v(struct nilfs_bmap *bmap, |
544 | union nilfs_bmap_ptr_req *oldreq, | 540 | union nilfs_bmap_ptr_req *oldreq, |
545 | union nilfs_bmap_ptr_req *newreq) | 541 | union nilfs_bmap_ptr_req *newreq) |
546 | { | ||
547 | bmap->b_pops->bpop_commit_end_ptr(bmap, oldreq); | ||
548 | bmap->b_pops->bpop_commit_alloc_ptr(bmap, newreq); | ||
549 | } | ||
550 | |||
551 | void nilfs_bmap_abort_update(struct nilfs_bmap *bmap, | ||
552 | union nilfs_bmap_ptr_req *oldreq, | ||
553 | union nilfs_bmap_ptr_req *newreq) | ||
554 | { | ||
555 | bmap->b_pops->bpop_abort_end_ptr(bmap, oldreq); | ||
556 | bmap->b_pops->bpop_abort_alloc_ptr(bmap, newreq); | ||
557 | } | ||
558 | |||
559 | static int nilfs_bmap_translate_v(const struct nilfs_bmap *bmap, __u64 ptr, | ||
560 | __u64 *ptrp) | ||
561 | { | 542 | { |
562 | sector_t blocknr; | 543 | struct inode *dat = nilfs_bmap_get_dat(bmap); |
563 | int ret; | ||
564 | |||
565 | ret = nilfs_dat_translate(nilfs_bmap_get_dat(bmap), ptr, &blocknr); | ||
566 | if (ret < 0) | ||
567 | return ret; | ||
568 | if (ptrp != NULL) | ||
569 | *ptrp = blocknr; | ||
570 | return 0; | ||
571 | } | ||
572 | 544 | ||
573 | static int nilfs_bmap_prepare_alloc_p(struct nilfs_bmap *bmap, | 545 | nilfs_dat_commit_end(dat, &oldreq->bpr_req, |
574 | union nilfs_bmap_ptr_req *req) | 546 | bmap->b_ptr_type == NILFS_BMAP_PTR_VS); |
575 | { | 547 | nilfs_dat_commit_alloc(dat, &newreq->bpr_req); |
576 | /* ignore target ptr */ | ||
577 | req->bpr_ptr = bmap->b_last_allocated_ptr++; | ||
578 | return 0; | ||
579 | } | 548 | } |
580 | 549 | ||
581 | static void nilfs_bmap_commit_alloc_p(struct nilfs_bmap *bmap, | 550 | void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap, |
582 | union nilfs_bmap_ptr_req *req) | 551 | union nilfs_bmap_ptr_req *oldreq, |
552 | union nilfs_bmap_ptr_req *newreq) | ||
583 | { | 553 | { |
584 | /* do nothing */ | 554 | struct inode *dat = nilfs_bmap_get_dat(bmap); |
585 | } | ||
586 | 555 | ||
587 | static void nilfs_bmap_abort_alloc_p(struct nilfs_bmap *bmap, | 556 | nilfs_dat_abort_end(dat, &oldreq->bpr_req); |
588 | union nilfs_bmap_ptr_req *req) | 557 | nilfs_dat_abort_alloc(dat, &newreq->bpr_req); |
589 | { | ||
590 | bmap->b_last_allocated_ptr--; | ||
591 | } | 558 | } |
592 | 559 | ||
593 | static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_v = { | ||
594 | .bpop_prepare_alloc_ptr = nilfs_bmap_prepare_alloc_v, | ||
595 | .bpop_commit_alloc_ptr = nilfs_bmap_commit_alloc_v, | ||
596 | .bpop_abort_alloc_ptr = nilfs_bmap_abort_alloc_v, | ||
597 | .bpop_prepare_end_ptr = nilfs_bmap_prepare_end_v, | ||
598 | .bpop_commit_end_ptr = nilfs_bmap_commit_end_v, | ||
599 | .bpop_abort_end_ptr = nilfs_bmap_abort_end_v, | ||
600 | |||
601 | .bpop_translate = nilfs_bmap_translate_v, | ||
602 | }; | ||
603 | |||
604 | static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_vmdt = { | ||
605 | .bpop_prepare_alloc_ptr = nilfs_bmap_prepare_alloc_v, | ||
606 | .bpop_commit_alloc_ptr = nilfs_bmap_commit_alloc_v, | ||
607 | .bpop_abort_alloc_ptr = nilfs_bmap_abort_alloc_v, | ||
608 | .bpop_prepare_end_ptr = nilfs_bmap_prepare_end_v, | ||
609 | .bpop_commit_end_ptr = nilfs_bmap_commit_end_vmdt, | ||
610 | .bpop_abort_end_ptr = nilfs_bmap_abort_end_v, | ||
611 | |||
612 | .bpop_translate = nilfs_bmap_translate_v, | ||
613 | }; | ||
614 | |||
615 | static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_p = { | ||
616 | .bpop_prepare_alloc_ptr = nilfs_bmap_prepare_alloc_p, | ||
617 | .bpop_commit_alloc_ptr = nilfs_bmap_commit_alloc_p, | ||
618 | .bpop_abort_alloc_ptr = nilfs_bmap_abort_alloc_p, | ||
619 | .bpop_prepare_end_ptr = NULL, | ||
620 | .bpop_commit_end_ptr = NULL, | ||
621 | .bpop_abort_end_ptr = NULL, | ||
622 | |||
623 | .bpop_translate = NULL, | ||
624 | }; | ||
625 | |||
626 | static const struct nilfs_bmap_ptr_operations nilfs_bmap_ptr_ops_gc = { | ||
627 | .bpop_prepare_alloc_ptr = NULL, | ||
628 | .bpop_commit_alloc_ptr = NULL, | ||
629 | .bpop_abort_alloc_ptr = NULL, | ||
630 | .bpop_prepare_end_ptr = NULL, | ||
631 | .bpop_commit_end_ptr = NULL, | ||
632 | .bpop_abort_end_ptr = NULL, | ||
633 | |||
634 | .bpop_translate = NULL, | ||
635 | }; | ||
636 | |||
637 | static struct lock_class_key nilfs_bmap_dat_lock_key; | 560 | static struct lock_class_key nilfs_bmap_dat_lock_key; |
638 | 561 | ||
639 | /** | 562 | /** |
@@ -660,20 +583,20 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode) | |||
660 | bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode; | 583 | bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode; |
661 | switch (bmap->b_inode->i_ino) { | 584 | switch (bmap->b_inode->i_ino) { |
662 | case NILFS_DAT_INO: | 585 | case NILFS_DAT_INO: |
663 | bmap->b_pops = &nilfs_bmap_ptr_ops_p; | 586 | bmap->b_ptr_type = NILFS_BMAP_PTR_P; |
664 | bmap->b_last_allocated_key = 0; /* XXX: use macro */ | 587 | bmap->b_last_allocated_key = 0; |
665 | bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT; | 588 | bmap->b_last_allocated_ptr = NILFS_BMAP_NEW_PTR_INIT; |
666 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key); | 589 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_dat_lock_key); |
667 | break; | 590 | break; |
668 | case NILFS_CPFILE_INO: | 591 | case NILFS_CPFILE_INO: |
669 | case NILFS_SUFILE_INO: | 592 | case NILFS_SUFILE_INO: |
670 | bmap->b_pops = &nilfs_bmap_ptr_ops_vmdt; | 593 | bmap->b_ptr_type = NILFS_BMAP_PTR_VS; |
671 | bmap->b_last_allocated_key = 0; /* XXX: use macro */ | 594 | bmap->b_last_allocated_key = 0; |
672 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; | 595 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; |
673 | break; | 596 | break; |
674 | default: | 597 | default: |
675 | bmap->b_pops = &nilfs_bmap_ptr_ops_v; | 598 | bmap->b_ptr_type = NILFS_BMAP_PTR_VM; |
676 | bmap->b_last_allocated_key = 0; /* XXX: use macro */ | 599 | bmap->b_last_allocated_key = 0; |
677 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; | 600 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; |
678 | break; | 601 | break; |
679 | } | 602 | } |
@@ -705,7 +628,7 @@ void nilfs_bmap_init_gc(struct nilfs_bmap *bmap) | |||
705 | memset(&bmap->b_u, 0, NILFS_BMAP_SIZE); | 628 | memset(&bmap->b_u, 0, NILFS_BMAP_SIZE); |
706 | init_rwsem(&bmap->b_sem); | 629 | init_rwsem(&bmap->b_sem); |
707 | bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode; | 630 | bmap->b_inode = &NILFS_BMAP_I(bmap)->vfs_inode; |
708 | bmap->b_pops = &nilfs_bmap_ptr_ops_gc; | 631 | bmap->b_ptr_type = NILFS_BMAP_PTR_U; |
709 | bmap->b_last_allocated_key = 0; | 632 | bmap->b_last_allocated_key = 0; |
710 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; | 633 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; |
711 | bmap->b_state = 0; | 634 | bmap->b_state = 0; |