aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/inode.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 826fb0b9d1c3..6ac0cef6c5f5 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1290,6 +1290,40 @@ sector_t bmap(struct inode * inode, sector_t block)
1290} 1290}
1291EXPORT_SYMBOL(bmap); 1291EXPORT_SYMBOL(bmap);
1292 1292
1293/*
1294 * With relative atime, only update atime if the previous atime is
1295 * earlier than either the ctime or mtime or if at least a day has
1296 * passed since the last atime update.
1297 */
1298static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
1299 struct timespec now)
1300{
1301
1302 if (!(mnt->mnt_flags & MNT_RELATIME))
1303 return 1;
1304 /*
1305 * Is mtime younger than atime? If yes, update atime:
1306 */
1307 if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
1308 return 1;
1309 /*
1310 * Is ctime younger than atime? If yes, update atime:
1311 */
1312 if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
1313 return 1;
1314
1315 /*
1316 * Is the previous atime value older than a day? If yes,
1317 * update atime:
1318 */
1319 if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60)
1320 return 1;
1321 /*
1322 * Good, we can skip the atime update:
1323 */
1324 return 0;
1325}
1326
1293/** 1327/**
1294 * touch_atime - update the access time 1328 * touch_atime - update the access time
1295 * @mnt: mount the inode is accessed on 1329 * @mnt: mount the inode is accessed on
@@ -1317,17 +1351,12 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
1317 goto out; 1351 goto out;
1318 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) 1352 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
1319 goto out; 1353 goto out;
1320 if (mnt->mnt_flags & MNT_RELATIME) {
1321 /*
1322 * With relative atime, only update atime if the previous
1323 * atime is earlier than either the ctime or mtime.
1324 */
1325 if (timespec_compare(&inode->i_mtime, &inode->i_atime) < 0 &&
1326 timespec_compare(&inode->i_ctime, &inode->i_atime) < 0)
1327 goto out;
1328 }
1329 1354
1330 now = current_fs_time(inode->i_sb); 1355 now = current_fs_time(inode->i_sb);
1356
1357 if (!relatime_need_update(mnt, inode, now))
1358 goto out;
1359
1331 if (timespec_equal(&inode->i_atime, &now)) 1360 if (timespec_equal(&inode->i_atime, &now))
1332 goto out; 1361 goto out;
1333 1362