Commit fc33a7bb9c6dd8f6e4a014976200f8fdabb3a45c

Authored by Christoph Hellwig
Committed by Linus Torvalds
1 parent 0d456fa426

[PATCH] per-mountpoint noatime/nodiratime

Turn noatime and nodiratime into per-mount instead of per-sb flags.

After all the preparations this is a rather trivial patch.  The mount code
needs to treat the two options as per-mount instead of per-superblock, and
touch_atime needs to be changed to check the new MNT_ flags in addition to
the MS_ flags that are kept for filesystems that are always
noatime/nodiratime but not user settable anymore.  Besides that core code
only nfs needed an update because it's leaving atime updates to the server
and thus sets the S_NOATIME flag on every inode, but needs to know whether
it's a real noatime mount for an getattr optimization.

While we're at it I've killed the IS_NOATIME/IS_NODIRATIME macros that were
only used by touch_atime.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 6 changed files with 44 additions and 18 deletions Side-by-side Diff

... ... @@ -22,6 +22,7 @@
22 22 #include <linux/cdev.h>
23 23 #include <linux/bootmem.h>
24 24 #include <linux/inotify.h>
  25 +#include <linux/mount.h>
25 26  
26 27 /*
27 28 * This is needed for the following functions:
28 29  
29 30  
... ... @@ -1189,12 +1190,20 @@
1189 1190 struct inode *inode = dentry->d_inode;
1190 1191 struct timespec now;
1191 1192  
1192   - /* per-mountpoint checks will go here */
1193   - if (IS_NOATIME(inode))
  1193 + if (IS_RDONLY(inode))
1194 1194 return;
1195   - if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
  1195 +
  1196 + if ((inode->i_flags & S_NOATIME) ||
  1197 + (inode->i_sb->s_flags & MS_NOATIME) ||
  1198 + ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
1196 1199 return;
1197   - if (IS_RDONLY(inode))
  1200 +
  1201 + /*
  1202 + * We may have a NULL vfsmount when coming from NFSD
  1203 + */
  1204 + if (mnt &&
  1205 + ((mnt->mnt_flags & MNT_NOATIME) ||
  1206 + ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))))
1198 1207 return;
1199 1208  
1200 1209 now = current_fs_time(inode->i_sb);
... ... @@ -355,14 +355,14 @@
355 355 { MS_SYNCHRONOUS, ",sync" },
356 356 { MS_DIRSYNC, ",dirsync" },
357 357 { MS_MANDLOCK, ",mand" },
358   - { MS_NOATIME, ",noatime" },
359   - { MS_NODIRATIME, ",nodiratime" },
360 358 { 0, NULL }
361 359 };
362 360 static struct proc_fs_info mnt_info[] = {
363 361 { MNT_NOSUID, ",nosuid" },
364 362 { MNT_NODEV, ",nodev" },
365 363 { MNT_NOEXEC, ",noexec" },
  364 + { MNT_NOATIME, ",noatime" },
  365 + { MNT_NODIRATIME, ",nodiratime" },
366 366 { 0, NULL }
367 367 };
368 368 struct proc_fs_info *fs_infop;
... ... @@ -1286,7 +1286,13 @@
1286 1286 mnt_flags |= MNT_NODEV;
1287 1287 if (flags & MS_NOEXEC)
1288 1288 mnt_flags |= MNT_NOEXEC;
1289   - flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE);
  1289 + if (flags & MS_NOATIME)
  1290 + mnt_flags |= MNT_NOATIME;
  1291 + if (flags & MS_NODIRATIME)
  1292 + mnt_flags |= MNT_NODIRATIME;
  1293 +
  1294 + flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
  1295 + MS_NOATIME | MS_NODIRATIME);
1290 1296  
1291 1297 /* ... and get the mountpoint */
1292 1298 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
... ... @@ -950,11 +950,20 @@
950 950  
951 951 /* Flush out writes to the server in order to update c/mtime */
952 952 nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
953   - if (__IS_FLG(inode, MS_NOATIME))
  953 +
  954 + /*
  955 + * We may force a getattr if the user cares about atime.
  956 + *
  957 + * Note that we only have to check the vfsmount flags here:
  958 + * - NFS always sets S_NOATIME by so checking it would give a
  959 + * bogus result
  960 + * - NFS never sets MS_NOATIME or MS_NODIRATIME so there is
  961 + * no point in checking those.
  962 + */
  963 + if ((mnt->mnt_flags & MNT_NOATIME) ||
  964 + ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
954 965 need_atime = 0;
955   - else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode))
956   - need_atime = 0;
957   - /* We may force a getattr if the user cares about atime */
  966 +
958 967 if (need_atime)
959 968 err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
960 969 else
fs/xfs/linux-2.6/xfs_iops.c
... ... @@ -54,6 +54,9 @@
54 54 #include <linux/xattr.h>
55 55 #include <linux/namei.h>
56 56  
  57 +#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \
  58 + (S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
  59 +
57 60 /*
58 61 * Change the requested timestamp in the given inode.
59 62 * We don't lock across timestamp updates, and we don't log them but
... ... @@ -114,8 +114,7 @@
114 114 /*
115 115 * Superblock flags that can be altered by MS_REMOUNT
116 116 */
117   -#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|\
118   - MS_NODIRATIME)
  117 +#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
119 118  
120 119 /*
121 120 * Old magic mount flag and mask
... ... @@ -161,8 +160,6 @@
161 160 #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
162 161 #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
163 162 #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
164   -#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
165   -#define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
166 163 #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
167 164  
168 165 #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
include/linux/mount.h
... ... @@ -20,10 +20,12 @@
20 20 #define MNT_NOSUID 0x01
21 21 #define MNT_NODEV 0x02
22 22 #define MNT_NOEXEC 0x04
23   -#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */
24   -#define MNT_UNBINDABLE 0x20 /* if the vfsmount is a unbindable mount */
  23 +#define MNT_NOATIME 0x08
  24 +#define MNT_NODIRATIME 0x10
25 25  
26   -#define MNT_PNODE_MASK (MNT_SHARED | MNT_UNBINDABLE)
  26 +#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
  27 +#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
  28 +#define MNT_PNODE_MASK 0x3000 /* propogation flag mask */
27 29  
28 30 struct vfsmount {
29 31 struct list_head mnt_hash;