[haiku-commits] Change in haiku[master]: devfs: translate partition offsets in B_TRIM_DEVICE

  • From: Gerrit <review@xxxxxxxxxxxxxxxxxxx>
  • To: waddlesplash <waddlesplash@xxxxxxxxx>, haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 17 Jan 2021 16:48:04 +0000

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

Other related posts:

  • » [haiku-commits] Change in haiku[master]: devfs: translate partition offsets in B_TRIM_DEVICE - Gerrit