aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2009-01-05 21:49:55 -0500
committerTheodore Ts'o <tytso@mit.edu>2009-01-05 21:49:55 -0500
commit2ccb5fb9f113dae969d1ae9b6c10e80fa34f8cd3 (patch)
treed9dc5bca94748d4173a7783e963d20b5a75f8db8 /fs
parent393418676a7602e1d7d3f6e560159c65c8cbd50e (diff)
ext4: Use new buffer_head flag to check uninit group bitmaps initialization
For uninit block group, the on-disk bitmap is not initialized. That implies we cannot depend on the uptodate flag on the bitmap buffer_head to find bitmap validity. Use a new buffer_head flag which would be set after we properly initialize the bitmap. This also prevents (re-)initializing the uninit group bitmap every time we call ext4_read_block_bitmap(). Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: stable@kernel.org
Diffstat (limited to 'fs')
-rw-r--r--fs/ext4/balloc.c25
-rw-r--r--fs/ext4/ext4.h18
-rw-r--r--fs/ext4/ialloc.c24
-rw-r--r--fs/ext4/mballoc.c24
4 files changed, 85 insertions, 6 deletions
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c
index 1b26b68aa428..6bba06b09dd1 100644
--- a/fs/ext4/balloc.c
+++ b/fs/ext4/balloc.c
@@ -320,20 +320,41 @@ ext4_read_block_bitmap(struct super_block *sb, ext4_group_t block_group)
320 block_group, bitmap_blk); 320 block_group, bitmap_blk);
321 return NULL; 321 return NULL;
322 } 322 }
323 if (buffer_uptodate(bh) && 323
324 !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT))) 324 if (bitmap_uptodate(bh))
325 return bh; 325 return bh;
326 326
327 lock_buffer(bh); 327 lock_buffer(bh);
328 if (bitmap_uptodate(bh)) {
329 unlock_buffer(bh);
330 return bh;
331 }
328 spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); 332 spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
329 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 333 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
330 ext4_init_block_bitmap(sb, bh, block_group, desc); 334 ext4_init_block_bitmap(sb, bh, block_group, desc);
335 set_bitmap_uptodate(bh);
331 set_buffer_uptodate(bh); 336 set_buffer_uptodate(bh);
332 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); 337 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
333 unlock_buffer(bh); 338 unlock_buffer(bh);
334 return bh; 339 return bh;
335 } 340 }
336 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); 341 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
342 if (buffer_uptodate(bh)) {
343 /*
344 * if not uninit if bh is uptodate,
345 * bitmap is also uptodate
346 */
347 set_bitmap_uptodate(bh);
348 unlock_buffer(bh);
349 return bh;
350 }
351 /*
352 * submit the buffer_head for read. We can
353 * safely mark the bitmap as uptodate now.
354 * We do it here so the bitmap uptodate bit
355 * get set with buffer lock held.
356 */
357 set_bitmap_uptodate(bh);
337 if (bh_submit_read(bh) < 0) { 358 if (bh_submit_read(bh) < 0) {
338 put_bh(bh); 359 put_bh(bh);
339 ext4_error(sb, __func__, 360 ext4_error(sb, __func__,
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index ec862f4ca89f..695b45cc34e7 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -19,6 +19,7 @@
19#include <linux/types.h> 19#include <linux/types.h>
20#include <linux/blkdev.h> 20#include <linux/blkdev.h>
21#include <linux/magic.h> 21#include <linux/magic.h>
22#include <linux/jbd2.h>
22#include "ext4_i.h" 23#include "ext4_i.h"
23 24
24/* 25/*
@@ -1352,6 +1353,23 @@ extern int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode,
1352extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, 1353extern int ext4_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
1353 __u64 start, __u64 len); 1354 __u64 start, __u64 len);
1354 1355
1356/*
1357 * Add new method to test wether block and inode bitmaps are properly
1358 * initialized. With uninit_bg reading the block from disk is not enough
1359 * to mark the bitmap uptodate. We need to also zero-out the bitmap
1360 */
1361#define BH_BITMAP_UPTODATE BH_JBDPrivateStart
1362
1363static inline int bitmap_uptodate(struct buffer_head *bh)
1364{
1365 return (buffer_uptodate(bh) &&
1366 test_bit(BH_BITMAP_UPTODATE, &(bh)->b_state));
1367}
1368static inline void set_bitmap_uptodate(struct buffer_head *bh)
1369{
1370 set_bit(BH_BITMAP_UPTODATE, &(bh)->b_state);
1371}
1372
1355#endif /* __KERNEL__ */ 1373#endif /* __KERNEL__ */
1356 1374
1357#endif /* _EXT4_H */ 1375#endif /* _EXT4_H */
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c
index d4e544f30be2..7b12aedc5319 100644
--- a/fs/ext4/ialloc.c
+++ b/fs/ext4/ialloc.c
@@ -115,20 +115,40 @@ ext4_read_inode_bitmap(struct super_block *sb, ext4_group_t block_group)
115 block_group, bitmap_blk); 115 block_group, bitmap_blk);
116 return NULL; 116 return NULL;
117 } 117 }
118 if (buffer_uptodate(bh) && 118 if (bitmap_uptodate(bh))
119 !(desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)))
120 return bh; 119 return bh;
121 120
122 lock_buffer(bh); 121 lock_buffer(bh);
122 if (bitmap_uptodate(bh)) {
123 unlock_buffer(bh);
124 return bh;
125 }
123 spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group)); 126 spin_lock(sb_bgl_lock(EXT4_SB(sb), block_group));
124 if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) { 127 if (desc->bg_flags & cpu_to_le16(EXT4_BG_INODE_UNINIT)) {
125 ext4_init_inode_bitmap(sb, bh, block_group, desc); 128 ext4_init_inode_bitmap(sb, bh, block_group, desc);
129 set_bitmap_uptodate(bh);
126 set_buffer_uptodate(bh); 130 set_buffer_uptodate(bh);
127 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); 131 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
128 unlock_buffer(bh); 132 unlock_buffer(bh);
129 return bh; 133 return bh;
130 } 134 }
131 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group)); 135 spin_unlock(sb_bgl_lock(EXT4_SB(sb), block_group));
136 if (buffer_uptodate(bh)) {
137 /*
138 * if not uninit if bh is uptodate,
139 * bitmap is also uptodate
140 */
141 set_bitmap_uptodate(bh);
142 unlock_buffer(bh);
143 return bh;
144 }
145 /*
146 * submit the buffer_head for read. We can
147 * safely mark the bitmap as uptodate now.
148 * We do it here so the bitmap uptodate bit
149 * get set with buffer lock held.
150 */
151 set_bitmap_uptodate(bh);
132 if (bh_submit_read(bh) < 0) { 152 if (bh_submit_read(bh) < 0) {
133 put_bh(bh); 153 put_bh(bh);
134 ext4_error(sb, __func__, 154 ext4_error(sb, __func__,
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
index aac33590ac64..18a52d39d094 100644
--- a/fs/ext4/mballoc.c
+++ b/fs/ext4/mballoc.c
@@ -794,22 +794,42 @@ static int ext4_mb_init_cache(struct page *page, char *incore)
794 if (bh[i] == NULL) 794 if (bh[i] == NULL)
795 goto out; 795 goto out;
796 796
797 if (buffer_uptodate(bh[i]) && 797 if (bitmap_uptodate(bh[i]))
798 !(desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)))
799 continue; 798 continue;
800 799
801 lock_buffer(bh[i]); 800 lock_buffer(bh[i]);
801 if (bitmap_uptodate(bh[i])) {
802 unlock_buffer(bh[i]);
803 continue;
804 }
802 spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); 805 spin_lock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
803 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) { 806 if (desc->bg_flags & cpu_to_le16(EXT4_BG_BLOCK_UNINIT)) {
804 ext4_init_block_bitmap(sb, bh[i], 807 ext4_init_block_bitmap(sb, bh[i],
805 first_group + i, desc); 808 first_group + i, desc);
809 set_bitmap_uptodate(bh[i]);
806 set_buffer_uptodate(bh[i]); 810 set_buffer_uptodate(bh[i]);
807 spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); 811 spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
808 unlock_buffer(bh[i]); 812 unlock_buffer(bh[i]);
809 continue; 813 continue;
810 } 814 }
811 spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i)); 815 spin_unlock(sb_bgl_lock(EXT4_SB(sb), first_group + i));
816 if (buffer_uptodate(bh[i])) {
817 /*
818 * if not uninit if bh is uptodate,
819 * bitmap is also uptodate
820 */
821 set_bitmap_uptodate(bh[i]);
822 unlock_buffer(bh[i]);
823 continue;
824 }
812 get_bh(bh[i]); 825 get_bh(bh[i]);
826 /*
827 * submit the buffer_head for read. We can
828 * safely mark the bitmap as uptodate now.
829 * We do it here so the bitmap uptodate bit
830 * get set with buffer lock held.
831 */
832 set_bitmap_uptodate(bh[i]);
813 bh[i]->b_end_io = end_buffer_read_sync; 833 bh[i]->b_end_io = end_buffer_read_sync;
814 submit_bh(READ, bh[i]); 834 submit_bh(READ, bh[i]);
815 mb_debug("read bitmap for group %u\n", first_group + i); 835 mb_debug("read bitmap for group %u\n", first_group + i);