POSIX: add posix_fallocate and a preallocate syscall

the preallocate syscall will call the preallocate filesystem hook, if available.

fix #6285

Change-Id: Ifff4595548610c8e009d4e5ffb64c37e0884e62d
Reviewed-on: https://review.haiku-os.org/c/haiku/+/3382
Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
Jérôme Duval 2020-11-05 20:16:42 +01:00
parent 1f7ac2962b
commit fe357eb9c9
7 changed files with 72 additions and 0 deletions

View File

@ -99,6 +99,7 @@ extern int openat(int fd, const char *path, int openMode, ...);
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
}

View File

@ -252,6 +252,7 @@ int _user_dup(int fd);
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);

View File

@ -338,6 +338,7 @@ extern status_t _kern_lock_node(int fd);
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);

View File

@ -6438,6 +6438,48 @@ common_unlock_node(int fd, bool kernel)
}
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)
@ -8435,6 +8477,13 @@ _kern_unlock_node(int fd)
}
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)
@ -9319,6 +9368,13 @@ _user_unlock_node(int fd)
}
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)

View File

@ -95,3 +95,12 @@ posix_fadvise(int fd, off_t offset, off_t len, int advice)
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);
}

View File

@ -2424,6 +2424,8 @@ void popen() {}
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() {}

View File

@ -2354,6 +2354,8 @@ void popen() {}
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() {}