Skip to content

Commit

Permalink
sys/kern: Add fdatasync(2)
Browse files Browse the repository at this point in the history
Based on the following FreeBSD commits in 2016.
295af703a0d7987c6cf4987e7b7f5f07b3ca1221
1c1cc89580f0fbfabaf6f6c7f0f6440eef0c128e

Add the syscall and also add it to pthread's cancellation point.
The default behavior is same as fsync(2), which is fine but inefficient.
  • Loading branch information
kusumi committed Sep 11, 2021
1 parent fef0a4b commit 74fa256
Show file tree
Hide file tree
Showing 18 changed files with 126 additions and 13 deletions.
2 changes: 0 additions & 2 deletions include/unistd.h
Expand Up @@ -435,9 +435,7 @@ extern int optind, opterr, optopt;

/* ISO/IEC 9945-1: 1996 */
#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
#if 0 /* XXX missing */
int fdatasync(int);
#endif
int fsync(int);

/*
Expand Down
3 changes: 3 additions & 0 deletions lib/libc/sys/Symbol.map
Expand Up @@ -336,6 +336,7 @@ DF510.0 {

DF602.0 {
posix_fallocate;
fdatasync;
};

DFprivate_1.0 {
Expand Down Expand Up @@ -408,6 +409,7 @@ DFprivate_1.0 {
__sys_fchown;
__sys_fchownat;
__sys_fcntl;
__sys_fdatasync;
__sys_fexecve;
__sys_fhopen;
__sys_fhstat;
Expand Down Expand Up @@ -712,6 +714,7 @@ DFprivate_1.0 {
_fchown;
_fchownat;
_fcntl;
_fdatasync;
_fexecve;
_fhopen;
_fhstat;
Expand Down
2 changes: 2 additions & 0 deletions lib/libthread_xu/pthread.map
Expand Up @@ -414,4 +414,6 @@ global:
clock_nanosleep
pthread_getname_np;
pthread_setname_np;
__fdatasync;
fdatasync;
};
18 changes: 18 additions & 0 deletions lib/libthread_xu/thread/thr_syscalls.c
Expand Up @@ -104,6 +104,7 @@ extern int __sys_aio_suspend(const struct aiocb * const[], int,
extern int __sys_accept(int, struct sockaddr *, socklen_t *);
extern int __sys_connect(int, const struct sockaddr *, socklen_t);
extern int __sys_fsync(int);
extern int __sys_fdatasync(int);
extern int __sys_msync(void *, size_t, int);
extern int __sys_poll(struct pollfd *, unsigned, int);
extern int __sys_ppoll(struct pollfd *, unsigned, const struct timespec *,
Expand All @@ -127,6 +128,7 @@ int __close(int);
int __connect(int, const struct sockaddr *, socklen_t);
int __fcntl(int, int,...);
int __fsync(int);
int __fdatasync(int);
int __msync(void *, size_t, int);
int __nanosleep(const struct timespec *, struct timespec *);
int __clock_nanosleep(clock_t, int, const struct timespec *,
Expand Down Expand Up @@ -294,6 +296,22 @@ __fsync(int fd)

__strong_reference(__fsync, fsync);

int
__fdatasync(int fd)
{
pthread_t curthread = tls_get_curthread();
int oldcancel;
int ret;

oldcancel = _thr_cancel_enter(curthread);
ret = __sys_fdatasync(fd);
_thr_cancel_leave(curthread, oldcancel);

return (ret);
}

__strong_reference(__fdatasync, fdatasync);

int
__msync(void *addr, size_t len, int flags)
{
Expand Down
1 change: 1 addition & 0 deletions sys/kern/init_sysent.c
Expand Up @@ -568,4 +568,5 @@ struct sysent sysent[] = {
{ AS(__realpath_args), (sy_call_t *)sys___realpath }, /* 551 = __realpath */
{ AS(fexecve_args), (sy_call_t *)sys_fexecve }, /* 552 = fexecve */
{ AS(posix_fallocate_args), (sy_call_t *)sys_posix_fallocate }, /* 553 = posix_fallocate */
{ AS(fdatasync_args), (sy_call_t *)sys_fdatasync }, /* 554 = fdatasync */
};
1 change: 1 addition & 0 deletions sys/kern/syscalls.c
Expand Up @@ -560,4 +560,5 @@ const char *syscallnames[] = {
"__realpath", /* 551 = __realpath */
"fexecve", /* 552 = fexecve */
"posix_fallocate" /* 553 = posix_fallocate */
"fdatasync" /* 554 = fdatasync */
};
1 change: 1 addition & 0 deletions sys/kern/syscalls.master
Expand Up @@ -737,3 +737,4 @@
551 STD { ssize_t __realpath(const char *path, char *buf, size_t len); }
552 STD { int fexecve(int fd, char **argv, char **envv); }
553 STD { int posix_fallocate(int fd, off_t offset, off_t len); }
554 STD { int fdatasync(int fd); }
7 changes: 7 additions & 0 deletions sys/kern/vfs_default.c
Expand Up @@ -74,6 +74,7 @@ struct vop_ops default_vnode_vops = {
.vop_default = vop_eopnotsupp,
.vop_advlock = (void *)vop_einval,
.vop_fsync = (void *)vop_null,
.vop_fdatasync = vop_stdfdatasync,
.vop_ioctl = (void *)vop_enotty,
.vop_mmap = (void *)vop_einval,
.vop_old_lookup = vop_nolookup,
Expand Down Expand Up @@ -1439,6 +1440,12 @@ vop_stdallocate(struct vop_allocate_args *ap)
return (error);
}

