aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/mdt.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/mdt.c')
-rw-r--r--fs/nilfs2/mdt.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 0066468609d..532f85acf27 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -622,6 +622,72 @@ int nilfs_mdt_save_to_shadow_map(struct inode *inode)
622 return ret; 622 return ret;
623} 623}
624 624
625int nilfs_mdt_freeze_buffer(struct inode *inode, struct buffer_head *bh)
626{
627 struct nilfs_shadow_map *shadow = NILFS_MDT(inode)->mi_shadow;
628 struct buffer_head *bh_frozen;
629 struct page *page;
630 int blkbits = inode->i_blkbits;
631 int ret = -ENOMEM;
632
633 page = grab_cache_page(&shadow->frozen_data, bh->b_page->index);
634 if (!page)
635 return ret;
636
637 if (!page_has_buffers(page))
638 create_empty_buffers(page, 1 << blkbits, 0);
639
640 bh_frozen = nilfs_page_get_nth_block(page, bh_offset(bh) >> blkbits);
641 if (bh_frozen) {
642 if (!buffer_uptodate(bh_frozen))
643 nilfs_copy_buffer(bh_frozen, bh);
644 if (list_empty(&bh_frozen->b_assoc_buffers)) {
645 list_add_tail(&bh_frozen->b_assoc_buffers,
646 &shadow->frozen_buffers);
647 set_buffer_nilfs_redirected(bh);
648 } else {
649 brelse(bh_frozen); /* already frozen */
650 }
651 ret = 0;
652 }
653 unlock_page(page);
654 page_cache_release(page);
655 return ret;
656}
657
658struct buffer_head *
659nilfs_mdt_get_frozen_buffer(struct inode *inode, struct buffer_head *bh)
660{
661 struct nilfs_shadow_map *shadow = NILFS_MDT(inode)->mi_shadow;
662 struct buffer_head *bh_frozen = NULL;
663 struct page *page;
664 int n;
665
666 page = find_lock_page(&shadow->frozen_data, bh->b_page->index);
667 if (page) {
668 if (page_has_buffers(page)) {
669 n = bh_offset(bh) >> inode->i_blkbits;
670 bh_frozen = nilfs_page_get_nth_block(page, n);
671 }
672 unlock_page(page);
673 page_cache_release(page);
674 }
675 return bh_frozen;
676}
677
678static void nilfs_release_frozen_buffers(struct nilfs_shadow_map *shadow)
679{
680 struct list_head *head = &shadow->frozen_buffers;
681 struct buffer_head *bh;
682
683 while (!list_empty(head)) {
684 bh = list_first_entry(head, struct buffer_head,
685 b_assoc_buffers);
686 list_del_init(&bh->b_assoc_buffers);
687 brelse(bh); /* drop ref-count to make it releasable */
688 }
689}
690
625/** 691/**
626 * nilfs_mdt_restore_from_shadow_map - restore dirty pages and bmap state 692 * nilfs_mdt_restore_from_shadow_map - restore dirty pages and bmap state
627 * @inode: inode of the metadata file 693 * @inode: inode of the metadata file
@@ -658,6 +724,7 @@ void nilfs_mdt_clear_shadow_map(struct inode *inode)
658 struct nilfs_shadow_map *shadow = mi->mi_shadow; 724 struct nilfs_shadow_map *shadow = mi->mi_shadow;
659 725
660 down_write(&mi->mi_sem); 726 down_write(&mi->mi_sem);
727 nilfs_release_frozen_buffers(shadow);
661 truncate_inode_pages(&shadow->frozen_data, 0); 728 truncate_inode_pages(&shadow->frozen_data, 0);
662 truncate_inode_pages(&shadow->frozen_btnodes, 0); 729 truncate_inode_pages(&shadow->frozen_btnodes, 0);
663 up_write(&mi->mi_sem); 730 up_write(&mi->mi_sem);