diff options
| author | Kotresh H R <khiremat@redhat.com> | 2014-06-06 03:27:21 +0530 | 
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2014-07-07 00:22:28 -0700 | 
| commit | 193d3b348a6c657e51f2a62c8bd9726fb635d582 (patch) | |
| tree | 1a8aabb17ad44ee2c1d1f96f696b1d699e692e87 | |
| parent | bf737d691cf812b40594e64c4c52f3c677a04e35 (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>
Reviewed-on: http://review.gluster.org/8234
Reviewed-by: Niels de Vos <ndevos@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 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;  | 
