[Cluster-devel] [GFS2 PATCH][v2] GFS2: Introduce new gfs2_log_header_v2

Steven Whitehouse swhiteho at redhat.com
Fri Dec 22 13:40:38 UTC 2017


Hi,


On 22/12/17 13:34, Bob Peterson wrote:
> Hi,
>
> Here is version 2 of this patch, which has been heavily revised
> based on comments from the initial patch. I'm still planning to
> do a third patch which saves a new debug field for log header
> origin.
>
> Bob
> ---
> This patch adds a new structure called gfs2_log_header_v2 which is
> used to store expanded fields into previously unused areas of the
> log headers. Some of these are used for debug purposes so we can
> backtrack when problems occur. Others are reserved for future
> expansion.
>
> This is based on a prototype patch from Steve Whitehouse.
>
> In addition to Steve's original code, we also replace the log
> flush types (NORMAL_FLUSH, SYNC_FLUSH, etc.) with new log header
> flags (GFS2_LOG_HEAD_*). This way the log flush type be
> automatically saved in the log header (as the UNMOUNT flag is now).
> A few extra flags are also defined so we can distinguish whether
> the log header was written by recovery, user space (gfs2-utils),
> or one of the log flush operations.
>
> Signed-off-by: Bob Peterson <rpeterso at redhat.com>
> ---
>   fs/gfs2/aops.c                   |  2 +-
>   fs/gfs2/file.c                   |  3 ++-
>   fs/gfs2/glops.c                  | 13 ++++++-----
>   fs/gfs2/log.c                    | 50 ++++++++++++++++++++++++++++------------
>   fs/gfs2/log.h                    |  8 +------
>   fs/gfs2/lops.c                   | 30 ++++++++++++++++++++----
>   fs/gfs2/lops.h                   |  2 ++
>   fs/gfs2/ops_fstype.c             |  2 +-
>   fs/gfs2/quota.c                  |  3 ++-
>   fs/gfs2/recovery.c               |  4 ++--
>   fs/gfs2/rgrp.c                   |  2 +-
>   fs/gfs2/super.c                  |  9 ++++----
>   fs/gfs2/trans.c                  |  2 +-
>   include/uapi/linux/gfs2_ondisk.h | 26 ++++++++++++++++++++-
>   14 files changed, 111 insertions(+), 45 deletions(-)
>
> diff --git a/fs/gfs2/aops.c b/fs/gfs2/aops.c
> index 658ca027cab9..7c64925735d3 100644
> --- a/fs/gfs2/aops.c
> +++ b/fs/gfs2/aops.c
> @@ -445,7 +445,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 58705ef8643a..475c601ef4d8 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 27e97d3de1e0..2cc00d28e907 100644
> --- a/fs/gfs2/log.c
> +++ b/fs/gfs2/log.c
> @@ -652,7 +652,7 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp)
>    * @sdp: The GFS2 superblock
>    * @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
> @@ -661,13 +661,18 @@ void gfs2_write_revokes(struct gfs2_sbd *sdp)
>   void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail,
>   			   u32 flags, int op_flags)
>   {
> +	struct gfs2_log_header_v2 *lh2;
>   	struct gfs2_log_header *lh;
>   	u32 hash;
>   	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;
>   
> -	lh = page_address(page);
> -	clear_page(lh);
> +	lh2 = page_address(page);
> +	clear_page(lh2);
>   
> +	lh = &lh2->lhv1;
>   	lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
>   	lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
>   	lh->lh_header.__pad0 = cpu_to_be64(0);
> @@ -680,7 +685,20 @@ void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail,
>   	hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header));
>   	lh->lh_hash = cpu_to_be32(hash);
>   
> -	gfs2_log_write_page(sdp, page);
> +	tv = current_kernel_time64();
> +	lh2->lh_nsec = cpu_to_be32(tv.tv_nsec);
> +	lh2->lh_sec = cpu_to_be64(tv.tv_sec);
> +	lh2->lh_jinode = cpu_to_be64(GFS2_I(sdp->sd_jdesc->jd_inode)->i_no_addr);
> +	lh2->lh_statfs_addr = cpu_to_be64(GFS2_I(sdp->sd_sc_inode)->i_no_addr);
> +	lh2->lh_quota_addr = cpu_to_be64(GFS2_I(sdp->sd_qc_inode)->i_no_addr);
> +
> +	spin_lock(&sdp->sd_statfs_spin);
> +	lh2->lh_local_total = cpu_to_be64(l_sc->sc_total);
> +	lh2->lh_local_free = cpu_to_be64(l_sc->sc_free);
> +	lh2->lh_local_dinodes = cpu_to_be64(l_sc->sc_dinodes);
> +	spin_unlock(&sdp->sd_statfs_spin);
> +
Bear in mind, that now this function writes the recovery log headers 
too, it must avoid writing the local node's statfs info into the log 
that has just been recovered (for another node). Likewise the other 
local inode info needs to match that for the node/log that has been 
recovered. Otherwise though, the patch looks good,

Steve.




More information about the Cluster-devel mailing list