diff --git a/include/unistd.h b/include/unistd.h index 0fb36e50e050..eab79f20eb7d 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -384,6 +384,7 @@ extern int optind, opterr, optopt; /* ISO/IEC 9945-1: 1996 */ #if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE int fsync(int); +int fdatasync(int); /* * ftruncate() was in the POSIX Realtime Extension (it's used for shared diff --git a/lib/libc/sys/Symbol.map b/lib/libc/sys/Symbol.map index c1532ac94bc4..312b3660cfdc 100644 --- a/lib/libc/sys/Symbol.map +++ b/lib/libc/sys/Symbol.map @@ -400,6 +400,10 @@ FBSD_1.4 { recvmmsg; }; +FBSD_1.5 { + fdatasync; +}; + FBSDprivate_1.0 { ___acl_aclcheck_fd; __sys___acl_aclcheck_fd; @@ -594,6 +598,8 @@ FBSDprivate_1.0 { __sys_fstatfs; _fsync; __sys_fsync; + _fdatasync; + __sys_fdatasync; _futimes; __sys_futimes; _getaudit; diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 4b4ff2713382..3172db49d93d 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -1081,3 +1081,4 @@ 549 AUE_NULL NOPROTO { int numa_setaffinity(cpuwhich_t which, \ id_t id, \ const struct vm_domain_policy *policy); } +550 AUE_FSYNC NOPROTO { int fdatasync(int fd); } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 08c0e0e533fc..2c5840639077 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -993,8 +993,9 @@ id_t id, \ struct vm_domain_policy_entry *policy); } 549 AUE_NULL STD { int numa_setaffinity(cpuwhich_t which, \ - id_t id, \ - const struct vm_domain_policy_entry *policy); } + id_t id, const struct \ + vm_domain_policy_entry *policy); } +550 AUE_FSYNC STD { int fdatasync(int fd); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 46443c6112b9..0e74b41d03ee 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -83,6 +83,7 @@ static int vop_stdset_text(struct vop_set_text_args *ap); static int vop_stdunset_text(struct vop_unset_text_args *ap); static int vop_stdget_writecount(struct vop_get_writecount_args *ap); static int vop_stdadd_writecount(struct vop_add_writecount_args *ap); +static int vop_stdfdatasync(struct vop_fdatasync_args *ap); static int vop_stdgetpages_async(struct vop_getpages_async_args *ap); /* @@ -111,6 +112,7 @@ struct vop_vector default_vnodeops = { .vop_bmap = vop_stdbmap, .vop_close = VOP_NULL, .vop_fsync = VOP_NULL, + .vop_fdatasync = vop_stdfdatasync, .vop_getpages = vop_stdgetpages, .vop_getpages_async = vop_stdgetpages_async, .vop_getwritemount = vop_stdgetwritemount, @@ -726,6 +728,13 @@ vop_stdfsync(ap) return (error); } +static int +vop_stdfdatasync(struct vop_fdatasync_args *ap) +{ + + return (VOP_FSYNC(ap->a_vp, MNT_WAIT, ap->a_td)); +} + /* XXX Needs good comment and more info in the manpage (VOP_GETPAGES(9)). */ int vop_stdgetpages(ap) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 68950e127e05..8419e360e559 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -3354,20 +3354,8 @@ freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap) } #endif -/* - * Sync an open file. - */ -#ifndef _SYS_SYSPROTO_H_ -struct fsync_args { - int fd; -}; -#endif -int -sys_fsync(td, uap) - struct thread *td; - struct fsync_args /* { - int fd; - } */ *uap; +static int +kern_fsync(struct thread *td, int fd, bool fullsync) { struct vnode *vp; struct mount *mp; @@ -3375,11 +3363,15 @@ sys_fsync(td, uap) cap_rights_t rights; int error, lock_flags; - AUDIT_ARG_FD(uap->fd); - error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_FSYNC), &fp); + AUDIT_ARG_FD(fd); + error = getvnode(td, fd, cap_rights_init(&rights, CAP_FSYNC), &fp); if (error != 0) return (error); vp = fp->f_vnode; +#if 0 + if (!fullsync) + /* XXXKIB: compete outstanding aio writes */; +#endif error = vn_start_write(vp, &mp, V_WAIT | PCATCH); if (error != 0) goto drop; @@ -3396,8 +3388,7 @@ sys_fsync(td, uap) vm_object_page_clean(vp->v_object, 0, 0, 0); VM_OBJECT_WUNLOCK(vp->v_object); } - error = VOP_FSYNC(vp, MNT_WAIT, td); - + error = fullsync ? VOP_FSYNC(vp, MNT_WAIT, td) : VOP_FDATASYNC(vp, td); VOP_UNLOCK(vp, 0); vn_finished_write(mp); drop: @@ -3405,6 +3396,28 @@ sys_fsync(td, uap) return (error); } +/* + * Sync an open file. + */ +#ifndef _SYS_SYSPROTO_H_ +struct fsync_args { + int fd; +}; +#endif +int +sys_fsync(struct thread *td, struct fsync_args *uap) +{ + + return (kern_fsync(td, uap->fd, true)); +} + +int +sys_fdatasync(struct thread *td, struct fdatasync_args *uap) +{ + + return (kern_fsync(td, uap->fd, false)); +} + /* * Rename files. Source and destination must either both be directories, or * both not be directories. If target is a directory, it must be empty. diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src index 9f3aa140d7ed..648de9a11263 100644 --- a/sys/kern/vnode_if.src +++ b/sys/kern/vnode_if.src @@ -703,6 +703,14 @@ vop_add_writecount { IN int inc; }; +%% fdatasync vp L L L + +vop_fdatasync { + IN struct vnode *vp; + IN struct thread *td; +}; + + # The VOPs below are spares at the end of the table to allow new VOPs to be # added in stable branches without breaking the KBI. New VOPs in HEAD should # be added above these spares. When merging a new VOP to a stable branch,