Skip to content

Commit 5385204

Browse files
support iouring fttruncate (#5811)
1 parent 64eeac5 commit 5385204

File tree

7 files changed

+90
-6
lines changed

7 files changed

+90
-6
lines changed

config.m4

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,22 @@ AC_DEFUN([AC_SWOOLE_HAVE_IOURING_STATX],
321321
])
322322
])
323323

324+
AC_DEFUN([AC_SWOOLE_HAVE_IOURING_FTRUNCATE],
325+
[
326+
AC_MSG_CHECKING([for io_uring ftruncate])
327+
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
328+
#define _GNU_SOURCE
329+
#include <liburing.h>
330+
]], [[
331+
int op = IORING_OP_FTRUNCATE;
332+
]])],[
333+
AC_DEFINE([HAVE_IOURING_FTRUNCATE], 1, [have io_uring ftruncate?])
334+
AC_MSG_RESULT([yes])
335+
],[
336+
AC_MSG_RESULT([no])
337+
])
338+
])
339+
324340
AC_DEFUN([AC_SWOOLE_CHECK_SOCKETS], [
325341
AC_CHECK_FUNCS([hstrerror socketpair if_nametoindex if_indextoname])
326342
AC_CHECK_HEADERS([netdb.h netinet/tcp.h sys/un.h sys/sockio.h])
@@ -1003,6 +1019,7 @@ EOF
10031019

10041020
AC_SWOOLE_HAVE_IOURING_STATX
10051021
AC_SWOOLE_HAVE_IOURING_FUTEX
1022+
AC_SWOOLE_HAVE_IOURING_FTRUNCATE
10061023

10071024
PHP_EVAL_LIBLINE($URING_LIBS, SWOOLE_SHARED_LIBADD)
10081025
PHP_EVAL_INCLINE($URING_CFLAGS)

include/swoole_coroutine_c_api.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ int swoole_coroutine_statvfs(const char *path, struct statvfs *buf);
6464
int swoole_coroutine_close_file(int fd);
6565
int swoole_coroutine_fsync(int fd);
6666
int swoole_coroutine_fdatasync(int fd);
67+
int swoole_coroutine_ftruncate(int fd, off_t length);
6768
/**
6869
* io_uring
6970
*/
@@ -72,6 +73,7 @@ int swoole_coroutine_iouring_open(const char *pathname, int flags, mode_t mode);
7273
int swoole_coroutine_iouring_close_file(int fd);
7374
ssize_t swoole_coroutine_iouring_read(int sockfd, void *buf, size_t count);
7475
ssize_t swoole_coroutine_iouring_write(int sockfd, const void *buf, size_t count);
76+
off_t swoole_coroutine_iouring_lseek(int fd, off_t offset, int whence);
7577
int swoole_coroutine_iouring_rename(const char *oldpath, const char *newpath);
7678
int swoole_coroutine_iouring_mkdir(const char *pathname, mode_t mode);
7779
int swoole_coroutine_iouring_unlink(const char *pathname);
@@ -80,6 +82,9 @@ int swoole_coroutine_iouring_fstat(int fd, struct stat *statbuf);
8082
int swoole_coroutine_iouring_stat(const char *path, struct stat *statbuf);
8183
int swoole_coroutine_iouring_lstat(const char *path, struct stat *statbuf);
8284
#endif
85+
#ifdef HAVE_IOURING_FTRUNCATE
86+
int swoole_coroutine_iouring_ftruncate(int fd, off_t length);
87+
#endif
8388
int swoole_coroutine_iouring_rmdir(const char *pathname);
8489
int swoole_coroutine_iouring_fsync(int fd);
8590
int swoole_coroutine_iouring_fdatasync(int fd);

include/swoole_file_hook.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@
2424
#define close_file(fd) swoole_coroutine_iouring_close_file(fd)
2525
#define read(fd, buf, count) swoole_coroutine_iouring_read(fd, buf, count)
2626
#define write(fd, buf, count) swoole_coroutine_iouring_write(fd, buf, count)
27+
#define lseek(fd, offset, whence) swoole_coroutine_iouring_lseek(fd, offset, whence)
2728
#define rename(oldpath, newpath) swoole_coroutine_iouring_rename(oldpath, newpath)
2829
#define mkdir(pathname, mode) swoole_coroutine_iouring_mkdir(pathname, mode)
2930
#define unlink(pathname) swoole_coroutine_iouring_unlink(pathname)
3031
#define rmdir(pathname) swoole_coroutine_iouring_rmdir(pathname)
3132
#define fsync(fd) swoole_coroutine_iouring_fsync(fd)
3233
#define fdatasync(fd) swoole_coroutine_iouring_fdatasync(fd)
34+
#define ftruncate(fd, length) swoole_coroutine_iouring_ftruncate(fd, length)
3335
#else
3436
#define open(pathname, flags, mode) swoole_coroutine_open(pathname, flags, mode)
3537
#define close_file(fd) swoole_coroutine_close_file(fd)
@@ -43,6 +45,7 @@
4345
#define rename(oldpath, newpath) swoole_coroutine_rename(oldpath, newpath)
4446
#define fsync(fd) swoole_coroutine_fsync(fd)
4547
#define fdatasync(fd) swoole_coroutine_fdatasync(fd)
48+
#define ftruncate(fd, length) swoole_coroutine_ftruncate(fd, length)
4649
#endif
4750

4851
#ifdef HAVE_IOURING_STATX

include/swoole_iouring.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ class Iouring {
8686
static int futex_wait(uint32_t *futex);
8787
static int futex_wakeup(uint32_t *futex);
8888
#endif
89+
#ifdef HAVE_IOURING_FTRUNCATE
90+
static int ftruncate(int fd, off_t length);
91+
#endif
8992

9093
static std::unordered_map<std::string, int> list_all_opcode();
9194
static int callback(Reactor *reactor, Event *event);

src/coroutine/hook.cc

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,16 @@ int swoole_coroutine_fdatasync(int fd) {
620620
return retval;
621621
}
622622

623+
int swoole_coroutine_ftruncate(int fd, off_t length) {
624+
if (sw_unlikely(is_no_coro())) {
625+
return ftruncate(fd, length);
626+
}
627+
628+
int retval = -1;
629+
async([&]() { retval = ftruncate(fd, length); });
630+
return retval;
631+
}
632+
623633
#ifdef SW_USE_IOURING
624634
int swoole_coroutine_iouring_open(const char *pathname, int flags, mode_t mode) {
625635
if (sw_unlikely(is_no_coro())) {
@@ -649,6 +659,10 @@ ssize_t swoole_coroutine_iouring_write(int sockfd, const void *buf, size_t size)
649659
return Iouring::write(sockfd, buf, size);
650660
}
651661

662+
off_t swoole_coroutine_iouring_lseek(int fd, off_t offset, int whence) {
663+
return lseek(fd, offset, whence);
664+
}
665+
652666
int swoole_coroutine_iouring_rename(const char *oldpath, const char *newpath) {
653667
if (sw_unlikely(is_no_coro())) {
654668
return rename(oldpath, newpath);
@@ -714,6 +728,15 @@ int swoole_coroutine_iouring_fdatasync(int fd) {
714728
}
715729
return Iouring::fdatasync(fd);
716730
}
731+
732+
#ifdef HAVE_IOURING_FTRUNCATE
733+
int swoole_coroutine_iouring_ftruncate(int fd, off_t length) {
734+
if (sw_unlikely(is_no_coro())) {
735+
return ftruncate(fd, length);
736+
}
737+
return Iouring::ftruncate(fd, length);
738+
}
739+
#endif
717740
#endif
718741

719742
SW_EXTERN_C_END

src/coroutine/iouring.cc

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ enum IouringOpcode {
4343
SW_IORING_OP_FUTEX_WAIT = IORING_OP_FUTEX_WAIT,
4444
SW_IORING_OP_FUTEX_WAKE = IORING_OP_FUTEX_WAKE,
4545
#endif
46+
#ifdef HAVE_IOURING_FTRUNCATE
47+
SW_IORING_OP_FTRUNCATE = IORING_OP_FTRUNCATE,
48+
#endif
4649

4750
SW_IORING_OP_FSTAT = 100,
4851
SW_IORING_OP_LSTAT = 101,
@@ -226,6 +229,10 @@ static const char *get_opcode_name(IouringOpcode opcode) {
226229
return "FUTEX_WAIT";
227230
case SW_IORING_OP_FUTEX_WAKE:
228231
return "FUTEX_WAKE";
232+
#endif
233+
#ifdef HAVE_IOURING_FTRUNCATE
234+
case SW_IORING_OP_FTRUNCATE:
235+
return "FTRUNCATE";
229236
#endif
230237
default:
231238
return "unknown";
@@ -307,7 +314,7 @@ bool Iouring::dispatch(IouringEvent *event) {
307314
case SW_IORING_OP_READ:
308315
case SW_IORING_OP_WRITE:
309316
sqe->fd = event->fd;
310-
sqe->addr = (uintptr_t) (event->opcode == SW_IORING_OP_READ ? event->rbuf : event->wbuf);
317+
sqe->addr = (uintptr_t)(event->opcode == SW_IORING_OP_READ ? event->rbuf : event->wbuf);
311318
sqe->len = event->size;
312319
sqe->off = -1;
313320
sqe->opcode = event->opcode;
@@ -384,6 +391,15 @@ bool Iouring::dispatch(IouringEvent *event) {
384391
sqe->futex_flags = 0;
385392
sqe->addr3 = FUTEX_BITSET_MATCH_ANY;
386393
break;
394+
#ifdef HAVE_IOURING_FTRUNCATE
395+
case SW_IORING_OP_FTRUNCATE:
396+
sqe->opcode = SW_IORING_OP_FTRUNCATE;
397+
sqe->fd = event->fd;
398+
sqe->off = event->size;
399+
sqe->addr = 0;
400+
sqe->len = 0;
401+
break;
402+
#endif
387403
#endif
388404
default:
389405
abort();
@@ -476,6 +492,16 @@ int Iouring::fdatasync(int fd) {
476492
return static_cast<int>(execute(&event));
477493
}
478494

495+
#ifdef HAVE_IOURING_FTRUNCATE
496+
int Iouring::ftruncate(int fd, off_t length) {
497+
INIT_EVENT(SW_IORING_OP_FTRUNCATE);
498+
event.fd = fd;
499+
event.size = length;
500+
501+
return static_cast<int>(execute(&event));
502+
}
503+
#endif
504+
479505
#ifdef HAVE_IOURING_STATX
480506
static void swoole_statx_to_stat(const struct statx *statxbuf, struct stat *statbuf) {
481507
statbuf->st_dev = (((unsigned int) statxbuf->stx_dev_major) << 8) | (unsigned int) statxbuf->stx_dev_minor;

tests/swoole_iouring/mix.phpt

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,18 @@ run(function() use ($results) {
7070
for ($i = 1; $i <= 10000; $i++) {
7171
go(function() use ($waitGroup, $i, $results){
7272
$waitGroup->add();
73-
file_put_contents('/tmp/file'.$i, $results[$i]);
74-
Assert::true($results[$i] == file_get_contents('/tmp/file'.$i));
75-
file_put_contents('/tmp/file'.$i, $results[$i], FILE_APPEND);
76-
file_put_contents('/tmp/file'.$i, $results[$i], FILE_APPEND);
77-
Assert::true(strlen($results[$i]) * 3 == strlen(file_get_contents('/tmp/file'.$i)));
73+
$filename = '/tmp/file'.$i;
74+
file_put_contents($filename, $results[$i]);
75+
Assert::true($results[$i] == file_get_contents($filename));
76+
file_put_contents($filename, $results[$i], FILE_APPEND);
77+
file_put_contents($filename, $results[$i], FILE_APPEND);
78+
Assert::true(strlen($results[$i]) * 3 == strlen(file_get_contents($filename)));
79+
80+
$stream = fopen($filename, 'r+');
81+
$size = rand(1, filesize($filename));
82+
Assert::true(ftruncate($stream, $size));
83+
fclose($stream);
84+
Assert::true($size == strlen(file_get_contents($filename)));
7885
$waitGroup->done();
7986
});
8087
}

0 commit comments

Comments
 (0)