
From: Andi Kleen <ak@suse.de>

This patch corrects a problem that was originally added with the nanosecond
timestamps in stat patch.  The problem is that some file systems don't have
enough space in their on disk inode to save nanosecond timestamps, so they
truncate the c/a/mtime to seconds when flushing an dirty node.  In core the
inode would have full jiffies granuality.

This can be observed by programs as a timestamp that jumps backwards under
specific loads when an inode is flushed and then reloaded from disk.

The problem was already known when the original patch went in, but it
wasn't deemed important enough at that time.  So far there has been only
one report of it causing problems.  Now Tridge is worried that it will
break running Excel over samba4 because Excel seems to do very anal
timestamp checking and samba4 will supply 100ns timestamps over the
network.

This patch solves it by putting the time resolution into the superblock of
a fs and always rounding the in core timestamps to that granuality.

This also supercedes some previous ext2/3 hacks to flush the inode less
often when only the subsecond timestamp changes.

I tried to keep the overhead low, in particular it tries to keep divisions
out of fast paths as far as possible.

The patch is quite big but 99% of it is just relatively straight forward
search'n'replace in a lot of fs.  Unconverted filesystems will default to a
1ns granuality, but may still show the problem if they continue to use
CURRENT_TIME.  I converted all in tree fs.

One possible future extension of this would be to have two time
granualities per superblock - one that specifies the visible resolution,
and the other to specify how often timestamps should be flushed to disk,
which could be tuned with a mount option per fs (e.g.  often m/atimes don't
need to be flushed every second).  Would be easy to do as an addon if
someone is interested.

Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/drivers/char/qtronix.c         |    3 +-
 25-akpm/drivers/char/random.c          |    5 ++-
 25-akpm/drivers/char/sonypi.c          |    2 -
 25-akpm/drivers/char/tty_io.c          |    5 ++-
 25-akpm/drivers/isdn/capi/capifs.c     |    1 
 25-akpm/drivers/misc/ibmasm/ibmasmfs.c |    1 
 25-akpm/drivers/oprofile/oprofilefs.c  |    1 
 25-akpm/drivers/usb/core/inode.c       |    1 
 25-akpm/drivers/usb/gadget/inode.c     |    1 
 25-akpm/fs/adfs/inode.c                |    2 -
 25-akpm/fs/affs/amigaffs.c             |    6 ++--
 25-akpm/fs/affs/file.c                 |    2 -
 25-akpm/fs/affs/inode.c                |    2 -
 25-akpm/fs/attr.c                      |   12 +++++---
 25-akpm/fs/autofs/inode.c              |    1 
 25-akpm/fs/autofs4/inode.c             |    1 
 25-akpm/fs/bad_inode.c                 |    3 +-
 25-akpm/fs/bfs/dir.c                   |   14 ++++-----
 25-akpm/fs/bfs/inode.c                 |    2 -
 25-akpm/fs/binfmt_misc.c               |    3 +-
 25-akpm/fs/cifs/connect.c              |    2 +
 25-akpm/fs/cifs/file.c                 |   10 ++++---
 25-akpm/fs/cifs/inode.c                |    4 +-
 25-akpm/fs/coda/dir.c                  |    2 -
 25-akpm/fs/coda/file.c                 |    2 -
 25-akpm/fs/coda/inode.c                |    2 -
 25-akpm/fs/devfs/base.c                |    1 
 25-akpm/fs/devpts/inode.c              |    1 
 25-akpm/fs/ext2/dir.c                  |    6 ++--
 25-akpm/fs/ext2/ialloc.c               |    2 -
 25-akpm/fs/ext2/inode.c                |    4 +-
 25-akpm/fs/ext2/ioctl.c                |    4 +-
 25-akpm/fs/ext2/namei.c                |    6 ++--
 25-akpm/fs/ext2/super.c                |    1 
 25-akpm/fs/ext2/xattr.c                |    2 -
 25-akpm/fs/ext3/ialloc.c               |    2 -
 25-akpm/fs/ext3/inode.c                |    4 +-
 25-akpm/fs/ext3/ioctl.c                |    4 +-
 25-akpm/fs/ext3/namei.c                |   14 ++++-----
 25-akpm/fs/ext3/super.c                |    1 
 25-akpm/fs/ext3/xattr.c                |    2 -
 25-akpm/fs/fat/dir.c                   |    2 -
 25-akpm/fs/fat/file.c                  |    4 +-
 25-akpm/fs/hfs/catalog.c               |    8 ++---
 25-akpm/fs/hfs/dir.c                   |    4 +-
 25-akpm/fs/hfs/inode.c                 |    2 -
 25-akpm/fs/hfsplus/catalog.c           |    8 ++---
 25-akpm/fs/hfsplus/dir.c               |    6 ++--
 25-akpm/fs/hfsplus/inode.c             |    2 -
 25-akpm/fs/hfsplus/ioctl.c             |    2 -
 25-akpm/fs/hpfs/file.c                 |    2 -
 25-akpm/fs/hugetlbfs/inode.c           |    1 
 25-akpm/fs/inode.c                     |   24 +++-------------
 25-akpm/fs/jffs/inode-v23.c            |    8 ++---
 25-akpm/fs/jffs2/fs.c                  |    2 -
 25-akpm/fs/jfs/namei.c                 |    2 -
 25-akpm/fs/jfs/super.c                 |    2 -
 25-akpm/fs/libfs.c                     |    2 +
 25-akpm/fs/locks.c                     |    2 -
 25-akpm/fs/minix/bitmap.c              |    2 -
 25-akpm/fs/minix/dir.c                 |    6 ++--
 25-akpm/fs/minix/itree_common.c        |    4 +-
 25-akpm/fs/minix/namei.c               |    4 +-
 25-akpm/fs/msdos/namei.c               |   16 +++++------
 25-akpm/fs/nfs/inode.c                 |    3 ++
 25-akpm/fs/ntfs/mft.c                  |    3 +-
 25-akpm/fs/ntfs/super.c                |    2 +
 25-akpm/fs/openpromfs/inode.c          |    1 
 25-akpm/fs/proc/inode.c                |    1 
 25-akpm/fs/qnx4/inode.c                |    2 -
 25-akpm/fs/qnx4/namei.c                |    4 +-
 25-akpm/fs/qnx4/truncate.c             |    2 -
 25-akpm/fs/ramfs/inode.c               |    1 
 25-akpm/fs/reiserfs/inode.c            |    3 +-
 25-akpm/fs/reiserfs/ioctl.c            |    4 +-
 25-akpm/fs/reiserfs/namei.c            |   12 ++++----
 25-akpm/fs/reiserfs/stree.c            |    4 +-
 25-akpm/fs/reiserfs/xattr.c            |    6 ++--
 25-akpm/fs/smbfs/file.c                |    5 ++-
 25-akpm/fs/smbfs/inode.c               |    3 +-
 25-akpm/fs/smbfs/proc.c                |    5 ++-
 25-akpm/fs/smbfs/proto.h               |    3 +-
 25-akpm/fs/super.c                     |    1 
 25-akpm/fs/sysfs/mount.c               |    1 
 25-akpm/fs/sysv/dir.c                  |    6 ++--
 25-akpm/fs/sysv/ialloc.c               |    2 -
 25-akpm/fs/sysv/itree.c                |    4 +-
 25-akpm/fs/sysv/namei.c                |    4 +-
 25-akpm/fs/udf/ialloc.c                |    2 -
 25-akpm/fs/udf/inode.c                 |    4 +-
 25-akpm/fs/udf/namei.c                 |   12 ++++----
 25-akpm/fs/udf/super.c                 |    1 
 25-akpm/fs/ufs/dir.c                   |    4 +-
 25-akpm/fs/ufs/ialloc.c                |    2 -
 25-akpm/fs/ufs/inode.c                 |    4 +-
 25-akpm/fs/ufs/namei.c                 |    4 +-
 25-akpm/fs/ufs/truncate.c              |    2 -
 25-akpm/fs/umsdos/emd.c                |    2 -
 25-akpm/fs/vfat/namei.c                |   19 +++++++------
 25-akpm/fs/xfs/linux-2.6/xfs_super.c   |    1 
 25-akpm/include/linux/fs.h             |    8 ++++-
 25-akpm/include/linux/time.h           |    3 ++
 25-akpm/kernel/time.c                  |   47 ++++++++++++++++++++++++++++++++-
 25-akpm/net/sunrpc/rpc_pipe.c          |    1 
 104 files changed, 269 insertions(+), 188 deletions(-)

diff -puN drivers/char/qtronix.c~sync-in-core-time-granuality-with-filesystems drivers/char/qtronix.c
--- 25/drivers/char/qtronix.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.653964816 -0800
+++ 25-akpm/drivers/char/qtronix.c	2004-12-03 20:55:58.804941864 -0800
@@ -537,7 +537,8 @@ repeat:
 		i--;
 	}
 	if (count-i) {
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+		struct inode *inode = file->f_dentry->d_inode;
+		inode->i_atime = current_fs_time(inode->i_sb);
 		return count-i;
 	}
 	if (signal_pending(current))
diff -puN drivers/char/random.c~sync-in-core-time-granuality-with-filesystems drivers/char/random.c
--- 25/drivers/char/random.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.655964512 -0800
+++ 25-akpm/drivers/char/random.c	2004-12-03 20:55:58.806941560 -0800
@@ -1721,8 +1721,9 @@ random_write(struct file * file, const c
 	if (p == buffer) {
 		return (ssize_t)ret;
 	} else {
-		file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
-		mark_inode_dirty(file->f_dentry->d_inode);
+		struct inode *inode = file->f_dentry->d_inode;
+	        inode->i_mtime = current_fs_time(inode->i_sb);
+		mark_inode_dirty(inode);
 		return (ssize_t)(p - buffer);
 	}
 }
diff -puN drivers/char/sonypi.c~sync-in-core-time-granuality-with-filesystems drivers/char/sonypi.c
--- 25/drivers/char/sonypi.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.656964360 -0800
+++ 25-akpm/drivers/char/sonypi.c	2004-12-03 20:55:58.807941408 -0800
@@ -537,7 +537,7 @@ static ssize_t sonypi_misc_read(struct f
 	}
 
 	if (ret > 0)
-		file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+		inode->i_atime = current_fs_time(inode->i_sb);
 
 	return ret;
 }
diff -puN drivers/char/tty_io.c~sync-in-core-time-granuality-with-filesystems drivers/char/tty_io.c
--- 25/drivers/char/tty_io.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.658964056 -0800
+++ 25-akpm/drivers/char/tty_io.c	2004-12-03 20:55:58.809941104 -0800
@@ -1013,7 +1013,7 @@ static ssize_t tty_read(struct file * fi
 	tty_ldisc_deref(ld);
 	unlock_kernel();
 	if (i > 0)
-		inode->i_atime = CURRENT_TIME;
+		inode->i_atime = current_fs_time(inode->i_sb);
 	return i;
 }
 
@@ -1090,7 +1090,8 @@ static inline ssize_t do_tty_write(
 		cond_resched();
 	}
 	if (written) {
-		file->f_dentry->d_inode->i_mtime = CURRENT_TIME;
+		struct inode *inode = file->f_dentry->d_inode;
+		inode->i_mtime = current_fs_time(inode->i_sb);
 		ret = written;
 	}
 	up(&tty->atomic_write);
