summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/features/marker/src/marker.c38
-rw-r--r--xlators/features/quota/src/quota.c51
-rw-r--r--xlators/storage/posix/src/posix-handle.c53
-rw-r--r--xlators/storage/posix/src/posix-messages.h10
-rw-r--r--xlators/storage/posix/src/posix.c9
-rw-r--r--xlators/system/posix-acl/src/posix-acl.c58
6 files changed, 149 insertions, 70 deletions
diff --git a/xlators/features/marker/src/marker.c b/xlators/features/marker/src/marker.c
index 48a275e2783..f4fdf2e415b 100644
--- a/xlators/features/marker/src/marker.c
+++ b/xlators/features/marker/src/marker.c
@@ -2982,38 +2982,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) {
@@ -3021,10 +3000,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 105d70cbea6..847c93f37c0 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 7f5cd5237ae..8e561e4a76f 100644
--- a/xlators/storage/posix/src/posix-handle.c
+++ b/xlators/storage/posix/src/posix-handle.c
@@ -30,24 +30,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
@@ -67,6 +85,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);
@@ -127,11 +147,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,
@@ -177,12 +202,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 ad16c1dc00c..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 107
+#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"
@@ -917,6 +917,14 @@
*
*/
+#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 dcd54bd35d6..b5df1d082ee 100644
--- a/xlators/storage/posix/src/posix.c
+++ b/xlators/storage/posix/src/posix.c
@@ -3803,11 +3803,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 2edaa408135..61d2d6647f6 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)
@@ -742,14 +777,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);
@@ -794,7 +829,6 @@ posix_acl_ctx_update (inode_t *inode, xlator_t *this, struct iatt *buf)
}
unlock:
UNLOCK(&inode->lock);
-out:
return ret;
}