Skip to content

Commit 3451cf3

Browse files
keithbuschaxboe
authored andcommitted
null_blk: allow byte aligned memory offsets
Allowing byte aligned memory provides a nice testing ground for direct-io. Signed-off-by: Keith Busch <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Johannes Thumshirn <[email protected]> Reviewed-by: Damien Le Moal <[email protected]> Reviewed-by: Chaitanya Kulkarni <[email protected]> Tested-by: Hans Holmberg <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 262a3dd commit 3451cf3

2 files changed

Lines changed: 25 additions & 22 deletions

File tree

drivers/block/null_blk/main.c

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1130,59 +1130,61 @@ static int null_make_cache_space(struct nullb *nullb, unsigned long n)
11301130
}
11311131

11321132
static blk_status_t copy_to_nullb(struct nullb *nullb, void *source,
1133-
sector_t sector, size_t n, bool is_fua)
1133+
loff_t pos, size_t n, bool is_fua)
11341134
{
11351135
size_t temp, count = 0;
1136-
unsigned int offset;
11371136
struct nullb_page *t_page;
1137+
sector_t sector;
11381138

11391139
while (count < n) {
1140-
temp = min_t(size_t, nullb->dev->blocksize, n - count);
1140+
temp = min3(nullb->dev->blocksize, n - count,
1141+
PAGE_SIZE - offset_in_page(pos));
1142+
sector = pos >> SECTOR_SHIFT;
11411143

11421144
if (null_cache_active(nullb) && !is_fua)
11431145
null_make_cache_space(nullb, PAGE_SIZE);
11441146

1145-
offset = (sector & SECTOR_MASK) << SECTOR_SHIFT;
11461147
t_page = null_insert_page(nullb, sector,
11471148
!null_cache_active(nullb) || is_fua);
11481149
if (!t_page)
11491150
return BLK_STS_NOSPC;
11501151

1151-
memcpy_to_page(t_page->page, offset, source + count, temp);
1152+
memcpy_to_page(t_page->page, offset_in_page(pos),
1153+
source + count, temp);
11521154

11531155
__set_bit(sector & SECTOR_MASK, t_page->bitmap);
11541156

11551157
if (is_fua)
11561158
null_free_sector(nullb, sector, true);
11571159

11581160
count += temp;
1159-
sector += temp >> SECTOR_SHIFT;
1161+
pos += temp;
11601162
}
11611163
return BLK_STS_OK;
11621164
}
11631165

1164-
static void copy_from_nullb(struct nullb *nullb, void *dest, sector_t sector,
1166+
static void copy_from_nullb(struct nullb *nullb, void *dest, loff_t pos,
11651167
size_t n)
11661168
{
11671169
size_t temp, count = 0;
1168-
unsigned int offset;
11691170
struct nullb_page *t_page;
1171+
sector_t sector;
11701172

11711173
while (count < n) {
1172-
temp = min_t(size_t, nullb->dev->blocksize, n - count);
1174+
temp = min3(nullb->dev->blocksize, n - count,
1175+
PAGE_SIZE - offset_in_page(pos));
1176+
sector = pos >> SECTOR_SHIFT;
11731177

1174-
offset = (sector & SECTOR_MASK) << SECTOR_SHIFT;
11751178
t_page = null_lookup_page(nullb, sector, false,
11761179
!null_cache_active(nullb));
1177-
11781180
if (t_page)
1179-
memcpy_from_page(dest + count, t_page->page, offset,
1180-
temp);
1181+
memcpy_from_page(dest + count, t_page->page,
1182+
offset_in_page(pos), temp);
11811183
else
11821184
memset(dest + count, 0, temp);
11831185

11841186
count += temp;
1185-
sector += temp >> SECTOR_SHIFT;
1187+
pos += temp;
11861188
}
11871189
}
11881190

@@ -1228,7 +1230,7 @@ static blk_status_t null_handle_flush(struct nullb *nullb)
12281230
}
12291231

12301232
static blk_status_t null_transfer(struct nullb *nullb, struct page *page,
1231-
unsigned int len, unsigned int off, bool is_write, sector_t sector,
1233+
unsigned int len, unsigned int off, bool is_write, loff_t pos,
12321234
bool is_fua)
12331235
{
12341236
struct nullb_device *dev = nullb->dev;
@@ -1240,10 +1242,10 @@ static blk_status_t null_transfer(struct nullb *nullb, struct page *page,
12401242
if (!is_write) {
12411243
if (dev->zoned)
12421244
valid_len = null_zone_valid_read_len(nullb,
1243-
sector, len);
1245+
pos >> SECTOR_SHIFT, len);
12441246

12451247
if (valid_len) {
1246-
copy_from_nullb(nullb, p, sector, valid_len);
1248+
copy_from_nullb(nullb, p, pos, valid_len);
12471249
off += valid_len;
12481250
len -= valid_len;
12491251
}
@@ -1253,7 +1255,7 @@ static blk_status_t null_transfer(struct nullb *nullb, struct page *page,
12531255
flush_dcache_page(page);
12541256
} else {
12551257
flush_dcache_page(page);
1256-
err = copy_to_nullb(nullb, p, sector, len, is_fua);
1258+
err = copy_to_nullb(nullb, p, pos, len, is_fua);
12571259
}
12581260

12591261
kunmap_local(p);
@@ -1271,7 +1273,7 @@ static blk_status_t null_handle_data_transfer(struct nullb_cmd *cmd,
12711273
struct nullb *nullb = cmd->nq->dev->nullb;
12721274
blk_status_t err = BLK_STS_OK;
12731275
unsigned int len;
1274-
sector_t sector = blk_rq_pos(rq);
1276+
loff_t pos = blk_rq_pos(rq) << SECTOR_SHIFT;
12751277
unsigned int max_bytes = nr_sectors << SECTOR_SHIFT;
12761278
unsigned int transferred_bytes = 0;
12771279
struct req_iterator iter;
@@ -1283,11 +1285,11 @@ static blk_status_t null_handle_data_transfer(struct nullb_cmd *cmd,
12831285
if (transferred_bytes + len > max_bytes)
12841286
len = max_bytes - transferred_bytes;
12851287
err = null_transfer(nullb, bvec.bv_page, len, bvec.bv_offset,
1286-
op_is_write(req_op(rq)), sector,
1288+
op_is_write(req_op(rq)), pos,
12871289
rq->cmd_flags & REQ_FUA);
12881290
if (err)
12891291
break;
1290-
sector += len >> SECTOR_SHIFT;
1292+
pos += len;
12911293
transferred_bytes += len;
12921294
if (transferred_bytes >= max_bytes)
12931295
break;
@@ -1944,6 +1946,7 @@ static int null_add_dev(struct nullb_device *dev)
19441946
.logical_block_size = dev->blocksize,
19451947
.physical_block_size = dev->blocksize,
19461948
.max_hw_sectors = dev->max_sectors,
1949+
.dma_alignment = 1,
19471950
};
19481951

19491952
struct nullb *nullb;

drivers/block/null_blk/zoned.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ size_t null_zone_valid_read_len(struct nullb *nullb,
242242
{
243243
struct nullb_device *dev = nullb->dev;
244244
struct nullb_zone *zone = &dev->zones[null_zone_no(dev, sector)];
245-
unsigned int nr_sectors = len >> SECTOR_SHIFT;
245+
unsigned int nr_sectors = DIV_ROUND_UP(len, SECTOR_SHIFT);
246246

247247
/* Read must be below the write pointer position */
248248
if (zone->type == BLK_ZONE_TYPE_CONVENTIONAL ||

0 commit comments

Comments
 (0)