diff options
-rw-r--r-- | fs/gfs2/Kconfig | 2 | ||||
-rw-r--r-- | fs/gfs2/aops.c | 2 | ||||
-rw-r--r-- | fs/gfs2/file.c | 3 | ||||
-rw-r--r-- | fs/gfs2/glops.c | 13 | ||||
-rw-r--r-- | fs/gfs2/log.c | 75 | ||||
-rw-r--r-- | fs/gfs2/log.h | 12 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 16 | ||||
-rw-r--r-- | fs/gfs2/lops.h | 3 | ||||
-rw-r--r-- | fs/gfs2/ops_fstype.c | 2 | ||||
-rw-r--r-- | fs/gfs2/quota.c | 3 | ||||
-rw-r--r-- | fs/gfs2/recovery.c | 17 | ||||
-rw-r--r-- | fs/gfs2/rgrp.c | 2 | ||||
-rw-r--r-- | fs/gfs2/super.c | 9 | ||||
-rw-r--r-- | fs/gfs2/trans.c | 2 | ||||
-rw-r--r-- | include/uapi/linux/gfs2_ondisk.h | 26 |
15 files changed, 128 insertions, 59 deletions
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index 43c827a7cce5..c0225d4b5435 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig @@ -3,6 +3,8 @@ config GFS2_FS depends on (64BIT || LBDAF) select FS_POSIX_ACL select CRC32 + select CRYPTO + select CRYPTO_CRC32C select QUOTACTL select FS_IOMAP help diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c index ac4a1e89da1e..462c3fd55929 100644 --- a/fs/gfs2/aops.c +++ b/fs/gfs2/aops.c @@ -448,7 +448,7 @@ static int gfs2_jdata_writepages(struct address_space *mapping, ret = gfs2_write_cache_jdata(mapping, wbc); if (ret == 0 && wbc->sync_mode == WB_SYNC_ALL) { - gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL); ret = gfs2_write_cache_jdata(mapping, wbc); } return ret; diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index bd60dc682676..7a02b4e6e9f3 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -246,7 +246,8 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask) } if ((flags ^ new_flags) & GFS2_DIF_JDATA) { if (new_flags & GFS2_DIF_JDATA) - gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, ip->i_gl, + GFS2_LOG_HEAD_FLUSH_NORMAL); error = filemap_fdatawrite(inode->i_mapping); if (error) goto out; diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index cdd1c5f06f45..2daab13a9e0b 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -107,7 +107,7 @@ static void gfs2_ail_empty_gl(struct gfs2_glock *gl) __gfs2_ail_flush(gl, 0, tr.tr_revokes); gfs2_trans_end(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); } void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) @@ -128,7 +128,7 @@ void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync) return; __gfs2_ail_flush(gl, fsync, max_revokes); gfs2_trans_end(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); } /** @@ -157,7 +157,7 @@ static void rgrp_go_sync(struct gfs2_glock *gl) return; GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); - gfs2_log_flush(sdp, gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, gl, GFS2_LOG_HEAD_FLUSH_NORMAL); filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end); error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end); mapping_set_error(mapping, error); @@ -252,7 +252,7 @@ static void inode_go_sync(struct gfs2_glock *gl) GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE); - gfs2_log_flush(gl->gl_name.ln_sbd, gl, NORMAL_FLUSH); + gfs2_log_flush(gl->gl_name.ln_sbd, gl, GFS2_LOG_HEAD_FLUSH_NORMAL); filemap_fdatawrite(metamapping); if (isreg) { struct address_space *mapping = ip->i_inode.i_mapping; @@ -303,7 +303,8 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) } if (ip == GFS2_I(gl->gl_name.ln_sbd->sd_rindex)) { - gfs2_log_flush(gl->gl_name.ln_sbd, NULL, NORMAL_FLUSH); + gfs2_log_flush(gl->gl_name.ln_sbd, NULL, + GFS2_LOG_HEAD_FLUSH_NORMAL); gl->gl_name.ln_sbd->sd_rindex_uptodate = 0; } if (ip && S_ISREG(ip->i_inode.i_mode)) @@ -495,7 +496,7 @@ static void freeze_go_sync(struct gfs2_glock *gl) gfs2_assert_withdraw(sdp, 0); } queue_work(gfs2_freeze_wq, &sdp->sd_freeze_work); - gfs2_log_flush(sdp, NULL, FREEZE_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_FREEZE); } } 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 @@ out_of_blocks: /** * 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); + + gfs2_log_write(sdp, page, sb->s_blocksize, 0, addr); gfs2_log_flush_bio(sdp, REQ_OP_WRITE, op_flags); log_flush_wait(sdp); } @@ -691,6 +726,7 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail, /** * log_write_header - Get and initialize a journal header buffer * @sdp: The GFS2 superblock + * @flags: The log header flags, including log header origin * * Returns: the initialized log buffer descriptor */ @@ -710,8 +746,8 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) op_flags = REQ_SYNC | REQ_META | REQ_PRIO; } sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); - gfs2_write_log_header(sdp, sdp->sd_log_sequence++, tail, flags, - op_flags); + gfs2_write_log_header(sdp, sdp->sd_jdesc, sdp->sd_log_sequence++, tail, + flags, op_flags); if (sdp->sd_log_tail != tail) log_pull_tail(sdp, tail); @@ -721,11 +757,11 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags) * gfs2_log_flush - flush incore transaction(s) * @sdp: the filesystem * @gl: The glock structure to flush. If NULL, flush the whole incore log + * @flags: The log header flags: GFS2_LOG_HEAD_FLUSH_* * */ -void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, - enum gfs2_flush_type type) +void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags) { struct gfs2_trans *tr; enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); @@ -739,7 +775,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, } trace_gfs2_log_flush(sdp, 1); - if (type == SHUTDOWN_FLUSH) + if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN) clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); sdp->sd_log_flush_head = sdp->sd_log_head; @@ -764,11 +800,11 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, if (sdp->sd_log_head != sdp->sd_log_flush_head) { log_flush_wait(sdp); - log_write_header(sdp, 0); + log_write_header(sdp, flags); } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ trace_gfs2_log_blocks(sdp, -1); - log_write_header(sdp, 0); + log_write_header(sdp, flags); } lops_after_commit(sdp, tr); @@ -785,7 +821,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, spin_unlock(&sdp->sd_ail_lock); gfs2_log_unlock(sdp); - if (type != NORMAL_FLUSH) { + if (!(flags & GFS2_LOG_HEAD_FLUSH_NORMAL)) { if (!sdp->sd_log_idle) { for (;;) { gfs2_ail1_start(sdp); @@ -795,12 +831,13 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, } atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ trace_gfs2_log_blocks(sdp, -1); - log_write_header(sdp, 0); + log_write_header(sdp, flags); sdp->sd_log_head = sdp->sd_log_flush_head; } - if (type == SHUTDOWN_FLUSH || type == FREEZE_FLUSH) + if (flags & (GFS2_LOG_HEAD_FLUSH_SHUTDOWN | + GFS2_LOG_HEAD_FLUSH_FREEZE)) gfs2_log_shutdown(sdp); - if (type == FREEZE_FLUSH) + if (flags & GFS2_LOG_HEAD_FLUSH_FREEZE) atomic_set(&sdp->sd_freeze_state, SFS_FROZEN); } @@ -956,7 +993,7 @@ int gfs2_logd(void *data) did_flush = false; if (gfs2_jrnl_flush_reqd(sdp) || t == 0) { gfs2_ail1_empty(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); did_flush = true; } @@ -964,7 +1001,7 @@ int gfs2_logd(void *data) gfs2_ail1_start(sdp); gfs2_ail1_wait(sdp); gfs2_ail1_empty(sdp); - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); did_flush = true; } diff --git a/fs/gfs2/log.h b/fs/gfs2/log.h index 619de9a1ff4f..93b52ac1ca1f 100644 --- a/fs/gfs2/log.h +++ b/fs/gfs2/log.h @@ -65,16 +65,10 @@ extern unsigned int gfs2_struct2blk(struct gfs2_sbd *sdp, unsigned int nstruct, extern void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks); extern int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks); -enum gfs2_flush_type { - NORMAL_FLUSH = 0, - SYNC_FLUSH, - SHUTDOWN_FLUSH, - FREEZE_FLUSH -}; -extern void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail, - u32 flags, int op_flags); +extern void gfs2_write_log_header(struct gfs2_sbd *sdp, struct gfs2_jdesc *jd, + u64 seq, u32 tail, u32 flags, int op_flags); extern void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, - enum gfs2_flush_type type); + u32 type); extern void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *trans); extern void gfs2_remove_from_ail(struct gfs2_bufdata *bd); extern void gfs2_ail1_flush(struct gfs2_sbd *sdp, struct writeback_control *wbc); diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index c8ff7b7954f0..4a60221c678f 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c @@ -18,6 +18,7 @@ #include <linux/fs.h> #include <linux/list_sort.h> +#include "dir.h" #include "gfs2.h" #include "incore.h" #include "inode.h" @@ -138,7 +139,7 @@ static void gfs2_log_incr_head(struct gfs2_sbd *sdp) sdp->sd_log_flush_head = 0; } -static u64 gfs2_log_bmap(struct gfs2_sbd *sdp) +u64 gfs2_log_bmap(struct gfs2_sbd *sdp) { unsigned int lbn = sdp->sd_log_flush_head; struct gfs2_journal_extent *je; @@ -306,23 +307,22 @@ static struct bio *gfs2_log_get_bio(struct gfs2_sbd *sdp, u64 blkno) return gfs2_log_alloc_bio(sdp, blkno); } - /** * gfs2_log_write - write to log * @sdp: the filesystem * @page: the page to write * @size: the size of the data to write * @offset: the offset within the page + * @blkno: block number of the log entry * * Try and add the page segment to the current bio. If that fails, * submit the current bio to the device and create a new one, and * then add the page segment to that. */ -static void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, - unsigned size, unsigned offset) +void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, + unsigned size, unsigned offset, u64 blkno) { - u64 blkno = gfs2_log_bmap(sdp); struct bio *bio; int ret; @@ -348,7 +348,8 @@ static void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) { - gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh)); + gfs2_log_write(sdp, bh->b_page, bh->b_size, bh_offset(bh), + gfs2_log_bmap(sdp)); } /** @@ -365,7 +366,8 @@ static void gfs2_log_write_bh(struct gfs2_sbd *sdp, struct buffer_head *bh) void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page) { struct super_block *sb = sdp->sd_vfs; - gfs2_log_write(sdp, page, sb->s_blocksize, 0); + gfs2_log_write(sdp, page, sb->s_blocksize, 0, + gfs2_log_bmap(sdp)); } static struct page *gfs2_get_log_desc(struct gfs2_sbd *sdp, u32 ld_type, diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index e529f536c117..e4949394f054 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h @@ -26,6 +26,9 @@ extern const struct gfs2_log_operations gfs2_revoke_lops; extern const struct gfs2_log_operations gfs2_databuf_lops; extern const struct gfs2_log_operations *gfs2_log_ops[]; +extern u64 gfs2_log_bmap(struct gfs2_sbd *sdp); +extern void gfs2_log_write(struct gfs2_sbd *sdp, struct page *page, + unsigned size, unsigned offset, u64 blkno); extern void gfs2_log_write_page(struct gfs2_sbd *sdp, struct page *page); extern void gfs2_log_flush_bio(struct gfs2_sbd *sdp, int op, int op_flags); extern void gfs2_pin(struct gfs2_sbd *sdp, struct buffer_head *bh); diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index ad55eb86a250..d6e620beb9db 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1382,7 +1382,7 @@ static void gfs2_kill_sb(struct super_block *sb) return; } - gfs2_log_flush(sdp, NULL, SYNC_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SYNC); dput(sdp->sd_root_dir); dput(sdp->sd_master_dir); sdp->sd_root_dir = NULL; diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index e700fb162664..2092df19e433 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c @@ -955,7 +955,8 @@ out: gfs2_glock_dq_uninit(&ghs[qx]); inode_unlock(&ip->i_inode); kfree(ghs); - gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(ip->i_gl->gl_name.ln_sbd, ip->i_gl, + GFS2_LOG_HEAD_FLUSH_NORMAL); return error; } diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 975f32166dfe..b6b258998bcd 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c @@ -14,6 +14,7 @@ #include <linux/buffer_head.h> #include <linux/gfs2_ondisk.h> #include <linux/crc32.h> +#include <linux/crc32c.h> #include "gfs2.h" #include "incore.h" @@ -137,7 +138,7 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, { struct gfs2_log_header *lh; struct buffer_head *bh; - u32 hash; + u32 hash, crc; int error; error = gfs2_replay_read_block(jd, blk, &bh); @@ -145,13 +146,17 @@ static int get_log_header(struct gfs2_jdesc *jd, unsigned int blk, return error; lh = (void *)bh->b_data; - hash = crc32(~0, lh, sizeof(*lh) - 4); + hash = crc32(~0, lh, LH_V1_SIZE - 4); hash = ~crc32_le_shift(hash, 4); /* assume lh_hash is zero */ + crc = crc32c(~0, (void *)lh + LH_V1_SIZE + 4, + bh->b_size - LH_V1_SIZE - 4); + error = lh->lh_header.mh_magic != cpu_to_be32(GFS2_MAGIC) || lh->lh_header.mh_type != cpu_to_be32(GFS2_METATYPE_LH) || be32_to_cpu(lh->lh_blkno) != blk || - be32_to_cpu(lh->lh_hash) != hash; + be32_to_cpu(lh->lh_hash) != hash || + (lh->lh_crc != 0 && be32_to_cpu(lh->lh_crc) != crc); brelse(bh); @@ -372,9 +377,9 @@ static void clean_journal(struct gfs2_jdesc *jd, sdp->sd_log_flush_head = head->lh_blkno; gfs2_replay_incr_blk(jd, &sdp->sd_log_flush_head); - gfs2_write_log_header(sdp, head->lh_sequence + 1, 0, - GFS2_LOG_HEAD_UNMOUNT, REQ_PREFLUSH | - REQ_FUA | REQ_META | REQ_SYNC); + gfs2_write_log_header(sdp, jd, head->lh_sequence + 1, 0, + GFS2_LOG_HEAD_UNMOUNT | GFS2_LOG_HEAD_RECOVERY, + REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC); } diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 6dea72f49316..00eab6c0525c 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c @@ -2093,7 +2093,7 @@ next_rgrp: } /* Flushing the log may release space */ if (loops == 2) - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); } return -ENOSPC; diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index d81d46e19726..fa3a19eaf0eb 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c @@ -757,7 +757,8 @@ static int gfs2_write_inode(struct inode *inode, struct writeback_control *wbc) bool flush_all = (wbc->sync_mode == WB_SYNC_ALL || gfs2_is_jdata(ip)); if (flush_all) - gfs2_log_flush(GFS2_SB(inode), ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(GFS2_SB(inode), ip->i_gl, + GFS2_LOG_HEAD_FLUSH_NORMAL); if (bdi->wb.dirty_exceeded) gfs2_ail1_flush(sdp, wbc); else @@ -853,7 +854,7 @@ static int gfs2_make_fs_ro(struct gfs2_sbd *sdp) gfs2_quota_sync(sdp->sd_vfs, 0); gfs2_statfs_sync(sdp->sd_vfs, 0); - gfs2_log_flush(sdp, NULL, SHUTDOWN_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_SHUTDOWN); wait_event(sdp->sd_reserving_log_wait, atomic_read(&sdp->sd_reserving_log) == 0); gfs2_assert_warn(sdp, atomic_read(&sdp->sd_log_blks_free) == sdp->sd_jdesc->jd_blocks); @@ -946,7 +947,7 @@ static int gfs2_sync_fs(struct super_block *sb, int wait) gfs2_quota_sync(sb, -1); if (wait) - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); return sdp->sd_log_error; } @@ -1650,7 +1651,7 @@ alloc_failed: goto out_unlock; out_truncate: - gfs2_log_flush(sdp, ip->i_gl, NORMAL_FLUSH); + gfs2_log_flush(sdp, ip->i_gl, GFS2_LOG_HEAD_FLUSH_NORMAL); metamapping = gfs2_glock2aspace(ip->i_gl); if (test_bit(GLF_DIRTY, &ip->i_gl->gl_flags)) { filemap_fdatawrite(metamapping); diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c index b95ebd166cac..7aec6d3434fa 100644 --- a/fs/gfs2/trans.c +++ b/fs/gfs2/trans.c @@ -117,7 +117,7 @@ void gfs2_trans_end(struct gfs2_sbd *sdp) up_read(&sdp->sd_log_flush_lock); if (sdp->sd_vfs->s_flags & SB_SYNCHRONOUS) - gfs2_log_flush(sdp, NULL, NORMAL_FLUSH); + gfs2_log_flush(sdp, NULL, GFS2_LOG_HEAD_FLUSH_NORMAL); if (alloced) sb_end_intwrite(sdp->sd_vfs); } diff --git a/include/uapi/linux/gfs2_ondisk.h b/include/uapi/linux/gfs2_ondisk.h index 09f0920f07e9..9a81d520f54a 100644 --- a/include/uapi/linux/gfs2_ondisk.h +++ b/include/uapi/linux/gfs2_ondisk.h @@ -403,7 +403,15 @@ struct gfs2_ea_header { * Log header structure */ -#define GFS2_LOG_HEAD_UNMOUNT 0x00000001 /* log is clean */ +#define GFS2_LOG_HEAD_UNMOUNT 0x00000001 /* log is clean */ +#define GFS2_LOG_HEAD_FLUSH_NORMAL 0x00000002 /* normal log flush */ +#define GFS2_LOG_HEAD_FLUSH_SYNC 0x00000004 /* Sync log flush */ +#define GFS2_LOG_HEAD_FLUSH_SHUTDOWN 0x00000008 /* Shutdown log flush */ +#define GFS2_LOG_HEAD_FLUSH_FREEZE 0x00000010 /* Freeze flush */ +#define GFS2_LOG_HEAD_RECOVERY 0x00000020 /* Journal recovery */ +#define GFS2_LOG_HEAD_USERSPACE 0x80000000 /* Written by gfs2-utils */ + +#define LH_V1_SIZE (offsetofend(struct gfs2_log_header, lh_hash)) struct gfs2_log_header { struct gfs2_meta_header lh_header; @@ -412,7 +420,21 @@ struct gfs2_log_header { __be32 lh_flags; /* GFS2_LOG_HEAD_... */ __be32 lh_tail; /* Block number of log tail */ __be32 lh_blkno; - __be32 lh_hash; + __be32 lh_hash; /* crc up to here with this field 0 */ + + /* Version 2 additional fields start here */ + __be32 lh_crc; /* crc32c from lh_nsec to end of block */ + __be32 lh_nsec; /* Nanoseconds of timestamp */ + __be64 lh_sec; /* Seconds of timestamp */ + __be64 lh_addr; /* Block addr of this log header (absolute) */ + __be64 lh_jinode; /* Journal inode number */ + __be64 lh_statfs_addr; /* Local statfs inode number */ + __be64 lh_quota_addr; /* Local quota change inode number */ + + /* Statfs local changes (i.e. diff from global statfs) */ + __be64 lh_local_total; + __be64 lh_local_free; + __be64 lh_local_dinodes; }; /* |