diff options
Diffstat (limited to 'libglusterfs/src/syncop.c')
| -rw-r--r-- | libglusterfs/src/syncop.c | 1380 |
1 files changed, 1228 insertions, 152 deletions
diff --git a/libglusterfs/src/syncop.c b/libglusterfs/src/syncop.c index 7b6f78248..c1620bb70 100644 --- a/libglusterfs/src/syncop.c +++ b/libglusterfs/src/syncop.c @@ -1,20 +1,11 @@ /* - Copyright (c) 2010-2011 Gluster, Inc. <http://www.gluster.com> + Copyright (c) 2008-2013 Red Hat, Inc. <http://www.redhat.com> This file is part of GlusterFS. - GlusterFS is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published - by the Free Software Foundation; either version 3 of the License, - or (at your option) any later version. - - GlusterFS is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see - <http://www.gnu.org/licenses/>. + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. */ #ifndef _CONFIG_H @@ -24,57 +15,250 @@ #include "syncop.h" -call_frame_t * -syncop_create_frame () +int +syncopctx_setfsuid (void *uid) { - struct synctask *task = NULL; - call_frame_t *frame = NULL; - - task = synctask_get (); + struct syncopctx *opctx = NULL; + int ret = 0; + + /* In args check */ + if (!uid) { + ret = -1; + errno = EINVAL; + goto out; + } + + opctx = syncopctx_getctx (); + + /* alloc for this thread the first time */ + if (!opctx) { + opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx); + if (!opctx) { + ret = -1; + goto out; + } + + ret = syncopctx_setctx (opctx); + if (ret != 0) { + GF_FREE (opctx); + opctx = NULL; + goto out; + } + } + +out: + if (opctx && uid) { + opctx->uid = *(uid_t *)uid; + opctx->valid |= SYNCOPCTX_UID; + } + + return ret; +} - if (task) { - frame = task->frame; - } +int +syncopctx_setfsgid (void *gid) +{ + struct syncopctx *opctx = NULL; + int ret = 0; + + /* In args check */ + if (!gid) { + ret = -1; + errno = EINVAL; + goto out; + } + + opctx = syncopctx_getctx (); + + /* alloc for this thread the first time */ + if (!opctx) { + opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx); + if (!opctx) { + ret = -1; + goto out; + } + + ret = syncopctx_setctx (opctx); + if (ret != 0) { + GF_FREE (opctx); + opctx = NULL; + goto out; + } + } + +out: + if (opctx && gid) { + opctx->gid = *(gid_t *)gid; + opctx->valid |= SYNCOPCTX_GID; + } + + return ret; +} - return (call_frame_t *)frame; +int +syncopctx_setfsgroups (int count, const void *groups) +{ + struct syncopctx *opctx = NULL; + gid_t *tmpgroups = NULL; + int ret = 0; + + /* In args check */ + if (count != 0 && !groups) { + ret = -1; + errno = EINVAL; + goto out; + } + + opctx = syncopctx_getctx (); + + /* alloc for this thread the first time */ + if (!opctx) { + opctx = GF_CALLOC (1, sizeof (*opctx), gf_common_mt_syncopctx); + if (!opctx) { + ret = -1; + goto out; + } + + ret = syncopctx_setctx (opctx); + if (ret != 0) { + GF_FREE (opctx); + opctx = NULL; + goto out; + } + } + + /* resize internal groups as required */ + if (count && opctx->grpsize < count) { + if (opctx->groups) { + tmpgroups = GF_REALLOC (opctx->groups, + (sizeof (gid_t) * count)); + /* NOTE: Not really required to zero the reallocation, + * as ngrps controls the validity of data, + * making a note irrespective */ + if (tmpgroups == NULL) { + opctx->grpsize = 0; + GF_FREE (opctx->groups); + opctx->groups = NULL; + ret = -1; + goto out; + } + } + else { + tmpgroups = GF_CALLOC (count, sizeof (gid_t), + gf_common_mt_syncopctx); + if (tmpgroups == NULL) { + opctx->grpsize = 0; + ret = -1; + goto out; + } + } + + opctx->groups = tmpgroups; + opctx->grpsize = count; + } + + /* copy out the groups passed */ + if (count) + memcpy (opctx->groups, groups, (sizeof (gid_t) * count)); + + /* set/reset the ngrps, this is where reset of groups is handled */ + opctx->ngrps = count; + opctx->valid |= SYNCOPCTX_GROUPS; + +out: + return ret; } -void -synctask_yield (struct synctask *task) +static void +__run (struct synctask *task) { - struct syncenv *env = NULL; + struct syncenv *env = NULL; env = task->env; - if (swapcontext (&task->ctx, &env->sched) < 0) { - gf_log ("syncop", GF_LOG_ERROR, - "swapcontext failed (%s)", strerror (errno)); + list_del_init (&task->all_tasks); + switch (task->state) { + case SYNCTASK_INIT: + case SYNCTASK_SUSPEND: + break; + case SYNCTASK_RUN: + gf_log (task->xl->name, GF_LOG_DEBUG, + "re-running already running task"); + env->runcount--; + break; + case SYNCTASK_WAIT: + env->waitcount--; + break; + case SYNCTASK_DONE: + gf_log (task->xl->name, GF_LOG_WARNING, + "running completed task"); + return; + case SYNCTASK_ZOMBIE: + gf_log (task->xl->name, GF_LOG_WARNING, + "attempted to wake up zombie!!"); + return; } + + list_add_tail (&task->all_tasks, &env->runq); + env->runcount++; + task->state = SYNCTASK_RUN; } -void -synctask_yawn (struct synctask *task) +static void +__wait (struct synctask *task) { - struct syncenv *env = NULL; + struct syncenv *env = NULL; - env = task->env; + env = task->env; - pthread_mutex_lock (&env->mutex); - { - list_del_init (&task->all_tasks); - list_add (&task->all_tasks, &env->waitq); + list_del_init (&task->all_tasks); + switch (task->state) { + case SYNCTASK_INIT: + case SYNCTASK_SUSPEND: + break; + case SYNCTASK_RUN: + env->runcount--; + break; + case SYNCTASK_WAIT: + gf_log (task->xl->name, GF_LOG_WARNING, + "re-waiting already waiting task"); + env->waitcount--; + break; + case SYNCTASK_DONE: + gf_log (task->xl->name, GF_LOG_WARNING, + "running completed task"); + return; + case SYNCTASK_ZOMBIE: + gf_log (task->xl->name, GF_LOG_WARNING, + "attempted to sleep a zombie!!"); + return; } - pthread_mutex_unlock (&env->mutex); + + list_add_tail (&task->all_tasks, &env->waitq); + env->waitcount++; + task->state = SYNCTASK_WAIT; } void -synctask_zzzz (struct synctask *task) +synctask_yield (struct synctask *task) { - synctask_yawn (task); + xlator_t *oldTHIS = THIS; - synctask_yield (task); +#if defined(__NetBSD__) && defined(_UC_TLSBASE) + /* Preserve pthread private pointer through swapcontex() */ + task->proc->sched.uc_flags &= ~_UC_TLSBASE; +#endif + + if (task->state != SYNCTASK_DONE) + task->state = SYNCTASK_SUSPEND; + if (swapcontext (&task->ctx, &task->proc->sched) < 0) { + gf_log ("syncop", GF_LOG_ERROR, + "swapcontext failed (%s)", strerror (errno)); + } + + THIS = oldTHIS; } @@ -87,33 +271,30 @@ synctask_wake (struct synctask *task) pthread_mutex_lock (&env->mutex); { - list_del_init (&task->all_tasks); - list_add_tail (&task->all_tasks, &env->runq); + task->woken = 1; + + if (task->slept) + __run (task); + + pthread_cond_broadcast (&env->cond); } pthread_mutex_unlock (&env->mutex); - - pthread_cond_broadcast (&env->cond); } - void synctask_wrap (struct synctask *old_task) { - int ret; struct synctask *task = NULL; /* Do not trust the pointer received. It may be wrong and can lead to crashes. */ task = synctask_get (); - ret = task->syncfn (task->opaque); - task->synccbk (ret, task->frame, task->opaque); + task->ret = task->syncfn (task->opaque); + if (task->synccbk) + task->synccbk (task->ret, task->frame, task->opaque); - /* cannot destroy @task right here as we are - in the execution stack of @task itself - */ - task->complete = 1; - synctask_wake (task); + task->state = SYNCTASK_DONE; synctask_yield (task); } @@ -125,36 +306,88 @@ synctask_destroy (struct synctask *task) if (!task) return; - if (task->stack) - FREE (task->stack); + FREE (task->stack); + + if (task->opframe) + STACK_DESTROY (task->opframe->root); + + if (task->synccbk == NULL) { + pthread_mutex_destroy (&task->mutex); + pthread_cond_destroy (&task->cond); + } + FREE (task); } +void +synctask_done (struct synctask *task) +{ + if (task->synccbk) { + synctask_destroy (task); + return; + } + + pthread_mutex_lock (&task->mutex); + { + task->state = SYNCTASK_ZOMBIE; + task->done = 1; + pthread_cond_broadcast (&task->cond); + } + pthread_mutex_unlock (&task->mutex); +} + + int -synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk, - call_frame_t *frame, void *opaque) +synctask_setid (struct synctask *task, uid_t uid, gid_t gid) +{ + if (!task) + return -1; + + if (uid != -1) + task->uid = uid; + + if (gid != -1) + task->gid = gid; + + return 0; +} + + +struct synctask * +synctask_create (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk, + call_frame_t *frame, void *opaque) { struct synctask *newtask = NULL; xlator_t *this = THIS; VALIDATE_OR_GOTO (env, err); VALIDATE_OR_GOTO (fn, err); - VALIDATE_OR_GOTO (cbk, err); - VALIDATE_OR_GOTO (frame, err); newtask = CALLOC (1, sizeof (*newtask)); if (!newtask) - return -ENOMEM; + return NULL; + newtask->frame = frame; + if (!frame) { + newtask->opframe = create_frame (this, this->ctx->pool); + } else { + newtask->opframe = copy_frame (frame); + } + if (!newtask->opframe) + goto err; newtask->env = env; newtask->xl = this; newtask->syncfn = fn; newtask->synccbk = cbk; newtask->opaque = opaque; - newtask->frame = frame; + + /* default to the uid/gid of the passed frame */ + newtask->uid = newtask->opframe->root->uid; + newtask->gid = newtask->opframe->root->gid; INIT_LIST_HEAD (&newtask->all_tasks); + INIT_LIST_HEAD (&newtask->waitq); if (getcontext (&newtask->ctx) < 0) { gf_log ("syncop", GF_LOG_ERROR, @@ -173,35 +406,114 @@ synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk, newtask->ctx.uc_stack.ss_sp = newtask->stack; newtask->ctx.uc_stack.ss_size = env->stacksize; - makecontext (&newtask->ctx, (void *) synctask_wrap, 2, newtask); + makecontext (&newtask->ctx, (void (*)(void)) synctask_wrap, 2, newtask); + + newtask->state = SYNCTASK_INIT; + + newtask->slept = 1; + + if (!cbk) { + pthread_mutex_init (&newtask->mutex, NULL); + pthread_cond_init (&newtask->cond, NULL); + newtask->done = 0; + } synctask_wake (newtask); + /* + * Make sure someone's there to execute anything we just put on the + * run queue. + */ + syncenv_scale(env); - return 0; + return newtask; err: if (newtask) { - if (newtask->stack) - FREE (newtask->stack); + FREE (newtask->stack); + if (newtask->opframe) + STACK_DESTROY (newtask->opframe->root); FREE (newtask); } - return -1; + + return NULL; +} + + +int +synctask_join (struct synctask *task) +{ + int ret = 0; + + pthread_mutex_lock (&task->mutex); + { + while (!task->done) + pthread_cond_wait (&task->cond, &task->mutex); + } + pthread_mutex_unlock (&task->mutex); + + ret = task->ret; + + synctask_destroy (task); + + return ret; +} + + +int +synctask_new (struct syncenv *env, synctask_fn_t fn, synctask_cbk_t cbk, + call_frame_t *frame, void *opaque) +{ + struct synctask *newtask = NULL; + int ret = 0; + + newtask = synctask_create (env, fn, cbk, frame, opaque); + if (!newtask) + return -1; + + if (!cbk) + ret = synctask_join (newtask); + + return ret; } struct synctask * -syncenv_task (struct syncenv *env) +syncenv_task (struct syncproc *proc) { + struct syncenv *env = NULL; struct synctask *task = NULL; + struct timespec sleep_till = {0, }; + int ret = 0; + + env = proc->env; pthread_mutex_lock (&env->mutex); { - while (list_empty (&env->runq)) - pthread_cond_wait (&env->cond, &env->mutex); + while (list_empty (&env->runq)) { + sleep_till.tv_sec = time (NULL) + SYNCPROC_IDLE_TIME; + ret = pthread_cond_timedwait (&env->cond, &env->mutex, + &sleep_till); + if (!list_empty (&env->runq)) + break; + if ((ret == ETIMEDOUT) && + (env->procs > env->procmin)) { + task = NULL; + env->procs--; + memset (proc, 0, sizeof (*proc)); + goto unlock; + } + } task = list_entry (env->runq.next, struct synctask, all_tasks); list_del_init (&task->all_tasks); + env->runcount--; + + task->woken = 0; + task->slept = 0; + + task->proc = proc; } +unlock: pthread_mutex_unlock (&env->mutex); return task; @@ -218,30 +530,51 @@ synctask_switchto (struct synctask *task) synctask_set (task); THIS = task->xl; - if (swapcontext (&env->sched, &task->ctx) < 0) { +#if defined(__NetBSD__) && defined(_UC_TLSBASE) + /* Preserve pthread private pointer through swapcontex() */ + task->ctx.uc_flags &= ~_UC_TLSBASE; +#endif + + if (swapcontext (&task->proc->sched, &task->ctx) < 0) { gf_log ("syncop", GF_LOG_ERROR, "swapcontext failed (%s)", strerror (errno)); } -} + if (task->state == SYNCTASK_DONE) { + synctask_done (task); + return; + } + + pthread_mutex_lock (&env->mutex); + { + if (task->woken) { + __run (task); + } else { + task->slept = 1; + __wait (task); + } + } + pthread_mutex_unlock (&env->mutex); +} void * syncenv_processor (void *thdata) { struct syncenv *env = NULL; + struct syncproc *proc = NULL; struct synctask *task = NULL; - env = thdata; + proc = thdata; + env = proc->env; for (;;) { - task = syncenv_task (env); - - if (task->complete) { - synctask_destroy (task); - continue; - } + task = syncenv_task (proc); + if (!task) + break; synctask_switchto (task); + + syncenv_scale (env); } return NULL; @@ -249,6 +582,45 @@ syncenv_processor (void *thdata) void +syncenv_scale (struct syncenv *env) +{ + int diff = 0; + int scale = 0; + int i = 0; + int ret = 0; + + pthread_mutex_lock (&env->mutex); + { + if (env->procs > env->runcount) + goto unlock; + + scale = env->runcount; + if (scale > env->procmax) + scale = env->procmax; + if (scale > env->procs) + diff = scale - env->procs; + while (diff) { + diff--; + for (; (i < env->procmax); i++) { + if (env->proc[i].processor == 0) + break; + } + + env->proc[i].env = env; + ret = gf_thread_create (&env->proc[i].processor, NULL, + syncenv_processor, &env->proc[i]); + if (ret) + break; + env->procs++; + i++; + } + } +unlock: + pthread_mutex_unlock (&env->mutex); +} + + +void syncenv_destroy (struct syncenv *env) { @@ -256,10 +628,19 @@ syncenv_destroy (struct syncenv *env) struct syncenv * -syncenv_new (size_t stacksize) +syncenv_new (size_t stacksize, int procmin, int procmax) { struct syncenv *newenv = NULL; int ret = 0; + int i = 0; + + if (!procmin || procmin < 0) + procmin = SYNCENV_PROC_MIN; + if (!procmax || procmax > SYNCENV_PROC_MAX) + procmax = SYNCENV_PROC_MAX; + + if (procmin > procmax) + return NULL; newenv = CALLOC (1, sizeof (*newenv)); @@ -275,9 +656,17 @@ syncenv_new (size_t stacksize) newenv->stacksize = SYNCENV_DEFAULT_STACKSIZE; if (stacksize) newenv->stacksize = stacksize; - - ret = pthread_create (&newenv->processor, NULL, - syncenv_processor, newenv); + newenv->procmin = procmin; + newenv->procmax = procmax; + + for (i = 0; i < newenv->procmin; i++) { + newenv->proc[i].env = newenv; + ret = gf_thread_create (&newenv->proc[i].processor, NULL, + syncenv_processor, &newenv->proc[i]); + if (ret) + break; + newenv->procs++; + } if (ret != 0) syncenv_destroy (newenv); @@ -286,13 +675,275 @@ syncenv_new (size_t stacksize) } +int +synclock_init (synclock_t *lock) +{ + if (!lock) + return -1; + + pthread_cond_init (&lock->cond, 0); + lock->lock = 0; + INIT_LIST_HEAD (&lock->waitq); + + return pthread_mutex_init (&lock->guard, 0); +} + + +int +synclock_destroy (synclock_t *lock) +{ + if (!lock) + return -1; + + pthread_cond_destroy (&lock->cond); + return pthread_mutex_destroy (&lock->guard); +} + + +static int +__synclock_lock (struct synclock *lock) +{ + struct synctask *task = NULL; + + if (!lock) + return -1; + + task = synctask_get (); + + while (lock->lock) { + if (task) { + /* called within a synctask */ + list_add_tail (&task->waitq, &lock->waitq); + pthread_mutex_unlock (&lock->guard); + synctask_yield (task); + /* task is removed from waitq in unlock, + * under lock->guard.*/ + pthread_mutex_lock (&lock->guard); + } else { + /* called by a non-synctask */ + pthread_cond_wait (&lock->cond, &lock->guard); + } + } + + lock->lock = _gf_true; + lock->owner = task; + + return 0; +} + + +int +synclock_lock (synclock_t *lock) +{ + int ret = 0; + + pthread_mutex_lock (&lock->guard); + { + ret = __synclock_lock (lock); + } + pthread_mutex_unlock (&lock->guard); + + return ret; +} + + +int +synclock_trylock (synclock_t *lock) +{ + int ret = 0; + + errno = 0; + + pthread_mutex_lock (&lock->guard); + { + if (lock->lock) { + errno = EBUSY; + ret = -1; + goto unlock; + } + + ret = __synclock_lock (lock); + } +unlock: + pthread_mutex_unlock (&lock->guard); + + return ret; +} + + +static int +__synclock_unlock (synclock_t *lock) +{ + struct synctask *task = NULL; + struct synctask *curr = NULL; + + if (!lock) + return -1; + + curr = synctask_get (); + + if (lock->owner != curr) { + /* warn ? */ + } + + lock->lock = _gf_false; + + /* There could be both synctasks and non synctasks + waiting (or none, or either). As a mid-approach + between maintaining too many waiting counters + at one extreme and a thundering herd on unlock + at the other, call a cond_signal (which wakes + one waiter) and first synctask waiter. So at + most we have two threads waking up to grab the + just released lock. + */ + pthread_cond_signal (&lock->cond); + if (!list_empty (&lock->waitq)) { + task = list_entry (lock->waitq.next, struct synctask, waitq); + list_del_init (&task->waitq); + synctask_wake (task); + } + + return 0; +} + + +int +synclock_unlock (synclock_t *lock) +{ + int ret = 0; + + pthread_mutex_lock (&lock->guard); + { + ret = __synclock_unlock (lock); + } + pthread_mutex_unlock (&lock->guard); + + return ret; +} + +/* Barriers */ + +int +syncbarrier_init (struct syncbarrier *barrier) +{ + if (!barrier) { + errno = EINVAL; + return -1; + } + + pthread_cond_init (&barrier->cond, 0); + barrier->count = 0; + INIT_LIST_HEAD (&barrier->waitq); + + return pthread_mutex_init (&barrier->guard, 0); +} + + +int +syncbarrier_destroy (struct syncbarrier *barrier) +{ + if (!barrier) { + errno = EINVAL; + return -1; + } + + pthread_cond_destroy (&barrier->cond); + return pthread_mutex_destroy (&barrier->guard); +} + + +static int +__syncbarrier_wait (struct syncbarrier *barrier, int waitfor) +{ + struct synctask *task = NULL; + + if (!barrier) { + errno = EINVAL; + return -1; + } + + task = synctask_get (); + + while (barrier->count < waitfor) { + if (task) { + /* called within a synctask */ + list_add_tail (&task->waitq, &barrier->waitq); + pthread_mutex_unlock (&barrier->guard); + synctask_yield (task); + pthread_mutex_lock (&barrier->guard); + } else { + /* called by a non-synctask */ + pthread_cond_wait (&barrier->cond, &barrier->guard); + } + } + + barrier->count = 0; + + return 0; +} + + +int +syncbarrier_wait (struct syncbarrier *barrier, int waitfor) +{ + int ret = 0; + + pthread_mutex_lock (&barrier->guard); + { + ret = __syncbarrier_wait (barrier, waitfor); + } + pthread_mutex_unlock (&barrier->guard); + + return ret; +} + + +static int +__syncbarrier_wake (struct syncbarrier *barrier) +{ + struct synctask *task = NULL; + + if (!barrier) { + errno = EINVAL; + return -1; + } + + barrier->count++; + + pthread_cond_signal (&barrier->cond); + if (!list_empty (&barrier->waitq)) { + task = list_entry (barrier->waitq.next, struct synctask, waitq); + list_del_init (&task->waitq); + synctask_wake (task); + } + + return 0; +} + + +int +syncbarrier_wake (struct syncbarrier *barrier) +{ + int ret = 0; + + pthread_mutex_lock (&barrier->guard); + { + ret = __syncbarrier_wake (barrier); + } + pthread_mutex_unlock (&barrier->guard); + + return ret; +} + + /* FOPS */ int syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, inode_t *inode, - struct iatt *iatt, dict_t *xattr, struct iatt *parent) + struct iatt *iatt, dict_t *xdata, struct iatt *parent) { struct syncargs *args = NULL; @@ -304,8 +955,8 @@ syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, if (op_ret == 0) { args->iatt1 = *iatt; args->iatt2 = *parent; - if (xattr) - args->xattr = dict_ref (xattr); + if (xdata) + args->xdata = dict_ref (xdata); } __wake (args); @@ -315,22 +966,22 @@ syncop_lookup_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int -syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req, - struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent) +syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xdata_req, + struct iatt *iatt, dict_t **xdata_rsp, struct iatt *parent) { struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_lookup_cbk, subvol->fops->lookup, - loc, xattr_req); + loc, xdata_req); if (iatt) *iatt = args.iatt1; if (parent) *parent = args.iatt2; - if (xattr_rsp) - *xattr_rsp = args.xattr; - else if (args.xattr) - dict_unref (args.xattr); + if (xdata_rsp) + *xdata_rsp = args.xdata; + else if (args.xdata) + dict_unref (args.xdata); errno = args.op_errno; return args.op_ret; @@ -348,6 +999,8 @@ entry_copy (gf_dirent_t *source) sink->d_type = source->d_type; sink->d_stat = source->d_stat; + if (source->inode) + sink->inode = inode_ref (source->inode); return sink; } @@ -357,7 +1010,7 @@ syncop_readdirp_cbk (call_frame_t *frame, xlator_t *this, int32_t op_ret, int32_t op_errno, - gf_dirent_t *entries) + gf_dirent_t *entries, dict_t *xdata) { struct syncargs *args = NULL; gf_dirent_t *entry = NULL; @@ -412,12 +1065,71 @@ syncop_readdirp (xlator_t *subvol, } int32_t +syncop_readdir_cbk (call_frame_t *frame, + void *cookie, + xlator_t *this, + int32_t op_ret, + int32_t op_errno, + gf_dirent_t *entries, dict_t *xdata) +{ + struct syncargs *args = NULL; + gf_dirent_t *entry = NULL; + gf_dirent_t *tmp = NULL; + + int count = 0; + + args = cookie; + + INIT_LIST_HEAD (&args->entries.list); + + args->op_ret = op_ret; + args->op_errno = op_errno; + + if (op_ret >= 0) { + list_for_each_entry (entry, &entries->list, list) { + tmp = entry_copy (entry); + gf_log (this->name, GF_LOG_TRACE, + "adding entry=%s, count=%d", + tmp->d_name, count); + list_add_tail (&tmp->list, &(args->entries.list)); + count++; + } + } + + __wake (args); + + return 0; + +} + +int +syncop_readdir (xlator_t *subvol, + fd_t *fd, + size_t size, + off_t off, + gf_dirent_t *entries) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_readdir_cbk, subvol->fops->readdir, + fd, size, off, NULL); + + if (entries) + list_splice_init (&args.entries.list, &entries->list); + /* TODO: need to free all the 'args.entries' in 'else' case */ + + errno = args.op_errno; + return args.op_ret; + +} + +int32_t syncop_opendir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - fd_t *fd) + fd_t *fd, dict_t *xdata) { struct syncargs *args = NULL; @@ -439,7 +1151,7 @@ syncop_opendir (xlator_t *subvol, struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_opendir_cbk, subvol->fops->opendir, - loc, fd); + loc, fd, NULL); errno = args.op_errno; return args.op_ret; @@ -447,8 +1159,36 @@ syncop_opendir (xlator_t *subvol, } int +syncop_fsyncdir_cbk (call_frame_t *frame, void* cookie, xlator_t *this, + int op_ret, int op_errno, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; +} + +int +syncop_fsyncdir (xlator_t *subvol, fd_t *fd, int datasync) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_fsyncdir_cbk, subvol->fops->fsyncdir, + fd, datasync, NULL); + + errno = args.op_errno; + return args.op_ret; +} + +int syncop_removexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno) + int op_ret, int op_errno, dict_t *xdata) { struct syncargs *args = NULL; @@ -468,7 +1208,7 @@ syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_removexattr_cbk, subvol->fops->removexattr, - loc, name); + loc, name, NULL); errno = args.op_errno; return args.op_ret; @@ -476,7 +1216,7 @@ syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name) int syncop_fremovexattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno) + int op_ret, int op_errno, dict_t *xdata) { struct syncargs *args = NULL; @@ -496,7 +1236,7 @@ syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_fremovexattr_cbk, - subvol->fops->fremovexattr, fd, name); + subvol->fops->fremovexattr, fd, name, NULL); errno = args.op_errno; return args.op_ret; @@ -504,7 +1244,7 @@ syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name) int syncop_setxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno) + int op_ret, int op_errno, dict_t *xdata) { struct syncargs *args = NULL; @@ -525,7 +1265,7 @@ syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_setxattr_cbk, subvol->fops->setxattr, - loc, dict, flags); + loc, dict, flags, NULL); errno = args.op_errno; return args.op_ret; @@ -533,7 +1273,7 @@ syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags) int syncop_fsetxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno) + int op_ret, int op_errno, dict_t *xdata) { struct syncargs *args = NULL; @@ -554,7 +1294,7 @@ syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_fsetxattr_cbk, subvol->fops->fsetxattr, - fd, dict, flags); + fd, dict, flags, NULL); errno = args.op_errno; return args.op_ret; @@ -562,7 +1302,7 @@ syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags) int syncop_getxattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int op_ret, int op_errno, dict_t *dict) + int op_ret, int op_errno, dict_t *dict, dict_t *xdata) { struct syncargs *args = NULL; @@ -584,7 +1324,7 @@ syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr, - loc, NULL); + loc, NULL, NULL); if (dict) *dict = args.xattr; @@ -601,7 +1341,7 @@ syncop_getxattr (xlator_t *subvol, loc_t *loc, dict_t **dict, const char *key) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->getxattr, - loc, key); + loc, key, NULL); if (dict) *dict = args.xattr; @@ -618,7 +1358,7 @@ syncop_fgetxattr (xlator_t *subvol, fd_t *fd, dict_t **dict, const char *key) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_getxattr_cbk, subvol->fops->fgetxattr, - fd, key); + fd, key, NULL); if (dict) *dict = args.xattr; @@ -632,7 +1372,7 @@ syncop_fgetxattr (xlator_t *subvol, fd_t *fd, dict_t **dict, const char *key) int syncop_statfs_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct statvfs *buf) + struct statvfs *buf, dict_t *xdata) { struct syncargs *args = NULL; @@ -659,7 +1399,7 @@ syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_statfs_cbk, subvol->fops->statfs, - loc); + loc, NULL); if (buf) *buf = args.statvfs_buf; @@ -671,7 +1411,7 @@ syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf) int syncop_setattr_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, - struct iatt *preop, struct iatt *postop) + struct iatt *preop, struct iatt *postop, dict_t *xdata) { struct syncargs *args = NULL; @@ -698,7 +1438,7 @@ syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid, struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->setattr, - loc, iatt, valid); + loc, iatt, valid, NULL); if (preop) *preop = args.iatt1; @@ -717,7 +1457,7 @@ syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid, struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_setattr_cbk, subvol->fops->fsetattr, - fd, iatt, valid); + fd, iatt, valid, NULL); if (preop) *preop = args.iatt1; @@ -731,7 +1471,7 @@ syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid, int32_t syncop_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, fd_t *fd) + int32_t op_ret, int32_t op_errno, fd_t *fd, dict_t *xdata) { struct syncargs *args = NULL; @@ -740,9 +1480,6 @@ syncop_open_cbk (call_frame_t *frame, void *cookie, xlator_t *this, args->op_ret = op_ret; args->op_errno = op_errno; - if (op_ret != -1) - fd_ref (fd); - __wake (args); return 0; @@ -754,7 +1491,7 @@ syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_open_cbk, subvol->fops->open, - loc, flags, fd, 0); + loc, flags, fd, NULL); errno = args.op_errno; return args.op_ret; @@ -765,7 +1502,8 @@ syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd) int32_t syncop_readv_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, struct iovec *vector, - int32_t count, struct iatt *stbuf, struct iobref *iobref) + int32_t count, struct iatt *stbuf, struct iobref *iobref, + dict_t *xdata) { struct syncargs *args = NULL; @@ -797,11 +1535,14 @@ syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off, struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_readv_cbk, subvol->fops->readv, - fd, size, off, flags); + fd, size, off, flags, NULL); + + if (args.op_ret < 0) + goto out; if (vector) *vector = args.vector; - else if (args.vector) + else GF_FREE (args.vector); if (count) @@ -813,6 +1554,7 @@ syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off, else if (args.iobref) iobref_unref (args.iobref); +out: errno = args.op_errno; return args.op_ret; @@ -821,7 +1563,7 @@ syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off, int syncop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, - struct iatt *postbuf) + struct iatt *postbuf, dict_t *xdata) { struct syncargs *args = NULL; @@ -836,14 +1578,15 @@ syncop_writev_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } int -syncop_writev (xlator_t *subvol, fd_t *fd, struct iovec *vector, +syncop_writev (xlator_t *subvol, fd_t *fd, const struct iovec *vector, int32_t count, off_t offset, struct iobref *iobref, uint32_t flags) { struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev, - fd, vector, count, offset, flags, iobref); + fd, (struct iovec *) vector, count, offset, flags, iobref, + NULL); errno = args.op_errno; return args.op_ret; @@ -859,7 +1602,7 @@ int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size, vec.iov_base = (void *)buf; SYNCOP (subvol, (&args), syncop_writev_cbk, subvol->fops->writev, - fd, &vec, 1, offset, flags, iobref); + fd, &vec, 1, offset, flags, iobref, NULL); errno = args.op_errno; return args.op_ret; @@ -878,7 +1621,7 @@ int32_t syncop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, fd_t *fd, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { struct syncargs *args = NULL; @@ -887,8 +1630,8 @@ syncop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, args->op_ret = op_ret; args->op_errno = op_errno; - if (op_ret != -1) - fd_ref (fd); + if (buf) + args->iatt1 = *buf; __wake (args); @@ -897,14 +1640,17 @@ syncop_create_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode, - fd_t *fd, dict_t *dict) + fd_t *fd, dict_t *xdata, struct iatt *iatt) { struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_create_cbk, subvol->fops->create, - loc, flags, mode, fd, dict); + loc, flags, mode, 0, fd, xdata); errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + return args.op_ret; } @@ -912,7 +1658,7 @@ syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode, int syncop_unlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { struct syncargs *args = NULL; @@ -931,16 +1677,114 @@ syncop_unlink (xlator_t *subvol, loc_t *loc) { struct syncargs args = {0, }; - SYNCOP (subvol, (&args), syncop_unlink_cbk, subvol->fops->unlink, loc); + SYNCOP (subvol, (&args), syncop_unlink_cbk, subvol->fops->unlink, loc, + 0, NULL); errno = args.op_errno; return args.op_ret; } int +syncop_rmdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; +} + +int +syncop_rmdir (xlator_t *subvol, loc_t *loc) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_rmdir_cbk, subvol->fops->rmdir, loc, + 0, NULL); + + errno = args.op_errno; + return args.op_ret; +} + + +int +syncop_link_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; +} + + +int +syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_link_cbk, subvol->fops->link, + oldloc, newloc, NULL); + + errno = args.op_errno; + + return args.op_ret; +} + + +int +syncop_rename_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, struct iatt *buf, + struct iatt *preoldparent, struct iatt *postoldparent, + struct iatt *prenewparent, struct iatt *postnewparent, + dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; +} + + +int +syncop_rename (xlator_t *subvol, loc_t *oldloc, loc_t *newloc) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_rename_cbk, subvol->fops->rename, + oldloc, newloc, NULL); + + errno = args.op_errno; + + return args.op_ret; +} + + +int syncop_ftruncate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, struct iatt *prebuf, - struct iatt *postbuf) + struct iatt *postbuf, dict_t *xdata) { struct syncargs *args = NULL; @@ -960,7 +1804,7 @@ syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->ftruncate, - fd, offset); + fd, offset, NULL); errno = args.op_errno; return args.op_ret; @@ -972,7 +1816,7 @@ syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_ftruncate_cbk, subvol->fops->truncate, - loc, offset); + loc, offset, NULL); errno = args.op_errno; return args.op_ret; @@ -981,7 +1825,7 @@ syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset) int syncop_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, - struct iatt *prebuf, struct iatt *postbuf) + struct iatt *prebuf, struct iatt *postbuf, dict_t *xdata) { struct syncargs *args = NULL; @@ -997,12 +1841,43 @@ syncop_fsync_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } int -syncop_fsync (xlator_t *subvol, fd_t *fd) +syncop_fsync (xlator_t *subvol, fd_t *fd, int dataonly) { struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_fsync_cbk, subvol->fops->fsync, - fd, 0); + fd, dataonly, NULL); + + errno = args.op_errno; + return args.op_ret; + +} + + +int +syncop_flush_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; + +} + +int +syncop_flush (xlator_t *subvol, fd_t *fd) +{ + struct syncargs args = {0}; + + SYNCOP (subvol, (&args), syncop_flush_cbk, subvol->fops->flush, + fd, NULL); errno = args.op_errno; return args.op_ret; @@ -1011,7 +1886,7 @@ syncop_fsync (xlator_t *subvol, fd_t *fd) int syncop_fstat_cbk (call_frame_t *frame, void *cookie, xlator_t *this, - int32_t op_ret, int32_t op_errno, struct iatt *stbuf) + int32_t op_ret, int32_t op_errno, struct iatt *stbuf, dict_t *xdata) { struct syncargs *args = NULL; @@ -1034,7 +1909,7 @@ syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->fstat, - fd); + fd, NULL); if (stbuf) *stbuf = args.iatt1; @@ -1050,7 +1925,7 @@ syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_fstat_cbk, subvol->fops->stat, - loc); + loc, NULL); if (stbuf) *stbuf = args.iatt1; @@ -1064,7 +1939,7 @@ int32_t syncop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { struct syncargs *args = NULL; @@ -1072,6 +1947,8 @@ syncop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, args->op_ret = op_ret; args->op_errno = op_errno; + if (buf) + args->iatt1 = *buf; __wake (args); @@ -1079,14 +1956,18 @@ syncop_symlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, } int -syncop_symlink (xlator_t *subvol, loc_t *loc, char *newpath, dict_t *dict) +syncop_symlink (xlator_t *subvol, loc_t *loc, const char *newpath, dict_t *dict, + struct iatt *iatt) { struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_symlink_cbk, subvol->fops->symlink, - newpath, loc, dict); + newpath, loc, 0, dict); errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + return args.op_ret; } @@ -1094,7 +1975,7 @@ syncop_symlink (xlator_t *subvol, loc_t *loc, char *newpath, dict_t *dict) int syncop_readlink_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int op_ret, int op_errno, const char *path, - struct iatt *stbuf) + struct iatt *stbuf, dict_t *xdata) { struct syncargs *args = NULL; @@ -1117,12 +1998,11 @@ syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size) struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_readlink_cbk, subvol->fops->readlink, - loc, size); + loc, size, NULL); if (buffer) *buffer = args.buffer; - else if (args.buffer) - GF_FREE (args.buffer); + else GF_FREE (args.buffer); errno = args.op_errno; return args.op_ret; @@ -1132,7 +2012,7 @@ int syncop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int32_t op_ret, int32_t op_errno, inode_t *inode, struct iatt *buf, struct iatt *preparent, - struct iatt *postparent) + struct iatt *postparent, dict_t *xdata) { struct syncargs *args = NULL; @@ -1141,6 +2021,9 @@ syncop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, args->op_ret = op_ret; args->op_errno = op_errno; + if (buf) + args->iatt1 = *buf; + __wake (args); return 0; @@ -1148,14 +2031,207 @@ syncop_mknod_cbk (call_frame_t *frame, void *cookie, xlator_t *this, int syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev, - dict_t *dict) + dict_t *dict, struct iatt *iatt) { struct syncargs args = {0, }; SYNCOP (subvol, (&args), syncop_mknod_cbk, subvol->fops->mknod, - loc, mode, rdev, dict); + loc, mode, rdev, 0, dict); errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + return args.op_ret; } + + +int +syncop_mkdir_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, inode_t *inode, + struct iatt *buf, struct iatt *preparent, + struct iatt *postparent, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + if (buf) + args->iatt1 = *buf; + + __wake (args); + + return 0; +} + + +int +syncop_mkdir (xlator_t *subvol, loc_t *loc, mode_t mode, dict_t *dict, + struct iatt *iatt) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_mkdir_cbk, subvol->fops->mkdir, + loc, mode, 0, dict); + + errno = args.op_errno; + if (iatt) + *iatt = args.iatt1; + + return args.op_ret; + +} + +int +syncop_access_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int32_t op_ret, int32_t op_errno, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + __wake (args); + + return 0; +} + +int +syncop_access (xlator_t *subvol, loc_t *loc, int32_t mask) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_access_cbk, subvol->fops->access, + loc, mask, NULL); + + errno = args.op_errno; + return args.op_ret; +} + + +int +syncop_fallocate_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; +} + +int +syncop_fallocate(xlator_t *subvol, fd_t *fd, int32_t keep_size, off_t offset, + size_t len) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_fallocate_cbk, subvol->fops->fallocate, + fd, keep_size, offset, len, NULL); + + errno = args.op_errno; + return args.op_ret; +} + + +int +syncop_discard_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; +} + +int +syncop_discard(xlator_t *subvol, fd_t *fd, off_t offset, size_t len) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_discard_cbk, subvol->fops->discard, + fd, offset, len, NULL); + + errno = args.op_errno; + return args.op_ret; +} + +int +syncop_zerofill_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct iatt *prebuf, + struct iatt *postbuf, dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + + __wake (args); + + return 0; +} + +int +syncop_zerofill(xlator_t *subvol, fd_t *fd, off_t offset, size_t len) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_zerofill_cbk, subvol->fops->zerofill, + fd, offset, len, NULL); + + errno = args.op_errno; + return args.op_ret; +} + + +int +syncop_lk_cbk (call_frame_t *frame, void *cookie, xlator_t *this, + int op_ret, int op_errno, struct gf_flock *flock, + dict_t *xdata) +{ + struct syncargs *args = NULL; + + args = cookie; + + args->op_ret = op_ret; + args->op_errno = op_errno; + if (flock) + args->flock = *flock; + __wake (args); + + return 0; +} + + +int +syncop_lk (xlator_t *subvol, fd_t *fd, int cmd, struct gf_flock *flock) +{ + struct syncargs args = {0, }; + + SYNCOP (subvol, (&args), syncop_lk_cbk, subvol->fops->lk, + fd, cmd, flock, NULL); + + errno = args.op_errno; + *flock = args.flock; + + return args.op_ret; +} |
