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; |