aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/inode.c47
-rw-r--r--fs/namespace.c11
2 files changed, 46 insertions, 12 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
diff --git a/fs/namespace.c b/fs/namespace.c
index 06f8e63f6cb1..f0e753097353 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -780,6 +780,7 @@ static void show_mnt_opts(struct seq_file *m, struct vfsmount *mnt)
780 { MNT_NOATIME, ",noatime" }, 780 { MNT_NOATIME, ",noatime" },
781 { MNT_NODIRATIME, ",nodiratime" }, 781 { MNT_NODIRATIME, ",nodiratime" },
782 { MNT_RELATIME, ",relatime" }, 782 { MNT_RELATIME, ",relatime" },
783 { MNT_STRICTATIME, ",strictatime" },
783 { 0, NULL } 784 { 0, NULL }
784 }; 785 };
785 const struct proc_fs_info *fs_infop; 786 const struct proc_fs_info *fs_infop;
@@ -1919,6 +1920,9 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1919 if (data_page) 1920 if (data_page)
1920 ((char *)data_page)[PAGE_SIZE - 1] = 0; 1921 ((char *)data_page)[PAGE_SIZE - 1] = 0;
1921 1922
1923 /* Default to relatime */
1924 mnt_flags |= MNT_RELATIME;
1925
1922 /* Separate the per-mountpoint flags */ 1926 /* Separate the per-mountpoint flags */
1923 if (flags & MS_NOSUID) 1927 if (flags & MS_NOSUID)
1924 mnt_flags |= MNT_NOSUID; 1928 mnt_flags |= MNT_NOSUID;
@@ -1930,13 +1934,14 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1930 mnt_flags |= MNT_NOATIME; 1934 mnt_flags |= MNT_NOATIME;
1931 if (flags & MS_NODIRATIME) 1935 if (flags & MS_NODIRATIME)
1932 mnt_flags |= MNT_NODIRATIME; 1936 mnt_flags |= MNT_NODIRATIME;
1933 if (flags & MS_RELATIME) 1937 if (flags & MS_STRICTATIME)
1934 mnt_flags |= MNT_RELATIME; 1938 mnt_flags &= ~(MNT_RELATIME | MNT_NOATIME);
1935 if (flags & MS_RDONLY) 1939 if (flags & MS_RDONLY)
1936 mnt_flags |= MNT_READONLY; 1940 mnt_flags |= MNT_READONLY;
1937 1941
1938 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | 1942 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
1939 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); 1943 MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT |
1944 MS_STRICTATIME);
1940 1945
1941 /* ... and get the mountpoint */ 1946 /* ... and get the mountpoint */
1942 retval = kern_path(dir_name, LOOKUP_FOLLOW, &path); 1947 retval = kern_path(dir_name, LOOKUP_FOLLOW, &path);