aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2010-03-11 21:31:09 -0500
committerJoel Becker <joel.becker@oracle.com>2010-03-23 21:22:40 -0400
commitb4414eea0e7b9c134262c801a87e338bf675962c (patch)
tree09829d99527f1da69cc19074a2d3baef1195955e /fs
parentb23179681c90a55e2a2083e1dde9f727ecffb2b7 (diff)
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: Mark Fasheh <mfasheh@suse.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/localalloc.c6
-rw-r--r--fs/ocfs2/ocfs2.h14
-rw-r--r--fs/ocfs2/suballoc.c116
-rw-r--r--fs/ocfs2/suballoc.h5
4 files changed, 95 insertions, 46 deletions
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 171c691b42a0..c983715d8d8c 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -872,8 +872,10 @@ static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
872 (unsigned long long)la_start_blk, 872 (unsigned long long)la_start_blk,
873 (unsigned long long)blkno); 873 (unsigned long long)blkno);
874 874
875 status = ocfs2_free_clusters(handle, main_bm_inode, 875 status = ocfs2_release_clusters(handle,
876 main_bm_bh, blkno, count); 876 main_bm_inode,
877 main_bm_bh, blkno,
878 count);
877 if (status < 0) { 879 if (status < 0) {
878 mlog_errno(status); 880 mlog_errno(status);
879 goto bail; 881 goto bail;
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 1238b491db90..adf5e2ebc2c4 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -763,8 +763,18 @@ static inline unsigned int ocfs2_megabytes_to_clusters(struct super_block *sb,
763 return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits); 763 return megs << (20 - OCFS2_SB(sb)->s_clustersize_bits);
764} 764}
765 765
766#define ocfs2_set_bit ext2_set_bit 766static inline void _ocfs2_set_bit(unsigned int bit, unsigned long *bitmap)
767#define ocfs2_clear_bit ext2_clear_bit 767{
768 ext2_set_bit(bit, bitmap);
769}
770#define ocfs2_set_bit(bit, addr) _ocfs2_set_bit((bit), (unsigned long *)(addr))
771
772static inline void _ocfs2_clear_bit(unsigned int bit, unsigned long *bitmap)
773{
774 ext2_clear_bit(bit, bitmap);
775}
776#define ocfs2_clear_bit(bit, addr) _ocfs2_clear_bit((bit), (unsigned long *)(addr))
777
768#define ocfs2_test_bit ext2_test_bit 778#define ocfs2_test_bit ext2_test_bit
769#define ocfs2_find_next_zero_bit ext2_find_next_zero_bit 779#define ocfs2_find_next_zero_bit ext2_find_next_zero_bit
770#define ocfs2_find_next_bit ext2_find_next_bit 780#define ocfs2_find_next_bit ext2_find_next_bit
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 0016503d83ef..19ba00f28547 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -95,13 +95,6 @@ static inline int ocfs2_block_group_set_bits(handle_t *handle,
95 struct buffer_head *group_bh, 95 struct buffer_head *group_bh,
96 unsigned int bit_off, 96 unsigned int bit_off,
97 unsigned int num_bits); 97 unsigned int num_bits);
98static inline int ocfs2_block_group_clear_bits(handle_t *handle,
99 struct inode *alloc_inode,
100 struct ocfs2_group_desc *bg,
101 struct buffer_head *group_bh,
102 unsigned int bit_off,
103 unsigned int num_bits);
104
105static int ocfs2_relink_block_group(handle_t *handle, 98static int ocfs2_relink_block_group(handle_t *handle,
106 struct inode *alloc_inode, 99 struct inode *alloc_inode,
107 struct buffer_head *fe_bh, 100 struct buffer_head *fe_bh,
@@ -1978,18 +1971,18 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
1978 bits_wanted, cluster_start, num_clusters); 1971 bits_wanted, cluster_start, num_clusters);
1979} 1972}
1980 1973
1981static inline int ocfs2_block_group_clear_bits(handle_t *handle, 1974static int ocfs2_block_group_clear_bits(handle_t *handle,
1982 struct inode *alloc_inode, 1975 struct inode *alloc_inode,
1983 struct ocfs2_group_desc *bg, 1976 struct ocfs2_group_desc *bg,
1984 struct buffer_head *group_bh, 1977 struct buffer_head *group_bh,
1985 unsigned int bit_off, 1978 unsigned int bit_off,
1986 unsigned int num_bits) 1979 unsigned int num_bits,
1980 void (*undo_fn)(unsigned int bit,
1981 unsigned long *bmap))
1987{ 1982{
1988 int status; 1983 int status;
1989 unsigned int tmp; 1984 unsigned int tmp;
1990 int journal_type = OCFS2_JOURNAL_ACCESS_WRITE;
1991 struct ocfs2_group_desc *undo_bg = NULL; 1985 struct ocfs2_group_desc *undo_bg = NULL;
1992 int cluster_bitmap = 0;
1993 1986
1994 mlog_entry_void(); 1987 mlog_entry_void();
1995 1988
@@ -1999,20 +1992,18 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
1999 1992
2000 mlog(0, "off = %u, num = %u\n", bit_off, num_bits); 1993 mlog(0, "off = %u, num = %u\n", bit_off, num_bits);
2001 1994
2002 if (ocfs2_is_cluster_bitmap(alloc_inode)) 1995 BUG_ON(undo_fn && !ocfs2_is_cluster_bitmap(alloc_inode));
2003 journal_type = OCFS2_JOURNAL_ACCESS_UNDO;
2004
2005 status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode), 1996 status = ocfs2_journal_access_gd(handle, INODE_CACHE(alloc_inode),
2006 group_bh, journal_type); 1997 group_bh,
1998 undo_fn ?
1999 OCFS2_JOURNAL_ACCESS_UNDO :
2000 OCFS2_JOURNAL_ACCESS_WRITE);
2007 if (status < 0) { 2001 if (status < 0) {
2008 mlog_errno(status); 2002 mlog_errno(status);
2009 goto bail; 2003 goto bail;
2010 } 2004 }
2011 2005
2012 if (ocfs2_is_cluster_bitmap(alloc_inode)) 2006 if (undo_fn) {
2013 cluster_bitmap = 1;
2014
2015 if (cluster_bitmap) {
2016 jbd_lock_bh_state(group_bh); 2007 jbd_lock_bh_state(group_bh);
2017 undo_bg = (struct ocfs2_group_desc *) 2008 undo_bg = (struct ocfs2_group_desc *)
2018 bh2jh(group_bh)->b_committed_data; 2009 bh2jh(group_bh)->b_committed_data;
@@ -2023,13 +2014,13 @@ static inline int ocfs2_block_group_clear_bits(handle_t *handle,
2023 while(tmp--) { 2014 while(tmp--) {
2024 ocfs2_clear_bit((bit_off + tmp), 2015 ocfs2_clear_bit((bit_off + tmp),
2025 (unsigned long *) bg->bg_bitmap); 2016 (unsigned long *) bg->bg_bitmap);
2026 if (cluster_bitmap) 2017 if (undo_fn)
2027 ocfs2_set_bit(bit_off + tmp, 2018 undo_fn(bit_off + tmp,
2028 (unsigned long *) undo_bg->bg_bitmap); 2019 (unsigned long *) undo_bg->bg_bitmap);
2029 } 2020 }
2030 le16_add_cpu(&bg->bg_free_bits_count, num_bits); 2021 le16_add_cpu(&bg->bg_free_bits_count, num_bits);
2031 2022
2032 if (cluster_bitmap) 2023 if (undo_fn)
2033 jbd_unlock_bh_state(group_bh); 2024 jbd_unlock_bh_state(group_bh);
2034 2025
2035 status = ocfs2_journal_dirty(handle, group_bh); 2026 status = ocfs2_journal_dirty(handle, group_bh);
@@ -2042,12 +2033,14 @@ bail:
2042/* 2033/*
2043 * expects the suballoc inode to already be locked. 2034 * expects the suballoc inode to already be locked.
2044 */ 2035 */
2045int ocfs2_free_suballoc_bits(handle_t *handle, 2036static int _ocfs2_free_suballoc_bits(handle_t *handle,
2046 struct inode *alloc_inode, 2037 struct inode *alloc_inode,
2047 struct buffer_head *alloc_bh, 2038 struct buffer_head *alloc_bh,
2048 unsigned int start_bit, 2039 unsigned int start_bit,
2049 u64 bg_blkno, 2040 u64 bg_blkno,
2050 unsigned int count) 2041 unsigned int count,
2042 void (*undo_fn)(unsigned int bit,
2043 unsigned long *bitmap))
2051{ 2044{
2052 int status = 0; 2045 int status = 0;
2053 u32 tmp_used; 2046 u32 tmp_used;
@@ -2082,7 +2075,7 @@ int ocfs2_free_suballoc_bits(handle_t *handle,
2082 2075
2083 status = ocfs2_block_group_clear_bits(handle, alloc_inode, 2076 status = ocfs2_block_group_clear_bits(handle, alloc_inode,
2084 group, group_bh, 2077 group, group_bh,
2085 start_bit, count); 2078 start_bit, count, undo_fn);
2086 if (status < 0) { 2079 if (status < 0) {
2087 mlog_errno(status); 2080 mlog_errno(status);
2088 goto bail; 2081 goto bail;
@@ -2113,6 +2106,17 @@ bail:
2113 return status; 2106 return status;
2114} 2107}
2115 2108
2109int ocfs2_free_suballoc_bits(handle_t *handle,
2110 struct inode *alloc_inode,
2111 struct buffer_head *alloc_bh,
2112 unsigned int start_bit,
2113 u64 bg_blkno,
2114 unsigned int count)
2115{
2116 return _ocfs2_free_suballoc_bits(handle, alloc_inode, alloc_bh,
2117 start_bit, bg_blkno, count, NULL);
2118}
2119
2116int ocfs2_free_dinode(handle_t *handle, 2120int ocfs2_free_dinode(handle_t *handle,
2117 struct inode *inode_alloc_inode, 2121 struct inode *inode_alloc_inode,
2118 struct buffer_head *inode_alloc_bh, 2122 struct buffer_head *inode_alloc_bh,
@@ -2126,11 +2130,13 @@ int ocfs2_free_dinode(handle_t *handle,
2126 inode_alloc_bh, bit, bg_blkno, 1); 2130 inode_alloc_bh, bit, bg_blkno, 1);
2127} 2131}
2128 2132
2129int ocfs2_free_clusters(handle_t *handle, 2133static int _ocfs2_free_clusters(handle_t *handle,
2130 struct inode *bitmap_inode, 2134 struct inode *bitmap_inode,
2131 struct buffer_head *bitmap_bh, 2135 struct buffer_head *bitmap_bh,
2132 u64 start_blk, 2136 u64 start_blk,
2133 unsigned int num_clusters) 2137 unsigned int num_clusters,
2138 void (*undo_fn)(unsigned int bit,
2139 unsigned long *bitmap))
2134{ 2140{
2135 int status; 2141 int status;
2136 u16 bg_start_bit; 2142 u16 bg_start_bit;
@@ -2157,9 +2163,9 @@ int ocfs2_free_clusters(handle_t *handle,
2157 mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n", 2163 mlog(0, "bg_blkno = %llu, bg_start_bit = %u\n",
2158 (unsigned long long)bg_blkno, bg_start_bit); 2164 (unsigned long long)bg_blkno, bg_start_bit);
2159 2165
2160 status = ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh, 2166 status = _ocfs2_free_suballoc_bits(handle, bitmap_inode, bitmap_bh,
2161 bg_start_bit, bg_blkno, 2167 bg_start_bit, bg_blkno,
2162 num_clusters); 2168 num_clusters, undo_fn);
2163 if (status < 0) { 2169 if (status < 0) {
2164 mlog_errno(status); 2170 mlog_errno(status);
2165 goto out; 2171 goto out;
@@ -2173,6 +2179,32 @@ out:
2173 return status; 2179 return status;
2174} 2180}
2175 2181
2182int ocfs2_free_clusters(handle_t *handle,
2183 struct inode *bitmap_inode,
2184 struct buffer_head *bitmap_bh,
2185 u64 start_blk,
2186 unsigned int num_clusters)
2187{
2188 return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
2189 start_blk, num_clusters,
2190 _ocfs2_set_bit);
2191}
2192
2193/*
2194 * Give never-used clusters back to the global bitmap. We don't need
2195 * to protect these bits in the undo buffer.
2196 */
2197int ocfs2_release_clusters(handle_t *handle,
2198 struct inode *bitmap_inode,
2199 struct buffer_head *bitmap_bh,
2200 u64 start_blk,
2201 unsigned int num_clusters)
2202{
2203 return _ocfs2_free_clusters(handle, bitmap_inode, bitmap_bh,
2204 start_blk, num_clusters,
2205 _ocfs2_clear_bit);
2206}
2207
2176static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg) 2208static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg)
2177{ 2209{
2178 printk("Block Group:\n"); 2210 printk("Block Group:\n");
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index fa60723c43e8..e0f46df357e6 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -127,6 +127,11 @@ int ocfs2_free_clusters(handle_t *handle,
127 struct buffer_head *bitmap_bh, 127 struct buffer_head *bitmap_bh,
128 u64 start_blk, 128 u64 start_blk,
129 unsigned int num_clusters); 129 unsigned int num_clusters);
130int ocfs2_release_clusters(handle_t *handle,
131 struct inode *bitmap_inode,
132 struct buffer_head *bitmap_bh,
133 u64 start_blk,
134 unsigned int num_clusters);
130 135
131static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit) 136static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
132{ 137{