aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/reiserfs/bitmap.c88
-rw-r--r--fs/reiserfs/resize.c1
-rw-r--r--fs/reiserfs/super.c114
-rw-r--r--include/linux/reiserfs_fs.h4
4 files changed, 94 insertions, 113 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 44d9410e9d6a..abdd6d9c4558 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -9,6 +9,7 @@
9#include <linux/buffer_head.h> 9#include <linux/buffer_head.h>
10#include <linux/kernel.h> 10#include <linux/kernel.h>
11#include <linux/pagemap.h> 11#include <linux/pagemap.h>
12#include <linux/vmalloc.h>
12#include <linux/reiserfs_fs_sb.h> 13#include <linux/reiserfs_fs_sb.h>
13#include <linux/reiserfs_fs_i.h> 14#include <linux/reiserfs_fs_i.h>
14#include <linux/quotaops.h> 15#include <linux/quotaops.h>
@@ -1285,3 +1286,90 @@ int reiserfs_can_fit_pages(struct super_block *sb /* superblock of filesystem
1285 1286
1286 return space > 0 ? space : 0; 1287 return space > 0 ? space : 0;
1287} 1288}
1289
1290void reiserfs_cache_bitmap_metadata(struct super_block *sb,
1291 struct buffer_head *bh,
1292 struct reiserfs_bitmap_info *info)
1293{
1294 unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size);
1295
1296 info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3);
1297
1298 while (--cur >= (unsigned long *)bh->b_data) {
1299 int base = ((char *)cur - bh->b_data) << 3;
1300
1301 /* 0 and ~0 are special, we can optimize for them */
1302 if (*cur == 0) {
1303 info->first_zero_hint = base;
1304 info->free_count += BITS_PER_LONG;
1305 } else if (*cur != ~0L) { /* A mix, investigate */
1306 int b;
1307 for (b = BITS_PER_LONG - 1; b >= 0; b--) {
1308 if (!reiserfs_test_le_bit(b, cur)) {
1309 info->first_zero_hint = base + b;
1310 info->free_count++;
1311 }
1312 }
1313 }
1314 }
1315 /* The first bit must ALWAYS be 1 */
1316 BUG_ON(info->first_zero_hint == 0);
1317}
1318
1319struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
1320 unsigned int bitmap)
1321{
1322 b_blocknr_t block = (sb->s_blocksize << 3) * bitmap;
1323 struct buffer_head *bh;
1324
1325 /* Way old format filesystems had the bitmaps packed up front.
1326 * I doubt there are any of these left, but just in case... */
1327 if (unlikely(test_bit(REISERFS_OLD_FORMAT,
1328 &(REISERFS_SB(sb)->s_properties))))
1329 block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap;
1330 else if (bitmap == 0)
1331 block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
1332
1333 bh = sb_getblk(sb, block);
1334 if (!buffer_uptodate(bh))
1335 ll_rw_block(READ, 1, &bh);
1336
1337 return bh;
1338}
1339
1340int reiserfs_init_bitmap_cache(struct super_block *sb)
1341{
1342 struct reiserfs_bitmap_info *bitmap;
1343 int i;
1344
1345 bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
1346 if (bitmap == NULL)
1347 return -ENOMEM;
1348
1349 memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb));
1350
1351 for (i = 0; i < SB_BMAP_NR(sb); i++)
1352 bitmap[i].bh = reiserfs_read_bitmap_block(sb, i);
1353
1354 /* make sure we have them all */
1355 for (i = 0; i < SB_BMAP_NR(sb); i++) {
1356 wait_on_buffer(bitmap[i].bh);
1357 if (!buffer_uptodate(bitmap[i].bh)) {
1358 reiserfs_warning(sb, "sh-2029: %s: "
1359 "bitmap block (#%lu) reading failed",
1360 __FUNCTION__, bitmap[i].bh->b_blocknr);
1361 for (i = 0; i < SB_BMAP_NR(sb); i++)
1362 brelse(bitmap[i].bh);
1363 vfree(bitmap);
1364 return -EIO;
1365 }
1366 }
1367
1368 /* Cache the info on the bitmaps before we get rolling */
1369 for (i = 0; i < SB_BMAP_NR(sb); i++)
1370 reiserfs_cache_bitmap_metadata(sb, bitmap[i].bh, &bitmap[i]);
1371
1372 SB_AP_BITMAP(sb) = bitmap;
1373
1374 return 0;
1375}
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c
index 958b75978994..90d39fd3096f 100644
--- a/fs/reiserfs/resize.c
+++ b/fs/reiserfs/resize.c
@@ -132,6 +132,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
132 get_bh(bh); 132 get_bh(bh);
133 memset(bh->b_data, 0, sb_blocksize(sb)); 133 memset(bh->b_data, 0, sb_blocksize(sb));
134 reiserfs_test_and_set_le_bit(0, bh->b_data); 134 reiserfs_test_and_set_le_bit(0, bh->b_data);
135 reiserfs_cache_bitmap_metadata(s, bh, bitmap + i);
135 136
136 set_buffer_uptodate(bh); 137 set_buffer_uptodate(bh);
137 mark_buffer_dirty(bh); 138 mark_buffer_dirty(bh);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index db2c581df766..c78e99e196fa 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -1243,118 +1243,6 @@ static int reiserfs_remount(struct super_block *s, int *mount_flags, char *arg)
1243 return 0; 1243 return 0;
1244} 1244}
1245 1245
1246/* load_bitmap_info_data - Sets up the reiserfs_bitmap_info structure from disk.
1247 * @sb - superblock for this filesystem
1248 * @bi - the bitmap info to be loaded. Requires that bi->bh is valid.
1249 *
1250 * This routine counts how many free bits there are, finding the first zero
1251 * as a side effect. Could also be implemented as a loop of test_bit() calls, or
1252 * a loop of find_first_zero_bit() calls. This implementation is similar to
1253 * find_first_zero_bit(), but doesn't return after it finds the first bit.
1254 * Should only be called on fs mount, but should be fairly efficient anyways.
1255 *
1256 * bi->first_zero_hint is considered unset if it == 0, since the bitmap itself
1257 * will * invariably occupt block 0 represented in the bitmap. The only
1258 * exception to this is when free_count also == 0, since there will be no
1259 * free blocks at all.
1260 */
1261
1262static void load_bitmap_info_data(struct super_block *sb,
1263 struct reiserfs_bitmap_info *bi)
1264{
1265 unsigned long *cur = (unsigned long *)bi->bh->b_data;
1266
1267 while ((char *)cur < (bi->bh->b_data + sb->s_blocksize)) {
1268
1269 /* No need to scan if all 0's or all 1's.
1270 * Since we're only counting 0's, we can simply ignore all 1's */
1271 if (*cur == 0) {
1272 if (bi->first_zero_hint == 0) {
1273 bi->first_zero_hint =
1274 ((char *)cur - bi->bh->b_data) << 3;
1275 }
1276 bi->free_count += sizeof(unsigned long) * 8;
1277 } else if (*cur != ~0L) {
1278 int b;
1279 for (b = 0; b < sizeof(unsigned long) * 8; b++) {
1280 if (!reiserfs_test_le_bit(b, cur)) {
1281 bi->free_count++;
1282 if (bi->first_zero_hint == 0)
1283 bi->first_zero_hint =
1284 (((char *)cur -
1285 bi->bh->b_data) << 3) + b;
1286 }
1287 }
1288 }
1289 cur++;
1290 }
1291
1292#ifdef CONFIG_REISERFS_CHECK
1293// This outputs a lot of unneded info on big FSes
1294// reiserfs_warning ("bitmap loaded from block %d: %d free blocks",
1295// bi->bh->b_blocknr, bi->free_count);
1296#endif
1297}
1298
1299static int read_bitmaps(struct super_block *s)
1300{
1301 int i, bmap_nr;
1302
1303 SB_AP_BITMAP(s) =
1304 vmalloc(sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
1305 if (SB_AP_BITMAP(s) == 0)
1306 return 1;
1307 memset(SB_AP_BITMAP(s), 0,
1308 sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
1309 for (i = 0, bmap_nr =
1310 REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize + 1;
1311 i < SB_BMAP_NR(s); i++, bmap_nr = s->s_blocksize * 8 * i) {
1312 SB_AP_BITMAP(s)[i].bh = sb_getblk(s, bmap_nr);
1313 if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh))
1314 ll_rw_block(READ, 1, &SB_AP_BITMAP(s)[i].bh);
1315 }
1316 for (i = 0; i < SB_BMAP_NR(s); i++) {
1317 wait_on_buffer(SB_AP_BITMAP(s)[i].bh);
1318 if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
1319 reiserfs_warning(s, "sh-2029: reiserfs read_bitmaps: "
1320 "bitmap block (#%lu) reading failed",
1321 SB_AP_BITMAP(s)[i].bh->b_blocknr);
1322 for (i = 0; i < SB_BMAP_NR(s); i++)
1323 brelse(SB_AP_BITMAP(s)[i].bh);
1324 vfree(SB_AP_BITMAP(s));
1325 SB_AP_BITMAP(s) = NULL;
1326 return 1;
1327 }
1328 load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
1329 }
1330 return 0;
1331}
1332
1333static int read_old_bitmaps(struct super_block *s)
1334{
1335 int i;
1336 struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
1337 int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */
1338
1339 /* read true bitmap */
1340 SB_AP_BITMAP(s) =
1341 vmalloc(sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
1342 if (SB_AP_BITMAP(s) == 0)
1343 return 1;
1344
1345 memset(SB_AP_BITMAP(s), 0,
1346 sizeof(struct reiserfs_buffer_info *) * sb_bmap_nr(rs));
1347
1348 for (i = 0; i < sb_bmap_nr(rs); i++) {
1349 SB_AP_BITMAP(s)[i].bh = sb_bread(s, bmp1 + i);
1350 if (!SB_AP_BITMAP(s)[i].bh)
1351 return 1;
1352 load_bitmap_info_data(s, SB_AP_BITMAP(s) + i);
1353 }
1354
1355 return 0;
1356}
1357
1358static int read_super_block(struct super_block *s, int offset) 1246static int read_super_block(struct super_block *s, int offset)
1359{ 1247{
1360 struct buffer_head *bh; 1248 struct buffer_head *bh;
@@ -1736,7 +1624,7 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent)
1736 sbi->s_mount_state = SB_REISERFS_STATE(s); 1624 sbi->s_mount_state = SB_REISERFS_STATE(s);
1737 sbi->s_mount_state = REISERFS_VALID_FS; 1625 sbi->s_mount_state = REISERFS_VALID_FS;
1738 1626
1739 if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { 1627 if ((errval = reiserfs_init_bitmap_cache(s))) {
1740 SWARN(silent, s, 1628 SWARN(silent, s,
1741 "jmacd-8: reiserfs_fill_super: unable to read bitmap"); 1629 "jmacd-8: reiserfs_fill_super: unable to read bitmap");
1742 goto error; 1630 goto error;
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h
index 9c63abffd7b2..7bc6bfb86253 100644
--- a/include/linux/reiserfs_fs.h
+++ b/include/linux/reiserfs_fs.h
@@ -2073,6 +2073,10 @@ void reiserfs_init_alloc_options(struct super_block *s);
2073 */ 2073 */
2074__le32 reiserfs_choose_packing(struct inode *dir); 2074__le32 reiserfs_choose_packing(struct inode *dir);
2075 2075
2076int reiserfs_init_bitmap_cache(struct super_block *sb);
2077void reiserfs_free_bitmap_cache(struct super_block *sb);
2078void reiserfs_cache_bitmap_metadata(struct super_block *sb, struct buffer_head *bh, struct reiserfs_bitmap_info *info);
2079struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, unsigned int bitmap);
2076int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value); 2080int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value);
2077void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *, 2081void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *,
2078 b_blocknr_t, int for_unformatted); 2082 b_blocknr_t, int for_unformatted);