mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
vfs: vfs_read/vfs_write: accept user addresses
This commit is contained in:
+28
-4
@@ -229,6 +229,7 @@ static int writenocache(vnode_t *node, page_t *page, uintmax_t pageoffset) {
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buffer can be a user address
|
||||||
int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *written, int flags) {
|
int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *written, int flags) {
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if (vfs_iscacheable(node)) {
|
if (vfs_iscacheable(node)) {
|
||||||
@@ -291,7 +292,11 @@ int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
|
|||||||
size_t writesize = min(PAGE_SIZE - startoffset, size);
|
size_t writesize = min(PAGE_SIZE - startoffset, size);
|
||||||
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
||||||
|
|
||||||
memcpy((void *)((uintptr_t)address + startoffset), buffer, writesize);
|
err = USERCOPY_POSSIBLY_FROM_USER((void *)((uintptr_t)address + startoffset), buffer, writesize);
|
||||||
|
if (err) {
|
||||||
|
pmm_release(FROM_HHDM(address));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
vmmcache_makedirty(page);
|
vmmcache_makedirty(page);
|
||||||
*written += writesize;
|
*written += writesize;
|
||||||
@@ -314,7 +319,13 @@ int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
|
|||||||
|
|
||||||
size_t writesize = min(PAGE_SIZE, size - *written);
|
size_t writesize = min(PAGE_SIZE, size - *written);
|
||||||
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
||||||
memcpy(address, (void *)((uintptr_t)buffer + *written), writesize);
|
|
||||||
|
err = USERCOPY_POSSIBLY_FROM_USER(address, (void *)((uintptr_t)buffer + *written), writesize);
|
||||||
|
if (err) {
|
||||||
|
pmm_release(FROM_HHDM(address));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
vmmcache_makedirty(page);
|
vmmcache_makedirty(page);
|
||||||
*written += writesize;
|
*written += writesize;
|
||||||
|
|
||||||
@@ -394,7 +405,13 @@ int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
|
|||||||
|
|
||||||
size_t readsize = min(PAGE_SIZE - startoffset, size);
|
size_t readsize = min(PAGE_SIZE - startoffset, size);
|
||||||
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
||||||
memcpy(buffer, (void *)((uintptr_t)address + startoffset), readsize);
|
|
||||||
|
err = USERCOPY_POSSIBLY_TO_USER(buffer, (void *)((uintptr_t)address + startoffset), readsize);
|
||||||
|
if (err) {
|
||||||
|
pmm_release(FROM_HHDM(address));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
*bytesread += readsize;
|
*bytesread += readsize;
|
||||||
pageoffset += 1;
|
pageoffset += 1;
|
||||||
pagecount -= 1;
|
pagecount -= 1;
|
||||||
@@ -403,6 +420,7 @@ int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
|
|||||||
// try to turn it into anonymous memory
|
// try to turn it into anonymous memory
|
||||||
vmmcache_evict(page);
|
vmmcache_evict(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
pmm_release(FROM_HHDM(address));
|
pmm_release(FROM_HHDM(address));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +432,13 @@ int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
|
|||||||
|
|
||||||
size_t readsize = min(PAGE_SIZE, size - *bytesread);
|
size_t readsize = min(PAGE_SIZE, size - *bytesread);
|
||||||
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
void *address = MAKE_HHDM(pmm_getpageaddress(page));
|
||||||
memcpy((void *)((uintptr_t)buffer + *bytesread), address, readsize);
|
|
||||||
|
err = USERCOPY_POSSIBLY_TO_USER((void *)((uintptr_t)buffer + *bytesread), address, readsize);
|
||||||
|
if (err) {
|
||||||
|
pmm_release(FROM_HHDM(address));
|
||||||
|
goto leave;
|
||||||
|
}
|
||||||
|
|
||||||
*bytesread += readsize;
|
*bytesread += readsize;
|
||||||
if (flags & V_FFLAGS_NOCACHE) {
|
if (flags & V_FFLAGS_NOCACHE) {
|
||||||
// try to turn it into anonymous memory
|
// try to turn it into anonymous memory
|
||||||
|
|||||||
Reference in New Issue
Block a user