diff options
-rw-r--r-- | fs/reiserfs/bitmap.c | 88 | ||||
-rw-r--r-- | fs/reiserfs/resize.c | 1 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 114 | ||||
-rw-r--r-- | include/linux/reiserfs_fs.h | 4 |
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 | |||
1290 | void 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 | |||
1319 | struct 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 | |||
1340 | int 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 | |||
1262 | static 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 | |||
1299 | static 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 | |||
1333 | static 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 | |||
1358 | static int read_super_block(struct super_block *s, int offset) | 1246 | static 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 | ||
2076 | int reiserfs_init_bitmap_cache(struct super_block *sb); | ||
2077 | void reiserfs_free_bitmap_cache(struct super_block *sb); | ||
2078 | void reiserfs_cache_bitmap_metadata(struct super_block *sb, struct buffer_head *bh, struct reiserfs_bitmap_info *info); | ||
2079 | struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, unsigned int bitmap); | ||
2076 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value); | 2080 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value); |
2077 | void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *, | 2081 | void reiserfs_free_block(struct reiserfs_transaction_handle *th, struct inode *, |
2078 | b_blocknr_t, int for_unformatted); | 2082 | b_blocknr_t, int for_unformatted); |