GFS2: Issue discards in 512b sectors

This patch changes GFS2's discard issuing code so that it calls
function sb_issue_discard rather than blkdev_issue_discard. The
code was calling blkdev_issue_discard and specifying the correct
sector offset and sector size, but blkdev_issue_discard expects
these values to be in terms of 512 byte sectors, even if the native
sector size for the device is different. Calling sb_issue_discard
with the BLOCK size instead ensures the correct block-to-512b-sector
translation. I verified that "minlen" is specified in blocks, so
comparing it to a number of blocks is correct.

Signed-off-by: Bob Peterson <rpeterso@redhat.com>
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
This commit is contained in:
Bob Peterson 2013-03-22 10:07:24 -04:00 committed by Steven Whitehouse
parent c2952d202f
commit b2c87cae0e
1 changed files with 13 additions and 17 deletions

View File

@ -1181,12 +1181,9 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
const struct gfs2_bitmap *bi, unsigned minlen, u64 *ptrimmed)
{
struct super_block *sb = sdp->sd_vfs;
struct block_device *bdev = sb->s_bdev;
const unsigned int sects_per_blk = sdp->sd_sb.sb_bsize /
bdev_logical_block_size(sb->s_bdev);
u64 blk;
sector_t start = 0;
sector_t nr_sects = 0;
sector_t nr_blks = 0;
int rv;
unsigned int x;
u32 trimmed = 0;
@ -1206,35 +1203,34 @@ int gfs2_rgrp_send_discards(struct gfs2_sbd *sdp, u64 offset,
if (diff == 0)
continue;
blk = offset + ((bi->bi_start + x) * GFS2_NBBY);
blk *= sects_per_blk; /* convert to sectors */
while(diff) {
if (diff & 1) {
if (nr_sects == 0)
if (nr_blks == 0)
goto start_new_extent;
if ((start + nr_sects) != blk) {
if (nr_sects >= minlen) {
rv = blkdev_issue_discard(bdev,
start, nr_sects,
if ((start + nr_blks) != blk) {
if (nr_blks >= minlen) {
rv = sb_issue_discard(sb,
start, nr_blks,
GFP_NOFS, 0);
if (rv)
goto fail;
trimmed += nr_sects;
trimmed += nr_blks;
}
nr_sects = 0;
nr_blks = 0;
start_new_extent:
start = blk;
}
nr_sects += sects_per_blk;
nr_blks++;
}
diff >>= 2;
blk += sects_per_blk;
blk++;
}
}
if (nr_sects >= minlen) {
rv = blkdev_issue_discard(bdev, start, nr_sects, GFP_NOFS, 0);
if (nr_blks >= minlen) {
rv = sb_issue_discard(sb, start, nr_blks, GFP_NOFS, 0);
if (rv)
goto fail;
trimmed += nr_sects;
trimmed += nr_blks;
}
if (ptrimmed)
*ptrimmed = trimmed;