diff options
| author | Christoph Hellwig <hch@lst.de> | 2006-01-09 23:52:17 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-10 11:01:34 -0500 |
| commit | fc33a7bb9c6dd8f6e4a014976200f8fdabb3a45c (patch) | |
| tree | 26f4d676de476075545e58057aa5d8c57618741d | |
| parent | 0d456fa4261f43433287a10fe3ec04a9818fac64 (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.c | 17 | ||||
| -rw-r--r-- | fs/namespace.c | 12 | ||||
| -rw-r--r-- | fs/nfs/inode.c | 17 | ||||
| -rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 3 | ||||
| -rw-r--r-- | include/linux/fs.h | 5 | ||||
| -rw-r--r-- | include/linux/mount.h | 8 |
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 | ||
| 28 | struct vfsmount { | 30 | struct vfsmount { |
| 29 | struct list_head mnt_hash; | 31 | struct list_head mnt_hash; |
