Blob Blame History Raw
From 8decf90c08992a1e5e34b0281c606354f76b6bab Mon Sep 17 00:00:00 2001
From: Jiffin Tony Thottan <jthottan@redhat.com>
Date: Thu, 25 Jun 2015 15:04:18 +0530
Subject: [PATCH 189/190] 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.

backport of http://review.gluster.org/#/c/11410/

>Change-Id: Ieee645154455a732edfb2c28834021bab4248810
>BUG: 1209735
>Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>

Change-Id: Ic6c251076a9d6b6c19093ff86ace996b29badba4
BUG: 1235147
Signed-off-by: Jiffin Tony Thottan <jthottan@redhat.com>
Reviewed-on: https://code.engineering.redhat.com/gerrit/51750
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Tested-by: Niels de Vos <ndevos@redhat.com>
---
 api/src/glfs-handleops.c |   25 +++++++++++++++++++++++--
 api/src/glfs-internal.h  |    3 +++
 api/src/glfs-resolve.c   |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/api/src/glfs-handleops.c b/api/src/glfs-handleops.c
index c010f0c..47f2139 100644
--- a/api/src/glfs-handleops.c
+++ b/api/src/glfs-handleops.c
@@ -1987,6 +1987,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;
 
@@ -2006,12 +2007,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:
@@ -2027,6 +2038,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;
 
@@ -2041,7 +2053,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;
 
@@ -2053,6 +2072,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 84935f5..83b4ade 100644
--- a/api/src/glfs-internal.h
+++ b/api/src/glfs-internal.h
@@ -365,4 +365,7 @@ 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 60e285d..2767abf 100644
--- a/api/src/glfs-resolve.c
+++ b/api/src/glfs-resolve.c
@@ -1026,3 +1026,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;
+}
-- 
1.7.1