summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/src/glfs-handleops.c25
-rw-r--r--api/src/glfs-internal.h4
-rw-r--r--api/src/glfs-resolve.c37
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;
+}