diff options
| -rw-r--r-- | libglusterfs/src/compat.h | 12 | ||||
| -rwxr-xr-x | tests/bugs/nfs/zero-atime.t | 31 | ||||
| -rw-r--r-- | xlators/storage/posix/src/posix.c | 26 | 
3 files changed, 63 insertions, 6 deletions
diff --git a/libglusterfs/src/compat.h b/libglusterfs/src/compat.h index ea722028eb5..fbaac76b9ee 100644 --- a/libglusterfs/src/compat.h +++ b/libglusterfs/src/compat.h @@ -444,6 +444,12 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags);  #ifdef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC  /* Linux, Solaris, Cygwin */ +#define ST_ATIM_SEC(stbuf) ((stbuf)->st_atim.tv_sec) +#define ST_CTIM_SEC(stbuf) ((stbuf)->st_ctim.tv_sec) +#define ST_MTIM_SEC(stbuf) ((stbuf)->st_mtim.tv_sec) +#define ST_ATIM_SEC_SET(stbuf, val) ((stbuf)->st_atim.tv_sec = (val)) +#define ST_MTIM_SEC_SET(stbuf, val) ((stbuf)->st_mtim.tv_sec = (val)) +#define ST_CTIM_SEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_sec = (val))  #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atim.tv_nsec)  #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctim.tv_nsec)  #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtim.tv_nsec) @@ -452,6 +458,12 @@ int gf_mkostemp (char *tmpl, int suffixlen, int flags);  #define ST_CTIM_NSEC_SET(stbuf, val) ((stbuf)->st_ctim.tv_nsec = (val))  #elif defined(HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC)  /* FreeBSD, NetBSD */ +#define ST_ATIM_SEC(stbuf) ((stbuf)->st_atimespec.tv_sec) +#define ST_CTIM_SEC(stbuf) ((stbuf)->st_ctimespec.tv_sec) +#define ST_MTIM_SEC(stbuf) ((stbuf)->st_mtimespec.tv_sec) +#define ST_ATIM_SEC_SET(stbuf, val) ((stbuf)->st_atimespec.tv_sec = (val)) +#define ST_MTIM_SEC_SET(stbuf, val) ((stbuf)->st_mtimespec.tv_sec = (val)) +#define ST_CTIM_SEC_SET(stbuf, val) ((stbuf)->st_ctimespec.tv_sec = (val))  #define ST_ATIM_NSEC(stbuf) ((stbuf)->st_atimespec.tv_nsec)  #define ST_CTIM_NSEC(stbuf) ((stbuf)->st_ctimespec.tv_nsec)  #define ST_MTIM_NSEC(stbuf) ((stbuf)->st_mtimespec.tv_nsec) diff --git a/tests/bugs/nfs/zero-atime.t b/tests/bugs/nfs/zero-atime.t new file mode 100755 index 00000000000..631240a692f --- /dev/null +++ b/tests/bugs/nfs/zero-atime.t @@ -0,0 +1,31 @@ +#!/bin/bash +# +# posix_do_utimes() sets atime and mtime to the values in the passed IATT. If +# not set, these values are 0 and cause a atime/mtime set to the Epoch. +# + +. $(dirname $0)/../../include.rc +. $(dirname $0)/../../volume.rc +. $(dirname $0)/../../nfs.rc + +cleanup + +TEST glusterd +TEST pidof glusterd + +TEST $CLI volume create $V0 $H0:$B0/$V0 +TEST $CLI volume set $V0 nfs.disable false +TEST $CLI volume start $V0 +EXPECT_WITHIN $NFS_EXPORT_TIMEOUT "1" is_nfs_export_available; +TEST mount_nfs $H0:/$V0 $N0 nolock + +# create a file for testing +TEST dd if=/dev/urandom of=$M0/small count=1 bs=1024k + +# timezone in UTC results in atime=0 if not set correctly +TEST TZ=UTC dd if=/dev/urandom of=$M0/small bs=64k count=1 conv=nocreat +TEST [ "$(stat --format=%X $M0/small)" != "0" ] + +TEST rm $M0/small + +cleanup diff --git a/xlators/storage/posix/src/posix.c b/xlators/storage/posix/src/posix.c index d7b175c9434..0b1fe56b9b4 100644 --- a/xlators/storage/posix/src/posix.c +++ b/xlators/storage/posix/src/posix.c @@ -375,7 +375,8 @@ posix_do_chown (xlator_t *this,  static int  posix_do_utimes (xlator_t *this,                   const char *path, -                 struct iatt *stbuf) +                 struct iatt *stbuf, +                 int valid)  {          int32_t ret = -1;          struct timeval tv[2]     = {{0,},{0,}}; @@ -392,10 +393,23 @@ posix_do_utimes (xlator_t *this,          if (S_ISLNK (stat.st_mode))                  is_symlink = 1; -        tv[0].tv_sec  = stbuf->ia_atime; -        tv[0].tv_usec = stbuf->ia_atime_nsec / 1000; -        tv[1].tv_sec  = stbuf->ia_mtime; -        tv[1].tv_usec = stbuf->ia_mtime_nsec / 1000; +        if ((valid & GF_SET_ATTR_ATIME) == GF_SET_ATTR_ATIME) { +                tv[0].tv_sec  = stbuf->ia_atime; +                tv[0].tv_usec = stbuf->ia_atime_nsec / 1000; +        } else { +                /* atime is not given, use current values */ +                tv[0].tv_sec  = ST_ATIM_SEC (&stat); +                tv[0].tv_usec = ST_ATIM_NSEC (&stat) / 1000; +        } + +        if ((valid & GF_SET_ATTR_MTIME) == GF_SET_ATTR_MTIME) { +                tv[1].tv_sec  = stbuf->ia_mtime; +                tv[1].tv_usec = stbuf->ia_mtime_nsec / 1000; +        } else { +                /* mtime is not given, use current values */ +                tv[1].tv_sec  = ST_MTIM_SEC (&stat); +                tv[1].tv_usec = ST_MTIM_NSEC (&stat) / 1000; +        }          ret = lutimes (path, tv);          if ((ret == -1) && (errno == ENOSYS)) { @@ -464,7 +478,7 @@ posix_setattr (call_frame_t *frame, xlator_t *this,          }          if (valid & (GF_SET_ATTR_ATIME | GF_SET_ATTR_MTIME)) { -                op_ret = posix_do_utimes (this, real_path, stbuf); +                op_ret = posix_do_utimes (this, real_path, stbuf, valid);                  if (op_ret == -1) {                          op_errno = errno;                          gf_msg (this->name, GF_LOG_ERROR, errno,  | 
