From db9a3a15d8942cbae87a375de73e24d236641ea0 Mon Sep 17 00:00:00 2001
From: vs <vs>
Date: Tue, 25 Nov 2008 11:24:04 +0000
Subject: [PATCH] Branch b1_666666 b=17359 i=adilger,bzzz use time obtained
 from a client to update inode timestamps on mds mds_reint_link,
 mds_reint_unlink and mds_reint_rename updated inode timestamps with local
 server time

---
 lustre/mds/mds_reint.c | 84 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 83 insertions(+), 1 deletion(-)

diff --git a/lustre/mds/mds_reint.c b/lustre/mds/mds_reint.c
index a551be9cbf..b4920a86ce 100644
--- a/lustre/mds/mds_reint.c
+++ b/lustre/mds/mds_reint.c
@@ -1831,10 +1831,19 @@ cleanup:
                 struct iattr iattr;
                 int err;
 
+                /* update ctime of unlinked file, even if last link is
+                   removed because open-unlinked file can be statted */
+                iattr.ia_valid = ATTR_CTIME;
+                LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                err = fsfilt_setattr(obd, dchild, handle, &iattr, 0);
+                if (err)
+                        CERROR("error on unlinked inode time update: "
+                               "rc = %d\n", err);
+
+                /* update mtime and ctime of parent directory*/
                 iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
                 LTIME_S(iattr.ia_mtime) = rec->ur_time;
                 LTIME_S(iattr.ia_ctime) = rec->ur_time;
-
                 err = fsfilt_setattr(obd, dparent, handle, &iattr, 0);
                 if (err)
                         CERROR("error on parent setattr: rc = %d\n", err);
@@ -1995,6 +2004,27 @@ static int mds_reint_link(struct mds_update_record *rec, int offset,
         UNLOCK_INODE_MUTEX(de_tgt_dir->d_inode);
         if (rc && rc != -EPERM && rc != -EACCES)
                 CERROR("vfs_link error %d\n", rc);
+        if (rc == 0) {
+                struct iattr iattr;
+                int err;
+
+                /* update ctime of old file */
+                iattr.ia_valid = ATTR_CTIME;
+                LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                err = fsfilt_setattr(obd, de_src, handle, &iattr, 0);
+                if (err)
+                        CERROR("error on old inode time update: "
+                               "rc = %d\n", err);
+
+                /* update mtime and ctime of target directory */
+                iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
+                LTIME_S(iattr.ia_mtime) = rec->ur_time;
+                LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                err = fsfilt_setattr(obd, de_tgt_dir, handle, &iattr, 0);
+                if (err)
+                        CERROR("error on target dir inode time update: "
+                               "rc = %d\n", err);
+        }
 cleanup:
         rc = mds_finish_transno(mds, de_tgt_dir ? de_tgt_dir->d_inode : NULL,
                                 handle, req, rc, 0, 0);
@@ -2371,6 +2401,58 @@ no_unlink:
                            de_tgtdir->d_inode, de_new, mds->mds_vfsmnt);
         unlock_kernel();
 
+        if (rc == 0) {
+                struct iattr iattr;
+                int err;
+
+                /* update ctime of renamed file */
+                iattr.ia_valid = ATTR_CTIME;
+                LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                if (S_ISDIR(de_old->d_inode->i_mode) &&
+                    de_srcdir->d_inode != de_tgtdir->d_inode) {
+                        /* cross directory rename of a directory, ".."
+                           changed, update mtime also */
+                        iattr.ia_valid |= ATTR_MTIME;
+                        LTIME_S(iattr.ia_mtime) = rec->ur_time;
+                }
+                err = fsfilt_setattr(obd, de_old, handle, &iattr, 0);
+                if (err)
+                        CERROR("error on old inode time update: "
+                               "rc = %d\n", err);
+
+                if (de_new->d_inode) {
+                        /* target file exists, update its ctime as it
+                           gets unlinked */
+                        iattr.ia_valid = ATTR_CTIME;
+                        LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                        err = fsfilt_setattr(obd, de_new, handle, &iattr, 0);
+                        if (err)
+                                CERROR("error on target inode time update: "
+                                       "rc = %d\n", err);
+                }
+
+                /* update mtime and ctime of old directory */
+                iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
+                LTIME_S(iattr.ia_mtime) = rec->ur_time;
+                LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                err = fsfilt_setattr(obd, de_srcdir, handle, &iattr, 0); 
+                if (err)
+                        CERROR("error on old dir inode update: "
+                               "rc = %d\n", err);
+
+                if (de_srcdir->d_inode != de_tgtdir->d_inode) {
+                        /* cross directory rename, update
+                           mtime and ctime of new directory */
+                        iattr.ia_valid = ATTR_MTIME | ATTR_CTIME;
+                        LTIME_S(iattr.ia_mtime) = rec->ur_time;
+                        LTIME_S(iattr.ia_ctime) = rec->ur_time;
+                        err = fsfilt_setattr(obd, de_tgtdir, handle, &iattr, 0);
+                        if (err)
+                                CERROR("error on new dir inode time update: "
+                                       "rc = %d\n", err);
+                }
+        }
+
         if (rc == 0 && new_inode != NULL && new_inode->i_nlink == 0) {
                 if (mds_orphan_open_count(new_inode) > 0)
                         rc = mds_orphan_add_link(rec, obd, de_new);
-- 
GitLab