summaryrefslogtreecommitdiffstats
path: root/xlators
diff options
context:
space:
mode:
authorXavi Hernandez <xhernandez@users.noreply.github.com>2021-02-11 16:11:19 +0100
committerGitHub <noreply@github.com>2021-02-11 16:11:19 +0100
commitaf5c2cb320068bd154caf54f063fa1787ae19995 (patch)
treec56457af6f1c415b279b60cb02cb3704189e01d0 /xlators
parent5223300bc65eb88a1fbe27bd2702dbb92768cb27 (diff)
downloadglusterfs-af5c2cb320068bd154caf54f063fa1787ae19995.tar.gz
glusterfs-af5c2cb320068bd154caf54f063fa1787ae19995.tar.xz
glusterfs-af5c2cb320068bd154caf54f063fa1787ae19995.zip
posix: fix chmod error on symlinks (#2155)
After glibc 2.32, lchmod() is returning EOPNOTSUPP instead of ENOSYS when called on symlinks. The man page says that the returned code is ENOTSUP. They are the same in linux, but this patch correctly handles all errors. Fixes: #2154 Change-Id: Ib3bb3d86d421cba3d7ec8d66b6beb131ef6e0925 Signed-off-by: Xavi Hernandez xhernandez@redhat.com
Diffstat (limited to 'xlators')
-rw-r--r--xlators/storage/posix/src/posix-inode-fd-ops.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/xlators/storage/posix/src/posix-inode-fd-ops.c b/xlators/storage/posix/src/posix-inode-fd-ops.c
index 3f51c49642..1ecf272d01 100644
--- a/xlators/storage/posix/src/posix-inode-fd-ops.c
+++ b/xlators/storage/posix/src/posix-inode-fd-ops.c
@@ -251,11 +251,15 @@ posix_do_chmod(xlator_t *this, const char *path, struct iatt *stbuf)
mode_bit = (mode & priv->create_mask) | priv->force_create_mode;
mode = posix_override_umask(mode, mode_bit);
}
- ret = lchmod(path, mode);
- if ((ret == -1) && (errno == ENOSYS)) {
- /* in Linux symlinks are always in mode 0777 and no
- such call as lchmod exists.
- */
+ ret = sys_lchmod(path, mode);
+ /* Before glibc 2.32, lchmod() was not implemented and calling it
+ * always returned ENOSYS. Starting with glibc 2.32 this request
+ * is using fchmodat() system call to implement it. However, linux
+ * doesn't support setting the mode for symlinks, so the system
+ * call returns EOPNOTSUPP (or ENOTSUP based on man page). We need
+ * to handle all cases. */
+ if ((ret < 0) &&
+ ((errno == ENOSYS) || (errno == EOPNOTSUPP) || (errno == ENOTSUP))) {
gf_msg_debug(this->name, 0, "%s (%s)", path, strerror(errno));
if (is_symlink) {
ret = 0;