summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKotresh H R <khiremat@redhat.com>2014-06-06 03:27:21 +0530
committerNiels de Vos <ndevos@redhat.com>2014-07-07 00:22:28 -0700
commit193d3b348a6c657e51f2a62c8bd9726fb635d582 (patch)
tree1a8aabb17ad44ee2c1d1f96f696b1d699e692e87
parentbf737d691cf812b40594e64c4c52f3c677a04e35 (diff)
feautre/gfid-access: Fix EINVAL when stat on .gfid
Problem: Some of the inode operations on '.gfid' virtual directory was resulting in the error EINVAL from dht after failing to find the layout. Solution: Inode operations on '.gfid' virtual directory should not wind further down and should be handled accordingly in the gfid-access translator itself. Change-Id: I156cb10ffea0c46b0d747e26f74538d7fb01a1dd BUG: 1105891 Signed-off-by: Kotresh H R <khiremat@redhat.com> Reviewed-on: http://review.gluster.org/8011 Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-by: Venky Shankar <vshankar@redhat.com> Reviewed-by: Vijay Bellur <vbellur@redhat.com> Reviewed-on: http://review.gluster.org/8234 Reviewed-by: Niels de Vos <ndevos@redhat.com>
-rw-r--r--xlators/features/gfid-access/src/gfid-access.c49
-rw-r--r--xlators/features/gfid-access/src/gfid-access.h10
2 files changed, 45 insertions, 14 deletions
diff --git a/xlators/features/gfid-access/src/gfid-access.c b/xlators/features/gfid-access/src/gfid-access.c
index 7a15165c4a5..a576e226660 100644
--- a/xlators/features/gfid-access/src/gfid-access.c
+++ b/xlators/features/gfid-access/src/gfid-access.c
@@ -577,13 +577,7 @@ ga_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
int ret = 0;
inode_t *unref = NULL;
- if ((loc->name && !strcmp (GF_GFID_DIR, loc->name)) &&
- ((loc->parent &&
- __is_root_gfid (loc->parent->gfid)) ||
- __is_root_gfid (loc->pargfid))) {
- op_errno = EPERM;
- goto err;
- }
+ GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
data = dict_get (dict, GF_FUSE_AUX_GFID_NEWFILE);
if (data) {
@@ -1102,7 +1096,7 @@ ga_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc,
{
int op_errno = 0;
- GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
+ GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
/* also check if the loc->inode itself is virtual
inode, if yes, return with failure, mainly because we
@@ -1126,8 +1120,10 @@ int32_t
ga_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
{
- inode_t *unref = NULL;
+ inode_t *unref = NULL;
+ int op_errno = 0;
+ GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
wind:
@@ -1138,13 +1134,28 @@ wind:
inode_unref (unref);
return 0;
+
+err:
+ STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL, xdata);
+ return 0;
}
int32_t
ga_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
dict_t *xdata)
{
- inode_t *unref = NULL;
+ inode_t *unref = NULL;
+ ga_private_t *priv = NULL;
+
+ GF_ASSERT (this);
+ priv = this->private;
+ GF_ASSERT (priv);
+
+ /* If stat is on ".gfid" itself, do not wind further,
+ * return fake stat and return success.
+ */
+ if (__is_gfid_access_dir(loc->gfid))
+ goto out;
GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
@@ -1155,6 +1166,10 @@ wind:
inode_unref (unref);
return 0;
+
+out:
+ STACK_UNWIND_STRICT (stat, frame, 0, 0, &priv->gfiddir_stbuf, xdata);
+ return 0;
}
int32_t
@@ -1162,8 +1177,10 @@ ga_setattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
struct iatt *stbuf, int32_t valid,
dict_t *xdata)
{
- inode_t *unref = NULL;
+ inode_t *unref = NULL;
+ int op_errno = 0;
+ GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
wind:
@@ -1174,14 +1191,19 @@ wind:
inode_unref (unref);
return 0;
+err:
+ STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL, xdata);
+ return 0;
}
int32_t
ga_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
{
- inode_t *unref = NULL;
+ inode_t *unref = NULL;
+ int op_errno = 0;
+ GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
wind:
@@ -1192,6 +1214,9 @@ wind:
inode_unref (unref);
return 0;
+err:
+ STACK_UNWIND_STRICT (removexattr, frame, -1, op_errno, xdata);
+ return 0;
}
diff --git a/xlators/features/gfid-access/src/gfid-access.h b/xlators/features/gfid-access/src/gfid-access.h
index e883eca696c..31c82e07891 100644
--- a/xlators/features/gfid-access/src/gfid-access.h
+++ b/xlators/features/gfid-access/src/gfid-access.h
@@ -69,7 +69,7 @@
((loc->parent && \
__is_root_gfid (loc->parent->gfid)) || \
__is_root_gfid (loc->pargfid))) { \
- err = EEXIST; \
+ err = ENOTSUP; \
goto lbl; \
} \
\
@@ -83,7 +83,13 @@
} \
} while (0)
-
+#define GFID_ACCESS_INODE_OP_CHECK(loc,err,lbl) do { \
+ /*Check if it is on .gfid*/ \
+ if (__is_gfid_access_dir(loc->gfid)) { \
+ err = ENOTSUP; \
+ goto lbl; \
+ } \
+ } while (0)
typedef struct {
unsigned int uid;
unsigned int gid;