From Jérôme Duval <jerome.duval@xxxxxxxxx>:
Jérôme Duval has uploaded this change for review. (
https://review.haiku-os.org/c/haiku/+/3382 )
Change subject: POSIX: add posix_fallocate and a preallocate syscall
......................................................................
POSIX: add posix_fallocate and a preallocate syscall
the preallocate syscall will call the preallocate filesystem hook, if available.
fix #6285
---
M headers/posix/fcntl.h
M headers/private/kernel/vfs.h
M headers/private/system/syscalls.h
M src/system/kernel/fs/vfs.cpp
M src/system/libroot/posix/fcntl.cpp
M src/system/libroot/stubbed/libroot_stubs.c
M src/system/libroot/stubbed/libroot_stubs_legacy.c
7 files changed, 72 insertions(+), 0 deletions(-)
git pull ssh://git.haiku-os.org:22/haiku refs/changes/82/3382/1
diff --git a/headers/posix/fcntl.h b/headers/posix/fcntl.h
index e16dd16..539034f 100644
--- a/headers/posix/fcntl.h
+++ b/headers/posix/fcntl.h
@@ -99,6 +99,7 @@
extern int fcntl(int fd, int op, ...);
extern int posix_fadvise(int fd, off_t offset, off_t len, int advice);
+extern int posix_fallocate(int fd, off_t offset, off_t len);
#ifdef __cplusplus
}
diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h
index b79731e..0bbdc82 100644
--- a/headers/private/kernel/vfs.h
+++ b/headers/private/kernel/vfs.h
@@ -252,6 +252,7 @@
int _user_dup2(int ofd, int nfd);
status_t _user_lock_node(int fd);
status_t _user_unlock_node(int fd);
+status_t _user_preallocate(int fd, off_t offset, off_t length);
/* socket user prototypes (implementation in socket.cpp) */
int _user_socket(int family, int type, int protocol);
diff --git a/headers/private/system/syscalls.h
b/headers/private/system/syscalls.h
index c844095..125a6e3 100644
--- a/headers/private/system/syscalls.h
+++ b/headers/private/system/syscalls.h
@@ -338,6 +338,7 @@
extern status_t _kern_unlock_node(int fd);
extern status_t _kern_get_next_fd_info(team_id team, uint32
*_cookie,
struct fd_info *info, size_t
infoSize);
+extern status_t _kern_preallocate(int fd, off_t offset, off_t
length);
// socket functions
extern int _kern_socket(int family, int type, int
protocol);
diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp
index f3d8ca2..e0a4a18 100644
--- a/src/system/kernel/fs/vfs.cpp
+++ b/src/system/kernel/fs/vfs.cpp
@@ -6439,6 +6439,48 @@
static status_t
+common_preallocate(int fd, off_t offset, off_t length, bool kernel)
+{
+ struct file_descriptor* descriptor;
+ struct vnode* vnode;
+
+ if (offset < 0 || length == 0)
+ return B_BAD_VALUE;
+ if (offset > OFF_MAX - length)
+ return B_FILE_TOO_LARGE;
+
+ descriptor = get_fd_and_vnode(fd, &vnode, kernel);
+ if (descriptor == NULL || (descriptor->open_mode & O_RWMASK) ==
O_RDONLY)
+ return B_FILE_ERROR;
+
+ switch (vnode->Type() & S_IFMT) {
+ case S_IFIFO:
+ case S_IFSOCK:
+ return ESPIPE;
+
+ case S_IFBLK:
+ case S_IFCHR:
+ case S_IFDIR:
+ case S_IFLNK:
+ return B_DEVICE_NOT_FOUND;
+
+ case S_IFREG:
+ break;
+ }
+
+ status_t status = B_OK;
+ if (HAS_FS_CALL(vnode, preallocate)) {
+ status = FS_CALL(vnode, preallocate, offset, length);
+ } else {
+ status = HAS_FS_CALL(vnode, write)
+ ? B_UNSUPPORTED : B_READ_ONLY_DEVICE;
+ }
+
+ return status;
+}
+
+
+static status_t
common_read_link(int fd, char* path, char* buffer, size_t* _bufferSize,
bool kernel)
{
@@ -8436,6 +8478,13 @@
status_t
+_kern_preallocate(int fd, off_t offset, off_t length)
+{
+ return common_preallocate(fd, offset, length, true);
+}
+
+
+status_t
_kern_create_dir_entry_ref(dev_t device, ino_t inode, const char* name,
int perms)
{
@@ -9320,6 +9369,13 @@
status_t
+_user_preallocate(int fd, off_t offset, off_t length)
+{
+ return common_preallocate(fd, offset, length, false);
+}
+
+
+status_t
_user_create_dir_entry_ref(dev_t device, ino_t inode, const char* userName,
int perms)
{
diff --git a/src/system/libroot/posix/fcntl.cpp
b/src/system/libroot/posix/fcntl.cpp
index 49f2f1c..ad9874a 100644
--- a/src/system/libroot/posix/fcntl.cpp
+++ b/src/system/libroot/posix/fcntl.cpp
@@ -95,3 +95,12 @@
return 0;
}
+
+int
+posix_fallocate(int fd, off_t offset, off_t len)
+{
+ if (len == 0 || offset < 0)
+ return EINVAL;
+
+ return _kern_preallocate(fd, offset, len);
+}
diff --git a/src/system/libroot/stubbed/libroot_stubs.c
b/src/system/libroot/stubbed/libroot_stubs.c
index 73d0c7d..1ace035 100644
--- a/src/system/libroot/stubbed/libroot_stubs.c
+++ b/src/system/libroot/stubbed/libroot_stubs.c
@@ -2424,6 +2424,8 @@
void port_buffer_size() {}
void port_buffer_size_etc() {}
void port_count() {}
+void posix_fadvise() {}
+void posix_fallocate() {}
void posix_madvise() {}
void posix_memalign() {}
void posix_openpt() {}
diff --git a/src/system/libroot/stubbed/libroot_stubs_legacy.c
b/src/system/libroot/stubbed/libroot_stubs_legacy.c
index 2de2f3a..b1ea457 100644
--- a/src/system/libroot/stubbed/libroot_stubs_legacy.c
+++ b/src/system/libroot/stubbed/libroot_stubs_legacy.c
@@ -2354,6 +2354,8 @@
void port_buffer_size() {}
void port_buffer_size_etc() {}
void port_count() {}
+void posix_fadvise() {}
+void posix_fallocate() {}
void posix_madvise() {}
void posix_memalign() {}
void posix_openpt() {}
--
To view, visit https://review.haiku-os.org/c/haiku/+/3382
To unsubscribe, or for help writing mail filters, visit
https://review.haiku-os.org/settings
Gerrit-Project: haiku
Gerrit-Branch: master
Gerrit-Change-Id: Ifff4595548610c8e009d4e5ffb64c37e0884e62d
Gerrit-Change-Number: 3382
Gerrit-PatchSet: 1
Gerrit-Owner: Jérôme Duval <jerome.duval@xxxxxxxxx>
Gerrit-MessageType: newchange