mirror of https://gitee.com/openkylin/linux.git
[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>
This commit is contained in:
parent
0d456fa426
commit
fc33a7bb9c
19
fs/inode.c
19
fs/inode.c
|
@ -22,6 +22,7 @@
|
||||||
#include <linux/cdev.h>
|
#include <linux/cdev.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
#include <linux/inotify.h>
|
#include <linux/inotify.h>
|
||||||
|
#include <linux/mount.h>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is needed for the following functions:
|
* This is needed for the following functions:
|
||||||
|
@ -1189,14 +1190,22 @@ void touch_atime(struct vfsmount *mnt, struct dentry *dentry)
|
||||||
struct inode *inode = dentry->d_inode;
|
struct inode *inode = dentry->d_inode;
|
||||||
struct timespec now;
|
struct timespec now;
|
||||||
|
|
||||||
/* per-mountpoint checks will go here */
|
|
||||||
if (IS_NOATIME(inode))
|
|
||||||
return;
|
|
||||||
if (IS_NODIRATIME(inode) && S_ISDIR(inode->i_mode))
|
|
||||||
return;
|
|
||||||
if (IS_RDONLY(inode))
|
if (IS_RDONLY(inode))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if ((inode->i_flags & S_NOATIME) ||
|
||||||
|
(inode->i_sb->s_flags & MS_NOATIME) ||
|
||||||
|
((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may have a NULL vfsmount when coming from NFSD
|
||||||
|
*/
|
||||||
|
if (mnt &&
|
||||||
|
((mnt->mnt_flags & MNT_NOATIME) ||
|
||||||
|
((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))))
|
||||||
|
return;
|
||||||
|
|
||||||
now = current_fs_time(inode->i_sb);
|
now = current_fs_time(inode->i_sb);
|
||||||
if (!timespec_equal(&inode->i_atime, &now)) {
|
if (!timespec_equal(&inode->i_atime, &now)) {
|
||||||
inode->i_atime = now;
|
inode->i_atime = now;
|
||||||
|
|
|
@ -355,14 +355,14 @@ static int show_vfsmnt(struct seq_file *m, void *v)
|
||||||
{ MS_SYNCHRONOUS, ",sync" },
|
{ MS_SYNCHRONOUS, ",sync" },
|
||||||
{ MS_DIRSYNC, ",dirsync" },
|
{ MS_DIRSYNC, ",dirsync" },
|
||||||
{ MS_MANDLOCK, ",mand" },
|
{ MS_MANDLOCK, ",mand" },
|
||||||
{ MS_NOATIME, ",noatime" },
|
|
||||||
{ MS_NODIRATIME, ",nodiratime" },
|
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
static struct proc_fs_info mnt_info[] = {
|
static struct proc_fs_info mnt_info[] = {
|
||||||
{ MNT_NOSUID, ",nosuid" },
|
{ MNT_NOSUID, ",nosuid" },
|
||||||
{ MNT_NODEV, ",nodev" },
|
{ MNT_NODEV, ",nodev" },
|
||||||
{ MNT_NOEXEC, ",noexec" },
|
{ MNT_NOEXEC, ",noexec" },
|
||||||
|
{ MNT_NOATIME, ",noatime" },
|
||||||
|
{ MNT_NODIRATIME, ",nodiratime" },
|
||||||
{ 0, NULL }
|
{ 0, NULL }
|
||||||
};
|
};
|
||||||
struct proc_fs_info *fs_infop;
|
struct proc_fs_info *fs_infop;
|
||||||
|
@ -1286,7 +1286,13 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
|
||||||
mnt_flags |= MNT_NODEV;
|
mnt_flags |= MNT_NODEV;
|
||||||
if (flags & MS_NOEXEC)
|
if (flags & MS_NOEXEC)
|
||||||
mnt_flags |= MNT_NOEXEC;
|
mnt_flags |= MNT_NOEXEC;
|
||||||
flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE);
|
if (flags & MS_NOATIME)
|
||||||
|
mnt_flags |= MNT_NOATIME;
|
||||||
|
if (flags & MS_NODIRATIME)
|
||||||
|
mnt_flags |= MNT_NODIRATIME;
|
||||||
|
|
||||||
|
flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
|
||||||
|
MS_NOATIME | MS_NODIRATIME);
|
||||||
|
|
||||||
/* ... and get the mountpoint */
|
/* ... and get the mountpoint */
|
||||||
retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
|
retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
|
||||||
|
|
|
@ -950,11 +950,20 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
|
||||||
|
|
||||||
/* Flush out writes to the server in order to update c/mtime */
|
/* Flush out writes to the server in order to update c/mtime */
|
||||||
nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
|
nfs_sync_inode(inode, 0, 0, FLUSH_WAIT|FLUSH_NOCOMMIT);
|
||||||
if (__IS_FLG(inode, MS_NOATIME))
|
|
||||||
|
/*
|
||||||
|
* We may force a getattr if the user cares about atime.
|
||||||
|
*
|
||||||
|
* Note that we only have to check the vfsmount flags here:
|
||||||
|
* - NFS always sets S_NOATIME by so checking it would give a
|
||||||
|
* bogus result
|
||||||
|
* - NFS never sets MS_NOATIME or MS_NODIRATIME so there is
|
||||||
|
* no point in checking those.
|
||||||
|
*/
|
||||||
|
if ((mnt->mnt_flags & MNT_NOATIME) ||
|
||||||
|
((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
|
||||||
need_atime = 0;
|
need_atime = 0;
|
||||||
else if (__IS_FLG(inode, MS_NODIRATIME) && S_ISDIR(inode->i_mode))
|
|
||||||
need_atime = 0;
|
|
||||||
/* We may force a getattr if the user cares about atime */
|
|
||||||
if (need_atime)
|
if (need_atime)
|
||||||
err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
|
err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
|
||||||
else
|
else
|
||||||
|
|
|
@ -54,6 +54,9 @@
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
#include <linux/namei.h>
|
#include <linux/namei.h>
|
||||||
|
|
||||||
|
#define IS_NOATIME(inode) ((inode->i_sb->s_flags & MS_NOATIME) || \
|
||||||
|
(S_ISDIR(inode->i_mode) && inode->i_sb->s_flags & MS_NODIRATIME))
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Change the requested timestamp in the given inode.
|
* Change the requested timestamp in the given inode.
|
||||||
* We don't lock across timestamp updates, and we don't log them but
|
* We don't lock across timestamp updates, and we don't log them but
|
||||||
|
|
|
@ -114,8 +114,7 @@ extern int dir_notify_enable;
|
||||||
/*
|
/*
|
||||||
* Superblock flags that can be altered by MS_REMOUNT
|
* Superblock flags that can be altered by MS_REMOUNT
|
||||||
*/
|
*/
|
||||||
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|\
|
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
|
||||||
MS_NODIRATIME)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Old magic mount flag and mask
|
* Old magic mount flag and mask
|
||||||
|
@ -161,8 +160,6 @@ extern int dir_notify_enable;
|
||||||
#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
|
#define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA)
|
||||||
#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
|
#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND)
|
||||||
#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
|
#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE)
|
||||||
#define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME))
|
|
||||||
#define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME)
|
|
||||||
#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
|
#define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL)
|
||||||
|
|
||||||
#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
|
#define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
|
||||||
|
|
|
@ -20,10 +20,12 @@
|
||||||
#define MNT_NOSUID 0x01
|
#define MNT_NOSUID 0x01
|
||||||
#define MNT_NODEV 0x02
|
#define MNT_NODEV 0x02
|
||||||
#define MNT_NOEXEC 0x04
|
#define MNT_NOEXEC 0x04
|
||||||
#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */
|
#define MNT_NOATIME 0x08
|
||||||
#define MNT_UNBINDABLE 0x20 /* if the vfsmount is a unbindable mount */
|
#define MNT_NODIRATIME 0x10
|
||||||
|
|
||||||
#define MNT_PNODE_MASK (MNT_SHARED | MNT_UNBINDABLE)
|
#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
|
||||||
|
#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
|
||||||
|
#define MNT_PNODE_MASK 0x3000 /* propogation flag mask */
|
||||||
|
|
||||||
struct vfsmount {
|
struct vfsmount {
|
||||||
struct list_head mnt_hash;
|
struct list_head mnt_hash;
|
||||||
|
|
Loading…
Reference in New Issue