diff options
-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; +} |