aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2006-01-09 23:52:17 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-01-10 11:01:34 -0500
commitfc33a7bb9c6dd8f6e4a014976200f8fdabb3a45c (patch)
tree26f4d676de476075545e58057aa5d8c57618741d
parent0d456fa4261f43433287a10fe3ec04a9818fac64 (diff)
[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>
-rw-r--r--fs/inode.c17
-rw-r--r--fs/namespace.c12
-rw-r--r--fs/nfs/inode.c17
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c3
-rw-r--r--include/linux/fs.h5
-rw-r--r--include/linux/mount.h8
6 files changed, 44 insertions, 18 deletions
diff --git a/fs/inode.c b/fs/inode.c
index 76980a9c92e7..108138d4e909 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -22,6 +22,7 @@
22#include <linux/cdev.h> 22#include <linux/cdev.h>
23#include <linux/bootmem.h> 23#include <linux/bootmem.h>
24#include <linux/inotify.h> 24#include <linux/inotify.h>
25#include <linux/mount.h>
25 26
26/* 27/*
27 * This is needed for the following functions: 28 * This is needed for the following functions:
@@ -1189,12 +1190,20 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
1189 struct inode *inode = dentry->d_inode; 1190 struct inode *inode = dentry->d_inode;
1190 struct timespec now; 1191 struct timespec now;
1191 1192
1192 /* per-mountpoint checks will go here */ 1193 if (IS_RDONLY(inode))
1193 if (IS_NOATIME(inode))
1194 return; 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 return; 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 return; 1207 return;
1199 1208
1200 now = current_fs_time(inode->i_sb); 1209 now = current_fs_time(inode->i_sb);
diff --git a/fs/namespace.c b/fs/namespace.c
index f0e353f5bc30..2ca6145f43d6 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -355,14 +355,14 @@ static int show_vfsmnt(struct seq_file *m, void *v)
355 { MS_SYNCHRONOUS, ",sync" }, 355 { MS_SYNCHRONOUS, ",sync" },
356 { MS_DIRSYNC, ",dirsync" }, 356 { MS_DIRSYNC, ",dirsync" },
357 { MS_MANDLOCK, ",mand" }, 357 { MS_MANDLOCK, ",mand" },
358 { MS_NOATIME, ",noatime" },
359 { MS_NODIRATIME, ",nodiratime" },
360 { 0, NULL } 358 { 0, NULL }
361 }; 359 };
362 static struct proc_fs_info mnt_info[] = { 360 static struct proc_fs_info mnt_info[] = {
363 { MNT_NOSUID, ",nosuid" }, 361 { MNT_NOSUID, ",nosuid" },
364 { MNT_NODEV, ",nodev" }, 362 { MNT_NODEV, ",nodev" },
365 { MNT_NOEXEC, ",noexec" }, 363 { MNT_NOEXEC, ",noexec" },
364 { MNT_NOATIME, ",noatime" },
365 { MNT_NODIRATIME, ",nodiratime" },
366 { 0, NULL } 366 { 0, NULL }
367 }; 367 };
368 struct proc_fs_info *fs_infop; 368 struct proc_fs_info *fs_infop;
@@ -1286,7 +1286,13 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
1286 mnt_flags |= MNT_NODEV; 1286 mnt_flags |= MNT_NODEV;
1287 if (flags & MS_NOEXEC) 1287 if (flags & MS_NOEXEC)
1288 mnt_flags |= MNT_NOEXEC; 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 /* ... and get the mountpoint */ 1297 /* ... and get the mountpoint */
1292 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); 1298 retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 3e4ba9cb7f80..a77ee95b7efb 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -950,11 +950,20 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
950 950
951 /* Flush out writes to the server in order to update c/mtime */ 951 /* Flush out writes to the server in order to update c/mtime */
952 nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT); 952 nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
953 if (__IS_FLG(inode, MS_NOATIME)) 953
954 need_atime = 0; 954 /*
955 else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode)) 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)))
956 need_atime = 0; 965 need_atime = 0;
957 /* We may force a getattr if the user cares about atime */ 966
958 if (need_atime) 967 if (need_atime)
959 err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); 968 err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
960 else 969 else
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 41c478bb1ffc..97fb1470cf28 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -54,6 +54,9 @@
54#include <linux/xattr.h> 54#include <linux/xattr.h>
55#include <linux/namei.h> 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 * Change the requested timestamp in the given inode. 61 * Change the requested timestamp in the given inode.
59 * We don't lock across timestamp updates, and we don't log them but 62 * We don't lock across timestamp updates, and we don't log them but
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 85c5656756b6..d1e370d25f7b 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -114,8 +114,7 @@ extern int dir_notify_enable;
114/* 114/*
115 * Superblock flags that can be altered by MS_REMOUNT 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|\ 117#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
118 MS_NODIRATIME)
119 118
120/* 119/*
121 * Old magic mount flag and mask 120 * Old magic mount flag and mask
@@ -161,8 +160,6 @@ extern int dir_notify_enable;
161#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) 160#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
162#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) 161#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
163#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) 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#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) 163#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
167 164
168#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) 165#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
diff --git a/include/linux/mount.h b/include/linux/mount.h
index b98a709f1794..b7472ae91fa4 100644
--- a/include/linux/mount.h
+++ b/include/linux/mount.h
@@ -20,10 +20,12 @@
20#define MNT_NOSUID 0x01 20#define MNT_NOSUID 0x01
21#define MNT_NODEV 0x02 21#define MNT_NODEV 0x02
22#define MNT_NOEXEC 0x04 22#define MNT_NOEXEC 0x04
23#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */ 23#define MNT_NOATIME 0x08
24#define MNT_UNBINDABLE 0x20 /* if the vfsmount is a unbindable mount */ 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
28struct vfsmount { 30struct vfsmount {
29 struct list_head mnt_hash; 31 struct list_head mnt_hash;