/* Copyright (c) 2008-2012 Red Hat, Inc. This file is part of GlusterFS. 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 _SYNCOP_H #define _SYNCOP_H #ifndef _CONFIG_H #define _CONFIG_H #include "config.h" #endif #include "xlator.h" #include #include #include #define SYNCENV_PROC_MAX 16 #define SYNCENV_PROC_MIN 2 struct synctask; struct syncproc; struct syncenv; typedef int (*synctask_cbk_t) (int ret, call_frame_t *frame, void *opaque); typedef int (*synctask_fn_t) (void *opaque); typedef enum { SYNCTASK_INIT = 0, SYNCTASK_RUN, SYNCTASK_SUSPEND, SYNCTASK_WAIT, SYNCTASK_DONE, } synctask_state_t; /* for one sequential execution of @syncfn */ struct synctask { struct list_head all_tasks; struct syncenv *env; xlator_t *xl; call_frame_t *frame; call_frame_t *opframe; synctask_cbk_t synccbk; synctask_fn_t syncfn; synctask_state_t state; void *opaque; void *stack; int woken; int slept; int ret; ucontext_t ctx; struct syncproc *proc; pthread_mutex_t mutex; /* for synchronous spawning of synctask */ pthread_cond_t cond; int done; }; struct syncproc { pthread_t processor; ucontext_t sched; struct syncenv *env; struct synctask *current; }; /* hosts the scheduler thread and framework for executing synctasks */ struct syncenv { struct syncproc proc[SYNCENV_PROC_MAX]; int procs; struct list_head runq; int runcount; struct list_head waitq; int waitcount; pthread_mutex_t mutex; pthread_cond_t cond; size_t stacksize; }; struct syncargs { int op_ret; int op_errno; struct iatt iatt1; struct iatt iatt2; dict_t *xattr; gf_dirent_t entries; struct statvfs statvfs_buf; struct iovec *vector; int count; struct iobref *iobref; char *buffer; dict_t *xdata; /* some more _cbk needs */ uuid_t uuid; char *errstr; dict_t *dict; /* do not touch */ struct synctask *task; }; #define __wake(args) synctask_wake(args->task) #define SYNCOP(subvol, stb, cbk, op, params ...) do { \ struct synctask *task = NULL; \ \ task = synctask_get (); \ stb->task = task; \ \ STACK_WIND_COOKIE (task->opframe, cbk, (void *)stb, \ subvol, op, params); \ task->state = SYNCTASK_SUSPEND; \ synctask_yield (stb->task); \ STACK_RESET (task->opframe->root); \ } while (0) #define SYNCENV_DEFAULT_STACKSIZE (2 * 1024 * 1024) struct syncenv * syncenv_new (); void syncenv_destroy (struct syncenv *); void syncenv_scale (struct syncenv *env); int synctask_new (struct syncenv *, synctask_fn_t, synctask_cbk_t, call_frame_t* frame, void *); void synctask_wake (struct synctask *task); void synctask_yield (struct synctask *task); int syncop_lookup (xlator_t *subvol, loc_t *loc, dict_t *xattr_req, /* out */ struct iatt *iatt, dict_t **xattr_rsp, struct iatt *parent); int syncop_readdirp (xlator_t *subvol, fd_t *fd, size_t size, off_t off, dict_t *dict, /* out */ gf_dirent_t *entries); int syncop_readdir (xlator_t *subvol, fd_t *fd, size_t size, off_t off, gf_dirent_t *entries); int syncop_opendir (xlator_t *subvol, loc_t *loc, fd_t *fd); int syncop_setattr (xlator_t *subvol, loc_t *loc, struct iatt *iatt, int valid, /* out */ struct iatt *preop, struct iatt *postop); int syncop_fsetattr (xlator_t *subvol, fd_t *fd, struct iatt *iatt, int valid, /* out */ struct iatt *preop, struct iatt *postop); int syncop_statfs (xlator_t *subvol, loc_t *loc, struct statvfs *buf); int syncop_setxattr (xlator_t *subvol, loc_t *loc, dict_t *dict, int32_t flags); int syncop_fsetxattr (xlator_t *subvol, fd_t *fd, dict_t *dict, int32_t flags); int syncop_listxattr (xlator_t *subvol, loc_t *loc, dict_t **dict); int syncop_getxattr (xlator_t *xl, loc_t *loc, dict_t **dict, const char *key); int syncop_fgetxattr (xlator_t *xl, fd_t *fd, dict_t **dict, const char *key); int syncop_removexattr (xlator_t *subvol, loc_t *loc, const char *name); int syncop_fremovexattr (xlator_t *subvol, fd_t *fd, const char *name); int syncop_create (xlator_t *subvol, loc_t *loc, int32_t flags, mode_t mode, fd_t *fd, dict_t *dict); int syncop_open (xlator_t *subvol, loc_t *loc, int32_t flags, fd_t *fd); int syncop_close (fd_t *fd); int syncop_write (xlator_t *subvol, fd_t *fd, const char *buf, int size, off_t offset, struct iobref *iobref, uint32_t flags); int syncop_writev (xlator_t *subvol, fd_t *fd, struct iovec *vector, int32_t count, off_t offset, struct iobref *iobref, uint32_t flags); int syncop_readv (xlator_t *subvol, fd_t *fd, size_t size, off_t off, uint32_t flags, /* out */ struct iovec **vector, int *count, struct iobref **iobref); int syncop_ftruncate (xlator_t *subvol, fd_t *fd, off_t offset); int syncop_truncate (xlator_t *subvol, loc_t *loc, off_t offset); int syncop_unlink (xlator_t *subvol, loc_t *loc); int syncop_fsync (xlator_t *subvol, fd_t *fd); int syncop_fstat (xlator_t *subvol, fd_t *fd, struct iatt *stbuf); int syncop_stat (xlator_t *subvol, loc_t *loc, struct iatt *stbuf); int syncop_symlink (xlator_t *subvol, loc_t *loc, char *newpath, dict_t *dict); int syncop_readlink (xlator_t *subvol, loc_t *loc, char **buffer, size_t size); int syncop_mknod (xlator_t *subvol, loc_t *loc, mode_t mode, dev_t rdev, dict_t *dict); int syncop_link (xlator_t *subvol, loc_t *oldloc, loc_t *newloc); #endif /* _SYNCOP_H */