From af54923a803db32ee1d2bdc6e8fdc9d3aacc1616 Mon Sep 17 00:00:00 2001 From: Matt Benjamin Date: Fri, 7 Jun 2019 10:20:01 -0400 Subject: [PATCH] rgw_file: all directories are virtual with respect to contents This change causes directory handles to always report an mtime of "now." This is not an invalidate per se--it interacts with the nfs implementation to produce that result when the implementation updates its cached attributes. Hence, it can be modulated by timers or other rules governing attribute caching at the upper layer. Fixes: http://tracker.ceph.com/issues/40204 Signed-off-by: Matt Benjamin (cherry picked from commit b4c7d0faeff667c25ab255786999ef0cc844ea2b) --- src/rgw/rgw_file.cc | 2 +- src/rgw/rgw_file.h | 41 +++++++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/rgw/rgw_file.cc b/src/rgw/rgw_file.cc index 5c0a4d3beffbd..4889b28b7b6aa 100644 --- a/src/rgw/rgw_file.cc +++ b/src/rgw/rgw_file.cc @@ -810,7 +810,7 @@ namespace rgw { default: break; }; - + /* if rgw_fh is a directory, mtime will be advanced */ return rgw_fh->stat(st); } /* RGWLibFS::getattr */ diff --git a/src/rgw/rgw_file.h b/src/rgw/rgw_file.h index 1bd9433240370..622294b674604 100644 --- a/src/rgw/rgw_file.h +++ b/src/rgw/rgw_file.h @@ -232,6 +232,15 @@ namespace rgw { void clear_state(); + void advance_mtime() { + /* intended for use on directories, fast-forward mtime so as to + * ensure a new, higher value for the change attribute */ + lock_guard guard(mtx); + /* sets ctime as well as mtime, to avoid masking updates should + * ctime inexplicably hold a higher value */ + set_times(real_clock::now()); + } + boost::variant variant_type; uint16_t depth; @@ -342,6 +351,8 @@ namespace rgw { switch (fh.fh_type) { case RGW_FS_TYPE_DIRECTORY: state.unix_mode = RGW_RWXMODE|S_IFDIR; + /* virtual directories are always invalid */ + advance_mtime(); break; case RGW_FS_TYPE_FILE: state.unix_mode = RGW_RWMODE|S_IFREG; @@ -413,8 +424,12 @@ namespace rgw { if (mask & RGW_SETATTR_ATIME) state.atime = st->st_atim; - if (mask & RGW_SETATTR_MTIME) - state.mtime = st->st_mtim; + + if (mask & RGW_SETATTR_MTIME) { + if (fh.fh_type != RGW_FS_TYPE_DIRECTORY) + state.mtime = st->st_mtim; + } + if (mask & RGW_SETATTR_CTIME) state.ctime = st->st_ctim; } @@ -430,18 +445,10 @@ namespace rgw { st->st_mode = state.unix_mode; -#ifdef HAVE_STAT_ST_MTIMESPEC_TV_NSEC - st->st_atimespec = state.atime; - st->st_mtimespec = state.mtime; - st->st_ctimespec = state.ctime; -#else - st->st_atim = state.atime; - st->st_mtim = state.mtime; - st->st_ctim = state.ctime; -#endif - switch (fh.fh_type) { case RGW_FS_TYPE_DIRECTORY: + /* virtual directories are always invalid */ + advance_mtime(); st->st_nlink = state.nlink; break; case RGW_FS_TYPE_FILE: @@ -460,6 +467,16 @@ namespace rgw { break; } +#ifdef HAVE_STAT_ST_MTIMESPEC_TV_NSEC + st->st_atimespec = state.atime; + st->st_mtimespec = state.mtime; + st->st_ctimespec = state.ctime; +#else + st->st_atim = state.atime; + st->st_mtim = state.mtime; + st->st_ctim = state.ctime; +#endif + return 0; } -- 2.39.5