diff options
author | Tao Ma <tao.ma@oracle.com> | 2010-03-22 02:20:18 -0400 |
---|---|---|
committer | Tao Ma <tao.ma@oracle.com> | 2010-03-22 02:20:18 -0400 |
commit | 74380c479ad83addeff8a172ab95f59557b5b0c3 (patch) | |
tree | 49b94f3ff48cd2ca6b53977a5e3070380ccecd6b | |
parent | af2bf0d86019e0b0306965321096f8380b7ca830 (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>
-rw-r--r-- | fs/ocfs2/alloc.c | 18 | ||||
-rw-r--r-- | fs/ocfs2/alloc.h | 2 | ||||
-rw-r--r-- | fs/ocfs2/dir.c | 5 | ||||
-rw-r--r-- | fs/ocfs2/refcounttree.c | 6 | ||||
-rw-r--r-- | fs/ocfs2/suballoc.c | 2 | ||||
-rw-r--r-- | fs/ocfs2/xattr.c | 5 |
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 | */ |
6204 | struct ocfs2_cached_block_free { | 6204 | struct 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 | ||
6440 | int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, | 6444 | int 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) | |||
209 | int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, | 209 | int ocfs2_cache_cluster_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, |
210 | u64 blkno, unsigned int bit); | 210 | u64 blkno, unsigned int bit); |
211 | int ocfs2_cache_block_dealloc(struct ocfs2_cached_dealloc_ctxt *ctxt, | 211 | int 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); |
214 | static inline int ocfs2_dealloc_has_cluster(struct ocfs2_cached_dealloc_ctxt *c) | 214 | static 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, |