aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/inode.c22
-rw-r--r--fs/namespace.c5
-rw-r--r--include/linux/fs.h1
-rw-r--r--include/linux/mount.h1
4 files changed, 24 insertions, 5 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 04536ebc5ac4..bf21dc6d0dbd 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -1177,13 +1177,27 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
1177 return; 1177 return;
1178 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)) 1178 if ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))
1179 return; 1179 return;
1180
1181 if (mnt->mnt_flags & MNT_RELATIME) {
1182 /*
1183 * With relative atime, only update atime if the
1184 * previous atime is earlier than either the ctime or
1185 * mtime.
1186 */
1187 if (timespec_compare(&inode->i_mtime,
1188 &inode->i_atime) < 0 &&
1189 timespec_compare(&inode->i_ctime,
1190 &inode->i_atime) < 0)
1191 return;
1192 }
1180 } 1193 }
1181 1194
1182 now = current_fs_time(inode->i_sb); 1195 now = current_fs_time(inode->i_sb);
1183 if (!timespec_equal(&inode->i_atime, &now)) { 1196 if (timespec_equal(&inode->i_atime, &now))
1184 inode->i_atime = now; 1197 return;
1185 mark_inode_dirty_sync(inode); 1198
1186 } 1199 inode->i_atime = now;
1200 mark_inode_dirty_sync(inode);
1187} 1201}
1188EXPORT_SYMBOL(touch_atime); 1202EXPORT_SYMBOL(touch_atime);
1189 1203
diff --git a/fs/namespace.c b/fs/namespace.c
index fde8553faa76..5ef336c1103c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -368,6 +368,7 @@ static int show_vfsmnt(struct seq_file *m, void *v)
368 { MNT_NOEXEC, ",noexec" }, 368 { MNT_NOEXEC, ",noexec" },
369 { MNT_NOATIME, ",noatime" }, 369 { MNT_NOATIME, ",noatime" },
370 { MNT_NODIRATIME, ",nodiratime" }, 370 { MNT_NODIRATIME, ",nodiratime" },
371 { MNT_RELATIME, ",relatime" },
371 { 0, NULL } 372 { 0, NULL }
372 }; 373 };
373 struct proc_fs_info *fs_infop; 374 struct proc_fs_info *fs_infop;
@@ -1405,9 +1406,11 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1405 mnt_flags |= MNT_NOATIME; 1406 mnt_flags |= MNT_NOATIME;
1406 if (flags & MS_NODIRATIME) 1407 if (flags & MS_NODIRATIME)
1407 mnt_flags |= MNT_NODIRATIME; 1408 mnt_flags |= MNT_NODIRATIME;
1409 if (flags & MS_RELATIME)
1410 mnt_flags |= MNT_RELATIME;
1408 1411
1409 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | 1412 flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
1410 MS_NOATIME | MS_NODIRATIME); 1413 MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
1411 1414
1412 /* ... and get the mountpoint */ 1415 /* ... and get the mountpoint */
1413 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); 1416 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index adce6e1d70c2..186da813541e 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -120,6 +120,7 @@ extern int dir_notify_enable;
120#define MS_PRIVATE (1<<18) /* change to private */ 120#define MS_PRIVATE (1<<18) /* change to private */
121#define MS_SLAVE (1<<19) /* change to slave */ 121#define MS_SLAVE (1<<19) /* change to slave */
122#define MS_SHARED (1<<20) /* change to shared */ 122#define MS_SHARED (1<<20) /* change to shared */
123#define MS_RELATIME (1<<21) /* Update atime relative to mtime/ctime. */
123#define MS_ACTIVE (1<<30) 124#define MS_ACTIVE (1<<30)
124#define MS_NOUSER (1<<31) 125#define MS_NOUSER (1<<31)
125 126
diff --git a/include/linux/mount.h b/include/linux/mount.h
index e357dc86a4de..1b7e178b0d84 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -27,6 +27,7 @@ struct mnt_namespace;
27#define MNT_NOEXEC 0x04 27#define MNT_NOEXEC 0x04
28#define MNT_NOATIME 0x08 28#define MNT_NOATIME 0x08
29#define MNT_NODIRATIME 0x10 29#define MNT_NODIRATIME 0x10
30#define MNT_RELATIME 0x20
30 31
31#define MNT_SHRINKABLE 0x100 32#define MNT_SHRINKABLE 0x100
32 33