From: viro@parcelfarce.linux.theplanet.co.uk cramfs and freevxfs explicitly mark themselves readonly (as other r/o fs do). afs marked noatime (ACKed by maintainer) filesystems that do not do update_atime() in their ->readdir() had been explicitly marked nodiratime. NOTE: cifs, coda and ncpfs almost certainly need full noatime as we currently have in nfs and afs. update_atime() call shifted to callers of ->readdir() and out of ->readdir() instances. Bugs caught: dcache_readdir() updated atime only if it reached EOF. bfs_readdir() - ditto. qnx4_readdir() - ditto. --- 25-akpm/fs/adfs/super.c | 2 ++ 25-akpm/fs/affs/super.c | 1 + 25-akpm/fs/afs/inode.c | 1 + 25-akpm/fs/bfs/dir.c | 1 - 25-akpm/fs/cifs/cifsfs.c | 1 + 25-akpm/fs/coda/dir.c | 4 +++- 25-akpm/fs/coda/inode.c | 1 + 25-akpm/fs/cramfs/inode.c | 2 ++ 25-akpm/fs/ext2/dir.c | 1 - 25-akpm/fs/ext3/dir.c | 2 -- 25-akpm/fs/fat/inode.c | 1 + 25-akpm/fs/freevxfs/vxfs_super.c | 2 ++ 25-akpm/fs/hfs/super.c | 1 + 25-akpm/fs/jffs/inode-v23.c | 2 ++ 25-akpm/fs/jffs2/super.c | 1 + 25-akpm/fs/libfs.c | 1 - 25-akpm/fs/minix/dir.c | 1 - 25-akpm/fs/ncpfs/inode.c | 1 + 25-akpm/fs/proc/inode.c | 1 + 25-akpm/fs/qnx4/dir.c | 2 -- 25-akpm/fs/readdir.c | 1 + 25-akpm/fs/reiserfs/dir.c | 1 - 25-akpm/fs/smbfs/inode.c | 1 + 25-akpm/fs/sysv/dir.c | 1 - 25-akpm/fs/udf/dir.c | 1 - 25-akpm/fs/ufs/dir.c | 1 - fs/openpromfs/inode.c | 0 27 files changed, 22 insertions(+), 13 deletions(-) diff -puN fs/adfs/super.c~readdir-cleanups fs/adfs/super.c --- 25/fs/adfs/super.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/adfs/super.c Thu Feb 26 13:40:59 2004 @@ -334,6 +334,8 @@ static int adfs_fill_super(struct super_ unsigned char *b_data; struct adfs_sb_info *asb; + sb->s_flags |= MS_NODIRATIME; + asb = kmalloc(sizeof(*asb), GFP_KERNEL); if (!asb) return -ENOMEM; diff -puN fs/affs/super.c~readdir-cleanups fs/affs/super.c --- 25/fs/affs/super.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/affs/super.c Thu Feb 26 13:40:59 2004 @@ -293,6 +293,7 @@ static int affs_fill_super(struct super_ sb->s_magic = AFFS_SUPER_MAGIC; sb->s_op = &affs_sops; + sb->s_flags |= MS_NODIRATIME; sbi = kmalloc(sizeof(struct affs_sb_info), GFP_KERNEL); if (!sbi) diff -puN fs/afs/inode.c~readdir-cleanups fs/afs/inode.c --- 25/fs/afs/inode.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/afs/inode.c Thu Feb 26 13:40:59 2004 @@ -188,6 +188,7 @@ inline int afs_iget(struct super_block * #endif /* okay... it's a new inode */ + inode->i_flags |= S_NOATIME; vnode->flags |= AFS_VNODE_CHANGED; ret = afs_inode_fetch_status(inode); if (ret<0) diff -puN fs/bfs/dir.c~readdir-cleanups fs/bfs/dir.c --- 25/fs/bfs/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/bfs/dir.c Thu Feb 26 13:40:59 2004 @@ -65,7 +65,6 @@ static int bfs_readdir(struct file * f, brelse(bh); } - update_atime(dir); unlock_kernel(); return 0; } diff -puN fs/cifs/cifsfs.c~readdir-cleanups fs/cifs/cifsfs.c --- 25/fs/cifs/cifsfs.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/cifs/cifsfs.c Thu Feb 26 13:40:59 2004 @@ -77,6 +77,7 @@ cifs_read_super(struct super_block *sb, struct cifs_sb_info *cifs_sb; int rc = 0; + sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */ sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); cifs_sb = CIFS_SB(sb); if(cifs_sb == NULL) diff -puN fs/coda/dir.c~readdir-cleanups fs/coda/dir.c --- 25/fs/coda/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/coda/dir.c Thu Feb 26 13:40:59 2004 @@ -510,8 +510,10 @@ int coda_readdir(struct file *coda_file, goto out; ret = -ENOENT; - if (!IS_DEADDIR(host_inode)) + if (!IS_DEADDIR(host_inode)) { ret = host_file->f_op->readdir(host_file, filldir, dirent); + update_atime(host_inode); + } } out: coda_file->f_pos = host_file->f_pos; diff -puN fs/coda/inode.c~readdir-cleanups fs/coda/inode.c --- 25/fs/coda/inode.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/coda/inode.c Thu Feb 26 13:40:59 2004 @@ -171,6 +171,7 @@ static int coda_fill_super(struct super_ sbi->sbi_vcomm = vc; sb->s_fs_info = sbi; + sb->s_flags |= MS_NODIRATIME; /* probably even noatime */ sb->s_blocksize = 1024; /* XXXXX what do we put here?? */ sb->s_blocksize_bits = 10; sb->s_magic = CODA_SUPER_MAGIC; diff -puN fs/cramfs/inode.c~readdir-cleanups fs/cramfs/inode.c --- 25/fs/cramfs/inode.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/cramfs/inode.c Thu Feb 26 13:40:59 2004 @@ -200,6 +200,8 @@ static int cramfs_fill_super(struct supe unsigned long root_offset; struct cramfs_sb_info *sbi; + sb->s_flags |= MS_RDONLY; + sbi = kmalloc(sizeof(struct cramfs_sb_info), GFP_KERNEL); if (!sbi) return -ENOMEM; diff -puN fs/ext2/dir.c~readdir-cleanups fs/ext2/dir.c --- 25/fs/ext2/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/ext2/dir.c Thu Feb 26 13:40:59 2004 @@ -310,7 +310,6 @@ ext2_readdir (struct file * filp, void * done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; filp->f_version = inode->i_version; - update_atime(inode); return 0; } diff -puN fs/ext3/dir.c~readdir-cleanups fs/ext3/dir.c --- 25/fs/ext3/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/ext3/dir.c Thu Feb 26 13:40:59 2004 @@ -224,7 +224,6 @@ revalidate: offset = 0; brelse (bh); } - update_atime(inode); out: return ret; } @@ -506,7 +505,6 @@ static int ext3_dx_readdir(struct file * } finished: info->last_pos = filp->f_pos; - update_atime(inode); return 0; } diff -puN fs/fat/inode.c~readdir-cleanups fs/fat/inode.c --- 25/fs/fat/inode.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/fat/inode.c Thu Feb 26 13:40:59 2004 @@ -778,6 +778,7 @@ int fat_fill_super(struct super_block *s sb->s_fs_info = sbi; memset(sbi, 0, sizeof(struct msdos_sb_info)); + sb->s_flags |= MS_NODIRATIME; sb->s_magic = MSDOS_SUPER_MAGIC; sb->s_op = &fat_sops; sb->s_export_op = &fat_export_ops; diff -puN fs/freevxfs/vxfs_super.c~readdir-cleanups fs/freevxfs/vxfs_super.c --- 25/fs/freevxfs/vxfs_super.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/freevxfs/vxfs_super.c Thu Feb 26 13:40:59 2004 @@ -144,6 +144,8 @@ static int vxfs_fill_super(struct super_ struct buffer_head *bp = NULL; u_long bsize; + sbp->s_flags |= MS_RDONLY; + infp = kmalloc(sizeof(*infp), GFP_KERNEL); if (!infp) { printk(KERN_WARNING "vxfs: unable to allocate incore superblock\n"); diff -puN fs/hfs/super.c~readdir-cleanups fs/hfs/super.c --- 25/fs/hfs/super.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/hfs/super.c Thu Feb 26 13:40:59 2004 @@ -268,6 +268,7 @@ static int hfs_fill_super(struct super_b } sb->s_op = &hfs_super_operations; + sb->s_flags |= MS_NODIRATIME; init_MUTEX(&sbi->bitmap_lock); res = hfs_mdb_get(sb); diff -puN fs/jffs2/super.c~readdir-cleanups fs/jffs2/super.c --- 25/fs/jffs2/super.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/jffs2/super.c Thu Feb 26 13:40:59 2004 @@ -129,6 +129,7 @@ static struct super_block *jffs2_get_sb_ mtd->index, mtd->name)); sb->s_op = &jffs2_super_operations; + sb->s_flags |= MS_NODIRATIME; ret = jffs2_do_fill_super(sb, data, (flags&MS_VERBOSE)?1:0); diff -puN fs/jffs/inode-v23.c~readdir-cleanups fs/jffs/inode-v23.c --- 25/fs/jffs/inode-v23.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/jffs/inode-v23.c Thu Feb 26 13:40:59 2004 @@ -70,6 +70,8 @@ static int jffs_fill_super(struct super_ struct inode *root_inode; struct jffs_control *c; + sb->s_flags |= MS_NODIRATIME; + D1(printk(KERN_NOTICE "JFFS: Trying to mount device %s.\n", sb->s_id)); diff -puN fs/libfs.c~readdir-cleanups fs/libfs.c --- 25/fs/libfs.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/libfs.c Thu Feb 26 13:40:59 2004 @@ -155,7 +155,6 @@ int dcache_readdir(struct file * filp, v } spin_unlock(&dcache_lock); } - update_atime(dentry->d_inode); return 0; } diff -puN fs/minix/dir.c~readdir-cleanups fs/minix/dir.c --- 25/fs/minix/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/minix/dir.c Thu Feb 26 13:40:59 2004 @@ -127,7 +127,6 @@ static int minix_readdir(struct file * f done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; - update_atime(inode); unlock_kernel(); return 0; } diff -puN fs/ncpfs/inode.c~readdir-cleanups fs/ncpfs/inode.c --- 25/fs/ncpfs/inode.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/ncpfs/inode.c Thu Feb 26 13:40:59 2004 @@ -479,6 +479,7 @@ static int ncp_fill_super(struct super_b else default_bufsize = 1024; + sb->s_flags |= MS_NODIRATIME; /* probably even noatime */ sb->s_maxbytes = 0xFFFFFFFFU; sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; diff -puN fs/openpromfs/inode.c~readdir-cleanups fs/openpromfs/inode.c diff -puN fs/proc/inode.c~readdir-cleanups fs/proc/inode.c --- 25/fs/proc/inode.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/proc/inode.c Thu Feb 26 13:41:01 2004 @@ -231,6 +231,7 @@ int proc_fill_super(struct super_block * { struct inode * root_inode; + s->s_flags |= MS_NODIRATIME; s->s_blocksize = 1024; s->s_blocksize_bits = 10; s->s_magic = PROC_SUPER_MAGIC; diff -puN fs/qnx4/dir.c~readdir-cleanups fs/qnx4/dir.c --- 25/fs/qnx4/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/qnx4/dir.c Thu Feb 26 13:41:01 2004 @@ -76,8 +76,6 @@ static int qnx4_readdir(struct file *fil } brelse(bh); } - update_atime(inode); - out: unlock_kernel(); return 0; diff -puN fs/readdir.c~readdir-cleanups fs/readdir.c --- 25/fs/readdir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/readdir.c Thu Feb 26 13:41:01 2004 @@ -32,6 +32,7 @@ int vfs_readdir(struct file *file, filld res = -ENOENT; if (!IS_DEADDIR(inode)) { res = file->f_op->readdir(file, buf, filler); + update_atime(inode); } up(&inode->i_sem); out: diff -puN fs/reiserfs/dir.c~readdir-cleanups fs/reiserfs/dir.c --- 25/fs/reiserfs/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/reiserfs/dir.c Thu Feb 26 13:41:01 2004 @@ -186,7 +186,6 @@ static int reiserfs_readdir (struct file filp->f_pos = next_pos; pathrelse (&path_to_entry); reiserfs_check_path(&path_to_entry) ; - update_atime(inode) ; out: reiserfs_write_unlock(inode->i_sb); return ret; diff -puN fs/smbfs/inode.c~readdir-cleanups fs/smbfs/inode.c --- 25/fs/smbfs/inode.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/smbfs/inode.c Thu Feb 26 13:41:01 2004 @@ -499,6 +499,7 @@ int smb_fill_super(struct super_block *s if (ver != SMB_MOUNT_OLDVERSION && cpu_to_be32(ver) != SMB_MOUNT_ASCII) goto out_wrong_data; + sb->s_flags |= MS_NODIRATIME; sb->s_blocksize = 1024; /* Eh... Is this correct? */ sb->s_blocksize_bits = 10; sb->s_magic = SMB_SUPER_MAGIC; diff -puN fs/sysv/dir.c~readdir-cleanups fs/sysv/dir.c --- 25/fs/sysv/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/sysv/dir.c Thu Feb 26 13:41:01 2004 @@ -116,7 +116,6 @@ static int sysv_readdir(struct file * fi done: filp->f_pos = (n << PAGE_CACHE_SHIFT) | offset; - update_atime(inode); unlock_kernel(); return 0; } diff -puN fs/udf/dir.c~readdir-cleanups fs/udf/dir.c --- 25/fs/udf/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/udf/dir.c Thu Feb 26 13:41:01 2004 @@ -98,7 +98,6 @@ int udf_readdir(struct file *filp, void } result = do_udf_readdir(dir, filp, filldir, dirent); - update_atime(dir); unlock_kernel(); return result; } diff -puN fs/ufs/dir.c~readdir-cleanups fs/ufs/dir.c --- 25/fs/ufs/dir.c~readdir-cleanups Thu Feb 26 13:40:59 2004 +++ 25-akpm/fs/ufs/dir.c Thu Feb 26 13:41:01 2004 @@ -166,7 +166,6 @@ revalidate: offset = 0; brelse (bh); } - update_atime(inode); unlock_kernel(); return 0; } _