diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index c27cbcebfe88..a2eb13c04591 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -14,6 +14,7 @@
#include <linux/buffer_head.h>
#include <linux/gfs2_ondisk.h>
#include <linux/crc32.h>
+#include <linux/crc32c.h>
#include <linux/delay.h>
#include <linux/kthread.h>
#include <linux/freezer.h>
@@ -653,20 +654,25 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp)
/**
* write_log_header - Write a journal log header buffer at
sd_log_flush_head
* @sdp: The GFS2 superblock
+ * @jd: journal descriptor of the journal to which we are writing
* @seq: sequence number
* @tail: tail of the log
- * @flags: log header flags
+ * @flags: log header flags GFS2_LOG_HEAD_*
* @op_flags: flags to pass to the bio
*
* Returns: the initialized log buffer descriptor
*/
-void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail,
- u32 flags, int op_flags)
+void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd,
+ u64 seq, u32 tail, u32 flags, int op_flags)
{
struct gfs2_log_header *lh;
- u32 hash;
+ u32 hash, crc;
struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
+ struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
+ struct timespec64 tv;
+ struct super_block *sb = sdp->sd_vfs;
+ u64 addr;
lh = page_address(page);
clear_page(lh);
@@ -680,10 +686,39 @@ void gfs2_write_log_header(struct gfs2_sbd
*sdp, u64 seq, u32 tail,
lh->lh_flags = cpu_to_be32(flags);
lh->lh_tail = cpu_to_be32(tail);
lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head);
- hash = ~crc32(~0, lh, sizeof(*lh));
+ hash = ~crc32(~0, lh, LH_V1_SIZE);
lh->lh_hash = cpu_to_be32(hash);
- gfs2_log_write_page(sdp, page);
+ tv = current_kernel_time64();
+ lh->lh_nsec = cpu_to_be32(tv.tv_nsec);
+ lh->lh_sec = cpu_to_be64(tv.tv_sec);
+ addr = gfs2_log_bmap(sdp);
+ lh->lh_addr = cpu_to_be64(addr);
+ lh->lh_jinode = cpu_to_be64(GFS2_I(jd->jd_inode)->i_no_addr);
+
+ /* We may only write local statfs, quota, etc., when writing to our
+ own journal. The values are left 0 when recovering a journal
+ different from our own. */
+ if (!(flags & GFS2_LOG_HEAD_RECOVERY)) {
+ lh->lh_statfs_addr =
+ cpu_to_be64(GFS2_I(sdp->sd_sc_inode)->i_no_addr);
+ lh->lh_quota_addr =
+ cpu_to_be64(GFS2_I(sdp->sd_qc_inode)->i_no_addr);
+
+ spin_lock(&sdp->sd_statfs_spin);
+ lh->lh_local_total = cpu_to_be64(l_sc->sc_total);
+ lh->lh_local_free = cpu_to_be64(l_sc->sc_free);
+ lh->lh_local_dinodes = cpu_to_be64(l_sc->sc_dinodes);
+ spin_unlock(&sdp->sd_statfs_spin);
+ }
+
+ BUILD_BUG_ON(offsetof(struct gfs2_log_header, lh_crc) !=
LH_V1_SIZE);
+
+ crc = crc32c(~0, (void *)lh + LH_V1_SIZE + 4,
+ sb->s_blocksize - LH_V1_SIZE - 4);
+ lh->lh_crc = cpu_to_be32(crc);