diff options
| -rw-r--r-- | fs/gfs2/rgrp.c | 54 |
1 files changed, 29 insertions, 25 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index e0ee195558d3..d7ff9cf6653f 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -126,41 +126,46 @@ static unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | |||
| 126 | * Return: the block number (bitmap buffer scope) that was found | 126 | * Return: the block number (bitmap buffer scope) that was found |
| 127 | */ | 127 | */ |
| 128 | 128 | ||
| 129 | static u32 gfs2_bitfit(struct gfs2_rgrpd *rgd, unsigned char *buffer, | 129 | static u32 gfs2_bitfit(unsigned char *buffer, unsigned int buflen, u32 goal, |
| 130 | unsigned int buflen, u32 goal, | 130 | unsigned char old_state) |
| 131 | unsigned char old_state) | ||
| 132 | { | 131 | { |
| 133 | unsigned char *byte, *end, alloc; | 132 | unsigned char *byte; |
| 134 | u32 blk = goal; | 133 | u32 blk = goal; |
| 135 | unsigned int bit; | 134 | unsigned int bit, bitlong; |
| 135 | unsigned long *plong, plong55; | ||
| 136 | static int c = 0; | ||
| 136 | 137 | ||
| 137 | byte = buffer + (goal / GFS2_NBBY); | 138 | byte = buffer + (goal / GFS2_NBBY); |
| 139 | plong = buffer + (goal / GFS2_NBBY); | ||
| 138 | bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; | 140 | bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; |
| 139 | end = buffer + buflen; | 141 | bitlong = bit; |
| 140 | alloc = (old_state == GFS2_BLKST_FREE) ? 0x55 : 0; | 142 | #if BITS_PER_LONG == 32 |
| 141 | 143 | plong55 = 0x55555555; | |
| 142 | while (byte < end) { | 144 | #else |
| 143 | /* If we're looking for a free block we can eliminate all | 145 | plong55 = 0x5555555555555555; |
| 144 | bitmap settings with 0x55, which represents four data | 146 | #endif |
| 145 | blocks in a row. If we're looking for a data block, we can | 147 | while (byte < buffer + buflen) { |
| 146 | eliminate 0x00 which corresponds to four free blocks. */ | 148 | |
| 147 | if ((*byte & 0x55) == alloc) { | 149 | if (bitlong == 0 && old_state == 0 && *plong == plong55) { |
| 148 | blk += (8 - bit) >> 1; | 150 | plong++; |
| 149 | 151 | byte += sizeof(unsigned long); | |
| 150 | bit = 0; | 152 | blk += sizeof(unsigned long) * GFS2_NBBY; |
| 151 | byte++; | ||
| 152 | |||
| 153 | continue; | 153 | continue; |
| 154 | } | 154 | } |
| 155 | 155 | if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) { | |
| 156 | if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) | 156 | c++; |
| 157 | return blk; | 157 | return blk; |
| 158 | 158 | } | |
| 159 | bit += GFS2_BIT_SIZE; | 159 | bit += GFS2_BIT_SIZE; |
| 160 | if (bit >= 8) { | 160 | if (bit >= 8) { |
| 161 | bit = 0; | 161 | bit = 0; |
| 162 | byte++; | 162 | byte++; |
| 163 | } | 163 | } |
| 164 | bitlong += GFS2_BIT_SIZE; | ||
| 165 | if (bitlong >= sizeof(unsigned long) * 8) { | ||
| 166 | bitlong = 0; | ||
| 167 | plong++; | ||
| 168 | } | ||
| 164 | 169 | ||
| 165 | blk++; | 170 | blk++; |
| 166 | } | 171 | } |
| @@ -1318,11 +1323,10 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
| 1318 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone | 1323 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone |
| 1319 | bitmaps, so we must search the originals for that. */ | 1324 | bitmaps, so we must search the originals for that. */ |
| 1320 | if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) | 1325 | if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) |
| 1321 | blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset, | 1326 | blk = gfs2_bitfit(bi->bi_clone + bi->bi_offset, |
| 1322 | bi->bi_len, goal, old_state); | 1327 | bi->bi_len, goal, old_state); |
| 1323 | else | 1328 | else |
| 1324 | blk = gfs2_bitfit(rgd, | 1329 | blk = gfs2_bitfit(bi->bi_bh->b_data + bi->bi_offset, |
| 1325 | bi->bi_bh->b_data + bi->bi_offset, | ||
| 1326 | bi->bi_len, goal, old_state); | 1330 | bi->bi_len, goal, old_state); |
| 1327 | if (blk != BFITNOENT) | 1331 | if (blk != BFITNOENT) |
| 1328 | break; | 1332 | break; |
