diff options
| author | Jiffin Tony Thottan <jthottan@redhat.com> | 2015-06-25 15:04:18 +0530 | 
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2015-06-28 00:53:13 -0700 | 
| commit | 049c8eec304d9548fccb127ee8ce82f179bc41b0 (patch) | |
| tree | 79b02905a18f25407d885c15a7e2a262879868bc /api/src | |
| parent | b68f671b2b8a0aafef8f98145aee7044edaa907d (diff) | |
gfapi : symlink resolution for glfs_object
Generally posix expects symlink should be resolved, before performing an
acl related operation. This patch introduces a new api glfs_h_resolve_symlink()
which will do the same.
Change-Id: Ieee645154455a732edfb2c28834021bab4248810
BUG: 1209735
Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
Reviewed-on: http://review.gluster.org/11410
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Reviewed-by: Raghavendra Talur <rtalur@redhat.com>
Tested-by: NetBSD Build System <jenkins@build.gluster.org>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Diffstat (limited to 'api/src')
| -rw-r--r-- | api/src/glfs-handleops.c | 25 | ||||
| -rw-r--r-- | api/src/glfs-internal.h | 4 | ||||
| -rw-r--r-- | api/src/glfs-resolve.c | 37 | 
3 files changed, 64 insertions, 2 deletions
diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c index f458cb4bd58..38d8ccba041 100644 --- a/api/src/glfs-handleops.c +++ b/api/src/glfs-handleops.c @@ -1999,6 +1999,7 @@ pub_glfs_h_acl_set (struct glfs *fs, struct glfs_object *object,          int ret = -1;          char *acl_s = NULL;          const char *acl_key = NULL; +        struct glfs_object *new_object = NULL;          DECLARE_OLD_THIS; @@ -2018,12 +2019,22 @@ pub_glfs_h_acl_set (struct glfs *fs, struct glfs_object *object,          if (!acl_s)                  goto out; -        ret = pub_glfs_h_setxattrs (fs, object, acl_key, acl_s, +        if (IA_ISLNK (object->inode->ia_type)) { +                new_object = glfs_h_resolve_symlink (fs, object); +                if (new_object == NULL) +                        goto out; +        } else +                new_object = object; + +        ret = pub_glfs_h_setxattrs (fs, new_object, acl_key, acl_s,                                      strlen (acl_s) + 1, 0);          acl_free (acl_s);  out: +        if (IA_ISLNK (object->inode->ia_type) && new_object) +                glfs_h_close (new_object); +          __GLFS_EXIT_FS;  invalid_fs: @@ -2039,6 +2050,7 @@ pub_glfs_h_acl_get (struct glfs *fs, struct glfs_object *object,          char *acl_s = NULL;          dict_t *xattr = NULL;          const char *acl_key = NULL; +        struct glfs_object *new_object = NULL;          DECLARE_OLD_THIS; @@ -2053,7 +2065,14 @@ pub_glfs_h_acl_get (struct glfs *fs, struct glfs_object *object,          if (!acl_key)                  goto out; -        ret = glfs_h_getxattrs_common (fs, object, &xattr, acl_key); +        if (IA_ISLNK (object->inode->ia_type)) { +                new_object = glfs_h_resolve_symlink (fs, object); +                if (new_object == NULL) +                        goto out; +        } else +                new_object = object; + +        ret = glfs_h_getxattrs_common (fs, new_object, &xattr, acl_key);          if (ret)                  goto out; @@ -2065,6 +2084,8 @@ pub_glfs_h_acl_get (struct glfs *fs, struct glfs_object *object,  out:          GF_FREE (acl_s); +        if (IA_ISLNK (object->inode->ia_type) && new_object) +                glfs_h_close (new_object);          __GLFS_EXIT_FS; diff --git a/api/src/glfs-internal.h b/api/src/glfs-internal.h index 5eb57d4b8e4..608b534b1ab 100644 --- a/api/src/glfs-internal.h +++ b/api/src/glfs-internal.h @@ -415,4 +415,8 @@ ssize_t  glfs_anonymous_pwritev (struct glfs *fs, struct glfs_object *object,                          const struct iovec *iovec, int iovcnt,                          off_t offset, int flags); + +struct glfs_object * +glfs_h_resolve_symlink (struct glfs *fs, struct glfs_object *object); +  #endif /* !_GLFS_INTERNAL_H */ diff --git a/api/src/glfs-resolve.c b/api/src/glfs-resolve.c index 287c48a13ad..c185e211a53 100644 --- a/api/src/glfs-resolve.c +++ b/api/src/glfs-resolve.c @@ -1021,3 +1021,40 @@ glfs_create_object (loc_t *loc, struct glfs_object **retobject)  	return 0;  } + +struct glfs_object * +glfs_h_resolve_symlink (struct glfs *fs, struct glfs_object *object) +{ + +        xlator_t                *subvol         = NULL; +        loc_t                   sym_loc         = {0,}; +        struct iatt             iatt            = {0,}; +        char                    *lpath          = NULL; +        int                     ret             = 0; +        struct glfs_object      *target_object  = NULL; + +        subvol = glfs_active_subvol (fs); +        if (!subvol) { +                ret = -1; +                errno = EIO; +                goto out; +        } + +        ret = glfs_resolve_symlink (fs, subvol, object->inode, &lpath); +        if (ret < 0) +                goto out; + +        ret = glfs_resolve_at (fs, subvol, NULL, lpath, +                               &sym_loc, &iatt, +                              /* always recurisvely follow while +                                following symlink +                              */ +                               1, 0); +        if (ret == 0) +                ret = glfs_create_object (&sym_loc, &target_object); + +out: +        loc_wipe (&sym_loc); +        GF_FREE (lpath); +        return target_object; +}  | 