int
vop_stdfdatasync(struct vop_fdatasync_args *ap)
{
return (VOP_FSYNC_FP(ap->a_vp, ap->a_waitfor, ap->a_flags, ap->a_fp));
}

int
vfs_stdroot(struct mount *mp, struct vnode **vpp)
{
Expand Down
35 changes: 27 additions & 8 deletions sys/kern/vfs_syscalls.c
Expand Up @@ -4050,21 +4050,16 @@ sys_ftruncate(struct sysmsg *sysmsg, const struct ftruncate_args *uap)
return (error);
}

/*
* fsync(int fd)
*
* Sync an open file.
*/
int
sys_fsync(struct sysmsg *sysmsg, const struct fsync_args *uap)
kern_fsync(int fd, bool fullsync)
{
struct thread *td = curthread;
struct vnode *vp;
struct file *fp;
vm_object_t obj;
int error;

if ((error = holdvnode(td, uap->fd, &fp)) != 0)
if ((error = holdvnode(td, fd, &fp)) != 0)
return (error);
vp = (struct vnode *)fp->f_data;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
Expand All @@ -4074,7 +4069,9 @@ sys_fsync(struct sysmsg *sysmsg, const struct fsync_args *uap)
vm_object_page_clean(obj, 0, 0, 0);
}
}
error = VOP_FSYNC_FP(vp, MNT_WAIT, VOP_FSYNC_SYSCALL, fp);
error = fullsync ?
VOP_FSYNC_FP(vp, MNT_WAIT, VOP_FSYNC_SYSCALL, fp) :
VOP_FDATASYNC_FP(vp, MNT_WAIT, VOP_FSYNC_SYSCALL, fp);
if (error == 0 && vp->v_mount)
error = buf_fsync(vp);
vn_unlock(vp);
Expand All @@ -4083,6 +4080,28 @@ sys_fsync(struct sysmsg *sysmsg, const struct fsync_args *uap)
return (error);
}

/*
* fsync(int fd)
*
* Sync an open file.
*/
int
sys_fsync(struct sysmsg *sysmsg, const struct fsync_args *uap)
{
return (kern_fsync(uap->fd, true));
}

/*
* fdatasync(int fd)
*
* Data-sync an open file.
*/
int
sys_fdatasync(struct sysmsg *sysmsg, const struct fdatasync_args *uap)
{
return (kern_fsync(uap->fd, false));
}

/*
* rename op.
*
Expand Down
35 changes: 35 additions & 0 deletions sys/kern/vfs_vopops.c
Expand Up @@ -106,6 +106,7 @@ VNODEOP_DESC_INIT(poll);
VNODEOP_DESC_INIT(kqfilter);
VNODEOP_DESC_INIT(mmap);
VNODEOP_DESC_INIT(fsync);
VNODEOP_DESC_INIT(fdatasync);
VNODEOP_DESC_INIT(old_remove);
VNODEOP_DESC_INIT(old_link);
VNODEOP_DESC_INIT(old_rename);
Expand Down Expand Up @@ -620,6 +621,31 @@ vop_fsync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags,
return(error);
}

/*
* MPSAFE
*/
int
vop_fdatasync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags,
struct file *fp)
{
struct vop_fdatasync_args ap;
VFS_MPLOCK_DECLARE;
int error;

ap.a_head.a_desc = &vop_fdatasync_desc;
ap.a_head.a_ops = ops;
ap.a_vp = vp;
ap.a_waitfor = waitfor;
ap.a_flags = flags;
ap.a_fp = fp;

VFS_MPLOCK(vp->v_mount);
DO_OPS(ops, error, &ap, vop_fdatasync);
VFS_MPUNLOCK();

return(error);
}

