summaryrefslogtreecommitdiffstats
path: root/xlators/features/gfid-access/src/gfid-access.c
diff options
context:
space:
mode:
Diffstat (limited to 'xlators/features/gfid-access/src/gfid-access.c')
-rw-r--r--xlators/features/gfid-access/src/gfid-access.c231
1 files changed, 142 insertions, 89 deletions
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;
}