Merge tag 'ext4_for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / fs / xfs / xfs_inode_item_recover.c
index 5e0d291..7b79518 100644 (file)
@@ -115,6 +115,82 @@ out_free_ip:
        return error;
 }
 
+static inline bool xfs_log_dinode_has_bigtime(const struct xfs_log_dinode *ld)
+{
+       return ld->di_version >= 3 &&
+              (ld->di_flags2 & XFS_DIFLAG2_BIGTIME);
+}
+
+/* Convert a log timestamp to an ondisk timestamp. */
+static inline xfs_timestamp_t
+xfs_log_dinode_to_disk_ts(
+       struct xfs_log_dinode           *from,
+       const xfs_log_timestamp_t       its)
+{
+       struct xfs_legacy_timestamp     *lts;
+       struct xfs_log_legacy_timestamp *lits;
+       xfs_timestamp_t                 ts;
+
+       if (xfs_log_dinode_has_bigtime(from))
+               return cpu_to_be64(its);
+
+       lts = (struct xfs_legacy_timestamp *)&ts;
+       lits = (struct xfs_log_legacy_timestamp *)&its;
+       lts->t_sec = cpu_to_be32(lits->t_sec);
+       lts->t_nsec = cpu_to_be32(lits->t_nsec);
+
+       return ts;
+}
+
+STATIC void
+xfs_log_dinode_to_disk(
+       struct xfs_log_dinode   *from,
+       struct xfs_dinode       *to)
+{
+       to->di_magic = cpu_to_be16(from->di_magic);
+       to->di_mode = cpu_to_be16(from->di_mode);
+       to->di_version = from->di_version;
+       to->di_format = from->di_format;
+       to->di_onlink = 0;
+       to->di_uid = cpu_to_be32(from->di_uid);
+       to->di_gid = cpu_to_be32(from->di_gid);
+       to->di_nlink = cpu_to_be32(from->di_nlink);
+       to->di_projid_lo = cpu_to_be16(from->di_projid_lo);
+       to->di_projid_hi = cpu_to_be16(from->di_projid_hi);
+       memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad));
+
+       to->di_atime = xfs_log_dinode_to_disk_ts(from, from->di_atime);
+       to->di_mtime = xfs_log_dinode_to_disk_ts(from, from->di_mtime);
+       to->di_ctime = xfs_log_dinode_to_disk_ts(from, from->di_ctime);
+
+       to->di_size = cpu_to_be64(from->di_size);
+       to->di_nblocks = cpu_to_be64(from->di_nblocks);
+       to->di_extsize = cpu_to_be32(from->di_extsize);
+       to->di_nextents = cpu_to_be32(from->di_nextents);
+       to->di_anextents = cpu_to_be16(from->di_anextents);
+       to->di_forkoff = from->di_forkoff;
+       to->di_aformat = from->di_aformat;
+       to->di_dmevmask = cpu_to_be32(from->di_dmevmask);
+       to->di_dmstate = cpu_to_be16(from->di_dmstate);
+       to->di_flags = cpu_to_be16(from->di_flags);
+       to->di_gen = cpu_to_be32(from->di_gen);
+
+       if (from->di_version == 3) {
+               to->di_changecount = cpu_to_be64(from->di_changecount);
+               to->di_crtime = xfs_log_dinode_to_disk_ts(from,
+                                                         from->di_crtime);
+               to->di_flags2 = cpu_to_be64(from->di_flags2);
+               to->di_cowextsize = cpu_to_be32(from->di_cowextsize);
+               to->di_ino = cpu_to_be64(from->di_ino);
+               to->di_lsn = cpu_to_be64(from->di_lsn);
+               memcpy(to->di_pad2, from->di_pad2, sizeof(to->di_pad2));
+               uuid_copy(&to->di_uuid, &from->di_uuid);
+               to->di_flushiter = 0;
+       } else {
+               to->di_flushiter = cpu_to_be16(from->di_flushiter);
+       }
+}
+
 STATIC int
 xlog_recover_inode_commit_pass2(
        struct xlog                     *log,