/*
* MPSAFE
*/
Expand Down Expand Up @@ -1893,6 +1919,15 @@ vop_fsync_ap(struct vop_fsync_args *ap)
return(error);
}

int
vop_fdatasync_ap(struct vop_fdatasync_args *ap)
{
int error;

DO_OPS(ap->a_head.a_ops, error, ap, vop_fdatasync);
return(error);
}

int
vop_readdir_ap(struct vop_readdir_args *ap)
{
Expand Down
1 change: 1 addition & 0 deletions sys/sys/kern_syscall.h
Expand Up @@ -170,6 +170,7 @@ int kern_utimensat(struct nlookupdata *nd, const struct timespec *ts, int flag);
int kern_utimes(struct nlookupdata *nd, struct timeval *tptr);
struct uuid *kern_uuidgen(struct uuid *store, size_t count);
int kern_posix_fallocate(int fd, off_t offset, off_t len);
int kern_fsync(int fd, bool fullsync);

/*
* Prototypes for syscalls in kern/kern_time.c
Expand Down
3 changes: 2 additions & 1 deletion sys/sys/param.h
Expand Up @@ -233,9 +233,10 @@
* 600102 - add nvmm(4) and libnvmm(3)
* 600103 - remove the old vmm code
* 600104 - add posix_fallocate()
* 600105 - add fdatasync()
*/
#undef __DragonFly_version
#define __DragonFly_version 600104 /* propagated to newvers */
#define __DragonFly_version 600105 /* propagated to newvers */

#include <sys/_null.h>

Expand Down
3 changes: 2 additions & 1 deletion sys/sys/syscall.h
Expand Up @@ -389,4 +389,5 @@
#define SYS___realpath 551
#define SYS_fexecve 552
#define SYS_posix_fallocate 553
#define SYS_MAXSYSCALL 554
#define SYS_fdatasync 554
#define SYS_MAXSYSCALL 555
3 changes: 2 additions & 1 deletion sys/sys/syscall.mk
Expand Up @@ -314,4 +314,5 @@ MIASM = \
getrandom.o \
__realpath.o \
fexecve.o \
posix_fallocate.o
posix_fallocate.o \
fdatasync.o
4 changes: 4 additions & 0 deletions sys/sys/sysproto.h
Expand Up @@ -1437,6 +1437,9 @@ struct posix_fallocate_args {
off_t offset; char offset_[PAD_(off_t)];
off_t len; char len_[PAD_(off_t)];
};
struct fdatasync_args {
int fd; char fd_[PAD_(int)];
};

#undef PAD_

Expand Down Expand Up @@ -1762,6 +1765,7 @@ int sys_getrandom (struct sysmsg *sysmsg, const struct getrandom_args *);
int sys___realpath (struct sysmsg *sysmsg, const struct __realpath_args *);
int sys_fexecve (struct sysmsg *sysmsg, const struct fexecve_args *);
int sys_posix_fallocate (struct sysmsg *sysmsg, const struct posix_fallocate_args *);
int sys_fdatasync (struct sysmsg *sysmsg, const struct fdatasync_args *);

#endif /* _KERNEL */

Expand Down
1 change: 1 addition & 0 deletions sys/sys/sysunion.h
Expand Up @@ -321,4 +321,5 @@ union sysunion {
struct __realpath_args __realpath;
struct fexecve_args fexecve;
struct posix_fallocate_args posix_fallocate;
struct fdatasync_args fdatasync;
};
18 changes: 18 additions & 0 deletions sys/sys/vfsops.h
Expand Up @@ -224,6 +224,14 @@ struct vop_fsync_args {
struct file *a_fp; /* FUSE */
};

struct vop_fdatasync_args {
struct vop_generic_args a_head;
struct vnode *a_vp;
int a_waitfor;
int a_flags;
struct file *a_fp; /* FUSE */
};

struct vop_old_remove_args {
struct vop_generic_args a_head;
struct vnode *a_dvp;
Expand Down Expand Up @@ -622,6 +630,7 @@ struct vop_ops {
int (*vop_unused01)(void *); /* was vop_revoke */
int (*vop_mmap)(struct vop_mmap_args *);
int (*vop_fsync)(struct vop_fsync_args *);
int (*vop_fdatasync)(struct vop_fdatasync_args *);
int (*vop_old_remove)(struct vop_old_remove_args *);
int (*vop_old_link)(struct vop_old_link_args *);
int (*vop_old_rename)(struct vop_old_rename_args *);
Expand Down Expand Up @@ -703,6 +712,7 @@ union vop_args_union {
struct vop_kqfilter_args vu_kqfilter;
struct vop_mmap_args vu_mmap;
struct vop_fsync_args vu_fsync;
struct vop_fdatasync_args vu_fdatasync;
struct vop_old_remove_args vu_remove;
struct vop_old_link_args vu_link;
struct vop_old_rename_args vu_rename;
Expand Down Expand Up @@ -792,6 +802,8 @@ int vop_mmap(struct vop_ops *ops, struct vnode *vp, int fflags,
struct ucred *cred);
int vop_fsync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags,
struct file *fp);
int vop_fdatasync(struct vop_ops *ops, struct vnode *vp, int waitfor, int flags,
struct file *fp);
int vop_old_remove(struct vop_ops *ops, struct vnode *dvp,
struct vnode *vp, struct componentname *cnp);
int vop_old_link(struct vop_ops *ops, struct vnode *tdvp,
Expand Down Expand Up @@ -907,6 +919,7 @@ int vop_poll_ap(struct vop_poll_args *ap);
int vop_kqfilter_ap(struct vop_kqfilter_args *ap);
int vop_mmap_ap(struct vop_mmap_args *ap);
int vop_fsync_ap(struct vop_fsync_args *ap);
int vop_fdatasync_ap(struct vop_fdatasync_args *ap);
int vop_old_remove_ap(struct vop_old_remove_args *ap);
int vop_old_link_ap(struct vop_old_link_args *ap);
int vop_old_rename_ap(struct vop_old_rename_args *ap);
Expand Down Expand Up @@ -971,6 +984,7 @@ extern struct syslink_desc vop_poll_desc;
extern struct syslink_desc vop_kqfilter_desc;
extern struct syslink_desc vop_mmap_desc;
extern struct syslink_desc vop_fsync_desc;
extern struct syslink_desc vop_fdatasync_desc;
extern struct syslink_desc vop_old_remove_desc;
extern struct syslink_desc vop_old_link_desc;
extern struct syslink_desc vop_old_rename_desc;
Expand Down Expand Up @@ -1059,6 +1073,10 @@ extern struct syslink_desc vop_nrename_desc;
vop_fsync(*(vp)->v_ops, vp, waitfor, flags, fp) /* FUSE*/
#define VOP_FSYNC(vp, waitfor, flags) \
VOP_FSYNC_FP(vp, waitfor, flags, NULL)
#define VOP_FDATASYNC_FP(vp, waitfor, flags, fp) \
vop_fdatasync(*(vp)->v_ops, vp, waitfor, flags, fp) /* FUSE*/
#define VOP_FDATASYNC(vp, waitfor, flags, fp) \
VOP_FDATASYNC_FP(*(vp)->v_ops, vp, waitfor, flags, NULL)
#define VOP_READDIR_FP(vp, uio, cred, eofflag, ncookies, cookies, fp) \
vop_readdir(*(vp)->v_ops, vp, uio, cred, eofflag, ncookies, cookies, fp) /* FUSE */
#define VOP_READDIR(vp, uio, cred, eofflag, ncookies, cookies) \
Expand Down
1 change: 1 addition & 0 deletions sys/sys/vnode.h
Expand Up @@ -532,6 +532,7 @@ int vop_stdallocate(struct vop_allocate_args *ap);
int vop_stdnoread(struct vop_read_args *ap);
int vop_stdnowrite(struct vop_write_args *ap);
int vop_stdpathconf (struct vop_pathconf_args *ap);
int vop_stdfdatasync(struct vop_fdatasync_args *ap);
int vop_eopnotsupp (struct vop_generic_args *ap);
int vop_ebadf (struct vop_generic_args *ap);
int vop_einval (struct vop_generic_args *ap);
Expand Down

0 comments on commit 74fa256

Please sign in to comment.