btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / private / kernel / util / fs_trim_support.h
blob22e6f9ac418c742a94c2848ffc04646ef9c30241
1 /*
2 * Copyright 2013, Axel Dörfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT license.
4 */
5 #ifndef _FS_TRIM_SUPPORT_H
6 #define _FS_TRIM_SUPPORT_H
9 #include <KernelExport.h>
11 #include <kernel.h>
12 #include <syscall_restart.h>
15 static inline status_t
16 get_trim_data_from_user(void* buffer, size_t size, MemoryDeleter& deleter,
17 fs_trim_data*& _trimData)
19 if (!is_called_via_syscall() && !IS_USER_ADDRESS(buffer)) {
20 // Called from kernel
21 _trimData = (fs_trim_data*)buffer;
22 return B_OK;
25 // Called from userland
26 if (!IS_USER_ADDRESS(buffer))
27 return B_BAD_ADDRESS;
29 uint32 count;
30 if (user_memcpy(&count, buffer, sizeof(count)) != B_OK)
31 return B_BAD_ADDRESS;
33 size_t bytes = (count - 1) * sizeof(uint64) * 2 + sizeof(fs_trim_data);
34 if (bytes > size)
35 return B_BAD_VALUE;
37 void* trimBuffer = malloc(bytes);
38 if (trimBuffer == NULL)
39 return B_NO_MEMORY;
41 if (user_memcpy(trimBuffer, buffer, bytes) != B_OK) {
42 free(trimBuffer);
43 return B_BAD_ADDRESS;
46 // The passed in MemoryDeleter needs to take care of freeing the buffer
47 // later, since we had to allocate it.
48 deleter.SetTo(trimBuffer);
50 _trimData = (fs_trim_data*)trimBuffer;
51 return B_OK;
55 static inline status_t
56 copy_trim_data_to_user(void* buffer, fs_trim_data* trimData)
58 if (!is_called_via_syscall() && !IS_USER_ADDRESS(buffer))
59 return B_OK;
61 if (!IS_USER_ADDRESS(buffer))
62 return B_BAD_ADDRESS;
64 // Do not copy any ranges
65 return user_memcpy(buffer, trimData, sizeof(uint64) * 2);
69 #endif // _FS_TRIM_SUPPORT_H