1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1997,2008 Oracle. All rights reserved. 5 * 6 * $Id: os_qnx_fsync.c,v 1.1 2008/05/06 03:03:37 david Exp $ 7 */ 8 9#include "db_config.h" 10 11#include "db_int.h" 12 13/* 14 * QNX has special requirements on FSYNC: if the file is a shared memory 15 * object, we can not call fsync because it is not implemented, instead, 16 * we set the O_DSYNC flag to the file descriptor and then do an empty 17 * write so that all data are synced. We only sync this way if the file 18 * is a shared memory object, other types of ordinary files are still synced 19 * using fsync, to be not only faster but also atomic. 20 * We don't just set the O_DSYNC flag on open, since it would force all writes 21 * to be sync'ed. And we remove the O_DSYNC if it is not originally set to 22 * the file descriptor before passed in to this function. 23 * This is slightly different to the VxWorks and hp code above, since QNX does 24 * supply a fsync call, it just has a unique requirement. 25 */ 26int 27__qnx_fsync(fhp) 28 DB_FH *fhp; 29{ 30 int ret; 31 int fd, unset, flags; 32 33 fd = fhp->fd; 34 unset = 1; 35 ret = flags = 0; 36 if (F_ISSET(fhp, DB_FH_REGION)) 37 { 38 RETRY_CHK(fcntl(fd, F_GETFL), ret); 39 if (ret == -1) 40 goto err; 41 /* 42 * if already has O_DSYNC flag, we can't remove it 43 * after the empty write 44 */ 45 if (ret & O_DSYNC != 0) 46 unset = 0; 47 else { 48 ret |= O_DSYNC; 49 flags = ret; 50 RETRY_CHK(fcntl(fd, F_SETFL, flags), ret); 51 if (ret == -1) 52 goto err; 53 } 54 /* Do an empty write, to force a sync */ 55 RETRY_CHK(write(fd, "", 0), ret); 56 if (ret == -1) 57 goto err; 58 /* remove the O_DSYNC flag if necessary */ 59 if (unset) { 60 RETRY_CHK(fcntl(fd, F_GETFL), ret); 61 if (ret == -1) 62 goto err; 63 ret &= ~O_DSYNC; 64 flags = ret; 65 RETRY_CHK(fcntl(fd, F_SETFL, flags), ret); 66 if (ret == -1) 67 goto err; 68 } 69 } else 70 RETRY_CHK(fdatasync(fd), ret); 71 72err: return (ret); 73} 74