1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1997,2008 Oracle.  All rights reserved.
5 *
6 * $Id: os_fsync.c,v 12.17 2008/05/06 03:03:37 david Exp $
7 */
8
9#include "db_config.h"
10
11#include "db_int.h"
12
13#ifdef	HAVE_VXWORKS
14#include "ioLib.h"
15
16#define	fsync(fd)	__vx_fsync(fd)
17
18int
19__vx_fsync(fd)
20	int fd;
21{
22	int ret;
23
24	/*
25	 * The results of ioctl are driver dependent.  Some will return the
26	 * number of bytes sync'ed.  Only if it returns 'ERROR' should we
27	 * flag it.
28	 */
29	if ((ret = ioctl(fd, FIOSYNC, 0)) != ERROR)
30		return (0);
31	return (ret);
32}
33#endif
34
35#ifdef __hp3000s900
36#define	fsync(fd)	__mpe_fsync(fd)
37
38int
39__mpe_fsync(fd)
40	int fd;
41{
42	extern FCONTROL(short, short, void *);
43
44	FCONTROL(_MPE_FILENO(fd), 2, NULL);	/* Flush the buffers */
45	FCONTROL(_MPE_FILENO(fd), 6, NULL);	/* Write the EOF */
46	return (0);
47}
48#endif
49
50/*
51 * __os_fsync --
52 *	Flush a file descriptor.
53 *
54 * PUBLIC: int __os_fsync __P((ENV *, DB_FH *));
55 */
56int
57__os_fsync(env, fhp)
58	ENV *env;
59	DB_FH *fhp;
60{
61	DB_ENV *dbenv;
62	int ret;
63
64	dbenv = env == NULL ? NULL : env->dbenv;
65
66	DB_ASSERT(env, F_ISSET(fhp, DB_FH_OPENED) && fhp->fd != -1);
67
68	/*
69	 * Do nothing if the file descriptor has been marked as not requiring
70	 * any sync to disk.
71	 */
72	if (F_ISSET(fhp, DB_FH_NOSYNC))
73		return (0);
74
75	if (dbenv != NULL && FLD_ISSET(dbenv->verbose, DB_VERB_FILEOPS_ALL))
76		__db_msg(env, "fileops: flush %s", fhp->name);
77
78	if (DB_GLOBAL(j_fsync) != NULL)
79		ret = DB_GLOBAL(j_fsync)(fhp->fd);
80	else {
81#if defined(F_FULLFSYNC)
82		RETRY_CHK((fcntl(fhp->fd, F_FULLFSYNC, 0)), ret);
83		/*
84		 * On OS X, F_FULLSYNC only works on HFS+, so we need to fall
85		 * back to regular fsync on other filesystems.
86		 */
87		if (ret == ENOTSUP)
88			RETRY_CHK((fsync(fhp->fd)), ret);
89#elif defined(HAVE_QNX)
90		ret = __qnx_fsync(fhp);
91#elif defined(HAVE_FDATASYNC)
92		RETRY_CHK((fdatasync(fhp->fd)), ret);
93#else
94		RETRY_CHK((fsync(fhp->fd)), ret);
95#endif
96	}
97
98	if (ret != 0) {
99		__db_syserr(env, ret, "fsync");
100		ret = __os_posix_err(ret);
101	}
102	return (ret);
103}
104