diff options
author | Kotresh H R <khiremat@redhat.com> | 2014-06-06 03:27:21 +0530 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-06-20 02:21:58 -0700 |
commit | 78e9180ca24f15e1366eb3d51cbb5e4576af91a2 (patch) | |
tree | 7b1f706c15a48b14b3f367477ab280210318bdcb | |
parent | 124ba991069099258e4e69ccf3eefae1c88ebb8c (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>
-rw-r--r-- | xlators/features/gfid-access/src/gfid-access.c | 49 | ||||
-rw-r--r-- | xlators/features/gfid-access/src/gfid-access.h | 10 |
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 040d530cb19..40b2f37e83e 100644 --- a/xlators/features/gfid-access/src/gfid-access.c +++ b/xlators/features/gfid-access/src/gfid-access.c @@ -580,13 +580,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) { @@ -1117,7 +1111,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 @@ -1141,8 +1135,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: @@ -1153,13 +1149,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); @@ -1170,6 +1181,10 @@ wind: inode_unref (unref); return 0; + +out: + STACK_UNWIND_STRICT (stat, frame, 0, 0, &priv->gfiddir_stbuf, xdata); + return 0; } int32_t @@ -1177,8 +1192,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: @@ -1189,14 +1206,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: @@ -1207,6 +1229,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 9bc4d2dfd2d..11d576191b4 100644 --- a/xlators/features/gfid-access/src/gfid-access.h +++ b/xlators/features/gfid-access/src/gfid-access.h @@ -68,7 +68,7 @@ ((loc->parent && \ __is_root_gfid (loc->parent->gfid)) || \ __is_root_gfid (loc->pargfid))) { \ - err = EEXIST; \ + err = ENOTSUP; \ goto lbl; \ } \ \ @@ -82,7 +82,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; |