21ab4e
From bdede85bb9ac8039171857913f6818f327557176 Mon Sep 17 00:00:00 2001
21ab4e
From: Krutika Dhananjay <kdhananj@redhat.com>
21ab4e
Date: Mon, 23 Jan 2017 17:40:40 +0530
21ab4e
Subject: [PATCH 468/473] storage/posix: Execute syscalls in xattrop under
21ab4e
 different locks
21ab4e
21ab4e
        Backport of: https://review.gluster.org/16462
21ab4e
21ab4e
... and not inode->lock. This is to prevent the epoll thread from
21ab4e
*potentially* being blocked on this lock in the worst case for
21ab4e
extended period elsewhere in the brick stack, while the syscalls
21ab4e
in xattrop are being performed under the same lock by a different
21ab4e
thread. This could potentially lead to ping-timeout, if the only
21ab4e
available epoll thread is busy waiting on the inode->lock, thereby
21ab4e
preventing it from picking up the ping request from the client(s).
21ab4e
21ab4e
Also removed some unused functions.
21ab4e
21ab4e
Change-Id: Ia8acbba6d0afec75b3b49485f234c598cec6571b
21ab4e
BUG: 1415178
21ab4e
Signed-off-by: Krutika Dhananjay <kdhananj@redhat.com>
21ab4e
Reviewed-on: https://code.engineering.redhat.com/gerrit/106796
21ab4e
Reviewed-by: Raghavendra Gowdappa <rgowdapp@redhat.com>
21ab4e
---
21ab4e
 xlators/storage/posix/src/posix-handle.c  |  8 +--
21ab4e
 xlators/storage/posix/src/posix-helpers.c | 85 ++++++++++++++++++++++++-------
21ab4e
 xlators/storage/posix/src/posix.c         | 36 ++++++++-----
21ab4e
 xlators/storage/posix/src/posix.h         | 18 ++++++-
21ab4e
 4 files changed, 111 insertions(+), 36 deletions(-)
21ab4e
21ab4e
diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c
21ab4e
index c8524a6..ef56d10 100644
21ab4e
--- a/xlators/storage/posix/src/posix-handle.c
21ab4e
+++ b/xlators/storage/posix/src/posix-handle.c
21ab4e
@@ -952,6 +952,7 @@ posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid, char *real_path,
21ab4e
         inode_t               *inode       = NULL;
21ab4e
         struct stat            stbuf       = {0,};
21ab4e
         struct posix_private  *priv        = NULL;
21ab4e
+        posix_inode_ctx_t     *ctx         = NULL;
21ab4e
 
21ab4e
         priv = this->private;
21ab4e
 
21ab4e
@@ -973,11 +974,11 @@ posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid, char *real_path,
21ab4e
 
21ab4e
                 LOCK (&inode->lock);
