aboutsummaryrefslogtreecommitdiffstats
path: root/fs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/inode.c')
-rw-r--r--fs/inode.c47
1 files changed, 38 insertions, 9 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 8a47ccd9fc38..643ac43e5a5c 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1300,6 +1300,40 @@ sector_t bmap(struct inode * inode, sector_t block)
1300} 1300}
1301EXPORT_SYMBOL(bmap); 1301EXPORT_SYMBOL(bmap);
1302 1302
1303/*
1304 * With relative atime, only update atime if the previous atime is
1305 * earlier than either the ctime or mtime or if at least a day has
1306 * passed since the last atime update.
1307 */
1308static int relatime_need_update(struct vfsmount *mnt, struct inode *inode,
1309 struct timespec now)
1310{
1311
1312 if (!(mnt->mnt_flags & MNT_RELATIME))
1313 return 1;
1314 /*
1315 * Is mtime younger than atime? If yes, update atime:
1316 */
1317 if (timespec_compare(&inode->i_mtime, &inode->i_atime) >= 0)
1318 return 1;
1319 /*
1320 * Is ctime younger than atime? If yes, update atime:
1321 */
1322 if (timespec_compare(&inode->i_ctime, &inode->i_atime) >= 0)
1323 return 1;
1324
1325 /*
1326 * Is the previous atime value older than a day? If yes,
1327 * update atime:
1328 */
1329 if ((long)(now.tv_sec - inode->i_atime.tv_sec) >= 24*60*60)
1330 return 1;
1331 /*
1332 * Good, we can skip the atime update:
1333 */
1334 return 0;
1335}
1336
1303/** 1337/**
1304 * touch_atime - update the access time 1338 * touch_atime - update the access time
1305 * @mnt: mount the inode is accessed on 1339 * @mnt: mount the inode is accessed on
@@ -1327,17 +1361,12 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
1327 goto out; 1361 goto out;
1328 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) 1362 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
1329 goto out; 1363 goto out;
1330 if (mnt->mnt_flags & MNT_RELATIME) {
1331 /*
1332 * With relative atime, only update atime if the previous
1333 * atime is earlier than either the ctime or mtime.
1334 */
1335 if (timespec_compare(&inode->i_mtime, &inode->i_atime) < 0 &&
1336 timespec_compare(&inode->i_ctime, &inode->i_atime) < 0)
1337 goto out;
1338 }
1339 1364
1340 now = current_fs_time(inode->i_sb); 1365 now = current_fs_time(inode->i_sb);
1366
1367 if (!relatime_need_update(mnt, inode, now))
1368 goto out;
1369
1341 if (timespec_equal(&inode->i_atime, &now)) 1370 if (timespec_equal(&inode->i_atime, &now))
1342 goto out; 1371 goto out;
1343 1372