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