diff options
Diffstat (limited to 'fs/gfs2/rgrp.c')
-rw-r--r-- | fs/gfs2/rgrp.c | 77 |
1 files changed, 47 insertions, 30 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index fbacf09ee34e..23637b9d1c73 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -442,6 +442,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd) | |||
442 | for (x = 0; x < length; x++) { | 442 | for (x = 0; x < length; x++) { |
443 | bi = rgd->rd_bits + x; | 443 | bi = rgd->rd_bits + x; |
444 | 444 | ||
445 | bi->bi_flags = 0; | ||
445 | /* small rgrp; bitmap stored completely in header block */ | 446 | /* small rgrp; bitmap stored completely in header block */ |
446 | if (length == 1) { | 447 | if (length == 1) { |
447 | bytes = bytes_left; | 448 | bytes = bytes_left; |
@@ -769,6 +770,8 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd) | |||
769 | } | 770 | } |
770 | 771 | ||
771 | if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) { | 772 | if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) { |
773 | for (x = 0; x < length; x++) | ||
774 | clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags); | ||
772 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); | 775 | gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data); |
773 | rgd->rd_flags |= GFS2_RDF_UPTODATE; | 776 | rgd->rd_flags |= GFS2_RDF_UPTODATE; |
774 | } | 777 | } |
@@ -897,6 +900,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd) | |||
897 | continue; | 900 | continue; |
898 | if (sdp->sd_args.ar_discard) | 901 | if (sdp->sd_args.ar_discard) |
899 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi); | 902 | gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi); |
903 | clear_bit(GBF_FULL, &bi->bi_flags); | ||
900 | memcpy(bi->bi_clone + bi->bi_offset, | 904 | memcpy(bi->bi_clone + bi->bi_offset, |
901 | bi->bi_bh->b_data + bi->bi_offset, bi->bi_len); | 905 | bi->bi_bh->b_data + bi->bi_offset, bi->bi_len); |
902 | } | 906 | } |
@@ -1309,30 +1313,37 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
1309 | { | 1313 | { |
1310 | struct gfs2_bitmap *bi = NULL; | 1314 | struct gfs2_bitmap *bi = NULL; |
1311 | const u32 length = rgd->rd_length; | 1315 | const u32 length = rgd->rd_length; |
1312 | u32 blk = 0; | 1316 | u32 blk = BFITNOENT; |
1313 | unsigned int buf, x; | 1317 | unsigned int buf, x; |
1314 | const unsigned int elen = *n; | 1318 | const unsigned int elen = *n; |
1315 | const u8 *buffer; | 1319 | const u8 *buffer = NULL; |
1316 | 1320 | ||
1317 | *n = 0; | 1321 | *n = 0; |
1318 | /* Find bitmap block that contains bits for goal block */ | 1322 | /* Find bitmap block that contains bits for goal block */ |
1319 | for (buf = 0; buf < length; buf++) { | 1323 | for (buf = 0; buf < length; buf++) { |
1320 | bi = rgd->rd_bits + buf; | 1324 | bi = rgd->rd_bits + buf; |
1321 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) | 1325 | /* Convert scope of "goal" from rgrp-wide to within found bit block */ |
1322 | break; | 1326 | if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) { |
1327 | goal -= bi->bi_start * GFS2_NBBY; | ||
1328 | goto do_search; | ||
1329 | } | ||
1323 | } | 1330 | } |
1331 | buf = 0; | ||
1332 | goal = 0; | ||
1324 | 1333 | ||
1325 | gfs2_assert(rgd->rd_sbd, buf < length); | 1334 | do_search: |
1326 | |||
1327 | /* Convert scope of "goal" from rgrp-wide to within found bit block */ | ||
1328 | goal -= bi->bi_start * GFS2_NBBY; | ||
1329 | |||
1330 | /* Search (up to entire) bitmap in this rgrp for allocatable block. | 1335 | /* Search (up to entire) bitmap in this rgrp for allocatable block. |
1331 | "x <= length", instead of "x < length", because we typically start | 1336 | "x <= length", instead of "x < length", because we typically start |
1332 | the search in the middle of a bit block, but if we can't find an | 1337 | the search in the middle of a bit block, but if we can't find an |
1333 | allocatable block anywhere else, we want to be able wrap around and | 1338 | allocatable block anywhere else, we want to be able wrap around and |
1334 | search in the first part of our first-searched bit block. */ | 1339 | search in the first part of our first-searched bit block. */ |
1335 | for (x = 0; x <= length; x++) { | 1340 | for (x = 0; x <= length; x++) { |
1341 | bi = rgd->rd_bits + buf; | ||
1342 | |||
1343 | if (test_bit(GBF_FULL, &bi->bi_flags) && | ||
1344 | (old_state == GFS2_BLKST_FREE)) | ||
1345 | goto skip; | ||
1346 | |||
1336 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone | 1347 | /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone |
1337 | bitmaps, so we must search the originals for that. */ | 1348 | bitmaps, so we must search the originals for that. */ |
1338 | buffer = bi->bi_bh->b_data + bi->bi_offset; | 1349 | buffer = bi->bi_bh->b_data + bi->bi_offset; |
@@ -1343,33 +1354,39 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal, | |||
1343 | if (blk != BFITNOENT) | 1354 | if (blk != BFITNOENT) |
1344 | break; | 1355 | break; |
1345 | 1356 | ||
1357 | if ((goal == 0) && (old_state == GFS2_BLKST_FREE)) | ||
1358 | set_bit(GBF_FULL, &bi->bi_flags); | ||
1359 | |||
1346 | /* Try next bitmap block (wrap back to rgrp header if at end) */ | 1360 | /* Try next bitmap block (wrap back to rgrp header if at end) */ |
1347 | buf = (buf + 1) % length; | 1361 | skip: |
1348 | bi = rgd->rd_bits + buf; | 1362 | buf++; |
1363 | buf %= length; | ||
1349 | goal = 0; | 1364 | goal = 0; |
1350 | } | 1365 | } |
1351 | 1366 | ||
1352 | if (blk != BFITNOENT && old_state != new_state) { | 1367 | if (blk == BFITNOENT) |
1353 | *n = 1; | 1368 | return blk; |
1354 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 1369 | *n = 1; |
1370 | if (old_state == new_state) | ||
1371 | goto out; | ||
1372 | |||
1373 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | ||
1374 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, | ||
1375 | bi->bi_len, blk, new_state); | ||
1376 | goal = blk; | ||
1377 | while (*n < elen) { | ||
1378 | goal++; | ||
1379 | if (goal >= (bi->bi_len * GFS2_NBBY)) | ||
1380 | break; | ||
1381 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | ||
1382 | GFS2_BLKST_FREE) | ||
1383 | break; | ||
1355 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, | 1384 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset, |
1356 | bi->bi_len, blk, new_state); | 1385 | bi->bi_len, goal, new_state); |
1357 | goal = blk; | 1386 | (*n)++; |
1358 | while (*n < elen) { | ||
1359 | goal++; | ||
1360 | if (goal >= (bi->bi_len * GFS2_NBBY)) | ||
1361 | break; | ||
1362 | if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) != | ||
1363 | GFS2_BLKST_FREE) | ||
1364 | break; | ||
1365 | gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, | ||
1366 | bi->bi_offset, bi->bi_len, goal, | ||
1367 | new_state); | ||
1368 | (*n)++; | ||
1369 | } | ||
1370 | } | 1387 | } |
1371 | 1388 | out: | |
1372 | return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk; | 1389 | return (bi->bi_start * GFS2_NBBY) + blk; |
1373 | } | 1390 | } |
1374 | 1391 | ||
1375 | /** | 1392 | /** |