From 193d3b348a6c657e51f2a62c8bd9726fb635d582 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 Reviewed-on: http://review.gluster.org/8234 Reviewed-by: Niels de Vos --- 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(-) (limited to 'xlators/features') 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; -- cgit