open(2): Add O_DSYNC flag.
POSIX O_DSYNC means that writes include an implicit fdatasync(2), just as O_SYNC implies fsync(2). VOP_WRITE() functions that understand the new IO_DATASYNC flag can act accordingly, but we'll still pass down IO_SYNC so that file systems that don't understand it will continue to provide the stronger O_SYNC behaviour. Flag also applies to fcntl(2). Reviewed by: kib, delphij Differential Revision: https://reviews.freebsd.org/D25090
This commit is contained in:
parent
81098ca81d
commit
a5e284038e
@ -28,7 +28,7 @@
|
||||
.\" @(#)fcntl.2 8.2 (Berkeley) 1/12/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd January 17, 2020
|
||||
.Dd January 6, 2021
|
||||
.Dt FCNTL 2
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -196,7 +196,7 @@ The flags for the
|
||||
.Dv F_GETFL
|
||||
and
|
||||
.Dv F_SETFL
|
||||
flags are as follows:
|
||||
commands are as follows:
|
||||
.Bl -tag -width O_NONBLOCKX
|
||||
.It Dv O_NONBLOCK
|
||||
Non-blocking I/O; if no data is available to a
|
||||
@ -225,6 +225,21 @@ Enable the
|
||||
signal to be sent to the process group
|
||||
when I/O is possible, e.g.,
|
||||
upon availability of data to be read.
|
||||
.It Dv O_SYNC
|
||||
Enable synchronous writes.
|
||||
Corresponds to the
|
||||
.Dv O_SYNC
|
||||
flag of
|
||||
.Xr open 2 .
|
||||
.Dv O_FSYNC
|
||||
is an historical synonym for
|
||||
.Dv O_SYNC .
|
||||
.It Dv O_DSYNC
|
||||
Enable synchronous data writes.
|
||||
Corresponds to the
|
||||
.Dv O_DSYNC
|
||||
flag of
|
||||
.Xr open 2 .
|
||||
.El
|
||||
.Pp
|
||||
The seals that may be applied with
|
||||
|
@ -181,8 +181,9 @@ O_EXCL error if create and file exists
|
||||
O_SHLOCK atomically obtain a shared lock
|
||||
O_EXLOCK atomically obtain an exclusive lock
|
||||
O_DIRECT eliminate or reduce cache effects
|
||||
O_FSYNC synchronous writes
|
||||
O_FSYNC synchronous writes (historical synonym for O_SYNC)
|
||||
O_SYNC synchronous writes
|
||||
O_DSYNC synchronous data writes
|
||||
O_NOFOLLOW do not follow symlinks
|
||||
O_NOCTTY ignored
|
||||
O_TTY_INIT ignored
|
||||
@ -230,15 +231,18 @@ returns immediately.
|
||||
The descriptor remains in non-blocking mode for subsequent operations.
|
||||
.Pp
|
||||
If
|
||||
.Dv O_FSYNC
|
||||
.Dv O_SYNC
|
||||
is used in the mask, all writes will
|
||||
immediately and synchronously be written to disk.
|
||||
.Pp
|
||||
.Dv O_SYNC
|
||||
is a synonym for
|
||||
.Dv O_FSYNC
|
||||
required by
|
||||
.Tn POSIX .
|
||||
is an historical synonym for
|
||||
.Dv O_SYNC .
|
||||
.Pp
|
||||
If
|
||||
.Dv O_DSYNC
|
||||
is used in the mask, all data and metadata required to read the data will be
|
||||
synchronously written to disk, but changes to metadata such as file access and
|
||||
modification timestamps may be written later.
|
||||
.Pp
|
||||
If
|
||||
.Dv O_NOFOLLOW
|
||||
@ -651,6 +655,8 @@ The
|
||||
.Fn openat
|
||||
function was introduced in
|
||||
.Fx 8.0 .
|
||||
.Dv O_DSYNC
|
||||
appeared in 13.0.
|
||||
.Sh BUGS
|
||||
The Open Group Extended API Set 2 specification requires that the test
|
||||
for whether
|
||||
|
@ -168,7 +168,6 @@ extern "C" {
|
||||
|
||||
#define O_LARGEFILE 0
|
||||
#define O_RSYNC 0
|
||||
#define O_DSYNC 0
|
||||
|
||||
#ifndef LOCORE
|
||||
#ifndef HAVE_RPC_TYPES
|
||||
|
@ -127,7 +127,9 @@ vn_is_readonly(vnode_t *vp)
|
||||
#define FCREAT O_CREAT
|
||||
#define FTRUNC O_TRUNC
|
||||
#define FEXCL O_EXCL
|
||||
#ifndef FDSYNC
|
||||
#define FDSYNC FFSYNC
|
||||
#endif
|
||||
#define FRSYNC FFSYNC
|
||||
#define FSYNC FFSYNC
|
||||
#define FOFFMAX 0x00
|
||||
|
@ -1066,6 +1066,13 @@ vn_write(struct file *fp, struct uio *uio, struct ucred *active_cred, int flags,
|
||||
if ((fp->f_flag & O_FSYNC) ||
|
||||
(vp->v_mount && (vp->v_mount->mnt_flag & MNT_SYNCHRONOUS)))
|
||||
ioflag |= IO_SYNC;
|
||||
/*
|
||||
* For O_DSYNC we set both IO_SYNC and IO_DATASYNC, so that VOP_WRITE()
|
||||
* implementations that don't understand IO_DATASYNC fall back to full
|
||||
* O_SYNC behavior.
|
||||
*/
|
||||
if (fp->f_flag & O_DSYNC)
|
||||
ioflag |= IO_SYNC | IO_DATASYNC;
|
||||
mp = NULL;
|
||||
if (vp->v_type != VCHR &&
|
||||
(error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0)
|
||||
|
@ -141,8 +141,10 @@ typedef __pid_t pid_t;
|
||||
return back */
|
||||
#endif
|
||||
|
||||
#define O_DSYNC 0x00800000 /* POSIX data sync */
|
||||
|
||||
/*
|
||||
* XXX missing O_DSYNC, O_RSYNC.
|
||||
* XXX missing O_RSYNC.
|
||||
*/
|
||||
|
||||
#ifdef _KERNEL
|
||||
@ -158,9 +160,9 @@ typedef __pid_t pid_t;
|
||||
#define OFLAGS(fflags) ((fflags) & O_EXEC ? (fflags) : (fflags) - 1)
|
||||
|
||||
/* bits to save after open */
|
||||
#define FMASK (FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FNONBLOCK|O_DIRECT|FEXEC)
|
||||
#define FMASK (FREAD|FWRITE|FAPPEND|FASYNC|FFSYNC|FDSYNC|FNONBLOCK|O_DIRECT|FEXEC)
|
||||
/* bits settable by fcntl(F_SETFL, ...) */
|
||||
#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FNONBLOCK|FRDAHEAD|O_DIRECT)
|
||||
#define FCNTLFLAGS (FAPPEND|FASYNC|FFSYNC|FDSYNC|FNONBLOCK|FRDAHEAD|O_DIRECT)
|
||||
|
||||
#if defined(COMPAT_FREEBSD7) || defined(COMPAT_FREEBSD6) || \
|
||||
defined(COMPAT_FREEBSD5) || defined(COMPAT_FREEBSD4)
|
||||
@ -185,15 +187,16 @@ typedef __pid_t pid_t;
|
||||
#define FAPPEND O_APPEND /* kernel/compat */
|
||||
#define FASYNC O_ASYNC /* kernel/compat */
|
||||
#define FFSYNC O_FSYNC /* kernel */
|
||||
#define FDSYNC O_DSYNC /* kernel */
|
||||
#define FNONBLOCK O_NONBLOCK /* kernel */
|
||||
#define FNDELAY O_NONBLOCK /* compat */
|
||||
#define O_NDELAY O_NONBLOCK /* compat */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We are out of bits in f_flag (which is a short). However,
|
||||
* the flag bits not set in FMASK are only meaningful in the
|
||||
* initial open syscall. Those bits can thus be given a
|
||||
* Historically, we ran out of bits in f_flag (which was once a short).
|
||||
* However, the flag bits not set in FMASK are only meaningful in the
|
||||
* initial open syscall. Those bits were thus given a
|
||||
* different meaning for fcntl(2).
|
||||
*/
|
||||
#if __BSD_VISIBLE
|
||||
|
@ -326,6 +326,7 @@ struct vattr {
|
||||
#define IO_NOMACCHECK 0x1000 /* MAC checks unnecessary */
|
||||
#define IO_BUFLOCKED 0x2000 /* ffs flag; indir buf is locked */
|
||||
#define IO_RANGELOCKED 0x4000 /* range locked */
|
||||
#define IO_DATASYNC 0x8000 /* do only data I/O synchronously */
|
||||
|
||||
#define IO_SEQMAX 0x7F /* seq heuristic max value */
|
||||
#define IO_SEQSHIFT 16 /* seq heuristic in upper 16 bits */
|
||||
|
Loading…
Reference in New Issue
Block a user