From Adrien Destugues <pulkomandy@xxxxxxxxx>:
Adrien Destugues has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/3640 ;)
Change subject: devfs: translate partition offsets in B_TRIM_DEVICE
......................................................................
devfs: translate partition offsets in B_TRIM_DEVICE
Fixes bfs part of #10336. Untested on SATA (don't have a testing drive
to sacrifice) but working fine on SD/MMC.
---
M headers/os/drivers/Drivers.h
M src/system/kernel/device_manager/devfs.cpp
2 files changed, 42 insertions(+), 7 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/40/3640/1
diff --git a/headers/os/drivers/Drivers.h b/headers/os/drivers/Drivers.h
index a854305..a8b4d7f 100644
--- a/headers/os/drivers/Drivers.h
+++ b/headers/os/drivers/Drivers.h
@@ -175,8 +175,8 @@
uint32 range_count;
uint64 trimmed_size; /* filled on return */
struct range {
- uint64 offset; /* offset (in bytes) */
- uint64 size;
+ off_t offset; /* offset (in bytes) */
+ off_t size;
} ranges[1];
} fs_trim_data;
diff --git a/src/system/kernel/device_manager/devfs.cpp
b/src/system/kernel/device_manager/devfs.cpp
index 65b9ce7..86fb1f7 100644
--- a/src/system/kernel/device_manager/devfs.cpp
+++ b/src/system/kernel/device_manager/devfs.cpp
@@ -33,6 +33,7 @@
#include <lock.h>
#include <Notifications.h>
#include <util/AutoLock.h>
+#include <util/fs_trim_support.h>
#include <vfs.h>
#include <vm/vm.h>
#include <wait_for_objects.h>
@@ -493,14 +494,14 @@
}
-static inline void
+template<typename size_type> static inline void
translate_partition_access(devfs_partition* partition, off_t& offset,
- size_t& size)
+ size_type& size)
{
ASSERT(offset >= 0);
ASSERT(offset < partition->info.size);
- size = (size_t)min_c((off_t)size, partition->info.size - offset);
+ size = (size_type)min_c((off_t)size, partition->info.size - offset);
offset += partition->info.offset;
}
@@ -1214,7 +1215,8 @@
if (pos >= vnode->stream.u.dev.partition->info.size)
return B_BAD_VALUE;
- translate_partition_access(vnode->stream.u.dev.partition, pos,
*_length);
+ translate_partition_access(vnode->stream.u.dev.partition, pos,
+ *_length);
}
if (*_length == 0)
@@ -1246,7 +1248,8 @@
if (pos >= vnode->stream.u.dev.partition->info.size)
return B_BAD_VALUE;
- translate_partition_access(vnode->stream.u.dev.partition, pos,
*_length);
+
translate_partition_access<size_t>(vnode->stream.u.dev.partition, pos,
+ *_length);
}
if (*_length == 0)
@@ -1460,6 +1463,38 @@
return user_memcpy(buffer, &geometry,
sizeof(device_geometry));
}
+ case B_TRIM_DEVICE:
+ {
+ struct devfs_partition* partition
+ = vnode->stream.u.dev.partition;
+ if (partition == NULL)
+ break;
+
+ fs_trim_data* trimData;
+ MemoryDeleter deleter;
+ status_t status =
get_trim_data_from_user(buffer, length, deleter,
+ trimData);
+ if (status != B_OK)
+ return status;
+
+ for (uint32 i = 0; i < trimData->range_count;
i++) {
+
translate_partition_access<off_t>(partition,
+ trimData->ranges[i].offset,
trimData->ranges[i].size);
+ }
+
+ // TODO not so great approach here: we copy the
fixed data back
+ // to userland, and the underlying device will
get it from
+ // there again. It's probably possible for disk
devices to know
+ // if the pointer is already to a kernel side
buffer, and not
+ // do the copy on their own then.
+ status = copy_trim_data_to_user(buffer,
trimData);
+ if (status != B_OK)
+ return status;
+
+ return vnode->stream.u.dev.device->Control(
+ cookie->device_cookie, op, buffer,
length);
+ }
+
case B_GET_DRIVER_FOR_DEVICE:
{
#if 0
--
To view, visit https://review.haiku-os.org/c/haiku/+/3640
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ie84b6a1d293828d33902a64b3c9d4b19aa6eacb1
Gerrit-Change-Number: 3640
Gerrit-PatchSet: 1
Gerrit-Owner: Adrien Destugues <pulkomandy@xxxxxxxxx>
Gerrit-MessageType: newchange