summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/basic/gfid-access.t60
-rw-r--r--xlators/features/gfid-access/src/gfid-access.c231
-rw-r--r--xlators/features/gfid-access/src/gfid-access.h31
3 files changed, 202 insertions, 120 deletions
diff --git a/tests/basic/gfid-access.t b/tests/basic/gfid-access.t
new file mode 100644
index 00000000000..24477acba5c
--- /dev/null
+++ b/tests/basic/gfid-access.t
@@ -0,0 +1,60 @@
+#!/bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../volume.rc
+
+cleanup;
+
+TEST glusterd
+TEST pidof glusterd
+TEST $CLI volume create $V0 $H0:$B0/${V0}0
+TEST $CLI volume start $V0
+TEST glusterfs --volfile-id=/$V0 --volfile-server=$H0 $M0 --attribute-timeout=0 --entry-timeout=0 --aux-gfid-mount
+TEST mkdir $M0/a
+TEST touch $M0/b
+a_gfid_str=$(gf_gfid_xattr_to_str $(gf_get_gfid_xattr $B0/${V0}0/a))
+b_gfid_str=$(gf_gfid_xattr_to_str $(gf_get_gfid_xattr $B0/${V0}0/b))
+
+#Operations on Directory
+TEST setfattr -n trusted.abc -v abc $M0/a
+EXPECT "abc" echo $(getfattr -n trusted.abc $M0/a)
+EXPECT "abc" echo $(getfattr -n trusted.abc $M0/.gfid/$a_gfid_str)
+TEST setfattr -x trusted.abc $M0/a
+TEST ! getfattr -n trusted.abc $M0/a
+TEST ! getfattr -n trusted.abc $M0/.gfid/$a_gfid_str
+TEST chmod 0777 $M0/a
+EXPECT "777" stat -c "%a" $M0/a
+EXPECT "777" stat -c "%a" $M0/.gfid/$a_gfid_str
+
+TEST setfattr -n trusted.abc -v def $M0/.gfid/$a_gfid_str
+EXPECT "def" echo $(getfattr -n trusted.abc $M0/a)
+EXPECT "def" echo $(getfattr -n trusted.abc $M0/.gfid/$a_gfid_str)
+TEST setfattr -x trusted.abc $M0/.gfid/$a_gfid_str
+TEST ! getfattr -n trusted.abc $M0/a
+TEST ! getfattr -n trusted.abc $M0/.gfid/$a_gfid_str
+TEST chmod 0777 $M0/.gfid/$a_gfid_str
+EXPECT "777" stat -c "%a" $M0/a
+EXPECT "777" stat -c "%a" $M0/.gfid/$a_gfid_str
+
+#Operations on File
+TEST setfattr -n trusted.abc -v abc $M0/b
+EXPECT "abc" echo $(getfattr -n trusted.abc $M0/b)
+EXPECT "abc" echo $(getfattr -n trusted.abc $M0/.gfid/$b_gfid_str)
+TEST setfattr -x trusted.abc $M0/b
+TEST ! getfattr -n trusted.abc $M0/b
+TEST ! getfattr -n trusted.abc $M0/.gfid/$b_gfid_str
+TEST chmod 0777 $M0/b
+EXPECT "777" stat -c "%a" $M0/b
+EXPECT "777" stat -c "%a" $M0/.gfid/$b_gfid_str
+
+TEST setfattr -n trusted.abc -v def $M0/.gfid/$b_gfid_str
+EXPECT "def" echo $(getfattr -n trusted.abc $M0/b)
+EXPECT "def" echo $(getfattr -n trusted.abc $M0/.gfid/$b_gfid_str)
+TEST setfattr -x trusted.abc $M0/.gfid/$b_gfid_str
+TEST ! getfattr -n trusted.abc $M0/b
+TEST ! getfattr -n trusted.abc $M0/.gfid/$b_gfid_str
+TEST chmod 0777 $M0/.gfid/$b_gfid_str
+EXPECT "777" stat -c "%a" $M0/b
+EXPECT "777" stat -c "%a" $M0/.gfid/$b_gfid_str
+
+cleanup
diff --git a/xlators/features/gfid-access/src/gfid-access.c b/xlators/features/gfid-access/src/gfid-access.c
index 40b2f37e83e..8b699ffc9d4 100644
--- a/xlators/features/gfid-access/src/gfid-access.c
+++ b/xlators/features/gfid-access/src/gfid-access.c
@@ -17,6 +17,48 @@
#include "byte-order.h"
+int
+ga_valid_inode_loc_copy (loc_t *dst, loc_t *src, xlator_t *this)
+{
+ int ret = 0;
+ uint64_t value = 0;
+
+ /* if its an entry operation, on the virtual */
+ /* directory inode as parent, we need to handle */
+ /* it properly */
+ ret = loc_copy (dst, src);
+ if (ret < 0)
+ goto out;
+
+ if (dst->parent) {
+ ret = inode_ctx_get (dst->parent, this, &value);
+ if (ret < 0) {
+ ret = 0; //real-inode
+ goto out;
+ }
+ inode_unref (dst->parent);
+ dst->parent = inode_ref ((inode_t*)value);
+ /* if parent is virtual, no need to handle */
+ /* loc->inode */
+ goto out;
+ }
+
+ /* if its an inode operation, on the virtual */
+ /* directory inode itself, we need to handle */
+ /* it properly */
+ if (dst->inode) {
+ ret = inode_ctx_get (dst->inode, this, &value);
+ if (ret < 0) {
+ ret = 0; //real-inode
+ goto out;
+ }
+ inode_unref (dst->inode);
+ dst->inode = inode_ref ((inode_t*)value);
+ goto out;
+ }
+out:
+ return ret;
+}
void
ga_newfile_args_free (ga_newfile_args_t *args)
@@ -574,11 +616,10 @@ int32_t
ga_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
int32_t flags, dict_t *xdata)
{
-
data_t *data = NULL;
int op_errno = ENOMEM;
int ret = 0;
- inode_t *unref = NULL;
+ loc_t ga_loc = {0, };
GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
@@ -600,15 +641,15 @@ ga_setxattr (call_frame_t *frame, xlator_t *this, loc_t *loc, dict_t *dict,
//If the inode is a virtual inode change the inode otherwise perform
//the operation on same inode
- GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
+ if (ret < 0)
+ goto err;
-wind:
STACK_WIND (frame, ga_setxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->setxattr, loc, dict, flags,
+ FIRST_CHILD(this)->fops->setxattr, &ga_loc, dict, flags,
xdata);
- if (unref)
- inode_unref (unref);
+ loc_wipe (&ga_loc);
return 0;
err:
STACK_UNWIND_STRICT (setxattr, frame, -1, op_errno, xdata);
@@ -903,7 +944,7 @@ int
ga_mkdir (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
mode_t umask, dict_t *xdata)
{
- int op_errno = 0;
+ int op_errno = ENOMEM;
GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
@@ -924,7 +965,7 @@ int
ga_create (call_frame_t *frame, xlator_t *this, loc_t *loc, int flags,
mode_t mode, mode_t umask, fd_t *fd, dict_t *xdata)
{
- int op_errno = 0;
+ int op_errno = ENOMEM;
GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
@@ -944,7 +985,7 @@ int
ga_symlink (call_frame_t *frame, xlator_t *this, const char *linkname,
loc_t *loc, mode_t umask, dict_t *xdata)
{
- int op_errno = 0;
+ int op_errno = ENOMEM;
GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
@@ -963,7 +1004,7 @@ int
ga_mknod (call_frame_t *frame, xlator_t *this, loc_t *loc, mode_t mode,
dev_t rdev, mode_t umask, dict_t *xdata)
{
- int op_errno = 0;
+ int op_errno = ENOMEM;
GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
@@ -983,20 +1024,21 @@ int
ga_rmdir (call_frame_t *frame, xlator_t *this, loc_t *loc, int flag,
dict_t *xdata)
{
- int op_errno = 0;
- inode_t *unref = NULL;
+ int op_errno = ENOMEM;
+ int ret = -1;
+ loc_t ga_loc = {0, };
GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
- GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
+ if (ret < 0)
+ goto err;
-wind:
STACK_WIND (frame, default_rmdir_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->rmdir,
- loc, flag, xdata);
- if (unref)
- inode_unref (unref);
+ &ga_loc, flag, xdata);
+ loc_wipe (&ga_loc);
return 0;
err:
STACK_UNWIND_STRICT (rmdir, frame, -1, op_errno, NULL,
@@ -1009,21 +1051,21 @@ int
ga_unlink (call_frame_t *frame, xlator_t *this, loc_t *loc, int32_t xflag,
dict_t *xdata)
{
- int op_errno = 0;
- inode_t *unref = NULL;
+ int op_errno = ENOMEM;
+ int ret = -1;
+ loc_t ga_loc = {0, };
GFID_ACCESS_ENTRY_OP_CHECK (loc, op_errno, err);
- GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
+ if (ret < 0)
+ goto err;
-wind:
STACK_WIND (frame, default_unlink_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->unlink,
- loc, xflag, xdata);
-
- if (unref)
- inode_unref (unref);
+ &ga_loc, xflag, xdata);
+ loc_wipe (&ga_loc);
return 0;
err:
STACK_UNWIND_STRICT (unlink, frame, -1, op_errno, NULL,
@@ -1036,30 +1078,30 @@ int
ga_rename (call_frame_t *frame, xlator_t *this,
loc_t *oldloc, loc_t *newloc, dict_t *xdata)
{
- int op_errno = 0;
- inode_t *oldloc_unref = NULL;
- inode_t *newloc_unref = NULL;
+ int op_errno = ENOMEM;
+ int ret = 0;
+ loc_t ga_oldloc = {0, };
+ loc_t ga_newloc = {0, };
GFID_ACCESS_ENTRY_OP_CHECK (oldloc, op_errno, err);
GFID_ACCESS_ENTRY_OP_CHECK (newloc, op_errno, err);
- GFID_ACCESS_GET_VALID_DIR_INODE (this, oldloc, oldloc_unref,
- handle_newloc);
+ ret = ga_valid_inode_loc_copy (&ga_oldloc, oldloc, this);
+ if (ret < 0)
+ goto err;
-handle_newloc:
- GFID_ACCESS_GET_VALID_DIR_INODE (this, newloc, newloc_unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_newloc, newloc, this);
+ if (ret < 0) {
+ loc_wipe (&ga_oldloc);
+ goto err;
+ }
-wind:
STACK_WIND (frame, default_rename_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->rename,
- oldloc, newloc, xdata);
-
- if (oldloc_unref)
- inode_unref (oldloc_unref);
-
- if (newloc_unref)
- inode_unref (newloc_unref);
+ &ga_oldloc, &ga_newloc, xdata);
+ loc_wipe (&ga_newloc);
+ loc_wipe (&ga_oldloc);
return 0;
err:
STACK_UNWIND_STRICT (rename, frame, -1, op_errno, NULL,
@@ -1073,31 +1115,32 @@ int
ga_link (call_frame_t *frame, xlator_t *this,
loc_t *oldloc, loc_t *newloc, dict_t *xdata)
{
- int op_errno = 0;
- inode_t *oldloc_unref = NULL;
- inode_t *newloc_unref = NULL;
+ int op_errno = ENOMEM;
+ int ret = 0;
+ loc_t ga_oldloc = {0, };
+ loc_t ga_newloc = {0, };
GFID_ACCESS_ENTRY_OP_CHECK (oldloc, op_errno, err);
GFID_ACCESS_ENTRY_OP_CHECK (newloc, op_errno, err);
- GFID_ACCESS_GET_VALID_DIR_INODE (this, oldloc, oldloc_unref,
- handle_newloc);
+ ret = ga_valid_inode_loc_copy (&ga_oldloc, oldloc, this);
+ if (ret < 0)
+ goto err;
-handle_newloc:
- GFID_ACCESS_GET_VALID_DIR_INODE (this, newloc, newloc_unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_newloc, newloc, this);
+ if (ret < 0) {
+ loc_wipe (&ga_oldloc);
+ goto err;
+ }
-wind:
STACK_WIND (frame, default_link_cbk,
FIRST_CHILD(this), FIRST_CHILD(this)->fops->link,
- oldloc, newloc, xdata);
-
- if (oldloc_unref)
- inode_unref (oldloc_unref);
-
- if (newloc_unref)
- inode_unref (newloc_unref);
+ &ga_oldloc, &ga_newloc, xdata);
+ loc_wipe (&ga_newloc);
+ loc_wipe (&ga_oldloc);
return 0;
+
err:
STACK_UNWIND_STRICT (link, frame, -1, op_errno, NULL,
NULL, NULL, NULL, xdata);
@@ -1109,7 +1152,7 @@ int32_t
ga_opendir (call_frame_t *frame, xlator_t *this, loc_t *loc,
fd_t *fd, dict_t *xdata)
{
- int op_errno = 0;
+ int op_errno = ENOMEM;
GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
@@ -1135,23 +1178,24 @@ int32_t
ga_getxattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
{
- inode_t *unref = NULL;
- int op_errno = 0;
+ int op_errno = ENOMEM;
+ int ret = -1;
+ loc_t ga_loc = {0, };
GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
- GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
+ if (ret < 0)
+ goto err;
-wind:
STACK_WIND (frame, default_getxattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->getxattr, loc, name, xdata);
+ FIRST_CHILD(this)->fops->getxattr, &ga_loc, name, xdata);
- if (unref)
- inode_unref (unref);
+ loc_wipe (&ga_loc);
return 0;
-
err:
STACK_UNWIND_STRICT (getxattr, frame, -1, op_errno, NULL, xdata);
+
return 0;
}
@@ -1159,26 +1203,30 @@ int32_t
ga_stat (call_frame_t *frame, xlator_t *this, loc_t *loc,
dict_t *xdata)
{
- inode_t *unref = NULL;
- ga_private_t *priv = NULL;
+ int op_errno = ENOMEM;
+ int ret = -1;
+ loc_t ga_loc = {0, };
+ 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);
+ ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
+ if (ret < 0)
+ goto err;
-wind:
STACK_WIND (frame, default_stat_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->stat, loc, xdata);
- if (unref)
- inode_unref (unref);
+ FIRST_CHILD(this)->fops->stat, &ga_loc, xdata);
+
+ loc_wipe (&ga_loc);
+ return 0;
+
+err:
+ STACK_UNWIND_STRICT (stat, frame, -1, op_errno, NULL, xdata);
return 0;
@@ -1192,22 +1240,24 @@ 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;
- int op_errno = 0;
+ int op_errno = ENOMEM;
+ int ret = -1;
+ loc_t ga_loc = {0, };
GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
- GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
+ if (ret < 0)
+ goto err;
-wind:
STACK_WIND (frame, default_setattr_cbk, FIRST_CHILD (this),
- FIRST_CHILD (this)->fops->setattr, loc, stbuf, valid,
+ FIRST_CHILD (this)->fops->setattr, &ga_loc, stbuf, valid,
xdata);
- if (unref)
- inode_unref (unref);
+ loc_wipe (&ga_loc);
return 0;
err:
STACK_UNWIND_STRICT (setattr, frame, -1, op_errno, NULL, NULL, xdata);
+
return 0;
}
@@ -1215,22 +1265,25 @@ int32_t
ga_removexattr (call_frame_t *frame, xlator_t *this, loc_t *loc,
const char *name, dict_t *xdata)
{
- inode_t *unref = NULL;
- int op_errno = 0;
+ int op_errno = ENOMEM;
+ int ret = -1;
+ loc_t ga_loc = {0, };
GFID_ACCESS_INODE_OP_CHECK (loc, op_errno, err);
- GFID_ACCESS_GET_VALID_DIR_INODE (this, loc, unref, wind);
+ ret = ga_valid_inode_loc_copy (&ga_loc, loc, this);
+ if (ret < 0)
+ goto err;
-wind:
STACK_WIND (frame, default_removexattr_cbk, FIRST_CHILD(this),
- FIRST_CHILD(this)->fops->removexattr, loc, name,
+ FIRST_CHILD(this)->fops->removexattr, &ga_loc, name,
xdata);
- if (unref)
- inode_unref (unref);
+ loc_wipe (&ga_loc);
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 11d576191b4..5c7a95af4c8 100644
--- a/xlators/features/gfid-access/src/gfid-access.h
+++ b/xlators/features/gfid-access/src/gfid-access.h
@@ -31,37 +31,6 @@
#define GF_GFID_DIR ".gfid"
#define GF_AUX_GFID 0xd
-#define GFID_ACCESS_GET_VALID_DIR_INODE(x,l,unref,lbl) do { \
- int ret = 0; \
- uint64_t value = 0; \
- \
- /* if its an entry operation, on the virtual */ \
- /* directory inode as parent, we need to handle */ \
- /* it properly */ \
- if (l->parent) { \
- ret = inode_ctx_get (l->parent, x, &value); \
- if (ret) \
- goto lbl; \
- unref = (inode_t *)value; \
- l->parent = inode_ref (unref); \
- /* if parent is virtual, no need to handle */ \
- /* loc->inode */ \
- break; \
- } \
- \
- /* if its an inode operation, on the virtual */ \
- /* directory inode itself, we need to handle */ \
- /* it properly */ \
- if (l->inode) { \
- ret = inode_ctx_get (l->inode, x, &value); \
- if (ret) \
- goto lbl; \
- unref = (inode_t *)value; \
- l->inode = inode_ref (unref); \
- } \
- \
- } while (0)
-
#define GFID_ACCESS_ENTRY_OP_CHECK(loc,err,lbl) do { \
/* need to check if the lookup is on virtual dir */ \
if ((loc->name && !strcmp (GF_GFID_DIR, loc->name)) && \