summaryrefslogtreecommitdiff
path: root/src/sys/dms/dms_subr.c
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-10-14 20:23:19 -0400
committerIan Moffett <ian@osmora.org>2025-10-14 20:23:19 -0400
commitaaa076ff1d68545085fb85ee24d5410b60a123bd (patch)
tree98b1642cd6aae676b15318e376661e7b343196f9 /src/sys/dms/dms_subr.c
parent6a0c08f51e59328d9a158bb521b1f1cf57663962 (diff)
kern: dms: Make DMS block size aware
In order to safely copy between disk and host memory through a programming interface, DMS must be aware of the hardware disk block size Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys/dms/dms_subr.c')
-rw-r--r--src/sys/dms/dms_subr.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/src/sys/dms/dms_subr.c b/src/sys/dms/dms_subr.c
index 240449a..085633b 100644
--- a/src/sys/dms/dms_subr.c
+++ b/src/sys/dms/dms_subr.c
@@ -30,6 +30,7 @@
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/queue.h>
+#include <sys/param.h>
#include <os/kalloc.h>
#include <dms/dms.h>
#include <string.h>
@@ -100,6 +101,9 @@ dms_get(disk_id_t disk_id)
ssize_t
dms_write(struct dms_disk *dp, void *p, off_t off, size_t len)
{
+ void *buf;
+ size_t real_len;
+ int error;
struct dms_ops *ops;
if (dp == NULL || p == NULL) {
@@ -114,13 +118,25 @@ dms_write(struct dms_disk *dp, void *p, off_t off, size_t len)
return -ENOTSUP;
}
- return ops->write(dp, p, off, len);
+ real_len = ALIGN_UP(len, dp->bsize);
+ if ((buf = kalloc(real_len)) == NULL) {
+ return -ENOMEM;
+ }
+
+ memset(buf, 0, real_len);
+ memcpy(buf, p, len);
+ error = ops->write(dp, buf, off, real_len);
+ kfree(buf);
+ return error;
}
ssize_t
dms_read(struct dms_disk *dp, void *p, off_t off, size_t len)
{
+ void *buf;
struct dms_ops *ops;
+ size_t real_len;
+ int error;
if (dp == NULL || p == NULL) {
return -EINVAL;
@@ -134,5 +150,20 @@ dms_read(struct dms_disk *dp, void *p, off_t off, size_t len)
return -ENOTSUP;
}
- return ops->read(dp, p, off, len);
+ /* Allocate a real sized buffer */
+ real_len = ALIGN_UP(len, dp->bsize);
+ if ((buf = kalloc(real_len)) == NULL) {
+ return -ENOMEM;
+ }
+
+ memset(buf, 0, real_len);
+ error = ops->read(dp, buf, off, real_len);
+ if (error < 0) {
+ kfree(buf);
+ return error;
+ }
+
+ memcpy(p, buf, len);
+ kfree(buf);
+ return 0;
}