| From 7e789895919d57d573ebb8faa147d1286104cd01 Mon Sep 17 00:00:00 2001 |
| From: Rui Wang <rui.wang@windriver.com> |
| Date: Mon, 24 Apr 2023 02:57:57 -0700 |
| Subject: [PATCH] attr: fix utime for symlink |
| |
| unfs3 has an old defect that it can not change the timestamps of a |
| symlink file because it only uses utime(), which will follow the |
| symlink. This will not cause an error if the symlink points to an |
| existent file. But under some special situation, such as installing |
| a rpm package, rpm tool will create the symlink first and try to |
| modify the timestamps of it, when the target file is non-existent. |
| This will cause an ESTALE error. Making rpm tool ignore this error |
| is a solution, but not the best one. An acceptable approach is |
| Making unfs3 support lutimes(), which can modify the symlink file |
| itself. Considering not every system support this function, so a |
| function checking is necessary. |
| |
| Upstream-Status: Submitted [https://github.com/unfs3/unfs3/pull/35] |
| |
| Signed-off-by: Chen Qi <Qi.Chen@windriver.com> |
| --- |
| attr.c | 15 +++++++++++---- |
| backend_unix.h | 2 ++ |
| configure.ac | 1 + |
| 3 files changed, 14 insertions(+), 4 deletions(-) |
| |
| diff --git a/attr.c b/attr.c |
| index 0ce9375..930ce6e 100644 |
| --- a/attr.c |
| +++ b/attr.c |
| @@ -285,7 +285,7 @@ post_op_attr get_post_cached(struct svc_req * req) |
| static nfsstat3 set_time(const char *path, backend_statstruct buf, sattr3 new) |
| { |
| time_t new_atime, new_mtime; |
| - struct utimbuf utim; |
| + struct timeval stamps[2]; |
| int res; |
| |
| /* set atime and mtime */ |
| @@ -307,10 +307,17 @@ static nfsstat3 set_time(const char *path, backend_statstruct buf, sattr3 new) |
| else /* DONT_CHANGE */ |
| new_mtime = buf.st_mtime; |
| |
| - utim.actime = new_atime; |
| - utim.modtime = new_mtime; |
| + stamps[0].tv_sec = new_atime; |
| + stamps[0].tv_usec = 0; |
| + stamps[1].tv_sec = new_mtime; |
| + stamps[1].tv_usec = 0; |
| + |
| +#if HAVE_LUTIMES |
| + res = backend_lutimes(path, stamps); |
| +#else |
| + res = backend_utimes(path, stamps); |
| +#endif |
| |
| - res = backend_utime(path, &utim); |
| if (res == -1) |
| return setattr_err(); |
| } |
| diff --git a/backend_unix.h b/backend_unix.h |
| index 4db72ae..9cce9ab 100644 |
| --- a/backend_unix.h |
| +++ b/backend_unix.h |
| @@ -61,6 +61,8 @@ |
| #define backend_symlink symlink |
| #define backend_truncate truncate |
| #define backend_utime utime |
| +#define backend_utimes utimes |
| +#define backend_lutimes lutimes |
| #define backend_statstruct struct stat |
| #define backend_dirstream DIR |
| #define backend_statvfsstruct struct statvfs |
| diff --git a/configure.ac b/configure.ac |
| index d46c905..c21afe3 100644 |
| --- a/configure.ac |
| +++ b/configure.ac |
| @@ -32,6 +32,7 @@ AC_CHECK_FUNCS(setresuid setresgid) |
| AC_CHECK_FUNCS(vsyslog) |
| AC_CHECK_FUNCS(lchown) |
| AC_CHECK_FUNCS(setgroups) |
| +AC_CHECK_FUNCS(lutimes) |
| UNFS3_COMPILE_WARNINGS |
| |
| PKG_CHECK_MODULES([TIRPC], [libtirpc]) |
| -- |
| 2.40.0 |
| |