diff options
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r-- | fs/ocfs2/alloc.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 0c335b51043d..f9baefc76cf9 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
@@ -5993,6 +5993,7 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
5993 | struct buffer_head *data_alloc_bh = NULL; | 5993 | struct buffer_head *data_alloc_bh = NULL; |
5994 | struct ocfs2_dinode *di; | 5994 | struct ocfs2_dinode *di; |
5995 | struct ocfs2_truncate_log *tl; | 5995 | struct ocfs2_truncate_log *tl; |
5996 | struct ocfs2_journal *journal = osb->journal; | ||
5996 | 5997 | ||
5997 | BUG_ON(inode_trylock(tl_inode)); | 5998 | BUG_ON(inode_trylock(tl_inode)); |
5998 | 5999 | ||
@@ -6013,6 +6014,20 @@ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb) | |||
6013 | goto out; | 6014 | goto out; |
6014 | } | 6015 | } |
6015 | 6016 | ||
6017 | /* Appending truncate log(TA) and and flushing truncate log(TF) are | ||
6018 | * two separated transactions. They can be both committed but not | ||
6019 | * checkpointed. If crash occurs then, both two transaction will be | ||
6020 | * replayed with several already released to global bitmap clusters. | ||
6021 | * Then truncate log will be replayed resulting in cluster double free. | ||
6022 | */ | ||
6023 | jbd2_journal_lock_updates(journal->j_journal); | ||
6024 | status = jbd2_journal_flush(journal->j_journal); | ||
6025 | jbd2_journal_unlock_updates(journal->j_journal); | ||
6026 | if (status < 0) { | ||
6027 | mlog_errno(status); | ||
6028 | goto out; | ||
6029 | } | ||
6030 | |||
6016 | data_alloc_inode = ocfs2_get_system_file_inode(osb, | 6031 | data_alloc_inode = ocfs2_get_system_file_inode(osb, |
6017 | GLOBAL_BITMAP_SYSTEM_INODE, | 6032 | GLOBAL_BITMAP_SYSTEM_INODE, |
6018 | OCFS2_INVALID_SLOT); | 6033 | OCFS2_INVALID_SLOT); |
@@ -6792,6 +6807,8 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, | |||
6792 | struct page *page, int zero, u64 *phys) | 6807 | struct page *page, int zero, u64 *phys) |
6793 | { | 6808 | { |
6794 | int ret, partial = 0; | 6809 | int ret, partial = 0; |
6810 | loff_t start_byte = ((loff_t)page->index << PAGE_SHIFT) + from; | ||
6811 | loff_t length = to - from; | ||
6795 | 6812 | ||
6796 | ret = ocfs2_map_page_blocks(page, phys, inode, from, to, 0); | 6813 | ret = ocfs2_map_page_blocks(page, phys, inode, from, to, 0); |
6797 | if (ret) | 6814 | if (ret) |
@@ -6811,7 +6828,8 @@ void ocfs2_map_and_dirty_page(struct inode *inode, handle_t *handle, | |||
6811 | if (ret < 0) | 6828 | if (ret < 0) |
6812 | mlog_errno(ret); | 6829 | mlog_errno(ret); |
6813 | else if (ocfs2_should_order_data(inode)) { | 6830 | else if (ocfs2_should_order_data(inode)) { |
6814 | ret = ocfs2_jbd2_file_inode(handle, inode); | 6831 | ret = ocfs2_jbd2_inode_add_write(handle, inode, |
6832 | start_byte, length); | ||
6815 | if (ret < 0) | 6833 | if (ret < 0) |
6816 | mlog_errno(ret); | 6834 | mlog_errno(ret); |
6817 | } | 6835 | } |