xfs: implement inode change count
authorDave Chinner <dchinner@redhat.com>
Thu, 27 Jun 2013 06:04:59 +0000 (16:04 +1000)
committerBen Myers <bpm@sgi.com>
Fri, 28 Jun 2013 18:00:05 +0000 (13:00 -0500)
For CRC enabled filesystems, add support for the monotonic inode
version change counter that is needed by protocols like NFSv4 for
determining if the inode has changed in any way at all between two
unrelated operations on the inode.

This bumps the change count the first time an inode is dirtied in a
transaction. Since all modifications to the inode are logged, this
will catch all changes that are made to the inode, including
timestamp updates that occur during data writes.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Mark Tinguely <tinguely@sgi.com>
Reviewed-by: Chandra Seetharaman <sekharan@us.ibm.com>
Signed-off-by: Ben Myers <bpm@sgi.com>
fs/xfs/xfs_super.c
fs/xfs/xfs_trans_inode.c

index 30ef68f8a390d2cbfe6e96971dbadd5ca887fa8c..e5e8b5ee8bfa0fa721e5b2dba216e01e6ffb3f69 100644 (file)
@@ -1477,6 +1477,10 @@ xfs_fs_fill_super(
        sb->s_time_gran = 1;
        set_posix_acl_flag(sb);
 
+       /* version 5 superblocks support inode version counters. */
+       if (XFS_SB_VERSION_NUM(&mp->m_sb) == XFS_SB_VERSION_5)
+               sb->s_flags |= MS_I_VERSION;
+
        error = xfs_mountfs(mp);
        if (error)
                goto out_filestream_unmount;
index ac6d567704dbef8beb6c2b74bc22250a2f5da77b..53dfe46f3680791a8eab2e72c1a92db3cb17c091 100644 (file)
@@ -112,6 +112,17 @@ xfs_trans_log_inode(
        ASSERT(ip->i_itemp != NULL);
        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 
+       /*
+        * First time we log the inode in a transaction, bump the inode change
+        * counter if it is configured for this to occur.
+        */
+       if (!(ip->i_itemp->ili_item.li_desc->lid_flags & XFS_LID_DIRTY) &&
+           IS_I_VERSION(VFS_I(ip))) {
+               inode_inc_iversion(VFS_I(ip));
+               ip->i_d.di_changecount = VFS_I(ip)->i_version;
+               flags |= XFS_ILOG_CORE;
+       }
+
        tp->t_flags |= XFS_TRANS_DIRTY;
        ip->i_itemp->ili_item.li_desc->lid_flags |= XFS_LID_DIRTY;