Add an implementation of fdatasync(2).
The syscall is a trivial wrapper around new VOP_FDATASYNC(), sharing code with fsync(2). For all filesystems, this commit provides the implementation which delegates the work of VOP_FDATASYNC() to VOP_FSYNC(). This is functionally correct but not efficient. This is not yet POSIX-compliant implementation, because it does not ensure that queued AIO requests are completed before returning. Reviewed by: mckusick Discussed with: avg (ZFS), jhb (AIO part) Tested by: pho Sponsored by: The FreeBSD Foundation MFC after: 2 weeks Differential revision: https://reviews.freebsd.org/D7471
This commit is contained in:
parent
576a9e496f
commit
295af703a0
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=304176
@ -384,6 +384,7 @@ extern int optind, opterr, optopt;
|
|||||||
/* ISO/IEC 9945-1: 1996 */
|
/* ISO/IEC 9945-1: 1996 */
|
||||||
#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
|
#if __POSIX_VISIBLE >= 199506 || __XSI_VISIBLE
|
||||||
int fsync(int);
|
int fsync(int);
|
||||||
|
int fdatasync(int);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ftruncate() was in the POSIX Realtime Extension (it's used for shared
|
* ftruncate() was in the POSIX Realtime Extension (it's used for shared
|
||||||
|
@ -400,6 +400,10 @@ FBSD_1.4 {
|
|||||||
recvmmsg;
|
recvmmsg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
FBSD_1.5 {
|
||||||
|
fdatasync;
|
||||||
|
};
|
||||||
|
|
||||||
FBSDprivate_1.0 {
|
FBSDprivate_1.0 {
|
||||||
___acl_aclcheck_fd;
|
___acl_aclcheck_fd;
|
||||||
__sys___acl_aclcheck_fd;
|
__sys___acl_aclcheck_fd;
|
||||||
@ -594,6 +598,8 @@ FBSDprivate_1.0 {
|
|||||||
__sys_fstatfs;
|
__sys_fstatfs;
|
||||||
_fsync;
|
_fsync;
|
||||||
__sys_fsync;
|
__sys_fsync;
|
||||||
|
_fdatasync;
|
||||||
|
__sys_fdatasync;
|
||||||
_futimes;
|
_futimes;
|
||||||
__sys_futimes;
|
__sys_futimes;
|
||||||
_getaudit;
|
_getaudit;
|
||||||
|
@ -1081,3 +1081,4 @@
|
|||||||
549 AUE_NULL NOPROTO { int numa_setaffinity(cpuwhich_t which, \
|
549 AUE_NULL NOPROTO { int numa_setaffinity(cpuwhich_t which, \
|
||||||
id_t id, \
|
id_t id, \
|
||||||
const struct vm_domain_policy *policy); }
|
const struct vm_domain_policy *policy); }
|
||||||
|
550 AUE_FSYNC NOPROTO { int fdatasync(int fd); }
|
||||||
|
@ -993,8 +993,9 @@
|
|||||||
id_t id, \
|
id_t id, \
|
||||||
struct vm_domain_policy_entry *policy); }
|
struct vm_domain_policy_entry *policy); }
|
||||||
549 AUE_NULL STD { int numa_setaffinity(cpuwhich_t which, \
|
549 AUE_NULL STD { int numa_setaffinity(cpuwhich_t which, \
|
||||||
id_t id, \
|
id_t id, const struct \
|
||||||
const struct vm_domain_policy_entry *policy); }
|
vm_domain_policy_entry *policy); }
|
||||||
|
550 AUE_FSYNC STD { int fdatasync(int fd); }
|
||||||
|
|
||||||
; Please copy any additions and changes to the following compatability tables:
|
; Please copy any additions and changes to the following compatability tables:
|
||||||
; sys/compat/freebsd32/syscalls.master
|
; sys/compat/freebsd32/syscalls.master
|
||||||
|
@ -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_stdunset_text(struct vop_unset_text_args *ap);
|
||||||
static int vop_stdget_writecount(struct vop_get_writecount_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_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);
|
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_bmap = vop_stdbmap,
|
||||||
.vop_close = VOP_NULL,
|
.vop_close = VOP_NULL,
|
||||||
.vop_fsync = VOP_NULL,
|
.vop_fsync = VOP_NULL,
|
||||||
|
.vop_fdatasync = vop_stdfdatasync,
|
||||||
.vop_getpages = vop_stdgetpages,
|
.vop_getpages = vop_stdgetpages,
|
||||||
.vop_getpages_async = vop_stdgetpages_async,
|
.vop_getpages_async = vop_stdgetpages_async,
|
||||||
.vop_getwritemount = vop_stdgetwritemount,
|
.vop_getwritemount = vop_stdgetwritemount,
|
||||||
@ -726,6 +728,13 @@ vop_stdfsync(ap)
|
|||||||
return (error);
|
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)). */
|
/* XXX Needs good comment and more info in the manpage (VOP_GETPAGES(9)). */
|
||||||
int
|
int
|
||||||
vop_stdgetpages(ap)
|
vop_stdgetpages(ap)
|
||||||
|
@ -3354,20 +3354,8 @@ freebsd6_ftruncate(struct thread *td, struct freebsd6_ftruncate_args *uap)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
static int
|
||||||
* Sync an open file.
|
kern_fsync(struct thread *td, int fd, bool fullsync)
|
||||||
*/
|
|
||||||
#ifndef _SYS_SYSPROTO_H_
|
|
||||||
struct fsync_args {
|
|
||||||
int fd;
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
int
|
|
||||||
sys_fsync(td, uap)
|
|
||||||
struct thread *td;
|
|
||||||
struct fsync_args /* {
|
|
||||||
int fd;
|
|
||||||
} */ *uap;
|
|
||||||
{
|
{
|
||||||
struct vnode *vp;
|
struct vnode *vp;
|
||||||
struct mount *mp;
|
struct mount *mp;
|
||||||
@ -3375,11 +3363,15 @@ sys_fsync(td, uap)
|
|||||||
cap_rights_t rights;
|
cap_rights_t rights;
|
||||||
int error, lock_flags;
|
int error, lock_flags;
|
||||||
|
|
||||||
AUDIT_ARG_FD(uap->fd);
|
AUDIT_ARG_FD(fd);
|
||||||
error = getvnode(td, uap->fd, cap_rights_init(&rights, CAP_FSYNC), &fp);
|
error = getvnode(td, fd, cap_rights_init(&rights, CAP_FSYNC), &fp);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
vp = fp->f_vnode;
|
vp = fp->f_vnode;
|
||||||
|
#if 0
|
||||||
|
if (!fullsync)
|
||||||
|
/* XXXKIB: compete outstanding aio writes */;
|
||||||
|
#endif
|
||||||
error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
|
error = vn_start_write(vp, &mp, V_WAIT | PCATCH);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
goto drop;
|
goto drop;
|
||||||
@ -3396,8 +3388,7 @@ sys_fsync(td, uap)
|
|||||||
vm_object_page_clean(vp->v_object, 0, 0, 0);
|
vm_object_page_clean(vp->v_object, 0, 0, 0);
|
||||||
VM_OBJECT_WUNLOCK(vp->v_object);
|
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);
|
VOP_UNLOCK(vp, 0);
|
||||||
vn_finished_write(mp);
|
vn_finished_write(mp);
|
||||||
drop:
|
drop:
|
||||||
@ -3405,6 +3396,28 @@ sys_fsync(td, uap)
|
|||||||
return (error);
|
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
|
* Rename files. Source and destination must either both be directories, or
|
||||||
* both not be directories. If target is a directory, it must be empty.
|
* both not be directories. If target is a directory, it must be empty.
|
||||||
|
@ -703,6 +703,14 @@ vop_add_writecount {
|
|||||||
IN int inc;
|
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
|
# 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
|
# 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,
|
# be added above these spares. When merging a new VOP to a stable branch,
|
||||||
|
Loading…
Reference in New Issue
Block a user