21ab4e
                 {
21ab4e
-                        ret = __inode_ctx_get0 (inode, this, &ctx_int);
21ab4e
+                        ret = __posix_inode_ctx_get_all (inode, this, &ctx;;
21ab4e
                         if (ret)
21ab4e
                                 goto unlock;
21ab4e
 
21ab4e
-                        if (ctx_int != GF_UNLINK_TRUE)
21ab4e
+                        if (ctx->unlink_flag != GF_UNLINK_TRUE)
21ab4e
                                 goto unlock;
21ab4e
 
21ab4e
                         POSIX_GET_FILE_UNLINK_PATH (priv->base_path, gfid,
21ab4e
@@ -997,7 +998,8 @@ posix_create_link_if_gfid_exists (xlator_t *this, uuid_t gfid, char *real_path,
21ab4e
                                 goto unlock;
21ab4e
                         }
21ab4e
                         ctx_int = GF_UNLINK_FALSE;
21ab4e
-                        ret = __inode_ctx_set0 (inode, this, &ctx_int);
21ab4e
+                        ret = __posix_inode_ctx_set_unlink_flag (inode, this,
21ab4e
+                                                                 ctx_int);
21ab4e
                 }
21ab4e
 unlock:
21ab4e
                 UNLOCK (&inode->lock);
21ab4e
diff --git a/xlators/storage/posix/src/posix-helpers.c b/xlators/storage/posix/src/posix-helpers.c
21ab4e
index 72f76c0..c09cecf 100644
21ab4e
--- a/xlators/storage/posix/src/posix-helpers.c
21ab4e
+++ b/xlators/storage/posix/src/posix-helpers.c
21ab4e
@@ -2270,39 +2270,88 @@ posix_fdget_objectsignature (int fd, dict_t *xattr)
21ab4e
         return -EINVAL;
21ab4e
 }
21ab4e
 
21ab4e
+posix_inode_ctx_t *
21ab4e
+__posix_inode_ctx_get (inode_t *inode, xlator_t *this)
21ab4e
+{
21ab4e
+        int                 ret      = -1;
21ab4e
+        uint64_t            ctx_uint = 0;
21ab4e
+        posix_inode_ctx_t  *ctx_p    = NULL;
21ab4e
+
21ab4e
+        ret = __inode_ctx_get (inode, this, &ctx_uint);
21ab4e
+        if (ret == 0) {
21ab4e
+                return (posix_inode_ctx_t *)ctx_uint;
21ab4e
+        }
21ab4e
+
21ab4e
+        ctx_p = GF_CALLOC (1, sizeof (*ctx_p), gf_posix_mt_inode_ctx_t);
21ab4e
+        if (!ctx_p)
21ab4e
+                return NULL;
21ab4e
+
21ab4e
+        pthread_mutex_init (&ctx_p->xattrop_lock, NULL);
21ab4e
+
21ab4e
+        ret = __inode_ctx_set (inode, this, (uint64_t *)&ctx_p);
21ab4e
+        if (ret < 0) {
21ab4e
+                pthread_mutex_destroy (&ctx_p->xattrop_lock);
21ab4e
+                GF_FREE (ctx_p);
21ab4e
+                return NULL;
21ab4e
+        }
21ab4e
+
21ab4e
+        return ctx_p;
21ab4e
+}
21ab4e
 
21ab4e
 int
21ab4e
-posix_inode_ctx_get (inode_t *inode, xlator_t *this, uint64_t *ctx)
21ab4e
+__posix_inode_ctx_set_unlink_flag (inode_t *inode, xlator_t *this, uint64_t ctx)
21ab4e
 {
21ab4e
-        int             ret     = -1;
21ab4e
-        uint64_t        ctx_int = 0;
21ab4e
+        posix_inode_ctx_t  *ctx_p    = NULL;
21ab4e
 
21ab4e
-        GF_VALIDATE_OR_GOTO (this->name, this, out);
21ab4e
-        GF_VALIDATE_OR_GOTO (this->name, inode, out);
21ab4e
+        ctx_p = __posix_inode_ctx_get (inode, this);
21ab4e
+        if (ctx_p == NULL)
21ab4e
+                return -1;
21ab4e
 
21ab4e
-        ret = inode_ctx_get (inode, this, &ctx_int);
21ab4e
+        ctx_p->unlink_flag = ctx;
21ab4e
 
21ab4e
-        if (ret)
21ab4e
-                return ret;
21ab4e
+        return 0;
21ab4e
+}
21ab4e
 
21ab4e
-        if (ctx)
21ab4e
-                *ctx = ctx_int;
21ab4e
+int
21ab4e
+posix_inode_ctx_set_unlink_flag (inode_t *inode, xlator_t *this, uint64_t ctx)
21ab4e
+{
21ab4e
+        int             ret = -1;
21ab4e
+
21ab4e
+        LOCK(&inode->lock);
21ab4e
+        {
21ab4e
+                ret = __posix_inode_ctx_set_unlink_flag (inode, this, ctx);
21ab4e
+        }
21ab4e
+        UNLOCK(&inode->lock);
21ab4e
 
21ab4e
-out:
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
+int
21ab4e
+__posix_inode_ctx_get_all (inode_t *inode, xlator_t *this,
21ab4e
+                           posix_inode_ctx_t **ctx)
21ab4e
+{
21ab4e
+        posix_inode_ctx_t  *ctx_p    = NULL;
21ab4e
+
21ab4e
+        ctx_p = __posix_inode_ctx_get (inode, this);
21ab4e
+        if (ctx_p == NULL)
21ab4e
+                return -1;
21ab4e
+
21ab4e
+        *ctx = ctx_p;
21ab4e
+
21ab4e
+        return 0;
21ab4e
+}
21ab4e
 
21ab4e
 int
21ab4e
-posix_inode_ctx_set (inode_t *inode, xlator_t *this, uint64_t ctx)
21ab4e
+posix_inode_ctx_get_all (inode_t *inode, xlator_t *this,
21ab4e
+                         posix_inode_ctx_t **ctx)
21ab4e
 {
21ab4e
-        int             ret = -1;
21ab4e
+        int ret = 0;
21ab4e
 
21ab4e
-        GF_VALIDATE_OR_GOTO (this->name, this, out);
21ab4e
-        GF_VALIDATE_OR_GOTO (this->name, inode, out);
21ab4e
-        GF_VALIDATE_OR_GOTO (this->name, ctx, out);
21ab4e
+        LOCK(&inode->lock);
21ab4e
+        {
21ab4e
+                ret = __posix_inode_ctx_get_all (inode, this, ctx);
21ab4e
+        }
21ab4e
+        UNLOCK(&inode->lock);
21ab4e
 
21ab4e
-        ret = inode_ctx_set (inode, this, &ctx;;
21ab4e
-out:
21ab4e
         return ret;
21ab4e
 }
21ab4e
diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c
21ab4e
index afd0ff8..7eaf98b 100644
21ab4e
--- a/xlators/storage/posix/src/posix.c
21ab4e
+++ b/xlators/storage/posix/src/posix.c
21ab4e
@@ -108,19 +108,21 @@ out:
21ab4e
 int
21ab4e
 posix_forget (xlator_t *this, inode_t *inode)
21ab4e
 {
21ab4e
-        uint64_t tmp_cache = 0;
21ab4e
-        int ret = 0;
21ab4e
-        char *unlink_path = NULL;
21ab4e
-        struct posix_private    *priv_posix = NULL;
21ab4e
+        int                     ret         = 0;
21ab4e
+        char                   *unlink_path = NULL;
21ab4e
+        uint64_t                ctx_uint    = 0;
21ab4e
+        posix_inode_ctx_t      *ctx         = NULL;
21ab4e
+        struct posix_private   *priv_posix  = NULL;
21ab4e
 
21ab4e
         priv_posix = (struct posix_private *) this->private;
21ab4e
 
21ab4e
-        ret = inode_ctx_del (inode, this, &tmp_cache);
21ab4e
-        if (ret < 0) {
21ab4e
-                ret = 0;
21ab4e
-                goto out;
21ab4e
-        }
21ab4e
-        if (tmp_cache == GF_UNLINK_TRUE) {
21ab4e
+        ret = inode_ctx_del (inode, this, &ctx_uint);
21ab4e
+        if (!ctx_uint)
21ab4e
+                return 0;
21ab4e
+
21ab4e
+        ctx = (posix_inode_ctx_t *)ctx_uint;
21ab4e
+
21ab4e
+        if (ctx->unlink_flag == GF_UNLINK_TRUE) {
21ab4e
                 POSIX_GET_FILE_UNLINK_PATH(priv_posix->base_path,
21ab4e
                                            inode->gfid, unlink_path);
21ab4e
                 if (!unlink_path) {
21ab4e
@@ -134,6 +136,8 @@ posix_forget (xlator_t *this, inode_t *inode)
21ab4e
                 ret = sys_unlink(unlink_path);
21ab4e
         }
21ab4e
 out:
21ab4e
+        pthread_mutex_destroy (&ctx->xattrop_lock);
21ab4e
+        GF_FREE (ctx);
21ab4e
         return ret;
21ab4e
 }
21ab4e
 
21ab4e
@@ -1696,7 +1700,7 @@ posix_add_unlink_to_ctx (inode_t *inode, xlator_t *this, char *unlink_path)
21ab4e
         }
21ab4e
 
21ab4e
         ctx = GF_UNLINK_TRUE;
21ab4e
-        ret = posix_inode_ctx_set (inode, this, ctx);
21ab4e
+        ret = posix_inode_ctx_set_unlink_flag (inode, this, ctx);
21ab4e
         if (ret < 0) {
21ab4e
                 goto out;
21ab4e
         }
21ab4e
@@ -5426,6 +5430,7 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
21ab4e
         inode_t              *inode    = NULL;
21ab4e
         xlator_t             *this     = NULL;
21ab4e
         posix_xattr_filler_t *filler   = NULL;
21ab4e
+        posix_inode_ctx_t    *ctx      = NULL;
21ab4e
 
21ab4e
         filler = tmp;
21ab4e
 
21ab4e
@@ -5448,8 +5453,13 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
21ab4e
                 }
21ab4e
         }
21ab4e
 #endif
21ab4e
+        op_ret = posix_inode_ctx_get_all (inode, this, &ctx;;
21ab4e
+        if (op_ret < 0) {
21ab4e
+                op_errno = ENOMEM;
21ab4e
+                goto out;
21ab4e
+        }
21ab4e
 
21ab4e
-        LOCK (&inode->lock);
21ab4e
+        pthread_mutex_lock (&ctx->xattrop_lock);
21ab4e
         {
21ab4e
                 if (filler->real_path) {
21ab4e
                         size = sys_lgetxattr (filler->real_path, k,
21ab4e
@@ -5558,7 +5568,7 @@ _posix_handle_xattr_keyvalue_pair (dict_t *d, char *k, data_t *v,
21ab4e
                 op_errno = errno;
21ab4e
         }
21ab4e
 unlock:
21ab4e
-        UNLOCK (&inode->lock);
21ab4e
+        pthread_mutex_unlock (&ctx->xattrop_lock);
21ab4e
 
21ab4e
         if (op_ret == -1)
21ab4e
                 goto out;
21ab4e
diff --git a/xlators/storage/posix/src/posix.h b/xlators/storage/posix/src/posix.h
21ab4e
index 6fd32c1..fb63004 100644
21ab4e
--- a/xlators/storage/posix/src/posix.h
21ab4e
+++ b/xlators/storage/posix/src/posix.h
21ab4e
@@ -190,6 +190,11 @@ typedef struct {
21ab4e
         int32_t     op_errno;
21ab4e
 } posix_xattr_filler_t;
21ab4e
 
21ab4e
+typedef struct {
21ab4e
+        uint64_t unlink_flag;
21ab4e
+        pthread_mutex_t xattrop_lock;
21ab4e
+} posix_inode_ctx_t;
21ab4e
+
21ab4e
 #define POSIX_BASE_PATH(this) (((struct posix_private *)this->private)->base_path)
21ab4e
 
21ab4e
 #define POSIX_BASE_PATH_LEN(this) (((struct posix_private *)this->private)->base_path_length)
21ab4e
@@ -217,8 +222,17 @@ typedef struct {
21ab4e
 
21ab4e
 
21ab4e
 /* Helper functions */
21ab4e
-int posix_inode_ctx_get (inode_t *inode, xlator_t *this, uint64_t *ctx);
21ab4e
-int posix_inode_ctx_set (inode_t *inode, xlator_t *this, uint64_t ctx);
21ab4e
+int posix_inode_ctx_set_unlink_flag (inode_t *inode, xlator_t *this,
21ab4e
+                                     uint64_t ctx);
21ab4e
+
21ab4e
+int posix_inode_ctx_get_all (inode_t *inode, xlator_t *this,
21ab4e
+                             posix_inode_ctx_t **ctx);
21ab4e
+
21ab4e
+int __posix_inode_ctx_set_unlink_flag (inode_t *inode, xlator_t *this,
21ab4e
+                                       uint64_t ctx);
21ab4e
+
21ab4e
+int __posix_inode_ctx_get_all (inode_t *inode, xlator_t *this,
21ab4e
+                               posix_inode_ctx_t **ctx);
21ab4e
 
21ab4e
 int posix_gfid_set (xlator_t *this, const char *path, loc_t *loc,
21ab4e
                     dict_t *xattr_req);
21ab4e
-- 
21ab4e
1.8.3.1
21ab4e