From be857905a86c39ca62b1435328b38f50627afbb5 Mon Sep 17 00:00:00 2001 From: Prasanna Kumar Kalever Date: Thu, 16 Feb 2017 19:20:37 +0530 Subject: meta: thread safe GB_METAUPDATE_OR_GOTO GB_METAUPDATE_OR_GOTO used an already opened glfs fd to update the meta data, since we have mpath number of threads writing to the same metadata file simultaneously, this will lead to thread concurrency and data consistency issues. Hence this patch protects GB_METAUPDATE_OR_GOTO with a lock and removes fd sharing by moving glfs_creat/open and glfs_close within the MACRO. Signed-off-by: Prasanna Kumar Kalever --- utils/utils.h | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'utils/utils.h') diff --git a/utils/utils.h b/utils/utils.h index b785f8b..ca65ba9 100644 --- a/utils/utils.h +++ b/utils/utils.h @@ -51,6 +51,16 @@ # define FAILED_DELETING_FILE "failed while deleting block file from gluster volume" +# define LOCK(x) \ + do { \ + pthread_mutex_lock(&x); \ + } while (0) + +# define UNLOCK(x) \ + do { \ + pthread_mutex_unlock(&x); \ + } while (0) + # define ERROR(fmt, ...) \ do { \ fprintf(stderr, "Error: " fmt " [at %s+%d :<%s>]\n", \ @@ -92,9 +102,31 @@ } \ } while (0) -# define GB_METAUPDATE_OR_GOTO(tgmfd, fname, volume, ret, label,...)\ +# define GB_METAUPDATE_OR_GOTO(lock, glfs, fname, \ + volume, ret, label,...) \ do { \ char *write; \ + struct glfs_fd *tgmfd; \ + LOCK(lock); \ + ret = glfs_chdir (glfs, GB_METADIR); \ + if (ret) { \ + LOG("gfapi", GB_LOG_ERROR, "glfs_chdir(%s) on " \ + "volume %s failed[%s]", GB_METADIR, volume, \ + strerror(errno)); \ + UNLOCK(lock); \ + ret = -1; \ + goto label; \ + } \ + tgmfd = glfs_creat(glfs, fname, O_WRONLY | O_APPEND, \ + S_IRUSR | S_IWUSR); \ + if (!tgmfd) { \ + LOG("mgmt", GB_LOG_ERROR, "glfs_creat(%s): on " \ + "volume %s failed[%s]", fname, volume, \ + strerror(errno)); \ + UNLOCK(lock); \ + ret = -1; \ + goto label; \ + } \ if (asprintf(&write, __VA_ARGS__) < 0) { \ ret = -1; \ goto label; \ @@ -103,10 +135,20 @@ LOG("mgmt", GB_LOG_ERROR, "glfs_write(%s): on " \ "volume %s failed[%s]", fname, volume, \ strerror(errno)); \ + UNLOCK(lock); \ ret = -1; \ goto label; \ } \ GB_FREE(write); \ + if (tgmfd && glfs_close(tgmfd) != 0) { \ + LOG("mgmt", GB_LOG_ERROR, "glfs_close(%s): on " \ + "volume %s failed[%s]", fname, volume, \ + strerror(errno)); \ + UNLOCK(lock); \ + ret = -1; \ + goto label; \ + } \ + UNLOCK(lock); \ } while (0) # define GB_METAUNLOCK(lkfd, volume, ret) \ -- cgit