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;
 }

_