diff -puN drivers/isdn/capi/capifs.c~sync-in-core-time-granuality-with-filesystems drivers/isdn/capi/capifs.c
--- 25/drivers/isdn/capi/capifs.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.659963904 -0800
+++ 25-akpm/drivers/isdn/capi/capifs.c	2004-12-03 20:55:58.810940952 -0800
@@ -93,6 +93,7 @@ capifs_fill_super(struct super_block *s,
 	s->s_blocksize_bits = 10;
 	s->s_magic = CAPIFS_SUPER_MAGIC;
 	s->s_op = &capifs_sops;
+	s->s_time_gran = 1;
 
 	inode = new_inode(s);
 	if (!inode)
diff -puN drivers/misc/ibmasm/ibmasmfs.c~sync-in-core-time-granuality-with-filesystems drivers/misc/ibmasm/ibmasmfs.c
--- 25/drivers/misc/ibmasm/ibmasmfs.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.661963600 -0800
+++ 25-akpm/drivers/misc/ibmasm/ibmasmfs.c	2004-12-03 20:55:58.811940800 -0800
@@ -131,6 +131,7 @@ static int ibmasmfs_fill_super (struct s
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = IBMASMFS_MAGIC;
 	sb->s_op = &ibmasmfs_s_ops;
+	sb->s_time_gran = 1;
 
 	root = ibmasmfs_make_inode (sb, S_IFDIR | 0500);
 	if (!root)
diff -puN drivers/oprofile/oprofilefs.c~sync-in-core-time-granuality-with-filesystems drivers/oprofile/oprofilefs.c
--- 25/drivers/oprofile/oprofilefs.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.662963448 -0800
+++ 25-akpm/drivers/oprofile/oprofilefs.c	2004-12-03 20:55:58.811940800 -0800
@@ -250,6 +250,7 @@ static int oprofilefs_fill_super(struct 
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = OPROFILEFS_MAGIC;
 	sb->s_op = &s_ops;
+	sb->s_time_gran = 1;
 
 	root_inode = oprofilefs_get_inode(sb, S_IFDIR | 0755);
 	if (!root_inode)
diff -puN drivers/usb/core/inode.c~sync-in-core-time-granuality-with-filesystems drivers/usb/core/inode.c
--- 25/drivers/usb/core/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.663963296 -0800
+++ 25-akpm/drivers/usb/core/inode.c	2004-12-03 20:55:58.812940648 -0800
@@ -434,6 +434,7 @@ static int usbfs_fill_super(struct super
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = USBDEVICE_SUPER_MAGIC;
 	sb->s_op = &usbfs_ops;
+	sb->s_time_gran = 1;
 	inode = usbfs_get_inode(sb, S_IFDIR | 0755, 0);
 
 	if (!inode) {
diff -puN drivers/usb/gadget/inode.c~sync-in-core-time-granuality-with-filesystems drivers/usb/gadget/inode.c
--- 25/drivers/usb/gadget/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.665962992 -0800
+++ 25-akpm/drivers/usb/gadget/inode.c	2004-12-03 20:55:58.814940344 -0800
@@ -2022,6 +2022,7 @@ gadgetfs_fill_super (struct super_block 
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = GADGETFS_MAGIC;
 	sb->s_op = &gadget_fs_operations;
+	sb->s_time_gran = 1;
 
 	/* root inode */
 	inode = gadgetfs_make_inode (sb,
diff -puN fs/adfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/adfs/inode.c
--- 25/fs/adfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.666962840 -0800
+++ 25-akpm/fs/adfs/inode.c	2004-12-03 20:55:58.814940344 -0800
@@ -210,7 +210,7 @@ adfs_adfs2unix_time(struct timespec *tv,
 	return;
 
  cur_time:
-	*tv = CURRENT_TIME;
+	*tv = CURRENT_TIME_SEC;
 	return;
 
  too_early:
diff -puN fs/affs/amigaffs.c~sync-in-core-time-granuality-with-filesystems fs/affs/amigaffs.c
--- 25/fs/affs/amigaffs.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.668962536 -0800
+++ 25-akpm/fs/affs/amigaffs.c	2004-12-03 20:55:58.815940192 -0800
@@ -68,7 +68,7 @@ affs_insert_hash(struct inode *dir, stru
 	mark_buffer_dirty_inode(dir_bh, dir);
 	affs_brelse(dir_bh);
 
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 
@@ -121,7 +121,7 @@ affs_remove_hash(struct inode *dir, stru
 
 	affs_brelse(bh);
 
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 
@@ -319,7 +319,7 @@ affs_remove_header(struct dentry *dentry
 	else
 		inode->i_nlink = 0;
 	affs_unlock_link(inode);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 
 done:
diff -puN fs/affs/file.c~sync-in-core-time-granuality-with-filesystems fs/affs/file.c
--- 25/fs/affs/file.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.669962384 -0800
+++ 25-akpm/fs/affs/file.c	2004-12-03 20:55:58.816940040 -0800
@@ -499,7 +499,7 @@ affs_file_write(struct file *file, const
 	retval = generic_file_write (file, buf, count, ppos);
 	if (retval >0) {
 		struct inode *inode = file->f_dentry->d_inode;
-		inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+		inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 	}
 	return retval;
diff -puN fs/affs/inode.c~sync-in-core-time-granuality-with-filesystems fs/affs/inode.c
--- 25/fs/affs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.670962232 -0800
+++ 25-akpm/fs/affs/inode.c	2004-12-03 20:55:58.816940040 -0800
@@ -322,7 +322,7 @@ affs_new_inode(struct inode *dir)
 	inode->i_gid     = current->fsgid;
 	inode->i_ino     = block;
 	inode->i_nlink   = 1;
-	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime   = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	AFFS_I(inode)->i_opencnt = 0;
 	AFFS_I(inode)->i_blkcnt = 0;
 	AFFS_I(inode)->i_lc = NULL;
diff -puN fs/attr.c~sync-in-core-time-granuality-with-filesystems fs/attr.c
--- 25/fs/attr.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.672961928 -0800
+++ 25-akpm/fs/attr.c	2004-12-03 20:55:58.817939888 -0800
@@ -14,6 +14,7 @@
 #include <linux/fcntl.h>
 #include <linux/quotaops.h>
 #include <linux/security.h>
+#include <linux/time.h>
 
 /* Taken over from the old code... */
 
@@ -87,11 +88,14 @@ int inode_setattr(struct inode * inode, 
 	if (ia_valid & ATTR_GID)
 		inode->i_gid = attr->ia_gid;
 	if (ia_valid & ATTR_ATIME)
-		inode->i_atime = attr->ia_atime;
+		inode->i_atime = timespec_trunc(attr->ia_atime,
+						inode->i_sb->s_time_gran);
 	if (ia_valid & ATTR_MTIME)
-		inode->i_mtime = attr->ia_mtime;
+		inode->i_mtime = timespec_trunc(attr->ia_mtime,
+						inode->i_sb->s_time_gran);
 	if (ia_valid & ATTR_CTIME)
-		inode->i_ctime = attr->ia_ctime;
+		inode->i_ctime = timespec_trunc(attr->ia_ctime,
+						inode->i_sb->s_time_gran);
 	if (ia_valid & ATTR_MODE) {
 		umode_t mode = attr->ia_mode;
 
@@ -133,7 +137,7 @@ int notify_change(struct dentry * dentry
 	struct inode *inode = dentry->d_inode;
 	mode_t mode = inode->i_mode;
 	int error;
-	struct timespec now = CURRENT_TIME;
+	struct timespec now = current_fs_time(inode->i_sb);
 	unsigned int ia_valid = attr->ia_valid;
 
 	if (!inode)
diff -puN fs/autofs4/inode.c~sync-in-core-time-granuality-with-filesystems fs/autofs4/inode.c
--- 25/fs/autofs4/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.673961776 -0800
+++ 25-akpm/fs/autofs4/inode.c	2004-12-03 20:55:58.817939888 -0800
@@ -211,6 +211,7 @@ int autofs4_fill_super(struct super_bloc
 	s->s_blocksize_bits = 10;
 	s->s_magic = AUTOFS_SUPER_MAGIC;
 	s->s_op = &autofs4_sops;
+	s->s_time_gran = 1;
 
 	/*
 	 * Get the root inode and dentry, but defer checking for errors.
diff -puN fs/autofs/inode.c~sync-in-core-time-granuality-with-filesystems fs/autofs/inode.c
--- 25/fs/autofs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.674961624 -0800
+++ 25-akpm/fs/autofs/inode.c	2004-12-03 20:55:58.817939888 -0800
@@ -147,6 +147,7 @@ int autofs_fill_super(struct super_block
 	s->s_blocksize_bits = 10;
 	s->s_magic = AUTOFS_SUPER_MAGIC;
 	s->s_op = &autofs_sops;
+	s->s_time_gran = 1;
 
 	root_inode = iget(s, AUTOFS_ROOT_INO);
 	root = d_alloc_root(root_inode);
diff -puN fs/bad_inode.c~sync-in-core-time-granuality-with-filesystems fs/bad_inode.c
--- 25/fs/bad_inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.676961320 -0800
+++ 25-akpm/fs/bad_inode.c	2004-12-03 20:55:58.818939736 -0800
@@ -105,7 +105,8 @@ void make_bad_inode(struct inode * inode
 	remove_inode_hash(inode);
 
 	inode->i_mode = S_IFREG;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_atime = inode->i_mtime = inode->i_ctime =
+		current_fs_time(inode->i_sb);
 	inode->i_op = &bad_inode_ops;	
 	inode->i_fop = &bad_file_ops;	
 }
diff -puN fs/bfs/dir.c~sync-in-core-time-granuality-with-filesystems fs/bfs/dir.c
--- 25/fs/bfs/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.677961168 -0800
+++ 25-akpm/fs/bfs/dir.c	2004-12-03 20:55:58.818939736 -0800
@@ -100,7 +100,7 @@ static int bfs_create(struct inode * dir
 	info->si_freei--;
 	inode->i_uid = current->fsuid;
 	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blocks = inode->i_blksize = 0;
 	inode->i_op = &bfs_file_inops;
 	inode->i_fop = &bfs_file_operations;
@@ -164,7 +164,7 @@ static int bfs_link(struct dentry * old,
 		return err;
 	}
 	inode->i_nlink++;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	atomic_inc(&inode->i_count);
 	d_instantiate(new, inode);
@@ -193,7 +193,7 @@ static int bfs_unlink(struct inode * dir
 	}
 	de->ino = 0;
 	mark_buffer_dirty(bh);
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	inode->i_ctime = dir->i_ctime;
@@ -245,11 +245,11 @@ static int bfs_rename(struct inode * old
 			goto end_rename;
 	}
 	old_de->ino = 0;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(new_inode);
 	}
 	mark_buffer_dirty(old_bh);
@@ -300,9 +300,9 @@ static int bfs_add_entry(struct inode * 
 			if (!de->ino) {
 				if ((block-sblock)*BFS_BSIZE + off >= dir->i_size) {
 					dir->i_size += BFS_DIRENT_SIZE;
-					dir->i_ctime = CURRENT_TIME;
+					dir->i_ctime = CURRENT_TIME_SEC;
 				}
-				dir->i_mtime = CURRENT_TIME;
+				dir->i_mtime = CURRENT_TIME_SEC;
 				mark_inode_dirty(dir);
 				de->ino = ino;
 				for (i=0; i<BFS_NAMELEN; i++)
diff -puN fs/bfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/bfs/inode.c
--- 25/fs/bfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.678961016 -0800
+++ 25-akpm/fs/bfs/inode.c	2004-12-03 20:55:58.819939584 -0800
@@ -149,7 +149,7 @@ static void bfs_delete_inode(struct inod
 	}
 	
 	inode->i_size = 0;
-	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	lock_kernel();
 	mark_inode_dirty(inode);
 	block = (ino - BFS_ROOT_INO)/BFS_INODES_PER_BLOCK + 1;
diff -puN fs/binfmt_misc.c~sync-in-core-time-granuality-with-filesystems fs/binfmt_misc.c
--- 25/fs/binfmt_misc.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.680960712 -0800
+++ 25-akpm/fs/binfmt_misc.c	2004-12-03 20:55:58.820939432 -0800
@@ -509,7 +509,8 @@ static struct inode *bm_get_inode(struct
 		inode->i_gid = 0;
 		inode->i_blksize = PAGE_CACHE_SIZE;
 		inode->i_blocks = 0;
-		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		inode->i_atime = inode->i_mtime = inode->i_ctime =
+			current_fs_time(inode->i_sb);
 	}
 	return inode;
 }
diff -puN fs/cifs/connect.c~sync-in-core-time-granuality-with-filesystems fs/cifs/connect.c
--- 25/fs/cifs/connect.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.682960408 -0800
+++ 25-akpm/fs/cifs/connect.c	2004-12-03 20:55:58.822939128 -0800
@@ -1472,6 +1472,8 @@ cifs_mount(struct super_block *sb, struc
 			sb->s_maxbytes = (u64) 1 << 31;	/* 2 GB */
 	}
 
+	sb->s_time_gran = 100;
+
 /* on error free sesinfo and tcon struct if needed */
 	if (rc) {
 		/* if session setup failed, use count is zero but
diff -puN fs/cifs/file.c~sync-in-core-time-granuality-with-filesystems fs/cifs/file.c
--- 25/fs/cifs/file.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.683960256 -0800
+++ 25-akpm/fs/cifs/file.c	2004-12-03 20:55:58.824938824 -0800
@@ -709,8 +709,9 @@ cifs_write(struct file * file, const cha
 	/* since the write may have blocked check these pointers again */
 	if(file->f_dentry) {
 		if(file->f_dentry->d_inode) {
-			file->f_dentry->d_inode->i_ctime = file->f_dentry->d_inode->i_mtime =
-				CURRENT_TIME;
+			struct inode *inode = file->f_dentry->d_inode;
+			inode->i_ctime = inode->i_mtime =
+				current_fs_time(inode->i_sb);
 			if (total_written > 0) {
 				if (*poffset > file->f_dentry->d_inode->i_size)
 					i_size_write(file->f_dentry->d_inode, *poffset);
@@ -784,7 +785,7 @@ cifs_partialpagewrite(struct page *page,
 					to-from, &offset);
 			read_lock(&GlobalSMBSeslock);
 		/* Does mm or vfs already set times? */
-			inode->i_atime = inode->i_mtime = CURRENT_TIME;
+			inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
 			if ((bytes_written > 0) && (offset)) {
 				rc = 0;
 			} else if(bytes_written < 0) {
@@ -1299,7 +1300,8 @@ static int cifs_readpage_worker(struct f
 		cFYI(1,("Bytes read %d ",rc));
 	}
                                                                                                                            
-	file->f_dentry->d_inode->i_atime = CURRENT_TIME;
+	file->f_dentry->d_inode->i_atime =
+		current_fs_time(file->f_dentry->d_inode->i_sb);
                                                                                                                            
 	if(PAGE_CACHE_SIZE > rc) {
 		memset(read_data+rc, 0, PAGE_CACHE_SIZE - rc);
diff -puN fs/cifs/inode.c~sync-in-core-time-granuality-with-filesystems fs/cifs/inode.c
--- 25/fs/cifs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.685959952 -0800
+++ 25-akpm/fs/cifs/inode.c	2004-12-03 20:55:58.825938672 -0800
@@ -451,7 +451,7 @@ cifs_unlink(struct inode *inode, struct 
 	cifsInode = CIFS_I(direntry->d_inode);
 	cifsInode->time = 0;	/* will force revalidate to get info when needed */
 	direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-	    CURRENT_TIME;
+	    current_fs_time(inode->i_sb);
 	cifsInode = CIFS_I(inode);
 	cifsInode->time = 0;	/* force revalidate of dir as well */
 
@@ -564,7 +564,7 @@ cifs_rmdir(struct inode *inode, struct d
 	cifsInode = CIFS_I(direntry->d_inode);
 	cifsInode->time = 0;	/* force revalidate to go get info when needed */
 	direntry->d_inode->i_ctime = inode->i_ctime = inode->i_mtime =
-	    CURRENT_TIME;
+	    current_fs_time(inode->i_sb);
 
 	if (full_path)
 		kfree(full_path);
diff -puN fs/coda/dir.c~sync-in-core-time-granuality-with-filesystems fs/coda/dir.c
--- 25/fs/coda/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.686959800 -0800
+++ 25-akpm/fs/coda/dir.c	2004-12-03 20:55:58.826938520 -0800
@@ -183,7 +183,7 @@ static inline void coda_dir_changed(stru
 	/* optimistically we can also act as if our nose bleeds. The
          * granularity of the mtime is coarse anyways so we might actually be
          * right most of the time. Note: we only do this for directories. */
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 #endif
 	if (link)
 		dir->i_nlink += link;
diff -puN fs/coda/file.c~sync-in-core-time-granuality-with-filesystems fs/coda/file.c
--- 25/fs/coda/file.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.687959648 -0800
+++ 25-akpm/fs/coda/file.c	2004-12-03 20:55:58.826938520 -0800
@@ -83,7 +83,7 @@ coda_file_write(struct file *coda_file, 
 
 	coda_inode->i_size = host_inode->i_size;
 	coda_inode->i_blocks = (coda_inode->i_size + 511) >> 9;
-	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME;
+	coda_inode->i_mtime = coda_inode->i_ctime = CURRENT_TIME_SEC;
 	up(&coda_inode->i_sem);
 
 	return ret;
diff -puN fs/coda/inode.c~sync-in-core-time-granuality-with-filesystems fs/coda/inode.c
--- 25/fs/coda/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.689959344 -0800
+++ 25-akpm/fs/coda/inode.c	2004-12-03 20:55:58.827938368 -0800
@@ -253,7 +253,7 @@ int coda_setattr(struct dentry *de, stru
 	
 	memset(&vattr, 0, sizeof(vattr)); 
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	coda_iattr_to_vattr(iattr, &vattr);
 	vattr.va_type = C_VNON; /* cannot set type */
 
diff -puN fs/devfs/base.c~sync-in-core-time-granuality-with-filesystems fs/devfs/base.c
--- 25/fs/devfs/base.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.690959192 -0800
+++ 25-akpm/fs/devfs/base.c	2004-12-03 20:55:58.829938064 -0800
@@ -2533,6 +2533,7 @@ static int devfs_fill_super(struct super
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = DEVFS_SUPER_MAGIC;
 	sb->s_op = &devfs_sops;
+	sb->s_time_gran = 1;
 	if ((root_inode = _devfs_get_vfs_inode(sb, root_entry, NULL)) == NULL)
 		goto out_no_root;
 	sb->s_root = d_alloc_root(root_inode);
diff -puN fs/devpts/inode.c~sync-in-core-time-granuality-with-filesystems fs/devpts/inode.c
--- 25/fs/devpts/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.692958888 -0800
+++ 25-akpm/fs/devpts/inode.c	2004-12-03 20:55:58.829938064 -0800
@@ -103,6 +103,7 @@ devpts_fill_super(struct super_block *s,
 	s->s_magic = DEVPTS_SUPER_MAGIC;
 	s->s_op = &devpts_sops;
 	s->s_xattr = devpts_xattr_handlers;
+	s->s_time_gran = 1;
 
 	inode = new_inode(s);
 	if (!inode)
diff -puN fs/ext2/dir.c~sync-in-core-time-granuality-with-filesystems fs/ext2/dir.c
--- 25/fs/ext2/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.693958736 -0800
+++ 25-akpm/fs/ext2/dir.c	2004-12-03 20:55:58.830937912 -0800
@@ -426,7 +426,7 @@ void ext2_set_link(struct inode *dir, st
 	ext2_set_de_type (de, inode);
 	err = ext2_commit_chunk(page, from, to);
 	ext2_put_page(page);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 }
@@ -516,7 +516,7 @@ got_it:
 	de->inode = cpu_to_le32(inode->i_ino);
 	ext2_set_de_type (de, inode);
 	err = ext2_commit_chunk(page, from, to);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(dir);
 	/* OFFSET_CACHE */
@@ -564,7 +564,7 @@ int ext2_delete_entry (struct ext2_dir_e
 		pde->rec_len = cpu_to_le16(to-from);
 	dir->inode = 0;
 	err = ext2_commit_chunk(page, from, to);
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
 	mark_inode_dirty(inode);
 out:
diff -puN fs/ext2/ialloc.c~sync-in-core-time-granuality-with-filesystems fs/ext2/ialloc.c
--- 25/fs/ext2/ialloc.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.694958584 -0800
+++ 25-akpm/fs/ext2/ialloc.c	2004-12-03 20:55:58.831937760 -0800
@@ -577,7 +577,7 @@ got:
 	inode->i_ino = ino;
 	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blocks = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	memset(ei->i_data, 0, sizeof(ei->i_data));
 	ei->i_flags = EXT2_I(dir)->i_flags & ~EXT2_BTREE_FL;
 	if (S_ISLNK(mode))
diff -puN fs/ext2/inode.c~sync-in-core-time-granuality-with-filesystems fs/ext2/inode.c
--- 25/fs/ext2/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.696958280 -0800
+++ 25-akpm/fs/ext2/inode.c	2004-12-03 20:55:58.832937608 -0800
@@ -493,7 +493,7 @@ static inline int ext2_splice_branch(str
 
 	/* We are done with atomic stuff, now do the rest of housekeeping */
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
@@ -953,7 +953,7 @@ do_indirects:
 		case EXT2_TIND_BLOCK:
 			;
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	if (inode_needs_sync(inode)) {
 		sync_mapping_buffers(inode->i_mapping);
 		ext2_sync_inode (inode);
diff -puN fs/ext2/ioctl.c~sync-in-core-time-granuality-with-filesystems fs/ext2/ioctl.c
--- 25/fs/ext2/ioctl.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.697958128 -0800
+++ 25-akpm/fs/ext2/ioctl.c	2004-12-03 20:55:58.833937456 -0800
@@ -59,7 +59,7 @@ int ext2_ioctl (struct inode * inode, st
 		ei->i_flags = flags;
 
 		ext2_set_inode_flags(inode);
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	}
@@ -72,7 +72,7 @@ int ext2_ioctl (struct inode * inode, st
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *) arg))
 			return -EFAULT;	
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	default:
diff -puN fs/ext2/namei.c~sync-in-core-time-granuality-with-filesystems fs/ext2/namei.c
--- 25/fs/ext2/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.699957824 -0800
+++ 25-akpm/fs/ext2/namei.c	2004-12-03 20:55:58.833937456 -0800
@@ -211,7 +211,7 @@ static int ext2_link (struct dentry * ol
 	if (inode->i_nlink >= EXT2_LINK_MAX)
 		return -EMLINK;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ext2_inc_count(inode);
 	atomic_inc(&inode->i_count);
 
@@ -337,7 +337,7 @@ static int ext2_rename (struct inode * o
 			goto out_dir;
 		ext2_inc_count(old_inode);
 		ext2_set_link(new_dir, new_de, new_page, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		ext2_dec_count(new_inode);
@@ -362,7 +362,7 @@ static int ext2_rename (struct inode * o
  	 * rename.
 	 * ext2_dec_count() will mark the inode dirty.
 	 */
-	old_inode->i_ctime = CURRENT_TIME;
+	old_inode->i_ctime = CURRENT_TIME_SEC;
 
 	ext2_delete_entry (old_de, old_page);
 	ext2_dec_count(old_inode);
diff -puN fs/ext2/super.c~sync-in-core-time-granuality-with-filesystems fs/ext2/super.c
--- 25/fs/ext2/super.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.700957672 -0800
+++ 25-akpm/fs/ext2/super.c	2004-12-03 20:55:58.834937304 -0800
@@ -592,7 +592,6 @@ static int ext2_fill_super(struct super_
 	es = (struct ext2_super_block *) (((char *)bh->b_data) + offset);
 	sbi->s_es = es;
 	sb->s_magic = le16_to_cpu(es->s_magic);
-	sb->s_flags |= MS_ONE_SECOND;
 
 	if (sb->s_magic != EXT2_SUPER_MAGIC)
 		goto cantfind_ext2;
diff -puN fs/ext2/xattr.c~sync-in-core-time-granuality-with-filesystems fs/ext2/xattr.c
--- 25/fs/ext2/xattr.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.702957368 -0800
+++ 25-akpm/fs/ext2/xattr.c	2004-12-03 20:55:58.835937152 -0800
@@ -697,7 +697,7 @@ ext2_xattr_set2(struct inode *inode, str
 
 	/* Update the inode. */
 	EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	if (IS_SYNC(inode)) {
 		error = ext2_sync_inode (inode);
 		if (error)
diff -puN fs/ext3/ialloc.c~sync-in-core-time-granuality-with-filesystems fs/ext3/ialloc.c
--- 25/fs/ext3/ialloc.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.703957216 -0800
+++ 25-akpm/fs/ext3/ialloc.c	2004-12-03 20:55:58.836937000 -0800
@@ -558,7 +558,7 @@ got:
 	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blksize = PAGE_SIZE;
 	inode->i_blocks = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 
 	memset(ei->i_data, 0, sizeof(ei->i_data));
 	ei->i_next_alloc_block = 0;
diff -puN fs/ext3/inode.c~sync-in-core-time-granuality-with-filesystems fs/ext3/inode.c
--- 25/fs/ext3/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.705956912 -0800
+++ 25-akpm/fs/ext3/inode.c	2004-12-03 20:55:58.838936696 -0800
@@ -626,7 +626,7 @@ static int ext3_splice_branch(handle_t *
 
 	/* We are done with atomic stuff, now do the rest of housekeeping */
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, inode);
 
 	/* had we spliced it onto indirect block? */
@@ -2199,7 +2199,7 @@ do_indirects:
 			;
 	}
 	up(&ei->truncate_sem);
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, inode);
 
 	/* In a multi-transaction truncate, we only make the final
diff -puN fs/ext3/ioctl.c~sync-in-core-time-granuality-with-filesystems fs/ext3/ioctl.c
--- 25/fs/ext3/ioctl.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.706956760 -0800
+++ 25-akpm/fs/ext3/ioctl.c	2004-12-03 20:55:58.839936544 -0800
@@ -87,7 +87,7 @@ int ext3_ioctl (struct inode * inode, st
 		ei->i_flags = flags;
 
 		ext3_set_inode_flags(inode);
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 
 		err = ext3_mark_iloc_dirty(handle, inode, &iloc);
 flags_err:
@@ -121,7 +121,7 @@ flags_err:
 			return PTR_ERR(handle);
 		err = ext3_reserve_inode_write(handle, inode, &iloc);
 		if (err == 0) {
-			inode->i_ctime = CURRENT_TIME;
+			inode->i_ctime = CURRENT_TIME_SEC;
 			inode->i_generation = generation;
 			err = ext3_mark_iloc_dirty(handle, inode, &iloc);
 		}
diff -puN fs/ext3/namei.c~sync-in-core-time-granuality-with-filesystems fs/ext3/namei.c
--- 25/fs/ext3/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.707956608 -0800
+++ 25-akpm/fs/ext3/namei.c	2004-12-03 20:55:58.841936240 -0800
@@ -1255,7 +1255,7 @@ static int add_dirent_to_buf(handle_t *h
 	 * happen is that the times are slightly out of date
 	 * and/or different from the directory change time.
 	 */
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	ext3_update_dx_flag(dir);
 	dir->i_version++;
 	ext3_mark_inode_dirty(handle, dir);
@@ -2033,7 +2033,7 @@ static int ext3_rmdir (struct inode * di
 	 * recovery. */
 	inode->i_size = 0;
 	ext3_orphan_add(handle, inode);
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, inode);
 	dir->i_nlink--;
 	ext3_update_dx_flag(dir);
@@ -2083,7 +2083,7 @@ static int ext3_unlink(struct inode * di
 	retval = ext3_delete_entry(handle, dir, de, bh);
 	if (retval)
 		goto end_unlink;
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	ext3_update_dx_flag(dir);
 	ext3_mark_inode_dirty(handle, dir);
 	inode->i_nlink--;
@@ -2173,7 +2173,7 @@ retry:
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_inc_count(handle, inode);
 	atomic_inc(&inode->i_count);
 
@@ -2274,7 +2274,7 @@ static int ext3_rename (struct inode * o
 	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
 	 */
-	old_inode->i_ctime = CURRENT_TIME;
+	old_inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, old_inode);
 
 	/*
@@ -2307,9 +2307,9 @@ static int ext3_rename (struct inode * o
 
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 	}
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	ext3_update_dx_flag(old_dir);
 	if (dir_bh) {
 		BUFFER_TRACE(dir_bh, "get_write_access");
diff -puN fs/ext3/super.c~sync-in-core-time-granuality-with-filesystems fs/ext3/super.c
--- 25/fs/ext3/super.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.709956304 -0800
+++ 25-akpm/fs/ext3/super.c	2004-12-03 20:55:58.842936088 -0800
@@ -1315,7 +1315,6 @@ static int ext3_fill_super (struct super
 	if (!parse_options ((char *) data, sb, &journal_inum, NULL, 0))
 		goto failed_mount;
 
-	sb->s_flags |= MS_ONE_SECOND;
 	sb->s_flags = (sb->s_flags & ~MS_POSIXACL) |
 		((sbi->s_mount_opt & EXT3_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0);
 
diff -puN fs/ext3/xattr.c~sync-in-core-time-granuality-with-filesystems fs/ext3/xattr.c
--- 25/fs/ext3/xattr.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.711956000 -0800
+++ 25-akpm/fs/ext3/xattr.c	2004-12-03 20:55:58.844935784 -0800
@@ -1285,7 +1285,7 @@ getblk_failed:
 
 	/* Update the inode. */
 	EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ext3_mark_inode_dirty(handle, inode);
 	if (IS_SYNC(inode))
 		handle->h_sync = 1;
diff -puN fs/fat/dir.c~sync-in-core-time-granuality-with-filesystems fs/fat/dir.c
--- 25/fs/fat/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.712955848 -0800
+++ 25-akpm/fs/fat/dir.c	2004-12-03 20:55:58.845935632 -0800
@@ -761,7 +761,7 @@ int fat_new_dir(struct inode *dir, struc
 	de[1].starthi = cpu_to_le16(MSDOS_I(parent)->i_logstart>>16);
 	mark_buffer_dirty(bh);
 	brelse(bh);
-	dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_atime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 
 	return 0;
diff -puN fs/fat/file.c~sync-in-core-time-granuality-with-filesystems fs/fat/file.c
--- 25/fs/fat/file.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.713955696 -0800
+++ 25-akpm/fs/fat/file.c	2004-12-03 20:55:58.845935632 -0800
@@ -77,7 +77,7 @@ static ssize_t fat_file_write(struct fil
 
 	retval = generic_file_write(filp, buf, count, ppos);
 	if (retval > 0) {
-		inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 		MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
 		mark_inode_dirty(inode);
 	}
@@ -103,6 +103,6 @@ void fat_truncate(struct inode *inode)
 	fat_free(inode, nr_clusters);
 	MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
 	unlock_kernel();
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 }
diff -puN fs/hfs/catalog.c~sync-in-core-time-granuality-with-filesystems fs/hfs/catalog.c
--- 25/fs/hfs/catalog.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.715955392 -0800
+++ 25-akpm/fs/hfs/catalog.c	2004-12-03 20:55:58.846935480 -0800
@@ -121,7 +121,7 @@ int hfs_cat_create(u32 cnid, struct inod
 		goto err1;
 
 	dir->i_size++;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	hfs_find_exit(&fd);
 	return 0;
@@ -248,7 +248,7 @@ int hfs_cat_delete(u32 cnid, struct inod
 	}
 
 	dir->i_size--;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	res = 0;
 out:
@@ -301,7 +301,7 @@ int hfs_cat_move(u32 cnid, struct inode 
 	if (err)
 		goto out;
 	dst_dir->i_size++;
-	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME;
+	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dst_dir);
 
 	/* finally remove the old entry */
@@ -313,7 +313,7 @@ int hfs_cat_move(u32 cnid, struct inode 
 	if (err)
 		goto out;
 	src_dir->i_size--;
-	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME;
+	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(src_dir);
 
 	type = entry.type;
diff -puN fs/hfs/dir.c~sync-in-core-time-granuality-with-filesystems fs/hfs/dir.c
--- 25/fs/hfs/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.716955240 -0800
+++ 25-akpm/fs/hfs/dir.c	2004-12-03 20:55:58.846935480 -0800
@@ -248,7 +248,7 @@ int hfs_unlink(struct inode *dir, struct
 
 	inode->i_nlink--;
 	hfs_delete_inode(inode);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 
 	return res;
@@ -274,7 +274,7 @@ int hfs_rmdir(struct inode *dir, struct 
 	if (res)
 		return res;
 	inode->i_nlink = 0;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	hfs_delete_inode(inode);
 	mark_inode_dirty(inode);
 	return 0;
diff -puN fs/hfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/hfs/inode.c
--- 25/fs/hfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.717955088 -0800
+++ 25-akpm/fs/hfs/inode.c	2004-12-03 20:55:58.847935328 -0800
@@ -169,7 +169,7 @@ struct inode *hfs_new_inode(struct inode
 	inode->i_uid = current->fsuid;
 	inode->i_gid = current->fsgid;
 	inode->i_nlink = 1;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blksize = HFS_SB(sb)->alloc_blksz;
 	HFS_I(inode)->flags = 0;
 	HFS_I(inode)->rsrc_inode = NULL;
diff -puN fs/hfsplus/catalog.c~sync-in-core-time-granuality-with-filesystems fs/hfsplus/catalog.c
--- 25/fs/hfsplus/catalog.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.719954784 -0800
+++ 25-akpm/fs/hfsplus/catalog.c	2004-12-03 20:55:58.848935176 -0800
@@ -187,7 +187,7 @@ int hfsplus_create_cat(u32 cnid, struct 
 		goto err1;
 
 	dir->i_size++;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	hfs_find_exit(&fd);
 	return 0;
@@ -269,7 +269,7 @@ int hfsplus_delete_cat(u32 cnid, struct 
 		goto out;
 
 	dir->i_size--;
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 out:
 	hfs_find_exit(&fd);
@@ -315,7 +315,7 @@ int hfsplus_rename_cat(u32 cnid,
 	if (err)
 		goto out;
 	dst_dir->i_size++;
-	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME;
+	dst_dir->i_mtime = dst_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dst_dir);
 
 	/* finally remove the old entry */
@@ -327,7 +327,7 @@ int hfsplus_rename_cat(u32 cnid,
 	if (err)
 		goto out;
 	src_dir->i_size--;
-	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME;
+	src_dir->i_mtime = src_dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(src_dir);
 
 	/* remove old thread entry */
diff -puN fs/hfsplus/dir.c~sync-in-core-time-granuality-with-filesystems fs/hfsplus/dir.c
--- 25/fs/hfsplus/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.720954632 -0800
+++ 25-akpm/fs/hfsplus/dir.c	2004-12-03 20:55:58.848935176 -0800
@@ -294,7 +294,7 @@ int hfsplus_link(struct dentry *src_dent
 	inode->i_nlink++;
 	hfsplus_instantiate(dst_dentry, inode, cnid);
 	atomic_inc(&inode->i_count);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	HFSPLUS_SB(sb).file_count++;
 	sb->s_dirt = 1;
@@ -340,7 +340,7 @@ int hfsplus_unlink(struct inode *dir, st
 		} else
 			inode->i_flags |= S_DEAD;
 	}
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 
 	return res;
@@ -379,7 +379,7 @@ int hfsplus_rmdir(struct inode *dir, str
 	if (res)
 		return res;
 	inode->i_nlink = 0;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	hfsplus_delete_inode(inode);
 	mark_inode_dirty(inode);
 	return 0;
diff -puN fs/hfsplus/inode.c~sync-in-core-time-granuality-with-filesystems fs/hfsplus/inode.c
--- 25/fs/hfsplus/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.722954328 -0800
+++ 25-akpm/fs/hfsplus/inode.c	2004-12-03 20:55:58.849935024 -0800
@@ -334,7 +334,7 @@ struct inode *hfsplus_new_inode(struct s
 	inode->i_uid = current->fsuid;
 	inode->i_gid = current->fsgid;
 	inode->i_nlink = 1;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blksize = HFSPLUS_SB(sb).alloc_blksz;
 	INIT_LIST_HEAD(&HFSPLUS_I(inode).open_dir_list);
 	init_MUTEX(&HFSPLUS_I(inode).extents_lock);
diff -puN fs/hfsplus/ioctl.c~sync-in-core-time-granuality-with-filesystems fs/hfsplus/ioctl.c
--- 25/fs/hfsplus/ioctl.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.723954176 -0800
+++ 25-akpm/fs/hfsplus/ioctl.c	2004-12-03 20:55:58.849935024 -0800
@@ -73,7 +73,7 @@ int hfsplus_ioctl(struct inode *inode, s
 		else
 			HFSPLUS_I(inode).userflags &= ~HFSPLUS_FLG_NODUMP;
 
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	}
diff -puN fs/hpfs/file.c~sync-in-core-time-granuality-with-filesystems fs/hpfs/file.c
--- 25/fs/hpfs/file.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.724954024 -0800
+++ 25-akpm/fs/hpfs/file.c	2004-12-03 20:55:58.850934872 -0800
@@ -116,7 +116,7 @@ static ssize_t hpfs_file_write(struct fi
 	retval = generic_file_write(file, buf, count, ppos);
 	if (retval > 0) {
 		struct inode *inode = file->f_dentry->d_inode;
-		inode->i_mtime = CURRENT_TIME;
+		inode->i_mtime = CURRENT_TIME_SEC;
 		hpfs_i(inode)->i_dirty = 1;
 	}
 	return retval;
diff -puN fs/hugetlbfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/hugetlbfs/inode.c
--- 25/fs/hugetlbfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.726953720 -0800
+++ 25-akpm/fs/hugetlbfs/inode.c	2004-12-03 20:55:58.850934872 -0800
@@ -670,6 +670,7 @@ hugetlbfs_fill_super(struct super_block 
 	sb->s_blocksize_bits = HPAGE_SHIFT;
 	sb->s_magic = HUGETLBFS_MAGIC;
 	sb->s_op = &hugetlbfs_ops;
+	sb->s_time_gran = 1;
 	inode = hugetlbfs_get_inode(sb, config.uid, config.gid,
 					S_IFDIR | config.mode, 0);
 	if (!inode)
diff -puN fs/inode.c~sync-in-core-time-granuality-with-filesystems fs/inode.c
--- 25/fs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.727953568 -0800
+++ 25-akpm/fs/inode.c	2004-12-03 20:55:58.852934568 -0800
@@ -1133,19 +1133,6 @@ sector_t bmap(struct inode * inode, sect
 
 EXPORT_SYMBOL(bmap);
 
-/*
- * Return true if the filesystem which backs this inode considers the two
- * passed timespecs to be sufficiently different to warrant flushing the
- * altered time out to disk.
- */
-static int inode_times_differ(struct inode *inode,
-			struct timespec *old, struct timespec *new)
-{
-	if (IS_ONE_SECOND(inode))
-		return old->tv_sec != new->tv_sec;
-	return !timespec_equal(old, new);
-}
-
 /**
  *	update_atime	-	update the access time
  *	@inode: inode accessed
@@ -1165,8 +1152,8 @@ void update_atime(struct inode *inode)
 	if (IS_RDONLY(inode))
 		return;
 
-	now = current_kernel_time();
-	if (inode_times_differ(inode, &inode->i_atime, &now)) {
+	now = current_fs_time(inode->i_sb);
+	if (!timespec_equal(&inode->i_atime, &now)) {
 		inode->i_atime = now;
 		mark_inode_dirty_sync(inode);
 	} else {
@@ -1196,14 +1183,13 @@ void inode_update_time(struct inode *ino
 	if (IS_RDONLY(inode))
 		return;
 
-	now = current_kernel_time();
-
-	if (inode_times_differ(inode, &inode->i_mtime, &now))
+	now = current_fs_time(inode->i_sb);
+	if (!timespec_equal(&inode->i_mtime, &now))
 		sync_it = 1;
 	inode->i_mtime = now;
 
 	if (ctime_too) {
-		if (inode_times_differ(inode, &inode->i_ctime, &now))
+		if (!timespec_equal(&inode->i_ctime, &now))
 			sync_it = 1;
 		inode->i_ctime = now;
 	}
diff -puN fs/jffs2/fs.c~sync-in-core-time-granuality-with-filesystems fs/jffs2/fs.c
--- 25/fs/jffs2/fs.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.728953416 -0800
+++ 25-akpm/fs/jffs2/fs.c	2004-12-03 20:55:58.852934568 -0800
@@ -427,7 +427,7 @@ struct inode *jffs2_new_inode (struct in
 	inode->i_mode = jemode_to_cpu(ri->mode);
 	inode->i_gid = je16_to_cpu(ri->gid);
 	inode->i_uid = je16_to_cpu(ri->uid);
-	inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_atime = inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	ri->atime = ri->mtime = ri->ctime = cpu_to_je32(I_SEC(inode->i_mtime));
 
 	inode->i_blksize = PAGE_SIZE;
diff -puN fs/jffs/inode-v23.c~sync-in-core-time-granuality-with-filesystems fs/jffs/inode-v23.c
--- 25/fs/jffs/inode-v23.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.730953112 -0800
+++ 25-akpm/fs/jffs/inode-v23.c	2004-12-03 20:55:58.854934264 -0800
@@ -298,7 +298,7 @@ jffs_setattr(struct dentry *dentry, stru
 		if (len) {
 			invalidate_inode_pages(inode->i_mapping);
 		}
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		inode->i_mtime = inode->i_ctime;
 	}
 	if (update_all || iattr->ia_valid & ATTR_ATIME) {
@@ -548,7 +548,7 @@ jffs_rename(struct inode *old_dir, struc
 	/* This is a kind of update of the inode we're about to make
 	   here.  This is what they do in ext2fs.  Kind of.  */
 	if ((inode = iget(new_dir->i_sb, f->ino))) {
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		iput(inode);
 	}
@@ -1051,7 +1051,7 @@ jffs_remove(struct inode *dir, struct de
 	   from the in-memory file system structures.  */
 	jffs_insert_node(c, del_f, &raw_inode, NULL, del_node);
 
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	inode->i_ctime = dir->i_ctime;
@@ -1518,7 +1518,7 @@ jffs_file_write(struct file *filp, const
 		inode->i_size = pos;
 		inode->i_blocks = (inode->i_size + 511) >> 9;
 	}
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	invalidate_inode_pages(inode->i_mapping);
 
diff -puN fs/jfs/namei.c~sync-in-core-time-granuality-with-filesystems fs/jfs/namei.c
--- 25/fs/jfs/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.731952960 -0800
+++ 25-akpm/fs/jfs/namei.c	2004-12-03 20:55:58.855934112 -0800
@@ -1233,7 +1233,7 @@ static int jfs_rename(struct inode *old_
 	old_ip->i_ctime = CURRENT_TIME;
 	mark_inode_dirty(old_ip);
 
-	new_dir->i_ctime = new_dir->i_mtime = CURRENT_TIME;
+	new_dir->i_ctime = new_dir->i_mtime = current_fs_time(new_dir->i_sb);
 	mark_inode_dirty(new_dir);
 
 	/* Build list of inodes modified by this transaction */
diff -puN fs/jfs/super.c~sync-in-core-time-granuality-with-filesystems fs/jfs/super.c
--- 25/fs/jfs/super.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.733952656 -0800
+++ 25-akpm/fs/jfs/super.c	2004-12-03 20:55:58.856933960 -0800
@@ -464,7 +464,7 @@ static int jfs_fill_super(struct super_b
 	 */
 	sb->s_maxbytes = min(((u64) PAGE_CACHE_SIZE << 32) - 1, sb->s_maxbytes);
 #endif
-
+	sb->s_time_gran = 1;
 	return 0;
 
 out_no_root:
diff -puN fs/libfs.c~sync-in-core-time-granuality-with-filesystems fs/libfs.c
--- 25/fs/libfs.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.734952504 -0800
+++ 25-akpm/fs/libfs.c	2004-12-03 20:55:58.856933960 -0800
@@ -212,6 +212,7 @@ get_sb_pseudo(struct file_system_type *f
 	s->s_blocksize_bits = 10;
 	s->s_magic = magic;
 	s->s_op = ops ? ops : &default_ops;
+	s->s_time_gran = 1;
 	root = new_inode(s);
 	if (!root)
 		goto Enomem;
@@ -374,6 +375,7 @@ int simple_fill_super(struct super_block
 	s->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	s->s_magic = magic;
 	s->s_op = &s_ops;
+	s->s_time_gran = 1;
 
 	inode = new_inode(s);
 	if (!inode)
diff -puN fs/locks.c~sync-in-core-time-granuality-with-filesystems fs/locks.c
--- 25/fs/locks.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.736952200 -0800
+++ 25-akpm/fs/locks.c	2004-12-03 20:55:58.858933656 -0800
@@ -1228,7 +1228,7 @@ void lease_get_mtime(struct inode *inode
 {
 	struct file_lock *flock = inode->i_flock;
 	if (flock && IS_LEASE(flock) && (flock->fl_type & F_WRLCK))
-		*time = CURRENT_TIME;
+		*time = current_fs_time(inode->i_sb);
 	else
 		*time = inode->i_mtime;
 }
diff -puN fs/minix/bitmap.c~sync-in-core-time-granuality-with-filesystems fs/minix/bitmap.c
--- 25/fs/minix/bitmap.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.737952048 -0800
+++ 25-akpm/fs/minix/bitmap.c	2004-12-03 20:55:58.858933656 -0800
@@ -253,7 +253,7 @@ struct inode * minix_new_inode(const str
 	inode->i_uid = current->fsuid;
 	inode->i_gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
 	inode->i_ino = j;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blocks = inode->i_blksize = 0;
 	memset(&minix_i(inode)->u, 0, sizeof(minix_i(inode)->u));
 	insert_inode_hash(inode);
diff -puN fs/minix/dir.c~sync-in-core-time-granuality-with-filesystems fs/minix/dir.c
--- 25/fs/minix/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.738951896 -0800
+++ 25-akpm/fs/minix/dir.c	2004-12-03 20:55:58.859933504 -0800
@@ -246,7 +246,7 @@ got_it:
 	memset (de->name + namelen, 0, sbi->s_dirsize - namelen - 2);
 	de->inode = inode->i_ino;
 	err = dir_commit_chunk(page, from, to);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 out_put:
 	dir_put_page(page);
@@ -275,7 +275,7 @@ int minix_delete_entry(struct minix_dir_
 		unlock_page(page);
 	}
 	dir_put_page(page);
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	return err;
 }
@@ -378,7 +378,7 @@ void minix_set_link(struct minix_dir_ent
 		unlock_page(page);
 	}
 	dir_put_page(page);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 }
 
diff -puN fs/minix/itree_common.c~sync-in-core-time-granuality-with-filesystems fs/minix/itree_common.c
--- 25/fs/minix/itree_common.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.740951592 -0800
+++ 25-akpm/fs/minix/itree_common.c	2004-12-03 20:55:58.859933504 -0800
@@ -124,7 +124,7 @@ static inline int splice_branch(struct i
 
 	/* We are done with atomic stuff, now do the rest of housekeeping */
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
@@ -342,7 +342,7 @@ do_indirects:
 		}
 		first_whole++;
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 }
 
diff -puN fs/minix/namei.c~sync-in-core-time-granuality-with-filesystems fs/minix/namei.c
--- 25/fs/minix/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.741951440 -0800
+++ 25-akpm/fs/minix/namei.c	2004-12-03 20:55:58.860933352 -0800
@@ -138,7 +138,7 @@ static int minix_link(struct dentry * ol
 	if (inode->i_nlink >= minix_sb(inode->i_sb)->s_link_max)
 		return -EMLINK;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	inc_count(inode);
 	atomic_inc(&inode->i_count);
 	return add_nondir(dentry, inode);
@@ -259,7 +259,7 @@ static int minix_rename(struct inode * o
 			goto out_dir;
 		inc_count(old_inode);
 		minix_set_link(new_de, new_page, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		dec_count(new_inode);
diff -puN fs/msdos/namei.c~sync-in-core-time-granuality-with-filesystems fs/msdos/namei.c
--- 25/fs/msdos/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.742951288 -0800
+++ 25-akpm/fs/msdos/namei.c	2004-12-03 20:55:58.861933200 -0800
@@ -243,7 +243,7 @@ static int msdos_add_entry(struct inode 
 	/*
 	 * XXX all times should be set by caller upon successful completion.
 	 */
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 
 	memcpy((*de)->name, name, MSDOS_NAME);
@@ -296,7 +296,7 @@ static int msdos_create(struct inode *di
 		unlock_kernel();
 		return res;
 	}
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	d_instantiate(dentry, inode);
 	unlock_kernel();
@@ -330,7 +330,7 @@ static int msdos_rmdir(struct inode *dir
 	mark_buffer_dirty(bh);
 	fat_detach(inode);
 	inode->i_nlink = 0;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	dir->i_nlink--;
 	mark_inode_dirty(inode);
 	mark_inode_dirty(dir);
@@ -392,7 +392,7 @@ out_unlock:
 
 mkdir_error:
 	inode->i_nlink = 0;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	dir->i_nlink--;
 	mark_inode_dirty(inode);
 	mark_inode_dirty(dir);
@@ -430,7 +430,7 @@ static int msdos_unlink(struct inode *di
 	fat_detach(inode);
 	brelse(bh);
 	inode->i_nlink = 0;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	mark_inode_dirty(dir);
 	res = 0;
@@ -493,11 +493,11 @@ static int do_msdos_rename(struct inode 
 		MSDOS_I(old_inode)->i_attrs &= ~ATTR_HIDDEN;
 	mark_inode_dirty(old_inode);
 	old_dir->i_version++;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(new_inode);
 	}
 	if (dotdot_bh) {
@@ -530,7 +530,7 @@ degenerate_case:
 		MSDOS_I(old_inode)->i_attrs &= ~ATTR_HIDDEN;
 	mark_inode_dirty(old_inode);
 	old_dir->i_version++;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	return 0;
 }
diff -puN fs/nfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/nfs/inode.c
--- 25/fs/nfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.744950984 -0800
+++ 25-akpm/fs/nfs/inode.c	2004-12-03 20:55:58.862933048 -0800
@@ -457,6 +457,7 @@ nfs_fill_super(struct super_block *sb, s
 	if (server->flags & NFS_MOUNT_VER3) {
 		if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
 			server->namelen = NFS3_MAXNAMLEN;
+		sb->s_time_gran = 1;
 	} else {
 		if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
 			server->namelen = NFS2_MAXNAMLEN;
@@ -1653,6 +1654,8 @@ static int nfs4_fill_super(struct super_
 		}
 	}
 
+	sb->s_time_gran = 1;
+
 	sb->s_op = &nfs4_sops;
 	err = nfs_sb_init(sb, authflavour);
 	if (err == 0)
diff -puN fs/ntfs/mft.c~sync-in-core-time-granuality-with-filesystems fs/ntfs/mft.c
--- 25/fs/ntfs/mft.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.746950680 -0800
+++ 25-akpm/fs/ntfs/mft.c	2004-12-03 20:55:58.865932592 -0800
@@ -2605,7 +2605,8 @@ mft_rec_already_initialized:
 			vi->i_mode &= ~S_IWUGO;
 
 		/* Set the inode times to the current time. */
-		vi->i_atime = vi->i_mtime = vi->i_ctime = current_kernel_time();
+		vi->i_atime = vi->i_mtime = vi->i_ctime =
+			current_fs_time(vi->i_sb);
 		/*
 		 * Set the file size to 0, the ntfs inode sizes are set to 0 by
 		 * the call to ntfs_init_big_inode() below.
diff -puN fs/ntfs/super.c~sync-in-core-time-granuality-with-filesystems fs/ntfs/super.c
--- 25/fs/ntfs/super.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.748950376 -0800
+++ 25-akpm/fs/ntfs/super.c	2004-12-03 20:55:58.867932288 -0800
@@ -2392,6 +2392,8 @@ static int ntfs_fill_super(struct super_
 	 */
 	sb->s_maxbytes = MAX_LFS_FILESIZE;
 
+	sb->s_time_gran = 100;
+
 	/*
 	 * Now load the metadata required for the page cache and our address
 	 * space operations to function. We do this by setting up a specialised
diff -puN fs/openpromfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/openpromfs/inode.c
--- 25/fs/openpromfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.749950224 -0800
+++ 25-akpm/fs/openpromfs/inode.c	2004-12-03 20:55:58.868932136 -0800
@@ -1039,6 +1039,7 @@ static int openprom_fill_super(struct su
 	s->s_blocksize_bits = 10;
 	s->s_magic = OPENPROM_SUPER_MAGIC;
 	s->s_op = &openprom_sops;
+	s->s_time_gran = 1;
 	root_inode = iget(s, OPENPROM_ROOT_INO);
 	if (!root_inode)
 		goto out_no_root;
diff -puN fs/proc/inode.c~sync-in-core-time-granuality-with-filesystems fs/proc/inode.c
--- 25/fs/proc/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.750950072 -0800
+++ 25-akpm/fs/proc/inode.c	2004-12-03 20:55:58.868932136 -0800
@@ -240,6 +240,7 @@ int proc_fill_super(struct super_block *
 	s->s_blocksize_bits = 10;
 	s->s_magic = PROC_SUPER_MAGIC;
 	s->s_op = &proc_sops;
+	s->s_time_gran = 1;
 	
 	root_inode = proc_get_inode(s, PROC_ROOT_INO, &proc_root);
 	if (!root_inode)
diff -puN fs/qnx4/inode.c~sync-in-core-time-granuality-with-filesystems fs/qnx4/inode.c
--- 25/fs/qnx4/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.752949768 -0800
+++ 25-akpm/fs/qnx4/inode.c	2004-12-03 20:55:58.869931984 -0800
@@ -189,7 +189,7 @@ struct buffer_head *qnx4_getblk(struct i
 	}
 	tst = tmp;
 #endif
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	return result;
 }
diff -puN fs/qnx4/namei.c~sync-in-core-time-granuality-with-filesystems fs/qnx4/namei.c
--- 25/fs/qnx4/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.753949616 -0800
+++ 25-akpm/fs/qnx4/namei.c	2004-12-03 20:55:58.869931984 -0800
@@ -189,7 +189,7 @@ int qnx4_rmdir(struct inode *dir, struct
 	mark_buffer_dirty(bh);
 	inode->i_nlink = 0;
 	mark_inode_dirty(inode);
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	dir->i_nlink--;
 	mark_inode_dirty(dir);
 	retval = 0;
@@ -233,7 +233,7 @@ int qnx4_unlink(struct inode *dir, struc
 	memset(de->di_fname, 0, sizeof de->di_fname);
 	de->di_mode = 0;
 	mark_buffer_dirty(bh);
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	inode->i_ctime = dir->i_ctime;
diff -puN fs/qnx4/truncate.c~sync-in-core-time-granuality-with-filesystems fs/qnx4/truncate.c
--- 25/fs/qnx4/truncate.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.754949464 -0800
+++ 25-akpm/fs/qnx4/truncate.c	2004-12-03 20:55:58.870931832 -0800
@@ -31,7 +31,7 @@ void qnx4_truncate(struct inode *inode)
 		/* TODO */
 	}
 	QNX4DEBUG(("qnx4: qnx4_truncate called\n"));
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	unlock_kernel();
 }
diff -puN fs/ramfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/ramfs/inode.c
--- 25/fs/ramfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.756949160 -0800
+++ 25-akpm/fs/ramfs/inode.c	2004-12-03 20:55:58.870931832 -0800
@@ -186,6 +186,7 @@ static int ramfs_fill_super(struct super
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = RAMFS_MAGIC;
 	sb->s_op = &ramfs_ops;
+	sb->s_time_gran = 1;
 	inode = ramfs_get_inode(sb, S_IFDIR | 0755, 0);
 	if (!inode)
 		return -ENOMEM;
diff -puN fs/reiserfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/reiserfs/inode.c
--- 25/fs/reiserfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.757949008 -0800
+++ 25-akpm/fs/reiserfs/inode.c	2004-12-03 20:55:58.872931528 -0800
@@ -1734,7 +1734,8 @@ int reiserfs_new_inode (struct reiserfs_
     if( S_ISLNK( inode -> i_mode ) )
 	    inode -> i_flags &= ~ ( S_IMMUTABLE | S_APPEND );
 
-    inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+    inode->i_mtime = inode->i_atime = inode->i_ctime =
+	    CURRENT_TIME_SEC;
     inode->i_size = i_size;
     inode->i_blocks = 0;
     inode->i_bytes = 0;
diff -puN fs/reiserfs/ioctl.c~sync-in-core-time-granuality-with-filesystems fs/reiserfs/ioctl.c
--- 25/fs/reiserfs/ioctl.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.759948704 -0800
+++ 25-akpm/fs/reiserfs/ioctl.c	2004-12-03 20:55:58.873931376 -0800
@@ -61,7 +61,7 @@ int reiserfs_ioctl (struct inode * inode
 		}
 		sd_attrs_to_i_attrs( flags, inode );
 		REISERFS_I(inode) -> i_attrs = flags;
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	}
@@ -74,7 +74,7 @@ int reiserfs_ioctl (struct inode * inode
 			return -EROFS;
 		if (get_user(inode->i_generation, (int __user *) arg))
 			return -EFAULT;	
-		inode->i_ctime = CURRENT_TIME;
+		inode->i_ctime = CURRENT_TIME_SEC;
 		mark_inode_dirty(inode);
 		return 0;
 	default:
diff -puN fs/reiserfs/namei.c~sync-in-core-time-granuality-with-filesystems fs/reiserfs/namei.c
--- 25/fs/reiserfs/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.760948552 -0800
+++ 25-akpm/fs/reiserfs/namei.c	2004-12-03 20:55:58.874931224 -0800
@@ -534,7 +534,7 @@ static int reiserfs_add_entry (struct re
     }
 
     dir->i_size += paste_size;
-    dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+    dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
     if (!S_ISDIR (inode->i_mode) && visible)
 	// reiserfs_mkdir or reiserfs_rename will do that by itself
 	reiserfs_update_sd (th, dir);
@@ -881,7 +881,7 @@ static int reiserfs_rmdir (struct inode 
 			  "!= 2 (%d)", __FUNCTION__, inode->i_nlink);
 
     inode->i_nlink = 0;
-    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+    inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
     reiserfs_update_sd (&th, inode);
 
     DEC_DIR_INODE_NLINK(dir)
@@ -969,11 +969,11 @@ static int reiserfs_unlink (struct inode
 	inode->i_nlink++;
 	goto end_unlink;
     }
-    inode->i_ctime = CURRENT_TIME;
+    inode->i_ctime = CURRENT_TIME_SEC;
     reiserfs_update_sd (&th, inode);
 
     dir->i_size -= (de.de_entrylen + DEH_SIZE);
-    dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+    dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
     reiserfs_update_sd (&th, dir);
 
     if (!savelink)
@@ -1121,7 +1121,7 @@ static int reiserfs_link (struct dentry 
 	return err ? err : retval;
     }
 
-    inode->i_ctime = CURRENT_TIME;
+    inode->i_ctime = CURRENT_TIME_SEC;
     reiserfs_update_sd (&th, inode);
 
     atomic_inc(&inode->i_count) ;
@@ -1368,7 +1368,7 @@ static int reiserfs_rename (struct inode
 
     mark_de_hidden (old_de.de_deh + old_de.de_entry_num);
     journal_mark_dirty (&th, old_dir->i_sb, old_de.de_bh);
-    ctime = CURRENT_TIME;
+    ctime = CURRENT_TIME_SEC;
     old_dir->i_ctime = old_dir->i_mtime = ctime;
     new_dir->i_ctime = new_dir->i_mtime = ctime;
     /* thanks to Alex Adriaanse <alex_a@caltech.edu> for patch which adds ctime update of
diff -puN fs/reiserfs/stree.c~sync-in-core-time-granuality-with-filesystems fs/reiserfs/stree.c
--- 25/fs/reiserfs/stree.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.762948248 -0800
+++ 25-akpm/fs/reiserfs/stree.c	2004-12-03 20:55:58.876930920 -0800
@@ -1922,7 +1922,7 @@ int reiserfs_do_truncate (struct reiserf
 	  decrement_counters_in_path(&s_search_path) ;
 
 	  if (update_timestamps) {
-	      p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME;
+	      p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
 	  } 
 	  reiserfs_update_sd(th, p_s_inode) ;
 
@@ -1945,7 +1945,7 @@ int reiserfs_do_truncate (struct reiserf
 update_and_out:
     if (update_timestamps) {
 	// this is truncate, not file closing
-	p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME;
+	    p_s_inode->i_mtime = p_s_inode->i_ctime = CURRENT_TIME_SEC;
     }
     reiserfs_update_sd (th, p_s_inode);
 
diff -puN fs/reiserfs/xattr.c~sync-in-core-time-granuality-with-filesystems fs/reiserfs/xattr.c
--- 25/fs/reiserfs/xattr.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.763948096 -0800
+++ 25-akpm/fs/reiserfs/xattr.c	2004-12-03 20:55:58.877930768 -0800
@@ -594,7 +594,7 @@ open_file:
      * gets marked dirty, but won't (ever) make it onto the dirty list until
      * it's synced explicitly to clear I_DIRTY. This is bad. */
     if (!hlist_unhashed(&inode->i_hash)) {
-        inode->i_ctime = CURRENT_TIME;
+        inode->i_ctime = CURRENT_TIME_SEC;
         mark_inode_dirty (inode);
     }
 
@@ -768,7 +768,7 @@ reiserfs_xattr_del (struct inode *inode,
     dput (dir);
 
     if (!err) {
-        inode->i_ctime = CURRENT_TIME;
+        inode->i_ctime = CURRENT_TIME_SEC;
         mark_inode_dirty (inode);
     }
 
@@ -1040,7 +1040,7 @@ reiserfs_removexattr (struct dentry *den
 
     err = reiserfs_xattr_del (dentry->d_inode, name);
 
-    dentry->d_inode->i_ctime = CURRENT_TIME;
+    dentry->d_inode->i_ctime = CURRENT_TIME_SEC;
     mark_inode_dirty (dentry->d_inode);
 
 out:
diff -puN fs/smbfs/file.c~sync-in-core-time-granuality-with-filesystems fs/smbfs/file.c
--- 25/fs/smbfs/file.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.765947792 -0800
+++ 25-akpm/fs/smbfs/file.c	2004-12-03 20:55:58.878930616 -0800
@@ -78,7 +78,8 @@ smb_readpage_sync(struct dentry *dentry,
 		count -= result;
 		offset += result;
 		buffer += result;
-		dentry->d_inode->i_atime = CURRENT_TIME;
+		dentry->d_inode->i_atime =
+			current_fs_time(dentry->d_inode->i_sb);
 		if (result < rsize)
 			break;
 	} while (count);
@@ -152,7 +153,7 @@ smb_writepage_sync(struct inode *inode, 
 		/*
 		 * Update the inode now rather than waiting for a refresh.
 		 */
-		inode->i_mtime = inode->i_atime = CURRENT_TIME;
+		inode->i_mtime = inode->i_atime = current_fs_time(inode->i_sb);
 		SMB_I(inode)->flags |= SMB_F_LOCALWRITE;
 		if (offset > inode->i_size)
 			inode->i_size = offset;
diff -puN fs/smbfs/inode.c~sync-in-core-time-granuality-with-filesystems fs/smbfs/inode.c
--- 25/fs/smbfs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.766947640 -0800
+++ 25-akpm/fs/smbfs/inode.c	2004-12-03 20:55:58.879930464 -0800
@@ -516,6 +516,7 @@ int smb_fill_super(struct super_block *s
 	sb->s_blocksize_bits = 10;
 	sb->s_magic = SMB_SUPER_MAGIC;
 	sb->s_op = &smb_sops;
+	sb->s_time_gran = 100;
 
 	server = smb_kmalloc(sizeof(struct smb_sb_info), GFP_KERNEL);
 	if (!server)
@@ -601,7 +602,7 @@ int smb_fill_super(struct super_block *s
 	/*
 	 * Keep the super block locked while we get the root inode.
 	 */
-	smb_init_root_dirent(server, &root);
+	smb_init_root_dirent(server, &root, sb);
 	root_inode = smb_iget(sb, &root);
 	if (!root_inode)
 		goto out_no_root;
diff -puN fs/smbfs/proc.c~sync-in-core-time-granuality-with-filesystems fs/smbfs/proc.c
--- 25/fs/smbfs/proc.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.768947336 -0800
+++ 25-akpm/fs/smbfs/proc.c	2004-12-03 20:55:58.881930160 -0800
@@ -1852,12 +1852,13 @@ smb_finish_dirent(struct smb_sb_info *se
 }
 
 void
-smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
+smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
+		     struct super_block *sb)
 {
 	smb_init_dirent(server, fattr);
 	fattr->attr = aDIR;
 	fattr->f_ino = 2; /* traditional root inode number */
-	fattr->f_mtime = CURRENT_TIME;
+	fattr->f_mtime = current_fs_time(sb);
 	smb_finish_dirent(server, fattr);
 }
 
diff -puN fs/smbfs/proto.h~sync-in-core-time-granuality-with-filesystems fs/smbfs/proto.h
--- 25/fs/smbfs/proto.h~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.769947184 -0800
+++ 25-akpm/fs/smbfs/proto.h	2004-12-03 20:55:58.882930008 -0800
@@ -23,7 +23,8 @@ extern int smb_proc_mkdir(struct dentry 
 extern int smb_proc_rmdir(struct dentry *dentry);
 extern int smb_proc_unlink(struct dentry *dentry);
 extern int smb_proc_flush(struct smb_sb_info *server, __u16 fileid);
-extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr);
+extern void smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
+				 struct super_block *sb);
 extern void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p);
 extern int smb_proc_getattr(struct dentry *dir, struct smb_fattr *fattr);
 extern int smb_proc_setattr(struct dentry *dir, struct smb_fattr *fattr);
diff -puN fs/super.c~sync-in-core-time-granuality-with-filesystems fs/super.c
--- 25/fs/super.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.770947032 -0800
+++ 25-akpm/fs/super.c	2004-12-03 20:55:58.882930008 -0800
@@ -84,6 +84,7 @@ static struct super_block *alloc_super(v
 		s->dq_op = sb_dquot_ops;
 		s->s_qcop = sb_quotactl_ops;
 		s->s_op = &default_op;
+		s->s_time_gran = 1000000000;
 	}
 out:
 	return s;
diff -puN fs/sysfs/mount.c~sync-in-core-time-granuality-with-filesystems fs/sysfs/mount.c
--- 25/fs/sysfs/mount.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.772946728 -0800
+++ 25-akpm/fs/sysfs/mount.c	2004-12-03 20:55:58.883929856 -0800
@@ -38,6 +38,7 @@ static int sysfs_fill_super(struct super
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = SYSFS_MAGIC;
 	sb->s_op = &sysfs_ops;
+	sb->s_time_gran = 1;
 	sysfs_sb = sb;
 
 	inode = sysfs_new_inode(S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
diff -puN fs/sysv/dir.c~sync-in-core-time-granuality-with-filesystems fs/sysv/dir.c
--- 25/fs/sysv/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.773946576 -0800
+++ 25-akpm/fs/sysv/dir.c	2004-12-03 20:55:58.883929856 -0800
@@ -231,7 +231,7 @@ got_it:
 	memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
 	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
 	err = dir_commit_chunk(page, from, to);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 out_page:
 	dir_put_page(page);
@@ -258,7 +258,7 @@ int sysv_delete_entry(struct sysv_dir_en
 	de->inode = 0;
 	err = dir_commit_chunk(page, from, to);
 	dir_put_page(page);
-	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	return err;
 }
@@ -358,7 +358,7 @@ void sysv_set_link(struct sysv_dir_entry
 	de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
 	err = dir_commit_chunk(page, from, to);
 	dir_put_page(page);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 }
 
diff -puN fs/sysv/ialloc.c~sync-in-core-time-granuality-with-filesystems fs/sysv/ialloc.c
--- 25/fs/sysv/ialloc.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.774946424 -0800
+++ 25-akpm/fs/sysv/ialloc.c	2004-12-03 20:55:58.884929704 -0800
@@ -169,7 +169,7 @@ struct inode * sysv_new_inode(const stru
 
 	inode->i_uid = current->fsuid;
 	inode->i_ino = fs16_to_cpu(sbi, ino);
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	inode->i_blocks = inode->i_blksize = 0;
 	memset(SYSV_I(inode)->i_data, 0, sizeof(SYSV_I(inode)->i_data));
 	SYSV_I(inode)->i_dir_start_lookup = 0;
diff -puN fs/sysv/itree.c~sync-in-core-time-granuality-with-filesystems fs/sysv/itree.c
--- 25/fs/sysv/itree.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.776946120 -0800
+++ 25-akpm/fs/sysv/itree.c	2004-12-03 20:55:58.884929704 -0800
@@ -178,7 +178,7 @@ static inline int splice_branch(struct i
 	*where->p = where->key;
 	write_unlock(&pointers_lock);
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 
 	/* had we spliced it onto indirect block? */
 	if (where->bh)
@@ -418,7 +418,7 @@ do_indirects:
 		}
 		n++;
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	if (IS_SYNC(inode))
 		sysv_sync_inode (inode);
 	else
diff -puN fs/sysv/namei.c~sync-in-core-time-granuality-with-filesystems fs/sysv/namei.c
--- 25/fs/sysv/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.777945968 -0800
+++ 25-akpm/fs/sysv/namei.c	2004-12-03 20:55:58.885929552 -0800
@@ -137,7 +137,7 @@ static int sysv_link(struct dentry * old
 	if (inode->i_nlink >= SYSV_SB(inode->i_sb)->s_link_max)
 		return -EMLINK;
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	inc_count(inode);
 	atomic_inc(&inode->i_count);
 
@@ -260,7 +260,7 @@ static int sysv_rename(struct inode * ol
 			goto out_dir;
 		inc_count(old_inode);
 		sysv_set_link(new_de, new_page, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		dec_count(new_inode);
diff -puN fs/udf/ialloc.c~sync-in-core-time-granuality-with-filesystems fs/udf/ialloc.c
--- 25/fs/udf/ialloc.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.778945816 -0800
+++ 25-akpm/fs/udf/ialloc.c	2004-12-03 20:55:58.885929552 -0800
@@ -157,7 +157,7 @@ struct inode * udf_new_inode (struct ino
 	else
 		UDF_I_ALLOCTYPE(inode) = ICBTAG_FLAG_AD_LONG;
 	inode->i_mtime = inode->i_atime = inode->i_ctime =
-		UDF_I_CRTIME(inode) = CURRENT_TIME;
+		UDF_I_CRTIME(inode) = current_fs_time(inode->i_sb);
 	insert_inode_hash(inode);
 	mark_inode_dirty(inode);
 
diff -puN fs/udf/inode.c~sync-in-core-time-granuality-with-filesystems fs/udf/inode.c
--- 25/fs/udf/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.780945512 -0800
+++ 25-akpm/fs/udf/inode.c	2004-12-03 20:55:58.887929248 -0800
@@ -568,7 +568,7 @@ static struct buffer_head * inode_getblk
 	*new = 1;
 	UDF_I_NEXT_ALLOC_BLOCK(inode) = block;
 	UDF_I_NEXT_ALLOC_GOAL(inode) = newblocknum;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = current_fs_time(inode->i_sb);
 
 	if (IS_SYNC(inode))
 		udf_sync_inode(inode);
@@ -912,7 +912,7 @@ void udf_truncate(struct inode * inode)
 		udf_truncate_extents(inode);
 	}	
 
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = current_fs_time(inode->i_sb);
 	if (IS_SYNC(inode))
 		udf_sync_inode (inode);
 	else
diff -puN fs/udf/namei.c~sync-in-core-time-granuality-with-filesystems fs/udf/namei.c
--- 25/fs/udf/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.781945360 -0800
+++ 25-akpm/fs/udf/namei.c	2004-12-03 20:55:58.888929096 -0800
@@ -887,7 +887,7 @@ static int udf_rmdir(struct inode * dir,
 	inode->i_size = 0;
 	mark_inode_dirty(inode);
 	dir->i_nlink --;
-	inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	inode->i_ctime = dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
 	mark_inode_dirty(dir);
 
 end_rmdir:
@@ -928,7 +928,7 @@ static int udf_unlink(struct inode * dir
 	retval = udf_delete_entry(dir, fi, &fibh, &cfi);
 	if (retval)
 		goto end_unlink;
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = current_fs_time(dir->i_sb);
 	mark_inode_dirty(dir);
 	inode->i_nlink--;
 	mark_inode_dirty(inode);
@@ -1158,7 +1158,7 @@ static int udf_link(struct dentry * old_
 		udf_release_data(fibh.ebh);
 	udf_release_data(fibh.sbh);
 	inode->i_nlink ++;
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = current_fs_time(inode->i_sb);
 	mark_inode_dirty(inode);
 	atomic_inc(&inode->i_count);
 	d_instantiate(dentry, inode);
@@ -1251,7 +1251,7 @@ static int udf_rename (struct inode * ol
 	 * Like most other Unix systems, set the ctime for inodes on a
 	 * rename.
 	 */
-	old_inode->i_ctime = CURRENT_TIME;
+	old_inode->i_ctime = current_fs_time(old_inode->i_sb);
 	mark_inode_dirty(old_inode);
 
 	/*
@@ -1269,10 +1269,10 @@ static int udf_rename (struct inode * ol
 	if (new_inode)
 	{
 		new_inode->i_nlink--;
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = current_fs_time(new_inode->i_sb);
 		mark_inode_dirty(new_inode);
 	}
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = current_fs_time(old_dir->i_sb);
 	mark_inode_dirty(old_dir);
 
 	if (dir_fi)
diff -puN fs/udf/super.c~sync-in-core-time-granuality-with-filesystems fs/udf/super.c
--- 25/fs/udf/super.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.783945056 -0800
+++ 25-akpm/fs/udf/super.c	2004-12-03 20:55:58.890928792 -0800
@@ -1567,6 +1567,7 @@ static int udf_fill_super(struct super_b
 	sb->dq_op = NULL;
 	sb->s_dirt = 0;
 	sb->s_magic = UDF_SUPER_MAGIC;
+	sb->s_time_gran = 1000;
 
 	if (udf_load_partition(sb, &fileset))
 	{
diff -puN fs/ufs/dir.c~sync-in-core-time-granuality-with-filesystems fs/ufs/dir.c
--- 25/fs/ufs/dir.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.784944904 -0800
+++ 25-akpm/fs/ufs/dir.c	2004-12-03 20:55:58.890928792 -0800
@@ -462,7 +462,7 @@ int ufs_add_link(struct dentry *dentry, 
 	if (IS_DIRSYNC(dir))
 		sync_dirty_buffer(bh);
 	brelse (bh);
-	dir->i_mtime = dir->i_ctime = CURRENT_TIME;
+	dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 
@@ -505,7 +505,7 @@ int ufs_delete_entry (struct inode * ino
 					fs16_to_cpu(sb, dir->d_reclen));
 			dir->d_ino = 0;
 			inode->i_version++;
-			inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+			inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
 			mark_inode_dirty(inode);
 			mark_buffer_dirty(bh);
 			if (IS_DIRSYNC(inode))
diff -puN fs/ufs/ialloc.c~sync-in-core-time-granuality-with-filesystems fs/ufs/ialloc.c
--- 25/fs/ufs/ialloc.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.785944752 -0800
+++ 25-akpm/fs/ufs/ialloc.c	2004-12-03 20:55:58.891928640 -0800
@@ -267,7 +267,7 @@ cg_found:
 	inode->i_ino = cg * uspi->s_ipg + bit;
 	inode->i_blksize = PAGE_SIZE;	/* This is the optimal IO size (for stat), not the fs block size */
 	inode->i_blocks = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	ufsi->i_flags = UFS_I(dir)->i_flags;
 	ufsi->i_lastfrag = 0;
 	ufsi->i_gen = 0;
diff -puN fs/ufs/inode.c~sync-in-core-time-granuality-with-filesystems fs/ufs/inode.c
--- 25/fs/ufs/inode.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.787944448 -0800
+++ 25-akpm/fs/ufs/inode.c	2004-12-03 20:55:58.892928488 -0800
@@ -272,7 +272,7 @@ repeat:
 		*new = 1;
 	}
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	if (IS_SYNC(inode))
 		ufs_sync_inode (inode);
 	mark_inode_dirty(inode);
@@ -363,7 +363,7 @@ repeat:
 	mark_buffer_dirty(bh);
 	if (IS_SYNC(inode))
 		sync_dirty_buffer(bh);
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 out:
 	brelse (bh);
diff -puN fs/ufs/namei.c~sync-in-core-time-granuality-with-filesystems fs/ufs/namei.c
--- 25/fs/ufs/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.788944296 -0800
+++ 25-akpm/fs/ufs/namei.c	2004-12-03 20:55:58.892928488 -0800
@@ -190,7 +190,7 @@ static int ufs_link (struct dentry * old
 		return -EMLINK;
 	}
 
-	inode->i_ctime = CURRENT_TIME;
+	inode->i_ctime = CURRENT_TIME_SEC;
 	ufs_inc_count(inode);
 	atomic_inc(&inode->i_count);
 
@@ -321,7 +321,7 @@ static int ufs_rename (struct inode * ol
 			goto out_dir;
 		ufs_inc_count(old_inode);
 		ufs_set_link(new_dir, new_de, new_bh, old_inode);
-		new_inode->i_ctime = CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 		if (dir_de)
 			new_inode->i_nlink--;
 		ufs_dec_count(new_inode);
diff -puN fs/ufs/truncate.c~sync-in-core-time-granuality-with-filesystems fs/ufs/truncate.c
--- 25/fs/ufs/truncate.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.789944144 -0800
+++ 25-akpm/fs/ufs/truncate.c	2004-12-03 20:55:58.893928336 -0800
@@ -469,7 +469,7 @@ void ufs_truncate (struct inode * inode)
 			brelse (bh);
 		}
 	}
-	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
 	ufsi->i_lastfrag = DIRECT_FRAGMENT;
 	unlock_kernel();
 	mark_inode_dirty(inode);
diff -puN fs/umsdos/emd.c~sync-in-core-time-granuality-with-filesystems fs/umsdos/emd.c
--- 25/fs/umsdos/emd.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.791943840 -0800
+++ 25-akpm/fs/umsdos/emd.c	2004-12-03 20:55:58.893928336 -0800
@@ -295,7 +295,7 @@ int umsdos_writeentry (struct dentry *pa
 	unlock_page(page);
 	page_cache_release(page);
 		
-	dir->i_ctime = dir->i_mtime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 
 out_dput:
diff -puN fs/vfat/namei.c~sync-in-core-time-granuality-with-filesystems fs/vfat/namei.c
--- 25/fs/vfat/namei.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.793943536 -0800
+++ 25-akpm/fs/vfat/namei.c	2004-12-03 20:55:58.895928032 -0800
@@ -735,10 +735,11 @@ static int vfat_add_entry(struct inode *
 
 	res = 0;
 	/* update timestamp */
-	dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME;
+	dir->i_ctime = dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
 	mark_inode_dirty(dir);
 
 	fat_date_unix2dos(dir->i_mtime.tv_sec, &(*de)->time, &(*de)->date);
+	dir->i_mtime.tv_nsec = 0;
 	(*de)->ctime = (*de)->time;
 	(*de)->adate = (*de)->cdate = (*de)->date;
 
@@ -848,7 +849,7 @@ static int vfat_create(struct inode *dir
 	if (!inode)
 		goto out;
 	res = 0;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	inode->i_version++;
 	dir->i_version++;
@@ -866,7 +867,7 @@ static void vfat_remove_entry(struct ino
 	int i;
 
 	/* remove the shortname */
-	dir->i_mtime = dir->i_atime = CURRENT_TIME;
+	dir->i_mtime = dir->i_atime = CURRENT_TIME_SEC;
 	dir->i_version++;
 	mark_inode_dirty(dir);
 	de->name[0] = DELETED_FLAG;
@@ -900,7 +901,7 @@ static int vfat_rmdir(struct inode *dir,
 		goto out;
 	res = 0;
 	dentry->d_inode->i_nlink = 0;
-	dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME;
+	dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME_SEC;
 	fat_detach(dentry->d_inode);
 	mark_inode_dirty(dentry->d_inode);
 	/* releases bh */
@@ -923,7 +924,7 @@ static int vfat_unlink(struct inode *dir
 	if (res < 0)
 		goto out;
 	dentry->d_inode->i_nlink = 0;
-	dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME;
+	dentry->d_inode->i_mtime = dentry->d_inode->i_atime = CURRENT_TIME_SEC;
 	fat_detach(dentry->d_inode);
 	mark_inode_dirty(dentry->d_inode);
 	/* releases bh */
@@ -950,7 +951,7 @@ static int vfat_mkdir(struct inode *dir,
 	inode = fat_build_inode(sb, de, sinfo.i_pos, &res);
 	if (!inode)
 		goto out_brelse;
-	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME_SEC;
 	mark_inode_dirty(inode);
 	inode->i_version++;
 	dir->i_version++;
@@ -969,7 +970,7 @@ out:
 
 mkdir_failed:
 	inode->i_nlink = 0;
-	inode->i_mtime = inode->i_atime = CURRENT_TIME;
+	inode->i_mtime = inode->i_atime = CURRENT_TIME_SEC;
 	fat_detach(inode);
 	mark_inode_dirty(inode);
 	/* releases bh */
@@ -1038,11 +1039,11 @@ static int vfat_rename(struct inode *old
 	mark_inode_dirty(old_inode);
 
 	old_dir->i_version++;
-	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME;
+	old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME_SEC;
 	mark_inode_dirty(old_dir);
 	if (new_inode) {
 		new_inode->i_nlink--;
-		new_inode->i_ctime=CURRENT_TIME;
+		new_inode->i_ctime = CURRENT_TIME_SEC;
 	}
 
 	if (is_dir) {
diff -puN fs/xfs/linux-2.6/xfs_super.c~sync-in-core-time-granuality-with-filesystems fs/xfs/linux-2.6/xfs_super.c
--- 25/fs/xfs/linux-2.6/xfs_super.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.794943384 -0800
+++ 25-akpm/fs/xfs/linux-2.6/xfs_super.c	2004-12-03 20:55:58.895928032 -0800
@@ -825,6 +825,7 @@ linvfs_fill_super(
 	sb->s_blocksize = statvfs.f_bsize;
 	sb->s_blocksize_bits = ffs(statvfs.f_bsize) - 1;
 	sb->s_maxbytes = xfs_max_file_offset(sb->s_blocksize_bits);
+	sb->s_time_gran = 1;
 	set_posix_acl_flag(sb);
 
 	VFS_ROOT(vfsp, &rootvp, error);
diff -puN include/linux/fs.h~sync-in-core-time-granuality-with-filesystems include/linux/fs.h
--- 25/include/linux/fs.h~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.796943080 -0800
+++ 25-akpm/include/linux/fs.h	2004-12-03 20:55:58.897927728 -0800
@@ -124,7 +124,6 @@ extern int dir_notify_enable;
 #define MS_REC		16384
 #define MS_VERBOSE	32768
 #define MS_POSIXACL	(1<<16)	/* VFS does not apply the umask */
-#define MS_ONE_SECOND	(1<<17)	/* fs has 1 sec a/m/ctime resolution */
 #define MS_ACTIVE	(1<<30)
 #define MS_NOUSER	(1<<31)
 
@@ -180,7 +179,6 @@ extern int dir_notify_enable;
 #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_ONE_SECOND(inode)	__IS_FLG(inode, MS_ONE_SECOND)
 
 #define IS_DEADDIR(inode)	((inode)->i_flags & S_DEAD)
 #define IS_NOCMTIME(inode)	((inode)->i_flags & S_NOCMTIME)
@@ -800,8 +798,14 @@ struct super_block {
 	 * even looking at it. You had been warned.
 	 */
 	struct semaphore s_vfs_rename_sem;	/* Kludge */
+
+	/* Granuality of c/m/atime in ns.
+	   Cannot be worse than a second */
+	u32		   s_time_gran;
 };
 
+extern struct timespec current_fs_time(struct super_block *sb);
+
 /*
  * Snapshotting support.
  */
diff -puN include/linux/time.h~sync-in-core-time-granuality-with-filesystems include/linux/time.h
--- 25/include/linux/time.h~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.797942928 -0800
+++ 25-akpm/include/linux/time.h	2004-12-03 20:55:58.898927576 -0800
@@ -90,6 +90,7 @@ static inline unsigned long get_seconds(
 struct timespec current_kernel_time(void);
 
 #define CURRENT_TIME (current_kernel_time())
+#define CURRENT_TIME_SEC ((struct timespec) { xtime.tv_sec, 0 })
 
 extern void do_gettimeofday(struct timeval *tv);
 extern int do_settimeofday(struct timespec *tv);
@@ -103,6 +104,8 @@ extern int do_setitimer(int which, struc
 extern int do_getitimer(int which, struct itimerval *value);
 extern void getnstimeofday (struct timespec *tv);
 
+extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
+
 static inline void
 set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
 {
diff -puN kernel/time.c~sync-in-core-time-granuality-with-filesystems kernel/time.c
--- 25/kernel/time.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.798942776 -0800
+++ 25-akpm/kernel/time.c	2004-12-03 20:55:58.899927424 -0800
@@ -33,6 +33,7 @@
 #include <linux/smp_lock.h>
 #include <linux/syscalls.h>
 #include <linux/security.h>
+#include <linux/fs.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -415,7 +416,7 @@ asmlinkage long sys_adjtimex(struct time
 	return copy_to_user(txc_p, &txc, sizeof(struct timex)) ? -EFAULT : ret;
 }
 
-struct timespec current_kernel_time(void)
+inline struct timespec current_kernel_time(void)
 {
         struct timespec now;
         unsigned long seq;
@@ -431,6 +432,50 @@ struct timespec current_kernel_time(void
 
 EXPORT_SYMBOL(current_kernel_time);
 
+/**
+ * current_fs_time - Return FS time
+ * @sb: Superblock.
+ *
+ * Return the current time truncated to the time granuality supported by
+ * the fs.
+ */
+struct timespec current_fs_time(struct super_block *sb)
+{
+	struct timespec now = current_kernel_time();
+	return timespec_trunc(now, sb->s_time_gran);
+}
+EXPORT_SYMBOL(current_fs_time);
+
+/**
+ * timespec_trunc - Truncate timespec to a granuality
+ * @t: Timespec
+ * @gran: Granuality in ns.
+ *
+ * Truncate a timespec to a granuality. gran must be smaller than a second.
+ * Always rounds down.
+ *
+ * This function should be only used for timestamps returned by
+ * current_kernel_time() or CURRENT_TIME, not with do_gettimeofday() because
+ * it doesn't handle the better resolution of the later.
+ */
+struct timespec timespec_trunc(struct timespec t, unsigned gran)
+{
+	/*
+	 * Division is pretty slow so avoid it for common cases.
+	 * Currently current_kernel_time() never returns better than
+	 * jiffies resolution. Exploit that.
+	 */
+	if (gran <= jiffies_to_usecs(1) * 1000) {
+		/* nothing */
+	} else if (gran == 1000000000) {
+		t.tv_nsec = 0;
+	} else {
+		t.tv_nsec -= t.tv_nsec % gran;
+	}
+	return t;
+}
+EXPORT_SYMBOL(timespec_trunc);
+
 #ifdef CONFIG_TIME_INTERPOLATION
 void getnstimeofday (struct timespec *tv)
 {
diff -puN net/sunrpc/rpc_pipe.c~sync-in-core-time-granuality-with-filesystems net/sunrpc/rpc_pipe.c
--- 25/net/sunrpc/rpc_pipe.c~sync-in-core-time-granuality-with-filesystems	2004-12-03 20:55:58.800942472 -0800
+++ 25-akpm/net/sunrpc/rpc_pipe.c	2004-12-03 20:55:58.899927424 -0800
@@ -769,6 +769,7 @@ rpc_fill_super(struct super_block *sb, v
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
 	sb->s_magic = RPCAUTH_GSSMAGIC;
 	sb->s_op = &s_ops;
+	sb->s_time_gran = 1;
 
 	inode = rpc_get_inode(sb, S_IFDIR | 0755);
 	if (!inode)
_
