diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/ocfs2/alloc.c | 38 | ||||
| -rw-r--r-- | fs/ocfs2/localalloc.c | 42 | ||||
| -rw-r--r-- | fs/ocfs2/localalloc.h | 6 |
3 files changed, 83 insertions, 3 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 8750ae1b8636..aada5801567a 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c | |||
| @@ -4742,6 +4742,7 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4742 | enum ocfs2_alloc_restarted *reason_ret) | 4742 | enum ocfs2_alloc_restarted *reason_ret) |
| 4743 | { | 4743 | { |
| 4744 | int status = 0, err = 0; | 4744 | int status = 0, err = 0; |
| 4745 | int need_free = 0; | ||
| 4745 | int free_extents; | 4746 | int free_extents; |
| 4746 | enum ocfs2_alloc_restarted reason = RESTART_NONE; | 4747 | enum ocfs2_alloc_restarted reason = RESTART_NONE; |
| 4747 | u32 bit_off, num_bits; | 4748 | u32 bit_off, num_bits; |
| @@ -4796,7 +4797,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4796 | OCFS2_JOURNAL_ACCESS_WRITE); | 4797 | OCFS2_JOURNAL_ACCESS_WRITE); |
| 4797 | if (status < 0) { | 4798 | if (status < 0) { |
| 4798 | mlog_errno(status); | 4799 | mlog_errno(status); |
| 4799 | goto leave; | 4800 | need_free = 1; |
| 4801 | goto bail; | ||
| 4800 | } | 4802 | } |
| 4801 | 4803 | ||
| 4802 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); | 4804 | block = ocfs2_clusters_to_blocks(osb->sb, bit_off); |
| @@ -4807,7 +4809,8 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4807 | num_bits, flags, meta_ac); | 4809 | num_bits, flags, meta_ac); |
| 4808 | if (status < 0) { | 4810 | if (status < 0) { |
| 4809 | mlog_errno(status); | 4811 | mlog_errno(status); |
| 4810 | goto leave; | 4812 | need_free = 1; |
| 4813 | goto bail; | ||
| 4811 | } | 4814 | } |
| 4812 | 4815 | ||
| 4813 | ocfs2_journal_dirty(handle, et->et_root_bh); | 4816 | ocfs2_journal_dirty(handle, et->et_root_bh); |
| @@ -4821,6 +4824,19 @@ int ocfs2_add_clusters_in_btree(handle_t *handle, | |||
| 4821 | reason = RESTART_TRANS; | 4824 | reason = RESTART_TRANS; |
| 4822 | } | 4825 | } |
| 4823 | 4826 | ||
| 4827 | bail: | ||
| 4828 | if (need_free) { | ||
| 4829 | if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) | ||
| 4830 | ocfs2_free_local_alloc_bits(osb, handle, data_ac, | ||
| 4831 | bit_off, num_bits); | ||
| 4832 | else | ||
| 4833 | ocfs2_free_clusters(handle, | ||
| 4834 | data_ac->ac_inode, | ||
| 4835 | data_ac->ac_bh, | ||
| 4836 | ocfs2_clusters_to_blocks(osb->sb, bit_off), | ||
| 4837 | num_bits); | ||
| 4838 | } | ||
| 4839 | |||
| 4824 | leave: | 4840 | leave: |
| 4825 | if (reason_ret) | 4841 | if (reason_ret) |
| 4826 | *reason_ret = reason; | 4842 | *reason_ret = reason; |
| @@ -6805,6 +6821,8 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6805 | struct buffer_head *di_bh) | 6821 | struct buffer_head *di_bh) |
| 6806 | { | 6822 | { |
| 6807 | int ret, i, has_data, num_pages = 0; | 6823 | int ret, i, has_data, num_pages = 0; |
| 6824 | int need_free = 0; | ||
| 6825 | u32 bit_off, num; | ||
| 6808 | handle_t *handle; | 6826 | handle_t *handle; |
| 6809 | u64 uninitialized_var(block); | 6827 | u64 uninitialized_var(block); |
| 6810 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 6828 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
| @@ -6850,7 +6868,6 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6850 | } | 6868 | } |
| 6851 | 6869 | ||
| 6852 | if (has_data) { | 6870 | if (has_data) { |
| 6853 | u32 bit_off, num; | ||
| 6854 | unsigned int page_end; | 6871 | unsigned int page_end; |
| 6855 | u64 phys; | 6872 | u64 phys; |
| 6856 | 6873 | ||
| @@ -6886,6 +6903,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6886 | ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages); | 6903 | ret = ocfs2_grab_eof_pages(inode, 0, end, pages, &num_pages); |
| 6887 | if (ret) { | 6904 | if (ret) { |
| 6888 | mlog_errno(ret); | 6905 | mlog_errno(ret); |
| 6906 | need_free = 1; | ||
| 6889 | goto out_commit; | 6907 | goto out_commit; |
| 6890 | } | 6908 | } |
| 6891 | 6909 | ||
| @@ -6896,6 +6914,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6896 | ret = ocfs2_read_inline_data(inode, pages[0], di_bh); | 6914 | ret = ocfs2_read_inline_data(inode, pages[0], di_bh); |
| 6897 | if (ret) { | 6915 | if (ret) { |
| 6898 | mlog_errno(ret); | 6916 | mlog_errno(ret); |
| 6917 | need_free = 1; | ||
| 6899 | goto out_commit; | 6918 | goto out_commit; |
| 6900 | } | 6919 | } |
| 6901 | 6920 | ||
| @@ -6927,6 +6946,7 @@ int ocfs2_convert_inline_data_to_extents(struct inode *inode, | |||
| 6927 | ret = ocfs2_insert_extent(handle, &et, 0, block, 1, 0, NULL); | 6946 | ret = ocfs2_insert_extent(handle, &et, 0, block, 1, 0, NULL); |
| 6928 | if (ret) { | 6947 | if (ret) { |
| 6929 | mlog_errno(ret); | 6948 | mlog_errno(ret); |
| 6949 | need_free = 1; | ||
| 6930 | goto out_commit; | 6950 | goto out_commit; |
| 6931 | } | 6951 | } |
| 6932 | 6952 | ||
| @@ -6938,6 +6958,18 @@ out_commit: | |||
| 6938 | dquot_free_space_nodirty(inode, | 6958 | dquot_free_space_nodirty(inode, |
| 6939 | ocfs2_clusters_to_bytes(osb->sb, 1)); | 6959 | ocfs2_clusters_to_bytes(osb->sb, 1)); |
| 6940 | 6960 | ||
| 6961 | if (need_free) { | ||
| 6962 | if (data_ac->ac_which == OCFS2_AC_USE_LOCAL) | ||
| 6963 | ocfs2_free_local_alloc_bits(osb, handle, data_ac, | ||
| 6964 | bit_off, num); | ||
| 6965 | else | ||
| 6966 | ocfs2_free_clusters(handle, | ||
| 6967 | data_ac->ac_inode, | ||
| 6968 | data_ac->ac_bh, | ||
| 6969 | ocfs2_clusters_to_blocks(osb->sb, bit_off), | ||
| 6970 | num); | ||
| 6971 | } | ||
| 6972 | |||
| 6941 | ocfs2_commit_trans(osb, handle); | 6973 | ocfs2_commit_trans(osb, handle); |
| 6942 | 6974 | ||
| 6943 | out_unlock: | 6975 | out_unlock: |
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c index cd5496b7a0a3..044013455621 100644 --- a/fs/ocfs2/localalloc.c +++ b/fs/ocfs2/localalloc.c | |||
| @@ -781,6 +781,48 @@ bail: | |||
| 781 | return status; | 781 | return status; |
| 782 | } | 782 | } |
| 783 | 783 | ||
| 784 | int ocfs2_free_local_alloc_bits(struct ocfs2_super *osb, | ||
| 785 | handle_t *handle, | ||
| 786 | struct ocfs2_alloc_context *ac, | ||
| 787 | u32 bit_off, | ||
| 788 | u32 num_bits) | ||
| 789 | { | ||
| 790 | int status, start; | ||
| 791 | u32 clear_bits; | ||
| 792 | struct inode *local_alloc_inode; | ||
| 793 | void *bitmap; | ||
| 794 | struct ocfs2_dinode *alloc; | ||
| 795 | struct ocfs2_local_alloc *la; | ||
| 796 | |||
| 797 | BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL); | ||
| 798 | |||
| 799 | local_alloc_inode = ac->ac_inode; | ||
| 800 | alloc = (struct ocfs2_dinode *) osb->local_alloc_bh->b_data; | ||
| 801 | la = OCFS2_LOCAL_ALLOC(alloc); | ||
| 802 | |||
| 803 | bitmap = la->la_bitmap; | ||
| 804 | start = bit_off - le32_to_cpu(la->la_bm_off); | ||
| 805 | clear_bits = num_bits; | ||
| 806 | |||
| 807 | status = ocfs2_journal_access_di(handle, | ||
| 808 | INODE_CACHE(local_alloc_inode), | ||
| 809 | osb->local_alloc_bh, | ||
| 810 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
| 811 | if (status < 0) { | ||
| 812 | mlog_errno(status); | ||
| 813 | goto bail; | ||
| 814 | } | ||
| 815 | |||
| 816 | while (clear_bits--) | ||
| 817 | ocfs2_clear_bit(start++, bitmap); | ||
| 818 | |||
| 819 | le32_add_cpu(&alloc->id1.bitmap1.i_used, -num_bits); | ||
| 820 | ocfs2_journal_dirty(handle, osb->local_alloc_bh); | ||
| 821 | |||
| 822 | bail: | ||
| 823 | return status; | ||
| 824 | } | ||
| 825 | |||
| 784 | static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) | 826 | static u32 ocfs2_local_alloc_count_bits(struct ocfs2_dinode *alloc) |
| 785 | { | 827 | { |
| 786 | u32 count; | 828 | u32 count; |
diff --git a/fs/ocfs2/localalloc.h b/fs/ocfs2/localalloc.h index 1be9b5864460..44a7d1fb2dec 100644 --- a/fs/ocfs2/localalloc.h +++ b/fs/ocfs2/localalloc.h | |||
| @@ -55,6 +55,12 @@ int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, | |||
| 55 | u32 *bit_off, | 55 | u32 *bit_off, |
| 56 | u32 *num_bits); | 56 | u32 *num_bits); |
| 57 | 57 | ||
| 58 | int ocfs2_free_local_alloc_bits(struct ocfs2_super *osb, | ||
| 59 | handle_t *handle, | ||
| 60 | struct ocfs2_alloc_context *ac, | ||
| 61 | u32 bit_off, | ||
| 62 | u32 num_bits); | ||
| 63 | |||
| 58 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, | 64 | void ocfs2_local_alloc_seen_free_bits(struct ocfs2_super *osb, |
| 59 | unsigned int num_clusters); | 65 | unsigned int num_clusters); |
| 60 | void ocfs2_la_enable_worker(struct work_struct *work); | 66 | void ocfs2_la_enable_worker(struct work_struct *work); |
