summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/brand/lx/syscall/lx_sync.c
blob: 614afca0b0d1ee04876dbaec28b49ceaf6defb90 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*
 * This file and its contents are supplied under the terms of the
 * Common Development and Distribution License ("CDDL"), version 1.0.
 * You may only use this file in accordance with the terms of version
 * 1.0 of the CDDL.
 *
 * A full copy of the text of the CDDL should have accompanied this
 * source.  A copy of the CDDL is also available via the Internet at
 * http://www.illumos.org/license/CDDL.
 */

/*
 * Copyright 2015 Joyent, Inc.
 */

#include <sys/systm.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/file.h>
#include <sys/vfs.h>
#include <sys/vnode.h>
#include <sys/lx_impl.h>
#include <sys/lx_brand.h>

long
lx_syncfs(int fd)
{
	file_t *fp;
	vfs_t *vfsp;

	if ((fp = getf(fd)) == NULL)
		return (set_errno(EBADF));

	vfsp = fp->f_vnode->v_vfsp;
	releasef(fd);

	(void) (vfsp->vfs_op->vfs_sync)(vfsp, 0, CRED());

	return (0);
}

#define	LX_SYNC_FILE_RANGE_WAIT_BEFORE	0x1
#define	LX_SYNC_FILE_RANGE_WRITE	0x2
#define	LX_SYNC_FILE_RANGE_WAIT_AFTER	0x4

#define	LX_SYNC_FILE_RANGE_VALID	(LX_SYNC_FILE_RANGE_WAIT_BEFORE | \
	LX_SYNC_FILE_RANGE_WRITE | LX_SYNC_FILE_RANGE_WAIT_AFTER)


long
lx_sync_file_range(int fd, off_t offset, off_t nbytes, int flags)
{
	file_t *fp;
	int error, sflags = 0;

	if ((flags & ~LX_SYNC_FILE_RANGE_VALID) != 0)
		return (set_errno(EINVAL));
	if (offset < 0 || nbytes < 0)
		return (set_errno(EINVAL));

	if ((fp = getf(fd)) == NULL)
		return (set_errno(EBADF));

	/*
	 * Since sync_file_range is implemented in terms of VOP_PUTPAGE, both
	 * SYNC_FILE_RANGE_WAIT flags are treated as forcing synchronous
	 * operation.  While this differs from the Linux behavior where
	 * BEFORE/AFTER are distinct, it achieves an adequate level of safety
	 * since the requested data is synced out at the end of the call.
	 */
	if ((flags & (LX_SYNC_FILE_RANGE_WAIT_BEFORE |
	    LX_SYNC_FILE_RANGE_WAIT_AFTER)) == 0) {
		sflags |= B_ASYNC;
	}

	error = VOP_PUTPAGE(fp->f_vnode, offset, nbytes, sflags, CRED(), NULL);
	if (error == ENOSYS) {
		error = ESPIPE;
	}

	releasef(fd);
	if (error != 0) {
		return (set_errno(error));
	}
	return (0);
}