aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/bitmap.c')
-rw-r--r--fs/reiserfs/bitmap.c216
1 files changed, 148 insertions, 68 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 4a7dbdee1b6d..1bfae42117ca 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>
@@ -50,16 +51,15 @@ static inline void get_bit_address(struct super_block *s,
50{ 51{
51 /* It is in the bitmap block number equal to the block 52 /* It is in the bitmap block number equal to the block
52 * number divided by the number of bits in a block. */ 53 * number divided by the number of bits in a block. */
53 *bmap_nr = block / (s->s_blocksize << 3); 54 *bmap_nr = block >> (s->s_blocksize_bits + 3);
54 /* Within that bitmap block it is located at bit offset *offset. */ 55 /* Within that bitmap block it is located at bit offset *offset. */
55 *offset = block & ((s->s_blocksize << 3) - 1); 56 *offset = block & ((s->s_blocksize << 3) - 1);
56 return;
57} 57}
58 58
59#ifdef CONFIG_REISERFS_CHECK 59#ifdef CONFIG_REISERFS_CHECK
60int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) 60int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
61{ 61{
62 int i, j; 62 int bmap, offset;
63 63
64 if (block == 0 || block >= SB_BLOCK_COUNT(s)) { 64 if (block == 0 || block >= SB_BLOCK_COUNT(s)) {
65 reiserfs_warning(s, 65 reiserfs_warning(s,
@@ -68,36 +68,32 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value)
68 return 0; 68 return 0;
69 } 69 }
70 70
71 /* it can't be one of the bitmap blocks */ 71 get_bit_address(s, block, &bmap, &offset);
72 for (i = 0; i < SB_BMAP_NR(s); i++) 72
73 if (block == SB_AP_BITMAP(s)[i].bh->b_blocknr) { 73 /* Old format filesystem? Unlikely, but the bitmaps are all up front so
74 * we need to account for it. */
75 if (unlikely(test_bit(REISERFS_OLD_FORMAT,
76 &(REISERFS_SB(s)->s_properties)))) {
77 b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1;
78 if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) {
79 reiserfs_warning(s, "vs: 4019: is_reusable: "
80 "bitmap block %lu(%u) can't be freed or reused",
81 block, SB_BMAP_NR(s));
82 return 0;
83 }
84 } else {
85 if (offset == 0) {
74 reiserfs_warning(s, "vs: 4020: is_reusable: " 86 reiserfs_warning(s, "vs: 4020: is_reusable: "
75 "bitmap block %lu(%u) can't be freed or reused", 87 "bitmap block %lu(%u) can't be freed or reused",
76 block, SB_BMAP_NR(s)); 88 block, SB_BMAP_NR(s));
77 return 0; 89 return 0;
78 } 90 }
79
80 get_bit_address(s, block, &i, &j);
81
82 if (i >= SB_BMAP_NR(s)) {
83 reiserfs_warning(s,
84 "vs-4030: is_reusable: there is no so many bitmap blocks: "
85 "block=%lu, bitmap_nr=%d", block, i);
86 return 0;
87 } 91 }
88 92
89 if ((bit_value == 0 && 93 if (bmap >= SB_BMAP_NR(s)) {
90 reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) ||
91 (bit_value == 1 &&
92 reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data) == 0)) {
93 reiserfs_warning(s, 94 reiserfs_warning(s,
94 "vs-4040: is_reusable: corresponding bit of block %lu does not " 95 "vs-4030: is_reusable: there is no so many bitmap blocks: "
95 "match required value (i==%d, j==%d) test_bit==%d", 96 "block=%lu, bitmap_nr=%d", block, bmap);
96 block, i, j, reiserfs_test_le_bit(j,
97 SB_AP_BITMAP
98 (s)[i].bh->
99 b_data));
100
101 return 0; 97 return 0;
102 } 98 }
103 99
@@ -141,6 +137,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
141{ 137{
142 struct super_block *s = th->t_super; 138 struct super_block *s = th->t_super;
143 struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; 139 struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n];
140 struct buffer_head *bh;
144 int end, next; 141 int end, next;
145 int org = *beg; 142 int org = *beg;
146 143
@@ -159,22 +156,25 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
159 bmap_n); 156 bmap_n);
160 return 0; 157 return 0;
161 } 158 }
162 if (buffer_locked(bi->bh)) { 159
163 PROC_INFO_INC(s, scan_bitmap.wait); 160 bh = reiserfs_read_bitmap_block(s, bmap_n);
164 __wait_on_buffer(bi->bh); 161 if (bh == NULL)
165 } 162 return 0;
166 163
167 while (1) { 164 while (1) {
168 cont: 165 cont:
169 if (bi->free_count < min) 166 if (bi->free_count < min) {
167 brelse(bh);
170 return 0; // No free blocks in this bitmap 168 return 0; // No free blocks in this bitmap
169 }
171 170
172 /* search for a first zero bit -- beggining of a window */ 171 /* search for a first zero bit -- beggining of a window */
173 *beg = reiserfs_find_next_zero_le_bit 172 *beg = reiserfs_find_next_zero_le_bit
174 ((unsigned long *)(bi->bh->b_data), boundary, *beg); 173 ((unsigned long *)(bh->b_data), boundary, *beg);
175 174
176 if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block 175 if (*beg + min > boundary) { /* search for a zero bit fails or the rest of bitmap block
177 * cannot contain a zero window of minimum size */ 176 * cannot contain a zero window of minimum size */
177 brelse(bh);
178 return 0; 178 return 0;
179 } 179 }
180 180
@@ -183,7 +183,7 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
183 /* first zero bit found; we check next bits */ 183 /* first zero bit found; we check next bits */
184 for (end = *beg + 1;; end++) { 184 for (end = *beg + 1;; end++) {
185 if (end >= *beg + max || end >= boundary 185 if (end >= *beg + max || end >= boundary
186 || reiserfs_test_le_bit(end, bi->bh->b_data)) { 186 || reiserfs_test_le_bit(end, bh->b_data)) {
187 next = end; 187 next = end;
188 break; 188 break;
189 } 189 }
@@ -197,12 +197,12 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
197 * (end) points to one bit after the window end */ 197 * (end) points to one bit after the window end */
198 if (end - *beg >= min) { /* it seems we have found window of proper size */ 198 if (end - *beg >= min) { /* it seems we have found window of proper size */
199 int i; 199 int i;
200 reiserfs_prepare_for_journal(s, bi->bh, 1); 200 reiserfs_prepare_for_journal(s, bh, 1);
201 /* try to set all blocks used checking are they still free */ 201 /* try to set all blocks used checking are they still free */
202 for (i = *beg; i < end; i++) { 202 for (i = *beg; i < end; i++) {
203 /* It seems that we should not check in journal again. */ 203 /* It seems that we should not check in journal again. */
204 if (reiserfs_test_and_set_le_bit 204 if (reiserfs_test_and_set_le_bit
205 (i, bi->bh->b_data)) { 205 (i, bh->b_data)) {
206 /* bit was set by another process 206 /* bit was set by another process
207 * while we slept in prepare_for_journal() */ 207 * while we slept in prepare_for_journal() */
208 PROC_INFO_INC(s, scan_bitmap.stolen); 208 PROC_INFO_INC(s, scan_bitmap.stolen);
@@ -214,17 +214,16 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th,
214 /* otherwise we clear all bit were set ... */ 214 /* otherwise we clear all bit were set ... */
215 while (--i >= *beg) 215 while (--i >= *beg)
216 reiserfs_test_and_clear_le_bit 216 reiserfs_test_and_clear_le_bit
217 (i, bi->bh->b_data); 217 (i, bh->b_data);
218 reiserfs_restore_prepared_buffer(s, 218 reiserfs_restore_prepared_buffer(s, bh);
219 bi->
220 bh);
221 *beg = org; 219 *beg = org;
222 /* ... and search again in current block from beginning */ 220 /* ... and search again in current block from beginning */
223 goto cont; 221 goto cont;
224 } 222 }
225 } 223 }
226 bi->free_count -= (end - *beg); 224 bi->free_count -= (end - *beg);
227 journal_mark_dirty(th, s, bi->bh); 225 journal_mark_dirty(th, s, bh);
226 brelse(bh);
228 227
229 /* free block count calculation */ 228 /* free block count calculation */
230 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 229 reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s),
@@ -266,9 +265,20 @@ static int bmap_hash_id(struct super_block *s, u32 id)
266 */ 265 */
267static inline int block_group_used(struct super_block *s, u32 id) 266static inline int block_group_used(struct super_block *s, u32 id)
268{ 267{
269 int bm; 268 int bm = bmap_hash_id(s, id);
270 bm = bmap_hash_id(s, id); 269 struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm];
271 if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100)) { 270
271 /* If we don't have cached information on this bitmap block, we're
272 * going to have to load it later anyway. Loading it here allows us
273 * to make a better decision. This favors long-term performace gain
274 * with a better on-disk layout vs. a short term gain of skipping the
275 * read and potentially having a bad placement. */
276 if (info->first_zero_hint == 0) {
277 struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm);
278 brelse(bh);
279 }
280
281 if (info->free_count > ((s->s_blocksize << 3) * 60 / 100)) {
272 return 0; 282 return 0;
273 } 283 }
274 return 1; 284 return 1;
@@ -373,7 +383,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
373{ 383{
374 struct super_block *s = th->t_super; 384 struct super_block *s = th->t_super;
375 struct reiserfs_super_block *rs; 385 struct reiserfs_super_block *rs;
376 struct buffer_head *sbh; 386 struct buffer_head *sbh, *bmbh;
377 struct reiserfs_bitmap_info *apbi; 387 struct reiserfs_bitmap_info *apbi;
378 int nr, offset; 388 int nr, offset;
379 389
@@ -394,16 +404,21 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th,
394 return; 404 return;
395 } 405 }
396 406
397 reiserfs_prepare_for_journal(s, apbi[nr].bh, 1); 407 bmbh = reiserfs_read_bitmap_block(s, nr);
408 if (!bmbh)
409 return;
410
411 reiserfs_prepare_for_journal(s, bmbh, 1);
398 412
399 /* clear bit for the given block in bit map */ 413 /* clear bit for the given block in bit map */
400 if (!reiserfs_test_and_clear_le_bit(offset, apbi[nr].bh->b_data)) { 414 if (!reiserfs_test_and_clear_le_bit(offset, bmbh->b_data)) {
401 reiserfs_warning(s, "vs-4080: reiserfs_free_block: " 415 reiserfs_warning(s, "vs-4080: reiserfs_free_block: "
402 "free_block (%s:%lu)[dev:blocknr]: bit already cleared", 416 "free_block (%s:%lu)[dev:blocknr]: bit already cleared",
403 reiserfs_bdevname(s), block); 417 reiserfs_bdevname(s), block);
404 } 418 }
405 apbi[nr].free_count++; 419 apbi[nr].free_count++;
406 journal_mark_dirty(th, s, apbi[nr].bh); 420 journal_mark_dirty(th, s, bmbh);
421 brelse(bmbh);
407 422
408 reiserfs_prepare_for_journal(s, sbh, 1); 423 reiserfs_prepare_for_journal(s, sbh, 1);
409 /* update super block */ 424 /* update super block */
@@ -1019,7 +1034,6 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
1019 b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1; 1034 b_blocknr_t finish = SB_BLOCK_COUNT(s) - 1;
1020 int passno = 0; 1035 int passno = 0;
1021 int nr_allocated = 0; 1036 int nr_allocated = 0;
1022 int bigalloc = 0;
1023 1037
1024 determine_prealloc_size(hint); 1038 determine_prealloc_size(hint);
1025 if (!hint->formatted_node) { 1039 if (!hint->formatted_node) {
@@ -1046,28 +1060,9 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
1046 hint->preallocate = hint->prealloc_size = 0; 1060 hint->preallocate = hint->prealloc_size = 0;
1047 } 1061 }
1048 /* for unformatted nodes, force large allocations */ 1062 /* for unformatted nodes, force large allocations */
1049 bigalloc = amount_needed;
1050 } 1063 }
1051 1064
1052 do { 1065 do {
1053 /* in bigalloc mode, nr_allocated should stay zero until
1054 * the entire allocation is filled
1055 */
1056 if (unlikely(bigalloc && nr_allocated)) {
1057 reiserfs_warning(s, "bigalloc is %d, nr_allocated %d\n",
1058 bigalloc, nr_allocated);
1059 /* reset things to a sane value */
1060 bigalloc = amount_needed - nr_allocated;
1061 }
1062 /*
1063 * try pass 0 and pass 1 looking for a nice big
1064 * contiguous allocation. Then reset and look
1065 * for anything you can find.
1066 */
1067 if (passno == 2 && bigalloc) {
1068 passno = 0;
1069 bigalloc = 0;
1070 }
1071 switch (passno++) { 1066 switch (passno++) {
1072 case 0: /* Search from hint->search_start to end of disk */ 1067 case 0: /* Search from hint->search_start to end of disk */
1073 start = hint->search_start; 1068 start = hint->search_start;
@@ -1105,8 +1100,7 @@ static inline int blocknrs_and_prealloc_arrays_from_search_start
1105 new_blocknrs + 1100 new_blocknrs +
1106 nr_allocated, 1101 nr_allocated,
1107 start, finish, 1102 start, finish,
1108 bigalloc ? 1103 1,
1109 bigalloc : 1,
1110 amount_needed - 1104 amount_needed -
1111 nr_allocated, 1105 nr_allocated,
1112 hint-> 1106 hint->
@@ -1263,3 +1257,89 @@ int reiserfs_can_fit_pages(struct super_block *sb /* superblock of filesystem
1263 1257
1264 return space > 0 ? space : 0; 1258 return space > 0 ? space : 0;
1265} 1259}
1260
1261void reiserfs_cache_bitmap_metadata(struct super_block *sb,
1262 struct buffer_head *bh,
1263 struct reiserfs_bitmap_info *info)
1264{
1265 unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size);
1266
1267 info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3);
1268
1269 while (--cur >= (unsigned long *)bh->b_data) {
1270 int base = ((char *)cur - bh->b_data) << 3;
1271
1272 /* 0 and ~0 are special, we can optimize for them */
1273 if (*cur == 0) {
1274 info->first_zero_hint = base;
1275 info->free_count += BITS_PER_LONG;
1276 } else if (*cur != ~0L) { /* A mix, investigate */
1277 int b;
1278 for (b = BITS_PER_LONG - 1; b >= 0; b--) {
1279 if (!reiserfs_test_le_bit(b, cur)) {
1280 info->first_zero_hint = base + b;
1281 info->free_count++;
1282 }
1283 }
1284 }
1285 }
1286 /* The first bit must ALWAYS be 1 */
1287 BUG_ON(info->first_zero_hint == 0);
1288}
1289
1290struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb,
1291 unsigned int bitmap)
1292{
1293 b_blocknr_t block = (sb->s_blocksize << 3) * bitmap;
1294 struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap;
1295 struct buffer_head *bh;
1296
1297 /* Way old format filesystems had the bitmaps packed up front.
1298 * I doubt there are any of these left, but just in case... */
1299 if (unlikely(test_bit(REISERFS_OLD_FORMAT,
1300 &(REISERFS_SB(sb)->s_properties))))
1301 block = REISERFS_SB(sb)->s_sbh->b_blocknr + 1 + bitmap;
1302 else if (bitmap == 0)
1303 block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1;
1304
1305 bh = sb_bread(sb, block);
1306 if (bh == NULL)
1307 reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) "
1308 "reading failed", __FUNCTION__, bh->b_blocknr);
1309 else {
1310 if (buffer_locked(bh)) {
1311 PROC_INFO_INC(sb, scan_bitmap.wait);
1312 __wait_on_buffer(bh);
1313 }
1314 BUG_ON(!buffer_uptodate(bh));
1315 BUG_ON(atomic_read(&bh->b_count) == 0);
1316
1317 if (info->first_zero_hint == 0)
1318 reiserfs_cache_bitmap_metadata(sb, bh, info);
1319 }
1320
1321 return bh;
1322}
1323
1324int reiserfs_init_bitmap_cache(struct super_block *sb)
1325{
1326 struct reiserfs_bitmap_info *bitmap;
1327
1328 bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb));
1329 if (bitmap == NULL)
1330 return -ENOMEM;
1331
1332 memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb));
1333
1334 SB_AP_BITMAP(sb) = bitmap;
1335
1336 return 0;
1337}
1338
1339void reiserfs_free_bitmap_cache(struct super_block *sb)
1340{
1341 if (SB_AP_BITMAP(sb)) {
1342 vfree(SB_AP_BITMAP(sb));
1343 SB_AP_BITMAP(sb) = NULL;
1344 }
1345}