In ll_md_blocking_ast(), we zero all timestamps to avoid these
'leftovers' interfering the new timestamps from MDS, especially
when the timestamps are set back by other clients. It's not
quite right to change timestamps in this way, because:
1. The pending lock can be matched by getattr, so these zero
timestamps can be fetched by application in a small race window.
2. It doesn't make sense to zero the mtime and ctime, because we
always use the newest ctime and mtime from MDS when do attributes
merge, they won't interfere new timestamps set by other clients.
Signed-off-by: Niu Yawei <yawei.niu@intel.com>
Change-Id: Ieb9577abe4938bc47dc0577454a4a1bbf4796876
Reviewed-on: https://review.whamcloud.com/24984
Tested-by: Jenkins
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
* All in all, the atime in Lustre does not strictly comply with
* POSIX. Solving this problem needs to send an RPC to MDT for each
* read, this will hurt performance. */
- if (LTIME_S(inode->i_atime) < lli->lli_atime)
+ if (LTIME_S(inode->i_atime) < lli->lli_atime || lli->lli_update_atime) {
LTIME_S(inode->i_atime) = lli->lli_atime;
+ lli->lli_update_atime = 0;
+ }
LTIME_S(inode->i_mtime) = lli->lli_mtime;
LTIME_S(inode->i_ctime) = lli->lli_ctime;
s64 lli_ctime;
spinlock_t lli_agl_lock;
+ /* update atime from MDS no matter if it's older than
+ * local inode atime. */
+ unsigned int lli_update_atime:1;
+
/* Try to make the d::member and f::member are aligned. Before using
* these members, make clear whether it is directory or not. */
union {
if (bits & MDS_INODELOCK_UPDATE) {
struct ll_inode_info *lli = ll_i2info(inode);
-
- spin_lock(&lli->lli_lock);
- LTIME_S(inode->i_mtime) = 0;
- LTIME_S(inode->i_atime) = 0;
- LTIME_S(inode->i_ctime) = 0;
- spin_unlock(&lli->lli_lock);
+ lli->lli_update_atime = 1;
}
if ((bits & MDS_INODELOCK_UPDATE) && S_ISDIR(inode->i_mode)) {