aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2010-03-22 02:20:18 -0400
committerTao Ma <tao.ma@oracle.com>2010-03-22 02:20:18 -0400
commit74380c479ad83addeff8a172ab95f59557b5b0c3 (patch)
tree49b94f3ff48cd2ca6b53977a5e3070380ccecd6b /fs/ocfs2
parentaf2bf0d86019e0b0306965321096f8380b7ca830 (diff)
ocfs2: Free block to the right block group.
In case the block we are going to free is allocated from a discontiguous block group, we have to use suballoc_loc to be the right group. Signed-off-by: Tao Ma <tao.ma@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/alloc.c18
-rw-r--r--fs/ocfs2/alloc.h2
-rw-r--r--fs/ocfs2/dir.c5
-rw-r--r--fs/ocfs2/refcounttree.c6
-rw-r--r--fs/ocfs2/suballoc.c2
-rw-r--r--fs/ocfs2/xattr.c5
6 files changed, 28 insertions, 10 deletions
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 479d2ecae340..af2d1bd00d0a 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -6203,6 +6203,7 @@ int ocfs2_truncate_log_init(struct ocfs2_super *osb)
6203 */ 6203 */
6204struct ocfs2_cached_block_free { 6204struct ocfs2_cached_block_free {
6205 struct ocfs2_cached_block_free *free_next; 6205 struct ocfs2_cached_block_free *free_next;
6206 u64 free_bg;
6206 u64 free_blk; 6207 u64 free_blk;
6207 unsigned int free_bit; 6208 unsigned int free_bit;
6208}; 6209};
@@ -6249,8 +6250,11 @@ static int ocfs2_free_cached_blocks(struct ocfs2_super *osb,
6249 } 6250 }
6250 6251
6251 while (head) { 6252 while (head) {
6252 bg_blkno = ocfs2_which_suballoc_group(head->free_blk, 6253 if (head->free_bg)
6253 head->free_bit); 6254 bg_blkno = head->free_bg;
6255 else
6256 bg_blkno = ocfs2_which_suballoc_group(head->free_blk,
6257 head->free_bit);
6254 mlog(0, "Free bit: (bit %u, blkno %llu)\n", 6258 mlog(0, "Free bit: (bit %u, blkno %llu)\n",
6255 head->free_bit, (unsigned long long)head->free_blk); 6259 head->free_bit, (unsigned long long)head->free_blk);
6256 6260
@@ -6298,7 +6302,7 @@ int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
6298 int ret = 0; 6302 int ret = 0;
6299 struct ocfs2_cached_block_free *item; 6303 struct ocfs2_cached_block_free *item;
6300 6304
6301 item = kmalloc(sizeof(*item), GFP_NOFS); 6305 item = kzalloc(sizeof(*item), GFP_NOFS);
6302 if (item == NULL) { 6306 if (item == NULL) {
6303 ret = -ENOMEM; 6307 ret = -ENOMEM;
6304 mlog_errno(ret); 6308 mlog_errno(ret);
@@ -6438,8 +6442,8 @@ ocfs2_find_per_slot_free_list(int type,
6438} 6442}
6439 6443
6440int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, 6444int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
6441 int type, int slot, u64 blkno, 6445 int type, int slot, u64 suballoc,
6442 unsigned int bit) 6446 u64 blkno, unsigned int bit)
6443{ 6447{
6444 int ret; 6448 int ret;
6445 struct ocfs2_per_slot_free_list *fl; 6449 struct ocfs2_per_slot_free_list *fl;
@@ -6452,7 +6456,7 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
6452 goto out; 6456 goto out;
6453 } 6457 }
6454 6458
6455 item = kmalloc(sizeof(*item), GFP_NOFS); 6459 item = kzalloc(sizeof(*item), GFP_NOFS);
6456 if (item == NULL) { 6460 if (item == NULL) {
6457 ret = -ENOMEM; 6461 ret = -ENOMEM;
6458 mlog_errno(ret); 6462 mlog_errno(ret);
@@ -6462,6 +6466,7 @@ int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
6462 mlog(0, "Insert: (type %d, slot %u, bit %u, blk %llu)\n", 6466 mlog(0, "Insert: (type %d, slot %u, bit %u, blk %llu)\n",
6463 type, slot, bit, (unsigned long long)blkno); 6467 type, slot, bit, (unsigned long long)blkno);
6464 6468
6469 item->free_bg = suballoc;
6465 item->free_blk = blkno; 6470 item->free_blk = blkno;
6466 item->free_bit = bit; 6471 item->free_bit = bit;
6467 item->free_next = fl->f_first; 6472 item->free_next = fl->f_first;
@@ -6478,6 +6483,7 @@ static int ocfs2_cache_extent_block_free(struct ocfs2_cached_dealloc_ctxt *ctxt,
6478{ 6483{
6479 return ocfs2_cache_block_dealloc(ctxt, EXTENT_ALLOC_SYSTEM_INODE, 6484 return ocfs2_cache_block_dealloc(ctxt, EXTENT_ALLOC_SYSTEM_INODE,
6480 le16_to_cpu(eb->h_suballoc_slot), 6485 le16_to_cpu(eb->h_suballoc_slot),
6486 le64_to_cpu(eb->h_suballoc_loc),
6481 le64_to_cpu(eb->h_blkno), 6487 le64_to_cpu(eb->h_blkno),
6482 le16_to_cpu(eb->h_suballoc_bit)); 6488 le16_to_cpu(eb->h_suballoc_bit));
6483} 6489}
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index 1db4359ccb90..fc28d64398c1 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -209,7 +209,7 @@ static inline void ocfs2_init_dealloc_ctxt(struct ocfs2_cached_dealloc_ctxt *c)
209int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, 209int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
210 u64 blkno, unsigned int bit); 210 u64 blkno, unsigned int bit);
211int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, 211int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt,
212 int type, int slot, u64 blkno, 212 int type, int slot, u64 suballoc, u64 blkno,
213 unsigned int bit); 213 unsigned int bit);
214static inline int ocfs2_dealloc_has_cluster(struct ocfs2_cached_dealloc_ctxt *c) 214static inline int ocfs2_dealloc_has_cluster(struct ocfs2_cached_dealloc_ctxt *c)
215{ 215{
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 341bb8f811e9..3fea52d0efd3 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -4466,7 +4466,10 @@ static int ocfs2_dx_dir_remove_index(struct inode *dir,
4466 4466
4467 blk = le64_to_cpu(dx_root->dr_blkno); 4467 blk = le64_to_cpu(dx_root->dr_blkno);
4468 bit = le16_to_cpu(dx_root->dr_suballoc_bit); 4468 bit = le16_to_cpu(dx_root->dr_suballoc_bit);
4469 bg_blkno = ocfs2_which_suballoc_group(blk, bit); 4469 if (dx_root->dr_suballoc_loc)
4470 bg_blkno = le64_to_cpu(dx_root->dr_suballoc_loc);
4471 else
4472 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
4470 ret = ocfs2_free_suballoc_bits(handle, dx_alloc_inode, dx_alloc_bh, 4473 ret = ocfs2_free_suballoc_bits(handle, dx_alloc_inode, dx_alloc_bh,
4471 bit, bg_blkno, 1); 4474 bit, bg_blkno, 1);
4472 if (ret) 4475 if (ret)
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 275920e8a40d..b34702984225 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -792,7 +792,10 @@ int ocfs2_remove_refcount_tree(struct inode *inode, struct buffer_head *di_bh)
792 if (le32_to_cpu(rb->rf_count) == 1) { 792 if (le32_to_cpu(rb->rf_count) == 1) {
793 blk = le64_to_cpu(rb->rf_blkno); 793 blk = le64_to_cpu(rb->rf_blkno);
794 bit = le16_to_cpu(rb->rf_suballoc_bit); 794 bit = le16_to_cpu(rb->rf_suballoc_bit);
795 bg_blkno = ocfs2_which_suballoc_group(blk, bit); 795 if (rb->rf_suballoc_loc)
796 bg_blkno = le64_to_cpu(rb->rf_suballoc_loc);
797 else
798 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
796 799
797 alloc_inode = ocfs2_get_system_file_inode(osb, 800 alloc_inode = ocfs2_get_system_file_inode(osb,
798 EXTENT_ALLOC_SYSTEM_INODE, 801 EXTENT_ALLOC_SYSTEM_INODE,
@@ -2108,6 +2111,7 @@ static int ocfs2_remove_refcount_extent(handle_t *handle,
2108 */ 2111 */
2109 ret = ocfs2_cache_block_dealloc(dealloc, EXTENT_ALLOC_SYSTEM_INODE, 2112 ret = ocfs2_cache_block_dealloc(dealloc, EXTENT_ALLOC_SYSTEM_INODE,
2110 le16_to_cpu(rb->rf_suballoc_slot), 2113 le16_to_cpu(rb->rf_suballoc_slot),
2114 le64_to_cpu(rb->rf_suballoc_loc),
2111 le64_to_cpu(rb->rf_blkno), 2115 le64_to_cpu(rb->rf_blkno),
2112 le16_to_cpu(rb->rf_suballoc_bit)); 2116 le16_to_cpu(rb->rf_suballoc_bit));
2113 if (ret) { 2117 if (ret) {
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 6f39da4a9a10..0c08353fddac 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -2349,6 +2349,8 @@ int ocfs2_free_dinode(handle_t *handle,
2349 u16 bit = le16_to_cpu(di->i_suballoc_bit); 2349 u16 bit = le16_to_cpu(di->i_suballoc_bit);
2350 u64 bg_blkno = ocfs2_which_suballoc_group(blk, bit); 2350 u64 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
2351 2351
2352 if (di->i_suballoc_loc)
2353 bg_blkno = le64_to_cpu(di->i_suballoc_loc);
2352 return ocfs2_free_suballoc_bits(handle, inode_alloc_inode, 2354 return ocfs2_free_suballoc_bits(handle, inode_alloc_inode,
2353 inode_alloc_bh, bit, bg_blkno, 1); 2355 inode_alloc_bh, bit, bg_blkno, 1);
2354} 2356}
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 805167e226c1..a1cf195935cf 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -2466,7 +2466,10 @@ static int ocfs2_xattr_free_block(struct inode *inode,
2466 xb = (struct ocfs2_xattr_block *)blk_bh->b_data; 2466 xb = (struct ocfs2_xattr_block *)blk_bh->b_data;
2467 blk = le64_to_cpu(xb->xb_blkno); 2467 blk = le64_to_cpu(xb->xb_blkno);
2468 bit = le16_to_cpu(xb->xb_suballoc_bit); 2468 bit = le16_to_cpu(xb->xb_suballoc_bit);
2469 bg_blkno = ocfs2_which_suballoc_group(blk, bit); 2469 if (xb->xb_suballoc_loc)
2470 bg_blkno = le64_to_cpu(xb->xb_suballoc_loc);
2471 else
2472 bg_blkno = ocfs2_which_suballoc_group(blk, bit);
2470 2473
2471 xb_alloc_inode = ocfs2_get_system_file_inode(osb, 2474 xb_alloc_inode = ocfs2_get_system_file_inode(osb,
2472 EXTENT_ALLOC_SYSTEM_INODE, 2475 EXTENT_ALLOC_SYSTEM_INODE,