aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/alloc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/alloc.c')
-rw-r--r--fs/ocfs2/alloc.c106
1 files changed, 99 insertions, 7 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 0cc2deb9394c..4614614084dd 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -5800,7 +5800,10 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb)
5800 */ 5800 */
5801 5801
5802/* 5802/*
5803 * Describes a single block free from a suballocator 5803 * Describe a single bit freed from a suballocator. For the block
5804 * suballocators, it represents one block. For the global cluster
5805 * allocator, it represents some clusters and free_bit indicates
5806 * clusters number.
5804 */ 5807 */
5805struct ocfs2_cached_block_free { 5808struct ocfs2_cached_block_free {
5806 struct ocfs2_cached_block_free *free_next; 5809 struct ocfs2_cached_block_free *free_next;
@@ -5815,10 +5818,10 @@ struct ocfs2_per_slot_free_list {
5815 struct ocfs2_cached_block_free *f_first; 5818 struct ocfs2_cached_block_free *f_first;
5816}; 5819};
5817 5820
5818static int ocfs2_free_cached_items(struct ocfs2_super *osb, 5821static int ocfs2_free_cached_blocks(struct ocfs2_super *osb,
5819 int sysfile_type, 5822 int sysfile_type,
5820 int slot, 5823 int slot,
5821 struct ocfs2_cached_block_free *head) 5824 struct ocfs2_cached_block_free *head)
5822{ 5825{
5823 int ret; 5826 int ret;
5824 u64 bg_blkno; 5827 u64 bg_blkno;
@@ -5893,6 +5896,82 @@ out:
5893 return ret; 5896 return ret;
5894} 5897}
5895 5898
5899int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
5900 u64 blkno, unsigned int bit)
5901{
5902 int ret = 0;
5903 struct ocfs2_cached_block_free *item;
5904
5905 item = kmalloc(sizeof(*item), GFP_NOFS);
5906 if (item == NULL) {
5907 ret = -ENOMEM;
5908 mlog_errno(ret);
5909 return ret;
5910 }
5911
5912 mlog(0, "Insert clusters: (bit %u, blk %llu)\n",
5913 bit, (unsigned long long)blkno);
5914
5915 item->free_blk = blkno;
5916 item->free_bit = bit;
5917 item->free_next = ctxt->c_global_allocator;
5918
5919 ctxt->c_global_allocator = item;
5920 return ret;
5921}
5922
5923static int ocfs2_free_cached_clusters(struct ocfs2_super *osb,
5924 struct ocfs2_cached_block_free *head)
5925{
5926 struct ocfs2_cached_block_free *tmp;
5927 struct inode *tl_inode = osb->osb_tl_inode;
5928 handle_t *handle;
5929 int ret = 0;
5930
5931 mutex_lock(&tl_inode->i_mutex);
5932
5933 while (head) {
5934 if (ocfs2_truncate_log_needs_flush(osb)) {
5935 ret = __ocfs2_flush_truncate_log(osb);
5936 if (ret < 0) {
5937 mlog_errno(ret);
5938 break;
5939 }
5940 }
5941
5942 handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_UPDATE);
5943 if (IS_ERR(handle)) {
5944 ret = PTR_ERR(handle);
5945 mlog_errno(ret);
5946 break;
5947 }
5948
5949 ret = ocfs2_truncate_log_append(osb, handle, head->free_blk,
5950 head->free_bit);
5951
5952 ocfs2_commit_trans(osb, handle);
5953 tmp = head;
5954 head = head->free_next;
5955 kfree(tmp);
5956
5957 if (ret < 0) {
5958 mlog_errno(ret);
5959 break;
5960 }
5961 }
5962
5963 mutex_unlock(&tl_inode->i_mutex);
5964
5965 while (head) {
5966 /* Premature exit may have left some dangling items. */
5967 tmp = head;
5968 head = head->free_next;
5969 kfree(tmp);
5970 }
5971
5972 return ret;
5973}
5974
5896int ocfs2_run_deallocs(struct ocfs2_super *osb, 5975int ocfs2_run_deallocs(struct ocfs2_super *osb,
5897 struct ocfs2_cached_dealloc_ctxt *ctxt) 5976 struct ocfs2_cached_dealloc_ctxt *ctxt)
5898{ 5977{
@@ -5908,8 +5987,10 @@ int ocfs2_run_deallocs(struct ocfs2_super *osb,
5908 if (fl->f_first) { 5987 if (fl->f_first) {
5909 mlog(0, "Free items: (type %u, slot %d)\n", 5988 mlog(0, "Free items: (type %u, slot %d)\n",
5910 fl->f_inode_type, fl->f_slot); 5989 fl->f_inode_type, fl->f_slot);
5911 ret2 = ocfs2_free_cached_items(osb, fl->f_inode_type, 5990 ret2 = ocfs2_free_cached_blocks(osb,
5912 fl->f_slot, fl->f_first); 5991 fl->f_inode_type,
5992 fl->f_slot,
5993 fl->f_first);
5913 if (ret2) 5994 if (ret2)
5914 mlog_errno(ret2); 5995 mlog_errno(ret2);
5915 if (!ret) 5996 if (!ret)
@@ -5920,6 +6001,17 @@ int ocfs2_run_deallocs(struct ocfs2_super *osb,
5920 kfree(fl); 6001 kfree(fl);
5921 } 6002 }
5922 6003
6004 if (ctxt->c_global_allocator) {
6005 ret2 = ocfs2_free_cached_clusters(osb,
6006 ctxt->c_global_allocator);
6007 if (ret2)
6008 mlog_errno(ret2);
6009 if (!ret)
6010 ret = ret2;
6011
6012 ctxt->c_global_allocator = NULL;
6013 }
6014
5923 return ret; 6015 return ret;
5924} 6016}
5925 6017