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/bootmem.h>
|
||||
#include <linux/inotify.h>
|
||||
#include <linux/mount.h>
|
||||
|
||||
/*
|
||||
* 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 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))
|
||||
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);
|
||||
if (!timespec_equal(&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_DIRSYNC, ",dirsync" },
|
||||
{ MS_MANDLOCK, ",mand" },
|
||||
{ MS_NOATIME, ",noatime" },
|
||||
{ MS_NODIRATIME, ",nodiratime" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
static struct proc_fs_info mnt_info[] = {
|
||||
{ MNT_NOSUID, ",nosuid" },
|
||||
{ MNT_NODEV, ",nodev" },
|
||||
{ MNT_NOEXEC, ",noexec" },
|
||||
{ MNT_NOATIME, ",noatime" },
|
||||
{ MNT_NODIRATIME, ",nodiratime" },
|
||||
{ 0, NULL }
|
||||
};
|
||||
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;
|
||||
if (flags & MS_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 */
|
||||
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 */
|
||||
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;
|
||||
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)
|
||||
err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
|
||||
else
|
||||
|
|
|
@ -54,6 +54,9 @@
|
|||
#include <linux/xattr.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.
|
||||
* 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
|
||||
*/
|
||||
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK|MS_NOATIME|\
|
||||
MS_NODIRATIME)
|
||||
#define MS_RMT_MASK (MS_RDONLY|MS_SYNCHRONOUS|MS_MANDLOCK)
|
||||
|
||||
/*
|
||||
* 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_APPEND(inode) ((inode)->i_flags & S_APPEND)
|
||||
#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_DEADDIR(inode) ((inode)->i_flags & S_DEAD)
|
||||
|
|
|
@ -20,10 +20,12 @@
|
|||
#define MNT_NOSUID 0x01
|
||||
#define MNT_NODEV 0x02
|
||||
#define MNT_NOEXEC 0x04
|
||||
#define MNT_SHARED 0x10 /* if the vfsmount is a shared mount */
|
||||
#define MNT_UNBINDABLE 0x20 /* if the vfsmount is a unbindable mount */
|
||||
#define MNT_NOATIME 0x08
|
||||
#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 list_head mnt_hash;
|
||||
|
|
Loading…
Reference in New Issue