src/xcalls/x_unlink.c

Go to the documentation of this file.
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/txdesc.h>
00019 #include <core/stats.h>
00020 #include <libc/syscalls.h>
00021 #include <xcalls/xcalls.h>
00022 
00023 
00024 typedef struct x_unlink_commit_args_s x_unlink_commit_args_t;
00025 
00026 struct x_unlink_commit_args_s {
00027         int       fd;
00028         txc_koa_t *koa;
00029         char      pathname[TXC_MAX_LEN_PATHNAME];
00030 };
00031 
00032 
00033 static
00034 void
00035 x_unlink_commit(void *args, int *result)
00036 {
00037         int                    local_errno = 0; 
00038         x_unlink_commit_args_t *myargs = (x_unlink_commit_args_t *) args;
00039         txc_koamgr_t           *koamgr;
00040         txc_result_t           xret;
00041 
00042         koamgr = txc_koa_get_koamgr(myargs->koa);
00043         txc_koa_lock_alias_cache(koamgr);
00044         txc_koa_lock_fds_refby_koa(myargs->koa);
00045         xret = txc_koa_detach(myargs->koa);
00046         if (xret == TXC_R_SUCCESS) {
00047                 if (txc_libc_unlink(myargs->pathname) < 0) {
00048                         local_errno = errno;
00049                 }       
00050         } else {
00051                 local_errno = EBADF;
00052 
00053         }
00054         txc_koa_unlock_fds_refby_koa(myargs->koa);
00055         txc_koa_unlock_alias_cache(koamgr);
00056         if (result) {
00057                 *result = local_errno;
00058         }
00059 }
00060 
00061 
00075 int
00076 XCALL_DEF(x_unlink)(const char *pathname, int *result) 
00077 {
00078         txc_tx_t               *txd;
00079         txc_koamgr_t           *koamgr = txc_g_koamgr;
00080         txc_koa_t              *koa;
00081         txc_sentinel_t         *sentinel;
00082         txc_result_t           xret;
00083         int                    ret;
00084         ino_t                  inode;
00085         x_unlink_commit_args_t *args_commit; 
00086         int                    local_result = 0;
00087 
00088         txd = txc_tx_get_txd();
00089 
00090         switch(txc_tx_get_xactstate(txd)) {
00091                 case TXC_XACTSTATE_TRANSACTIONAL_RETRYABLE:
00092                         txc_koa_lock_alias_cache(koamgr);
00093                         txc_koa_path2inode(pathname, &inode);
00094                         if (inode == 0) {
00095                                 /* File does not exist. */
00096                                 txc_koa_unlock_alias_cache(koamgr);
00097                                 local_result = EACCES;
00098                                 ret = -1;
00099                                 goto done;
00100                         } else {
00101                                 if (txc_koa_alias_cache_lookup_inode(koamgr, inode, &koa) 
00102                                     == TXC_R_SUCCESS) 
00103                                 {
00104                                         /* 
00105                                          * CASE 1:
00106                                          *  - KOA exists in the alias cache so other in-flight 
00107                                          *    transaction may operate on the file.
00108                                          */
00109                                         txc_koa_lock_fds_refby_koa(koa);
00110                                         txc_koa_attach(koa);
00111                                         sentinel = txc_koa_get_sentinel(koa);
00112                                         xret = txc_sentinel_tryacquire(txd, sentinel, 
00113                                                                        TXC_SENTINEL_ACQUIREONRETRY);
00114                                         if (xret == TXC_R_BUSYSENTINEL) {
00115                                                 txc_koa_detach(koa);
00116                                                 txc_koa_unlock_fds_refby_koa(koa);
00117                                                 txc_koa_unlock_alias_cache(koamgr);
00118                                                 txc_tx_abort_transaction(txd, TXC_ABORTREASON_BUSYSENTINEL);
00119                                                 TXC_INTERNALERROR("Never gets here. Transaction abort failed.\n");
00120                                         }
00121                                         txc_koa_unlock_fds_refby_koa(koa);
00122                                 } else {
00123                                         /* 
00124                                          * CASE 2:
00125                                          * - KOA does not exist in the alias cache so there is no
00126                                          *   way for some other in-flight transaction to have a reference 
00127                                          *   to the file to operate on it.
00128                                          */
00129                                         txc_koa_create(koamgr, &koa, TXC_KOA_IS_FILE, (void *) inode);
00130                                         txc_koa_attach(koa);
00131                                         sentinel = txc_koa_get_sentinel(koa);
00132                                         xret = txc_sentinel_tryacquire(txd, sentinel, 0);
00133                                         if (xret != TXC_R_SUCCESS) {
00134                                                 TXC_INTERNALERROR("Cannot acquire the sentinel of the KOA I've just created!\n");
00135                                         }
00136                                 }
00137                                 args_commit = (x_unlink_commit_args_t *)
00138                                               txc_buffer_linear_malloc(txd->buffer_linear, 
00139                                                                        sizeof(x_unlink_commit_args_t));
00140                                 if (args_commit == NULL) {
00141                                         TXC_INTERNALERROR("Allocation failed. Linear buffer out of space.\n");
00142                                 }
00143 
00144                                 args_commit->koa = koa;
00145                                 strcpy(args_commit->pathname, pathname);
00146 
00147                                 txc_tx_register_commit_action(txd, x_unlink_commit, 
00148                                                               (void *) args_commit, result,
00149                                                               TXC_KOA_DESTROY_COMMIT_ACTION_ORDER);
00150                                 
00151                                 txc_koa_unlock_alias_cache(koamgr);
00152                                 ret = 0;
00153                         }
00154                         txc_stats_txstat_increment(txd, XCALL, x_unlink, 1);
00155                         break;
00156 
00157                 case TXC_XACTSTATE_TRANSACTIONAL_IRREVOCABLE:
00158                 case TXC_XACTSTATE_NONTRANSACTIONAL:
00159                         if ((ret = txc_libc_unlink(pathname)) < 0) { 
00160                                 local_result = errno;
00161                         }
00162                         ret = 0;
00163         }       
00164 done:
00165         if (result) {
00166                 *result = local_result;
00167         }
00168         return ret;
00169 }

Generated on Wed Dec 9 20:32:39 2009 for xCalls by  doxygen 1.4.7