Optimize xpt_getattr().

Do not allocate temporary buffer for attributes we are going to return
as-is, just make sure to NUL-terminate them.  Do not zero temporary 64KB
buffer for CDAI_TYPE_SCSI_DEVID, XPT tells us how much data it filled
and there are also length fields inside the returned data also.

MFC after:	2 weeks
Sponsored by:	iXsystems, Inc.
This commit is contained in:
Alexander Motin 2019-06-20 20:29:42 +00:00
parent 17795d8234
commit 35a9ffc350
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=349243

View File

@ -1253,6 +1253,7 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
cdai.ccb_h.func_code = XPT_DEV_ADVINFO;
cdai.flags = CDAI_FLAG_NONE;
cdai.bufsiz = len;
cdai.buf = buf;
if (!strcmp(attr, "GEOM::ident"))
cdai.buftype = CDAI_TYPE_SERIAL_NUM;
@ -1262,14 +1263,14 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
strcmp(attr, "GEOM::lunname") == 0) {
cdai.buftype = CDAI_TYPE_SCSI_DEVID;
cdai.bufsiz = CAM_SCSI_DEVID_MAXLEN;
cdai.buf = malloc(cdai.bufsiz, M_CAMXPT, M_NOWAIT);
if (cdai.buf == NULL) {
ret = ENOMEM;
goto out;
}
} else
goto out;
cdai.buf = malloc(cdai.bufsiz, M_CAMXPT, M_NOWAIT|M_ZERO);
if (cdai.buf == NULL) {
ret = ENOMEM;
goto out;
}
xpt_action((union ccb *)&cdai); /* can only be synchronous */
if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0)
cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE);
@ -1334,13 +1335,15 @@ xpt_getattr(char *buf, size_t len, const char *attr, struct cam_path *path)
ret = EFAULT;
}
} else {
ret = 0;
if (strlcpy(buf, cdai.buf, len) >= len)
if (cdai.provsiz < len) {
cdai.buf[cdai.provsiz] = 0;
ret = 0;
} else
ret = EFAULT;
}
out:
if (cdai.buf != NULL)
if ((char *)cdai.buf != buf)
free(cdai.buf, M_CAMXPT);
return ret;
}