Commit b4414eea authored by Mark Fasheh's avatar Mark Fasheh Committed by Joel Becker

ocfs2: Clear undo bits when local alloc is freed

When the local alloc file changes windows, unused bits are freed back to the
global bitmap. By defnition, those bits can not be in use by any file. Also,
the local alloc will never have been able to allocate those bits if they
were part of a previous truncate. Therefore it makes sense that we should
clear unused local alloc bits in the undo buffer so that they can be used
immediatly.

[ Modified to call it ocfs2_release_clusters() -- Joel ]
Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
Signed-off-by: default avatarJoel Becker <joel.becker@oracle.com>
parent b2317968
...@@ -872,8 +872,10 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, ...@@ -872,8 +872,10 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
(unsigned long long)la_start_blk, (unsigned long long)la_start_blk,
(unsigned long long)blkno); (unsigned long long)blkno);
status = ocfs2_free_clusters(handle, main_bm_inode, status = ocfs2_release_clusters(handle,
main_bm_bh, blkno, count); main_bm_inode,
main_bm_bh, blkno,
count);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
......
...@@ -763,8 +763,18 @@ static inline unsigned int ocfs2_megabytes_to_clusters(struct super_block *sb, ...@@ -763,8 +763,18 @@ static inline unsigned int ocfs2_megabytes_to_clusters(struct super_block *sb,
return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits); return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits);
} }
#define ocfs2_set_bit ext2_set_bit static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
#define ocfs2_clear_bit ext2_clear_bit {
ext2_set_bit(bit, bitmap);
}
#define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr))
static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap)
{
ext2_clear_bit(bit, bitmap);
}
#define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr))
#define ocfs2_test_bit ext2_test_bit #define ocfs2_test_bit ext2_test_bit
#define ocfs2_find_next_zero_bit ext2_find_next_zero_bit #define ocfs2_find_next_zero_bit ext2_find_next_zero_bit
#define ocfs2_find_next_bit ext2_find_next_bit #define ocfs2_find_next_bit ext2_find_next_bit
......
...@@ -95,13 +95,6 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle, ...@@ -95,13 +95,6 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle,
struct buffer_head *group_bh, struct buffer_head *group_bh,
unsigned int bit_off, unsigned int bit_off,
unsigned int num_bits); unsigned int num_bits);
static inline int ocfs2_block_group_clear_bits(handle_t *handle,
struct inode *alloc_inode,
struct ocfs2_group_desc *bg,
struct buffer_head *group_bh,
unsigned int bit_off,
unsigned int num_bits);
static int ocfs2_relink_block_group(handle_t *handle, static int ocfs2_relink_block_group(handle_t *handle,
struct inode *alloc_inode, struct inode *alloc_inode,
struct buffer_head *fe_bh, struct buffer_head *fe_bh,
...@@ -1978,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb, ...@@ -1978,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
bits_wanted, cluster_start, num_clusters); bits_wanted, cluster_start, num_clusters);
} }
static inline int ocfs2_block_group_clear_bits(handle_t *handle, static int ocfs2_block_group_clear_bits(handle_t *handle,
struct inode *alloc_inode, struct inode *alloc_inode,
struct ocfs2_group_desc *bg, struct ocfs2_group_desc *bg,
struct buffer_head *group_bh, struct buffer_head *group_bh,
unsigned int bit_off, unsigned int bit_off,
unsigned int num_bits) unsigned int num_bits,
void (*undo_fn)(unsigned int bit,
unsigned long *bmap))
{ {
int status; int status;
unsigned int tmp; unsigned int tmp;
int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
struct ocfs2_group_desc *undo_bg = NULL; struct ocfs2_group_desc *undo_bg = NULL;
int cluster_bitmap = 0;
mlog_entry_void(); mlog_entry_void();
...@@ -1999,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, ...@@ -1999,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
mlog(0, "off = %u, num = %u\n", bit_off, num_bits); mlog(0, "off = %u, num = %u\n", bit_off, num_bits);
if (ocfs2_is_cluster_bitmap(alloc_inode)) BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode));
journal_type = OCFS2_JOURNAL_ACCESS_UNDO;
status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode),
group_bh, journal_type); group_bh,
undo_fn ?
OCFS2_JOURNAL_ACCESS_UNDO :
OCFS2_JOURNAL_ACCESS_WRITE);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
} }
if (ocfs2_is_cluster_bitmap(alloc_inode)) if (undo_fn) {
cluster_bitmap = 1;
if (cluster_bitmap) {
jbd_lock_bh_state(group_bh); jbd_lock_bh_state(group_bh);
undo_bg = (struct ocfs2_group_desc *) undo_bg = (struct ocfs2_group_desc *)
bh2jh(group_bh)->b_committed_data; bh2jh(group_bh)->b_committed_data;
...@@ -2023,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, ...@@ -2023,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
while(tmp--) { while(tmp--) {
ocfs2_clear_bit((bit_off + tmp), ocfs2_clear_bit((bit_off + tmp),
(unsigned long *) bg->bg_bitmap); (unsigned long *) bg->bg_bitmap);
if (cluster_bitmap) if (undo_fn)
ocfs2_set_bit(bit_off + tmp, undo_fn(bit_off + tmp,
(unsigned long *) undo_bg->bg_bitmap); (unsigned long *) undo_bg->bg_bitmap);
} }
le16_add_cpu(&bg->bg_free_bits_count, num_bits); le16_add_cpu(&bg->bg_free_bits_count, num_bits);
if (cluster_bitmap) if (undo_fn)
jbd_unlock_bh_state(group_bh); jbd_unlock_bh_state(group_bh);
status = ocfs2_journal_dirty(handle, group_bh); status = ocfs2_journal_dirty(handle, group_bh);
...@@ -2042,12 +2033,14 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle, ...@@ -2042,12 +2033,14 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
/* /*
* expects the suballoc inode to already be locked. * expects the suballoc inode to already be locked.
*/ */
int ocfs2_free_suballoc_bits(handle_t *handle, static int _ocfs2_free_suballoc_bits(handle_t *handle,
struct inode *alloc_inode, struct inode *alloc_inode,
struct buffer_head *alloc_bh, struct buffer_head *alloc_bh,
unsigned int start_bit, unsigned int start_bit,
u64 bg_blkno, u64 bg_blkno,
unsigned int count) unsigned int count,
void (*undo_fn)(unsigned int bit,
unsigned long *bitmap))
{ {
int status = 0; int status = 0;
u32 tmp_used; u32 tmp_used;
...@@ -2082,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle, ...@@ -2082,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle,
status = ocfs2_block_group_clear_bits(handle, alloc_inode, status = ocfs2_block_group_clear_bits(handle, alloc_inode,
group, group_bh, group, group_bh,
start_bit, count); start_bit, count, undo_fn);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto bail; goto bail;
...@@ -2113,6 +2106,17 @@ int ocfs2_free_suballoc_bits(handle_t *handle, ...@@ -2113,6 +2106,17 @@ int ocfs2_free_suballoc_bits(handle_t *handle,
return status; return status;
} }
int ocfs2_free_suballoc_bits(handle_t *handle,
struct inode *alloc_inode,
struct buffer_head *alloc_bh,
unsigned int start_bit,
u64 bg_blkno,
unsigned int count)
{
return _ocfs2_free_suballoc_bits(handle, alloc_inode, alloc_bh,
start_bit, bg_blkno, count, NULL);
}
int ocfs2_free_dinode(handle_t *handle, int ocfs2_free_dinode(handle_t *handle,
struct inode *inode_alloc_inode, struct inode *inode_alloc_inode,
struct buffer_head *inode_alloc_bh, struct buffer_head *inode_alloc_bh,
...@@ -2126,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle, ...@@ -2126,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle,
inode_alloc_bh, bit, bg_blkno, 1); inode_alloc_bh, bit, bg_blkno, 1);
} }
int ocfs2_free_clusters(handle_t *handle, static int _ocfs2_free_clusters(handle_t *handle,
struct inode *bitmap_inode, struct inode *bitmap_inode,
struct buffer_head *bitmap_bh, struct buffer_head *bitmap_bh,
u64 start_blk, u64 start_blk,
unsigned int num_clusters) unsigned int num_clusters,
void (*undo_fn)(unsigned int bit,
unsigned long *bitmap))
{ {
int status; int status;
u16 bg_start_bit; u16 bg_start_bit;
...@@ -2157,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle, ...@@ -2157,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle,
mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n",
(unsigned long long)bg_blkno, bg_start_bit); (unsigned long long)bg_blkno, bg_start_bit);
status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
bg_start_bit, bg_blkno, bg_start_bit, bg_blkno,
num_clusters); num_clusters, undo_fn);
if (status < 0) { if (status < 0) {
mlog_errno(status); mlog_errno(status);
goto out; goto out;
...@@ -2173,6 +2179,32 @@ int ocfs2_free_clusters(handle_t *handle, ...@@ -2173,6 +2179,32 @@ int ocfs2_free_clusters(handle_t *handle,
return status; return status;
} }
int ocfs2_free_clusters(handle_t *handle,
struct inode *bitmap_inode,
struct buffer_head *bitmap_bh,
u64 start_blk,
unsigned int num_clusters)
{
return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
start_blk, num_clusters,
_ocfs2_set_bit);
}
/*
* Give never-used clusters back to the global bitmap. We don't need
* to protect these bits in the undo buffer.
*/
int ocfs2_release_clusters(handle_t *handle,
struct inode *bitmap_inode,
struct buffer_head *bitmap_bh,
u64 start_blk,
unsigned int num_clusters)
{
return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
start_blk, num_clusters,
_ocfs2_clear_bit);
}
static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg) static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg)
{ {
printk("Block Group:\n"); printk("Block Group:\n");
......
...@@ -127,6 +127,11 @@ int ocfs2_free_clusters(handle_t *handle, ...@@ -127,6 +127,11 @@ int ocfs2_free_clusters(handle_t *handle,
struct buffer_head *bitmap_bh, struct buffer_head *bitmap_bh,
u64 start_blk, u64 start_blk,
unsigned int num_clusters); unsigned int num_clusters);
int ocfs2_release_clusters(handle_t *handle,
struct inode *bitmap_inode,
struct buffer_head *bitmap_bh,
u64 start_blk,
unsigned int num_clusters);
static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit) static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment