diff options
Diffstat (limited to 'xlators')
| -rw-r--r-- | xlators/features/marker/src/marker.c | 38 | ||||
| -rw-r--r-- | xlators/features/quota/src/quota.c | 51 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-handle.c | 53 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix-messages.h | 26 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 9 | ||||
| -rw-r--r-- | xlators/system/posix-acl/src/posix-acl.c | 58 | 
6 files changed, 165 insertions, 70 deletions
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c index a48218083d6..e731f19d350 100644 --- a/xlators/features/marker/src/marker.c +++ b/xlators/features/marker/src/marker.c @@ -2984,38 +2984,17 @@ marker_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                             int op_ret, int op_errno, gf_dirent_t *entries,                             dict_t *xdata)  { -        gf_dirent_t *entry = NULL; -        loc_t        loc    = {0, }; -        inode_t     *parent = NULL; -        int          ret    = -1; +        gf_dirent_t        *entry  = NULL; +        quota_inode_ctx_t  *ctx    = NULL; +        int                 ret    = -1;          if ((op_ret <= 0) || (entries == NULL)) {                  goto out;          }          list_for_each_entry (entry, &entries->list, list) { -                if (entry->inode == entry->inode->table->root) { -                        inode_unref (parent); -                        parent = NULL; -                } - -                if (parent) -                        _marker_inode_loc_fill (entry->inode, parent, -                                                entry->d_name, &loc); -                else -                        ret = marker_inode_loc_fill (entry->inode, &loc); - -                if (ret) { -                        gf_log (this->name, GF_LOG_WARNING, "Couldn't build " -                                "loc for %s/%s", -                                parent? uuid_utoa (parent->gfid): NULL, -                                entry->d_name); +                if (entry->inode == NULL)                          continue; -                } - -                inode_unref (parent); -                parent = inode_ref (entry->inode); -                loc_wipe (&loc);                  ret = marker_key_set_ver (this, entry->dict);                  if (ret < 0) { @@ -3023,10 +3002,13 @@ marker_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                          op_errno = ENOMEM;                          break;                  } -        } -        if (parent) -                inode_unref (parent); +                ctx = mq_inode_ctx_new (entry->inode, this); +                if (ctx == NULL) +                        gf_log (this->name, GF_LOG_WARNING, "mq_inode_ctx_new " +                                "failed for %s", +                                uuid_utoa (entry->inode->gfid)); +        }  out:          STACK_UNWIND_STRICT (readdirp, frame, op_ret, op_errno, entries, xdata); diff --git a/xlators/features/quota/src/quota.c b/xlators/features/quota/src/quota.c index 8b983715cdf..aaf9cf89d6b 100644 --- a/xlators/features/quota/src/quota.c +++ b/xlators/features/quota/src/quota.c @@ -737,13 +737,17 @@ quota_build_ancestry_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)  { -        inode_t           *parent  = NULL, *tmp_parent = NULL; -        gf_dirent_t       *entry   = NULL; -        loc_t              loc     = {0, }; -        quota_dentry_t    *dentry  = NULL, *tmp = NULL; -        quota_inode_ctx_t *ctx     = NULL; -        struct list_head   parents = {0, }; -        quota_local_t     *local   = NULL; +        inode_t           *parent       = NULL; +        inode_t           *tmp_parent   = NULL; +        inode_t           *linked_inode = NULL; +        inode_t           *tmp_inode    = NULL; +        gf_dirent_t       *entry        = NULL; +        loc_t              loc          = {0, }; +        quota_dentry_t    *dentry       = NULL; +        quota_dentry_t    *tmp          = NULL; +        quota_inode_ctx_t *ctx          = NULL; +        struct list_head   parents      = {0, }; +        quota_local_t     *local        = NULL;          INIT_LIST_HEAD (&parents); @@ -753,14 +757,6 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,          if (op_ret < 0)                  goto err; -        parent = inode_parent (local->loc.inode, 0, NULL); -        if (parent == NULL) { -                gf_msg (this->name, GF_LOG_WARNING, EINVAL, -                        Q_MSG_PARENT_NULL, "parent is NULL"); -                op_errno = EINVAL; -                goto err; -        } -          if ((op_ret > 0) && (entries != NULL)) {                  list_for_each_entry (entry, &entries->list, list) {                          if (__is_root_gfid (entry->inode->gfid)) { @@ -776,6 +772,23 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                                   */                                  tmp_parent = NULL; +                        } else { +                                /* For a non-root entry, link this inode */ +                                linked_inode = inode_link (entry->inode, +                                                           tmp_parent, +                                                           entry->d_name, +                                                           &entry->d_stat); +                                if (linked_inode) { +                                        tmp_inode = entry->inode; +                                        entry->inode = linked_inode; +                                        inode_unref (tmp_inode); +                                } else { +                                        gf_msg (this->name, GF_LOG_WARNING, +                                                EINVAL, Q_MSG_PARENT_NULL, +                                                "inode link failed"); +                                                op_errno = EINVAL; +                                                goto err; +                                }                          }                          gf_uuid_copy (loc.gfid, entry->d_stat.ia_gfid); @@ -793,6 +806,14 @@ quota_build_ancestry_cbk (call_frame_t *frame, void *cookie, xlator_t *this,                  }          } +        parent = inode_parent (local->loc.inode, 0, NULL); +        if (parent == NULL) { +                gf_msg (this->name, GF_LOG_WARNING, EINVAL, +                        Q_MSG_PARENT_NULL, "parent is NULL"); +                op_errno = EINVAL; +                goto err; +        } +          quota_inode_ctx_get (local->loc.inode, this, &ctx, 0);          quota_add_parents_from_ctx (ctx, &parents); diff --git a/xlators/storage/posix/src/posix-handle.c b/xlators/storage/posix/src/posix-handle.c index aad7db61430..d9086530322 100644 --- a/xlators/storage/posix/src/posix-handle.c +++ b/xlators/storage/posix/src/posix-handle.c @@ -35,24 +35,42 @@ inode_t *  posix_resolve (xlator_t *this, inode_table_t *itable, inode_t *parent,                 char *bname, struct iatt *iabuf)  { -        inode_t     *inode = NULL, *linked_inode = NULL; +        inode_t     *inode = NULL;          int          ret   = -1;          ret = posix_istat (this, parent->gfid, bname, iabuf); -        if (ret < 0) +        if (ret < 0) { +                gf_log (this->name, GF_LOG_WARNING, "gfid: %s, bname: %s " +                        "failed", uuid_utoa (parent->gfid), bname);                  goto out; +        } -        inode = inode_find (itable, iabuf->ia_gfid); -        if (inode == NULL) { -                inode = inode_new (itable); +        if (__is_root_gfid (iabuf->ia_gfid) && !strcmp (bname, "/")) { +                inode = itable->root; +        } else { +                inode = inode_find (itable, iabuf->ia_gfid); +                if (inode == NULL) { +                        inode = inode_new (itable); +                        gf_uuid_copy (inode->gfid, iabuf->ia_gfid); +                }          } -        linked_inode = inode_link (inode, parent, bname, iabuf); +        /* Linking an inode here, can cause a race in posix_acl. +           Parent inode gets linked here, but before +           it reaches posix_acl_readdirp_cbk, create/lookup can +           come on a leaf-inode, as parent-inode-ctx not yet updated +           in posix_acl_readdirp_cbk, create and lookup can fail +           with EACCESS. So do the inode linking in the quota xlator + +        if (__is_root_gfid (iabuf->ia_gfid) && !strcmp (bname, "/")) +                linked_inode = itable->root; +        else +                linked_inode = inode_link (inode, parent, bname, iabuf); -        inode_unref (inode); +        inode_unref (inode);*/  out: -        return linked_inode; +        return inode;  }  int @@ -72,6 +90,8 @@ posix_make_ancestral_node (const char *priv_base_path, char *path, int pathsize,          }          strcat (path, dir_name); +        if (*dir_name != '/') +                strcat (path, "/");          if (type & POSIX_ANCESTRY_DENTRY) {                  entry = gf_dirent_for_name (dir_name); @@ -132,11 +152,16 @@ posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize,                          *parent = inode_ref (itable->root);                  } -                inode = itable->root; -                memset (&iabuf, 0, sizeof (iabuf)); -                gf_uuid_copy (iabuf.ia_gfid, inode->gfid); -                iabuf.ia_type = inode->ia_type; +                inode = posix_resolve (this, itable, *parent, "/", &iabuf); +                if (!inode) { +                        gf_msg (this->name, GF_LOG_ERROR, +                                P_MSG_INODE_RESOLVE_FAILED, 0, +                                "posix resolve on the root inode %s failed", +                                uuid_utoa (gfid)); +                        *op_errno = ESTALE; +                        goto out; +                }                  ret = posix_make_ancestral_node (priv_base_path, path, pathsize,                                                   head, "/", &iabuf, inode, type, @@ -182,12 +207,14 @@ posix_make_ancestryfromgfid (xlator_t *this, char *path, int pathsize,          inode = posix_resolve (this, itable, *parent, dir_name, &iabuf);          if (inode == NULL) { +                gf_msg (this->name, GF_LOG_ERROR, P_MSG_INODE_RESOLVE_FAILED, +                        0, "posix resolve on the root inode %s failed", +                        uuid_utoa (gfid));                  *op_errno = ESTALE;                  ret = -1;                  goto out;          } -        strcat (dir_name, "/");          ret = posix_make_ancestral_node (priv_base_path, path, pathsize, head,                                           dir_name, &iabuf, inode, type, xdata);          if (*parent != NULL) { diff --git a/xlators/storage/posix/src/posix-messages.h b/xlators/storage/posix/src/posix-messages.h index 961a706cc36..4efdef0a6b9 100644 --- a/xlators/storage/posix/src/posix-messages.h +++ b/xlators/storage/posix/src/posix-messages.h @@ -45,7 +45,7 @@   */  #define POSIX_COMP_BASE         GLFS_MSGID_COMP_POSIX -#define GLFS_NUM_MESSAGES       105 +#define GLFS_NUM_MESSAGES       108  #define GLFS_MSGID_END          (POSIX_COMP_BASE + GLFS_NUM_MESSAGES + 1)  /* Messaged with message IDs */  #define glfs_msg_start_x POSIX_COMP_BASE, "Invalid: Start of messages" @@ -901,6 +901,30 @@   *   */ +#define P_MSG_SEEK_UNKOWN                       (POSIX_COMP_BASE + 106) +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ + +#define P_MSG_SEEK_FAILED                       (POSIX_COMP_BASE + 107) +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ + +#define P_MSG_INODE_RESOLVE_FAILED              (POSIX_COMP_BASE + 108) +/*! + * @messageid + * @diagnosis + * @recommendedaction + * + */ +  /*------------*/  #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index 761bc4e5946..c43029edd72 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -3753,11 +3753,18 @@ posix_links_in_same_directory (char *dirpath, int count, inode_t *leaf_inode,                  if (entry->d_ino != stbuf->st_ino)                          continue; +                /* Linking an inode here, can cause a race in posix_acl. +                   Parent inode gets linked here, but before +                   it reaches posix_acl_readdirp_cbk, create/lookup can +                   come on a leaf-inode, as parent-inode-ctx not yet updated +                   in posix_acl_readdirp_cbk, create and lookup can fail +                   with EACCESS. So do the inode linking in the quota xlator +                  linked_inode = inode_link (leaf_inode, parent,                                             entry->d_name, NULL);                  GF_ASSERT (linked_inode == leaf_inode); -                inode_unref (linked_inode); +                inode_unref (linked_inode);*/                  if (type & POSIX_ANCESTRY_DENTRY) {                          loc_t loc = {0, }; diff --git a/xlators/system/posix-acl/src/posix-acl.c b/xlators/system/posix-acl/src/posix-acl.c index 6f6deec7d34..1ec3144500c 100644 --- a/xlators/system/posix-acl/src/posix-acl.c +++ b/xlators/system/posix-acl/src/posix-acl.c @@ -193,8 +193,12 @@ acl_permits (call_frame_t *frame, inode_t *inode, int want)          conf = frame->this->private;          ctx = posix_acl_ctx_get (inode, frame->this); -        if (!ctx) +        if (!ctx) { +                gf_log_callingfn (frame->this->name, GF_LOG_ERROR, +                                  "inode ctx is NULL for %s", +                                  uuid_utoa (inode->gfid));                  goto red; +        }          if (frame_is_super_user (frame))                  goto green; @@ -287,21 +291,52 @@ out:  struct posix_acl_ctx * -posix_acl_ctx_get (inode_t *inode, xlator_t *this) +__posix_acl_ctx_get (inode_t *inode, xlator_t *this, gf_boolean_t create)  {          struct posix_acl_ctx *ctx = NULL;          uint64_t              int_ctx = 0;          int                   ret = 0; -        ret = inode_ctx_get (inode, this, &int_ctx); +        ret = __inode_ctx_get (inode, this, &int_ctx);          if ((ret == 0) && (int_ctx))                  return PTR(int_ctx); +        if (create == _gf_false) +                return NULL; +          ctx = GF_CALLOC (1, sizeof (*ctx), gf_posix_acl_mt_ctx_t);          if (!ctx)                  return NULL; -        ret = inode_ctx_put (inode, this, UINT64 (ctx)); +        ret = __inode_ctx_put (inode, this, UINT64 (ctx)); + +        return ctx; +} + +struct posix_acl_ctx * +posix_acl_ctx_new (inode_t *inode, xlator_t *this) +{ +        struct posix_acl_ctx *ctx = NULL; + +        LOCK (&inode->lock); +        { +                ctx = __posix_acl_ctx_get (inode, this, _gf_true); +        } +        UNLOCK (&inode->lock); + +        return ctx; +} + +struct posix_acl_ctx * +posix_acl_ctx_get (inode_t *inode, xlator_t *this) +{ +        struct posix_acl_ctx *ctx = NULL; + +        LOCK (&inode->lock); +        { +                ctx = __posix_acl_ctx_get (inode, this, _gf_false); +        } +        UNLOCK (&inode->lock);          return ctx;  } @@ -636,7 +671,7 @@ posix_acl_inherit (xlator_t *this, loc_t *loc, dict_t *params, mode_t mode,          if (!par_default)                  goto out; -        ctx = posix_acl_ctx_get (loc->inode, this); +        ctx = posix_acl_ctx_new (loc->inode, this);          acl_access = posix_acl_dup (this, par_default);          if (!acl_access) @@ -740,14 +775,14 @@ posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf)          int                   ret = 0;  	int                   i = 0; -        ctx = posix_acl_ctx_get (inode, this); -        if (!ctx) { -                ret = -1; -                goto out; -        } -          LOCK(&inode->lock);          { +                ctx = __posix_acl_ctx_get (inode, this, _gf_true); +                if (!ctx) { +                        ret = -1; +                        goto unlock; +                } +                  ctx->uid   = buf->ia_uid;                  ctx->gid   = buf->ia_gid;                  ctx->perm  = st_mode_from_ia (buf->ia_prot, buf->ia_type); @@ -792,7 +827,6 @@ posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf)          }  unlock:          UNLOCK(&inode->lock); -out:          return ret;  }  | 
