[Cluster-devel] [PATCH v5 2/3] GFS2: Introduce new gfs2_log_header_v2
Andrew Price
anprice at redhat.com
Fri Jan 19 12:19:14 UTC 2018
On 19/01/18 10:53, Steven Whitehouse wrote:
> On 19/01/18 10:47, Andrew Price wrote:
>> On 18/01/18 16:04, Andreas Gruenbacher wrote:
>> <snip>
>>> 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);
>>
>> This seems to be at odds with the field comment:
>>
>> > + __be32 lh_crc; /* crc32 of whole block with this field 0 */
>>
>> Is it really just CRCing the block from lh_crc + 4 onwards?
>>
>> Andy
>>
> Yes, the comment needs updating to match the code, if we are going to do
> that. I'm not too concerned either way, but it might be a good plan to
> make an inline function to calculate the checksum there, just to make
> the clearer how it is done, and because we are going to need the same
> code in multiple places eventually,
Thanks for clarifying. I have another query: in the gfs2_jadd case the
new journal is written via an fd so the lh_addr is unknown when writing
the log headers it initialises the journal with. Is it ok to leave that
zero?
Andy
More information about the Cluster-devel
mailing list