Skip to content

Commit

Permalink
sg: Improve zbc_sg_get_max_cmd_blocks()
Browse files Browse the repository at this point in the history
Some HBAs report a maximum SG count equal to the the device reported
count + 1 for handling buffer alignment internally. This leads to errors
if the maximum command size is calculated using that incremented value.
So also get the maximum reported command size and preferably use this
value rather than the SG count times system page size as the maximum
command size.

Signed-off-by: Damien Le Moal <damien.lemoal@wdc.com>
  • Loading branch information
damien-lemoal committed Nov 7, 2018
1 parent 6424ded commit 38fd87c
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions lib/zbc_sg.c
Expand Up @@ -19,6 +19,7 @@
#include <libgen.h>
#include <string.h>
#include <linux/limits.h>
#include <linux/fs.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
Expand Down Expand Up @@ -543,7 +544,8 @@ static unsigned long zbc_sg_get_max_bytes(struct zbc_device *dev)
*/
void zbc_sg_get_max_cmd_blocks(struct zbc_device *dev)
{
unsigned long max_bytes = 0, max_segs = ZBC_SG_MAX_SEGMENTS;
unsigned int max_bytes = 0, max_segs = ZBC_SG_MAX_SEGMENTS;
size_t pagesize = sysconf_pagesize();
struct stat st;
int ret;

Expand All @@ -564,15 +566,26 @@ void zbc_sg_get_max_cmd_blocks(struct zbc_device *dev)
strerror(errno));
max_segs = ZBC_SG_MAX_SEGMENTS;
}
max_bytes = 0;

ret = ioctl(dev->zbd_sg_fd, BLKSECTGET, &max_bytes);
if (ret != 0) {
zbc_debug("%s: BLKSECTGET ioctl failed %d (%s)\n",
dev->zbd_filename,
errno,
strerror(errno));
max_bytes = 0;
}
} else if (S_ISBLK(st.st_mode)) {
max_segs = zbc_sg_get_max_segments(dev);
max_bytes = zbc_sg_get_max_bytes(dev);
} else {
/* Use default */
max_segs = ZBC_SG_MAX_SEGMENTS;
}

out:
if (!max_bytes || max_segs * sysconf_pagesize() < max_bytes)
max_bytes = max_segs * sysconf_pagesize();
if (!max_bytes || max_bytes > max_segs * pagesize)
max_bytes = max_segs * pagesize;
dev->zbd_info.zbd_max_rw_sectors = max_bytes >> 9;

zbc_debug("%s: Maximum command data transfer size is %llu sectors\n",
Expand Down

0 comments on commit 38fd87c

Please sign in to comment.