mirror of
https://github.com/SCST-project/scst.git
synced 2026-08-18 05:06:31 +00:00
vdisk_fileio, async mode: Support multi-page sgv's for kernels < v5.1
This commit is contained in:
committed by
Gleb Chesnokov
parent
414805bb4d
commit
a08e8b8b35
@@ -5133,6 +5133,23 @@ static inline int scst_get_buf_count(struct scst_cmd *cmd)
|
||||
return (cmd->sg_cnt == 0) ? 1 : cmd->sg_cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns approximate higher rounded buffers count in pages
|
||||
*/
|
||||
static inline int scst_get_buf_page_count(struct scst_cmd *cmd)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
int page_cnt = 0, i;
|
||||
|
||||
if (unlikely(cmd->sg_cnt == 0))
|
||||
return 1;
|
||||
|
||||
for (i = 0, sg = cmd->sg; i < cmd->sg_cnt; i++, sg = sg_next_inline(sg))
|
||||
page_cnt += PAGE_ALIGN(sg->offset + sg->length) >> PAGE_SHIFT;
|
||||
|
||||
return page_cnt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns approximate higher rounded buffers count that
|
||||
* scst_get_out_buf_[first|next]() return.
|
||||
|
||||
@@ -3175,7 +3175,11 @@ static bool vdisk_alloc_async_bvec(struct scst_cmd *cmd,
|
||||
{
|
||||
int n;
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
|
||||
n = scst_get_buf_page_count(cmd);
|
||||
#else
|
||||
n = scst_get_buf_count(cmd);
|
||||
#endif
|
||||
if (n <= ARRAY_SIZE(p->async.small_bvec)) {
|
||||
p->async.bvec = &p->async.small_bvec[0];
|
||||
return true;
|
||||
@@ -3191,6 +3195,42 @@ static bool vdisk_alloc_async_bvec(struct scst_cmd *cmd,
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline
|
||||
struct bio_vec *vdisk_map_pages_to_bvec(struct bio_vec *bvec, struct page *page,
|
||||
ssize_t length, int offset)
|
||||
{
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
|
||||
ssize_t page_len = min_t(ssize_t, length, PAGE_SIZE - offset);
|
||||
#else
|
||||
ssize_t page_len = length;
|
||||
#endif
|
||||
|
||||
*bvec++ = (struct bio_vec) {
|
||||
.bv_page = page,
|
||||
.bv_offset = offset,
|
||||
.bv_len = page_len,
|
||||
};
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 1, 0)
|
||||
length -= page_len;
|
||||
|
||||
while (length > 0) {
|
||||
page++;
|
||||
page_len = min_t(ssize_t, length, PAGE_SIZE);
|
||||
|
||||
*bvec++ = (struct bio_vec) {
|
||||
.bv_page = page,
|
||||
.bv_offset = 0,
|
||||
.bv_len = page_len,
|
||||
};
|
||||
|
||||
length -= page_len;
|
||||
}
|
||||
#endif
|
||||
|
||||
return bvec;
|
||||
}
|
||||
|
||||
static void fileio_async_complete(struct kiocb *iocb, long ret
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)
|
||||
, long ret2
|
||||
@@ -3262,11 +3302,8 @@ static enum compl_status_e fileio_exec_async(struct vdisk_cmd_params *p)
|
||||
bvec = p->async.bvec;
|
||||
length = scst_get_sg_page_first(cmd, &page, &offset);
|
||||
while (length) {
|
||||
*bvec++ = (struct bio_vec){
|
||||
.bv_page = page,
|
||||
.bv_offset = offset,
|
||||
.bv_len = length,
|
||||
};
|
||||
bvec = vdisk_map_pages_to_bvec(bvec, page, length, offset);
|
||||
|
||||
total += length;
|
||||
sg_cnt++;
|
||||
length = scst_get_sg_page_next(cmd, &page, &offset);
|
||||
|
||||
Reference in New Issue
Block a user