diff options
author | Xavi Hernandez <xhernandez@users.noreply.github.com> | 2021-02-11 16:11:19 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-11 16:11:19 +0100 |
commit | af5c2cb320068bd154caf54f063fa1787ae19995 (patch) | |
tree | c56457af6f1c415b279b60cb02cb3704189e01d0 /xlators | |
parent | 5223300bc65eb88a1fbe27bd2702dbb92768cb27 (diff) | |
download | glusterfs-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.c | 14 |
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; |