00001
00007 #include <fcntl.h>
00008 #include <unistd.h>
00009 #include <errno.h>
00010 #include <string.h>
00011 #include <stdlib.h>
00012 #include <misc/debug.h>
00013 #include <misc/errno.h>
00014 #include <core/tx.h>
00015 #include <core/config.h>
00016 #include <core/koa.h>
00017 #include <core/buffer.h>
00018 #include <core/stats.h>
00019 #include <libc/syscalls.h>
00020 #include <core/txdesc.h>
00021 #include <xcalls/xcalls.h>
00022
00023
00024 #include <fcntl.h>
00025 #include <unistd.h>
00026 #include <errno.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <misc/debug.h>
00030 #include <misc/errno.h>
00031 #include <core/tx.h>
00032 #include <core/config.h>
00033 #include <core/koa.h>
00034 #include <core/buffer.h>
00035 #include <core/stats.h>
00036 #include <libc/syscalls.h>
00037 #include <core/txdesc.h>
00038 #include <xcalls/xcalls.h>
00039
00040
00041 typedef struct x_fsync_commit_args_s x_fsync_commit_args_t;
00042
00043 struct x_fsync_commit_args_s {
00044 int fd;
00045 };
00046
00047
00048 static
00049 void
00050 x_fsync_commit(void *args, int *result)
00051 {
00052 x_fsync_commit_args_t *args_commit = (x_fsync_commit_args_t *) args;
00053 int local_result = 0;
00054
00055 if (txc_libc_fsync(args_commit->fd) < 0)
00056 {
00057 local_result = errno;
00058 }
00059 if (result) {
00060 *result = local_result;
00061 }
00062 }
00063
00064
00077 int
00078 XCALL_DEF(x_fsync)(int fildes, int *result)
00079 {
00080 txc_tx_t *txd;
00081 txc_koamgr_t *koamgr = txc_g_koamgr;
00082 txc_koa_t *koa;
00083 txc_sentinel_t *sentinel;
00084 txc_result_t xret;
00085 int ret;
00086 x_fsync_commit_args_t *args_commit;
00087 int local_result = 0;
00088
00089 txd = txc_tx_get_txd();
00090
00091 switch(txc_tx_get_xactstate(txd)) {
00092 case TXC_XACTSTATE_TRANSACTIONAL_RETRYABLE:
00093 txc_koa_lock_fd(koamgr, fildes);
00094 xret = txc_koa_lookup_fd2koa(koamgr, fildes, &koa);
00095 if (xret == TXC_R_FAILURE) {
00096
00097
00098
00099
00100 txc_koa_unlock_fd(koamgr, fildes);
00101 local_result = EBADF;
00102 ret = -1;
00103 goto done;
00104 }
00105
00106 sentinel = txc_koa_get_sentinel(koa);
00107 xret = txc_sentinel_tryacquire(txd, sentinel, TXC_SENTINEL_ACQUIREONRETRY);
00108 if (xret == TXC_R_BUSYSENTINEL) {
00109 txc_koa_unlock_fd(koamgr, fildes);
00110 txc_tx_abort_transaction(txd, TXC_ABORTREASON_BUSYSENTINEL);
00111 TXC_INTERNALERROR("Never gets here. Transaction abort failed.\n");
00112 } else {
00113 txc_koa_unlock_fd(koamgr, fildes);
00114 }
00115
00116 args_commit = (x_fsync_commit_args_t *)
00117 txc_buffer_linear_malloc(txd->buffer_linear,
00118 sizeof(x_fsync_commit_args_t));
00119 if (args_commit == NULL) {
00120 TXC_INTERNALERROR("Allocation failed. Linear buffer out of space.\n");
00121 }
00122 args_commit->fd = fildes;
00123
00124 txc_tx_register_commit_action(txd, x_fsync_commit,
00125 (void *) args_commit, result,
00126 TXC_TX_REGULAR_COMMIT_ACTION_ORDER);
00127
00128 txc_koa_unlock_fd(koamgr, fildes);
00129 ret = 0;
00130 txc_stats_txstat_increment(txd, XCALL, x_fsync, 1);
00131 break;
00132 case TXC_XACTSTATE_TRANSACTIONAL_IRREVOCABLE:
00133 case TXC_XACTSTATE_NONTRANSACTIONAL:
00134 if ((ret = txc_libc_fsync(fildes)) < 0) {
00135 local_result = errno;
00136 goto done;
00137 }
00138 }
00139 done:
00140 if (result) {
00141 *result = local_result;
00142 }
00143 return ret;
00144 }