1From 3f4fcb62661059bad77a2e957b4621137797bc2f Mon Sep 17 00:00:00 2001 2From: Rui Wang <rui.wang@windriver.com> 3Date: Fri, 15 Jun 2018 14:19:10 +0800 4Subject: [PATCH] attr: fix utime for symlink 5 6unfs3 has an old defect that it can not change the timestamps of a 7symlink file because it only uses utime(), which will follow the 8symlink. This will not cause an error if the symlink points to an 9existent file. But under some special situation, such as installing 10a rpm package, rpm tool will create the symlink first and try to 11modify the timestamps of it, when the target file is non-existent. 12This will cause an ESTALE error. Making rpm tool ignore this error 13is a solution, but not the best one. An acceptable approach is 14Making unfs3 support lutimes(), which can modify the symlink file 15itself. Considering not every system support this function, so a 16function checking is necessary. 17 18Upstream-Status: Submitted [https://sourceforge.net/p/unfs3/bugs/12/] 19 20Signed-off-by: Rui Wang <rui.wang@windriver.com> 21--- 22 attr.c | 15 +++++++++++---- 23 backend_unix.h | 2 ++ 24 configure.ac | 1 + 25 3 files changed, 14 insertions(+), 4 deletions(-) 26 27diff --git a/attr.c b/attr.c 28index 73e5c75..427d0e2 100644 29--- a/attr.c 30+++ b/attr.c 31@@ -280,7 +280,7 @@ post_op_attr get_post_cached(struct svc_req * req) 32 static nfsstat3 set_time(const char *path, backend_statstruct buf, sattr3 new) 33 { 34 time_t new_atime, new_mtime; 35- struct utimbuf utim; 36+ struct timeval stamps[2]; 37 int res; 38 39 /* set atime and mtime */ 40@@ -302,10 +302,17 @@ static nfsstat3 set_time(const char *path, backend_statstruct buf, sattr3 new) 41 else /* DONT_CHANGE */ 42 new_mtime = buf.st_mtime; 43 44- utim.actime = new_atime; 45- utim.modtime = new_mtime; 46+ stamps[0].tv_sec = new_atime; 47+ stamps[0].tv_usec = 0; 48+ stamps[1].tv_sec = new_mtime; 49+ stamps[1].tv_usec = 0; 50+ 51+#if HAVE_LUTIMES 52+ res = backend_lutimes(path, stamps); 53+#else 54+ res = backend_utimes(path, stamps); 55+#endif 56 57- res = backend_utime(path, &utim); 58 if (res == -1) 59 return setattr_err(); 60 } 61diff --git a/backend_unix.h b/backend_unix.h 62index fbc2af3..813ffd3 100644 63--- a/backend_unix.h 64+++ b/backend_unix.h 65@@ -61,6 +61,8 @@ 66 #define backend_symlink symlink 67 #define backend_truncate truncate 68 #define backend_utime utime 69+#define backend_utimes utimes 70+#define backend_lutimes lutimes 71 #define backend_statstruct struct stat 72 #define backend_dirstream DIR 73 #define backend_statvfsstruct struct statvfs 74diff --git a/configure.ac b/configure.ac 75index aeec598..ea7f167 100644 76--- a/configure.ac 77+++ b/configure.ac 78@@ -37,6 +37,7 @@ AC_CHECK_FUNCS(setresuid setresgid) 79 AC_CHECK_FUNCS(vsyslog) 80 AC_CHECK_FUNCS(lchown) 81 AC_CHECK_FUNCS(setgroups) 82+AC_CHECK_FUNCS(lutimes) 83 UNFS3_SOLARIS_RPC 84 UNFS3_PORTMAP_DEFINE 85 UNFS3_COMPILE_WARNINGS 86