Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F115884728
D25071.id81744.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
5 KB
Referenced Files
None
Subscribers
None
D25071.id81744.diff
View Options
diff --git a/lib/libc/sys/aio_fsync.2 b/lib/libc/sys/aio_fsync.2
--- a/lib/libc/sys/aio_fsync.2
+++ b/lib/libc/sys/aio_fsync.2
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd August 19, 2016
+.Dd January 6, 2021
.Dt AIO_FSYNC 2
.Os
.Sh NAME
@@ -49,11 +49,15 @@
.Pp
The
.Fa op
-argument can only be set to
+argument can be set to
.Dv O_SYNC
to cause all currently queued I/O operations to be completed
as if by a call to
-.Xr fsync 2 .
+.Xr fsync 2 ,
+or
+.Dv O_DSYNC
+for
+.Xr fdatasync 2 .
.Pp
If _POSIX_PRIORITIZED_IO is defined, and the descriptor supports it,
then the enqueued operation is submitted at a priority equal to that
@@ -112,7 +116,9 @@
A value of the
.Fa op
argument is not set to
-.Dv O_SYNC .
+.Dv O_SYNC
+or
+.Dv O_DSYNC .
.El
.Pp
The following conditions may be synchronously detected when the
@@ -176,3 +182,7 @@
.Fn aio_fsync
system call first appeared in
.Fx 7.0 .
+The
+.Dv O_DSYNC
+option appeared in
+.Fx 13.0 .
diff --git a/sys/kern/vfs_aio.c b/sys/kern/vfs_aio.c
--- a/sys/kern/vfs_aio.c
+++ b/sys/kern/vfs_aio.c
@@ -718,10 +718,10 @@
/*
* Move all data to a permanent storage device. This code
- * simulates the fsync syscall.
+ * simulates the fsync and fdatasync syscalls.
*/
static int
-aio_fsync_vnode(struct thread *td, struct vnode *vp)
+aio_fsync_vnode(struct thread *td, struct vnode *vp, int op)
{
struct mount *mp;
int error;
@@ -734,7 +734,10 @@
vm_object_page_clean(vp->v_object, 0, 0, 0);
VM_OBJECT_WUNLOCK(vp->v_object);
}
- error = VOP_FSYNC(vp, MNT_WAIT, td);
+ if (op == LIO_DSYNC)
+ error = VOP_FDATASYNC(vp, td);
+ else
+ error = VOP_FSYNC(vp, MNT_WAIT, td);
VOP_UNLOCK(vp);
vn_finished_write(mp);
@@ -838,12 +841,15 @@
struct file *fp = job->fd_file;
int error = 0;
- KASSERT(job->uaiocb.aio_lio_opcode == LIO_SYNC,
+ KASSERT(job->uaiocb.aio_lio_opcode == LIO_SYNC ||
+ job->uaiocb.aio_lio_opcode == LIO_DSYNC,
("%s: opcode %d", __func__, job->uaiocb.aio_lio_opcode));
td->td_ucred = job->cred;
- if (fp->f_vnode != NULL)
- error = aio_fsync_vnode(td, fp->f_vnode);
+ if (fp->f_vnode != NULL) {
+ error = aio_fsync_vnode(td, fp->f_vnode,
+ job->uaiocb.aio_lio_opcode);
+ }
td->td_ucred = td_savedcred;
if (error)
aio_complete(job, -1, error);
@@ -1579,6 +1585,7 @@
error = fget_read(td, fd, &cap_pread_rights, &fp);
break;
case LIO_SYNC:
+ case LIO_DSYNC:
error = fget(td, fd, &cap_fsync_rights, &fp);
break;
case LIO_MLOCK:
@@ -1592,7 +1599,7 @@
if (error)
goto err3;
- if (opcode == LIO_SYNC && fp->f_vnode == NULL) {
+ if ((opcode == LIO_SYNC || opcode == LIO_DSYNC) && fp->f_vnode == NULL) {
error = EINVAL;
goto err3;
}
@@ -1805,10 +1812,12 @@
error = 0;
break;
case LIO_SYNC:
+ case LIO_DSYNC:
AIO_LOCK(ki);
TAILQ_FOREACH(job2, &ki->kaio_jobqueue, plist) {
if (job2->fd_file == job->fd_file &&
job2->uaiocb.aio_lio_opcode != LIO_SYNC &&
+ job2->uaiocb.aio_lio_opcode != LIO_DSYNC &&
job2->seqno < job->seqno) {
job2->jobflags |= KAIOCB_CHECKSYNC;
job->pending++;
@@ -2587,10 +2596,20 @@
kern_aio_fsync(struct thread *td, int op, struct aiocb *ujob,
struct aiocb_ops *ops)
{
+ int listop;
- if (op != O_SYNC) /* XXX lack of O_DSYNC */
+ switch (op) {
+ case O_SYNC:
+ listop = LIO_SYNC;
+ break;
+ case O_DSYNC:
+ listop = LIO_DSYNC;
+ break;
+ default:
return (EINVAL);
- return (aio_aqueue(td, ujob, NULL, LIO_SYNC, ops));
+ }
+
+ return (aio_aqueue(td, ujob, NULL, listop, ops));
}
int
diff --git a/sys/sys/aio.h b/sys/sys/aio.h
--- a/sys/sys/aio.h
+++ b/sys/sys/aio.h
@@ -48,6 +48,7 @@
#define LIO_MLOCK 0x4
#define LIO_WRITEV 0x5
#define LIO_READV 0x6
+#define LIO_DSYNC 0x7
#endif
/*
diff --git a/tests/sys/aio/aio_test.c b/tests/sys/aio/aio_test.c
--- a/tests/sys/aio/aio_test.c
+++ b/tests/sys/aio/aio_test.c
@@ -1259,7 +1259,7 @@
ATF_REQUIRE_MSG(fd != -1, "open failed: %s", strerror(errno));
unlink(FILE_PATHNAME);
- /* aio_fsync should return EINVAL unless op is O_SYNC */
+ /* aio_fsync should return EINVAL unless op is O_SYNC or O_DSYNC */
memset(&iocb, 0, sizeof(iocb));
iocb.aio_fildes = fd;
ATF_CHECK_EQ(-1, aio_fsync(666, &iocb));
@@ -1282,8 +1282,8 @@
/*
* This test just performs a basic test of aio_fsync().
*/
-ATF_TC_WITHOUT_HEAD(aio_fsync_test);
-ATF_TC_BODY(aio_fsync_test, tc)
+static void
+aio_fsync_test(int op)
{
struct aiocb synccb, *iocbp;
struct {
@@ -1328,7 +1328,7 @@
/* Queue the aio_fsync request. */
memset(&synccb, 0, sizeof(synccb));
synccb.aio_fildes = fd;
- ATF_REQUIRE(aio_fsync(O_SYNC, &synccb) == 0);
+ ATF_REQUIRE(aio_fsync(op, &synccb) == 0);
/* Wait for requests to complete. */
for (;;) {
@@ -1359,6 +1359,18 @@
close(fd);
}
+ATF_TC_WITHOUT_HEAD(aio_fsync_sync_test);
+ATF_TC_BODY(aio_fsync_sync_test, tc)
+{
+ aio_fsync_test(O_SYNC);
+}
+
+ATF_TC_WITHOUT_HEAD(aio_fsync_dsync_test);
+ATF_TC_BODY(aio_fsync_dsync_test, tc)
+{
+ aio_fsync_test(O_DSYNC);
+}
+
/*
* We shouldn't be able to DoS the system by setting iov_len to an insane
* value
@@ -1782,7 +1794,8 @@
ATF_TP_ADD_TC(tp, md_thread);
ATF_TP_ADD_TC(tp, md_waitcomplete);
ATF_TP_ADD_TC(tp, aio_fsync_errors);
- ATF_TP_ADD_TC(tp, aio_fsync_test);
+ ATF_TP_ADD_TC(tp, aio_fsync_sync_test);
+ ATF_TP_ADD_TC(tp, aio_fsync_dsync_test);
ATF_TP_ADD_TC(tp, aio_large_read_test);
ATF_TP_ADD_TC(tp, aio_socket_two_reads);
ATF_TP_ADD_TC(tp, aio_socket_blocking_short_write);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, May 1, 12:10 AM (15 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17862940
Default Alt Text
D25071.id81744.diff (5 KB)
Attached To
Mode
D25071: aio_fsync(O_DSYNC)
Attached
Detach File
Event Timeline
Log In to Comment