Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Christoph Hellwig and committed by
Linus Torvalds
fc33a7bb 0d456fa4

+45 -19
+14 -5
fs/inode.c
··· 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: ··· 1190 1189 struct inode *inode = dentry->d_inode; 1191 1190 struct timespec now; 1192 1191 1193 - /* per-mountpoint checks will go here */ 1194 - if (IS_NOATIME(inode)) 1195 - return; 1196 - if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode)) 1197 - return; 1198 1192 if (IS_RDONLY(inode)) 1193 + return; 1194 + 1195 + if ((inode->i_flags & S_NOATIME) || 1196 + (inode->i_sb->s_flags & MS_NOATIME) || 1197 + ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode))) 1198 + return; 1199 + 1200 + /* 1201 + * We may have a NULL vfsmount when coming from NFSD 1202 + */ 1203 + if (mnt && 1204 + ((mnt->mnt_flags & MNT_NOATIME) || 1205 + ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))) 1199 1206 return; 1200 1207 1201 1208 now = current_fs_time(inode->i_sb);
+9 -3
fs/namespace.c
··· 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 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);
+13 -4
fs/nfs/inode.c
··· 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
+3
fs/xfs/linux-2.6/xfs_iops.c
··· 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
+1 -4
include/linux/fs.h
··· 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 ··· 160 161 #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) 161 162 #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) 162 163 #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) 163 - #define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME)) 164 - #define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME) 165 164 #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) 166 165 167 166 #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
+5 -3
include/linux/mount.h
··· 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;