| From 3f4fcb62661059bad77a2e957b4621137797bc2f Mon Sep 17 00:00:00 2001 |
| From: Rui Wang <rui.wang@windriver.com> |
| Date: Fri, 15 Jun 2018 14:19:10 +0800 |
| 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://sourceforge.net/p/unfs3/bugs/12/] |
| |
| Signed-off-by: Rui Wang <rui.wang@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 73e5c75..427d0e2 100644 |
| --- a/attr.c |
| +++ b/attr.c |
| @@ -280,7 +280,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 */ |
| @@ -302,10 +302,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 fbc2af3..813ffd3 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 aeec598..ea7f167 100644 |
| --- a/configure.ac |
| +++ b/configure.ac |
| @@ -37,6 +37,7 @@ AC_CHECK_FUNCS(setresuid setresgid) |
| AC_CHECK_FUNCS(vsyslog) |
| AC_CHECK_FUNCS(lchown) |
| AC_CHECK_FUNCS(setgroups) |
| +AC_CHECK_FUNCS(lutimes) |
| UNFS3_SOLARIS_RPC |
| UNFS3_PORTMAP_DEFINE |
| UNFS3_COMPILE_WARNINGS |