From 78e9180ca24f15e1366eb3d51cbb5e4576af91a2 Mon Sep 17 00:00:00 2001 From: Kotresh H R Date: Fri, 6 Jun 2014 03:27:21 +0530 Subject: 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 Reviewed-on: http://review.gluster.org/8011 Tested-by: Gluster Build System Reviewed-by: Raghavendra G Reviewed-by: Venky Shankar Reviewed-by: Vijay Bellur --- xlators/features/gfid-access/src/gfid-access.c | 49 +++++++++++++++++++------- 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; -- cgit