From: Steven Whitehouse <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [gfs2-utils PATCH] fsck.gfs2: Check and repair per_node contents such as quota_changeX
Date: Thu, 05 Sep 2013 16:30:03 +0100 [thread overview]
Message-ID: <1378395003.2698.8.camel@menhir> (raw)
In-Reply-To: <1543446674.9269193.1378394736712.JavaMail.root@redhat.com>
Hi,
Sounds good, but I wonder do we really need to continue doing anything
with the inum range files, now that nothing uses them. Maybe worth
looking to see how we can drop those eventually,
Steve.
On Thu, 2013-09-05 at 11:25 -0400, Bob Peterson wrote:
> Hi,
>
> This patch gives fsck.gfs2 the ability to check the system files that
> are in the per_node directory: All the inum_rangeX, statfs_changeX
> and quota_changeX files. If they're found to be corrupt, they are
> deleted and rebuilt.
>
> Regards,
>
> Bob Peterson
> Red Hat File Systems
>
> Signed-off-by: Bob Peterson <rpeterso@redhat.com>
> ---
> diff --git a/gfs2/fsck/pass2.c b/gfs2/fsck/pass2.c
> index 727cc18..26f7d48 100644
> --- a/gfs2/fsck/pass2.c
> +++ b/gfs2/fsck/pass2.c
> @@ -1595,6 +1595,116 @@ struct metawalk_fxns pass2_fxns = {
> .repair_leaf = pass2_repair_leaf,
> };
>
> +static int check_metalist_qc(struct gfs2_inode *ip, uint64_t block,
> + struct gfs2_buffer_head **bh, int h,
> + int *is_valid, int *was_duplicate, void *private)
> +{
> + *was_duplicate = 0;
> + *is_valid = 1;
> + *bh = bread(ip->i_sbd, block);
> + return meta_is_good;
> +}
> +
> +static int check_data_qc(struct gfs2_inode *ip, uint64_t metablock,
> + uint64_t block, void *private)
> +{
> + struct gfs2_buffer_head *bh;
> +
> + /* At this point, basic data block checks have already been done,
> + so we only need to make sure they're QC blocks. */
> + if (!valid_block(ip->i_sbd, block))
> + return -1;
> +
> + bh = bread(ip->i_sbd, block);
> + if (gfs2_check_meta(bh, GFS2_METATYPE_QC) != 0) {
> + log_crit(_("Error: quota_change block at %lld (0x%llx) is "
> + "the wrong metadata type.\n"),
> + (unsigned long long)block, (unsigned long long)block);
> + brelse(bh);
> + return -1;
> + }
> + brelse(bh);
> + return 0;
> +}
> +
> +struct metawalk_fxns quota_change_fxns = {
> + .check_metalist = check_metalist_qc,
> + .check_data = check_data_qc,
> +};
> +
> +/* check_pernode_for - verify a file within the system per_node directory
> + * @x - index number X
> + * @per_node - pointer to the per_node inode
> + * @fn - system file name
> + * @filelen - the file length the system file needs to be
> + * @multiple - the file length must be a multiple (versus the exact value)
> + * @pass - a metawalk function for checking the data blocks (if any)
> + * @builder - a rebuild function for the file
> + *
> + * Returns: 0 if all went well, else error. */
> +static int check_pernode_for(int x, struct gfs2_inode *pernode, const char *fn,
> + unsigned long long filelen, int multiple,
> + struct metawalk_fxns *pass,
> + int builder(struct gfs2_inode *per_node,
> + unsigned int j))
> +{
> + struct gfs2_inode *ip;
> + int error, valid_size = 1;
> +
> + log_debug(_("Checking system file %s\n"), fn);
> + error = gfs2_lookupi(pernode, fn, strlen(fn), &ip);
> + if (error) {
> + log_err(_("System file %s is missing.\n"), fn);
> + if (!query( _("Rebuild the system file? (y/n) ")))
> + return 0;
> + goto build_it;
> + }
> + if (!ip->i_di.di_size)
> + valid_size = 0;
> + else if (!multiple && ip->i_di.di_size != filelen)
> + valid_size = 0;
> + else if (multiple && (ip->i_di.di_size % filelen))
> + valid_size = 0;
> + if (!valid_size) {
> + log_err(_("System file %s has an invalid size. Is %llu, "
> + "should be %llu.\n"), fn, ip->i_di.di_size, filelen);
> + if (!query( _("Rebuild the system file? (y/n) ")))
> + goto out_good;
> + fsck_inode_put(&ip);
> + goto build_it;
> + }
> + if (pass) {
> + error = check_metatree(ip, pass);
> + if (!error)
> + goto out_good;
> + log_err(_("System file %s has bad contents.\n"), fn);
> + if (!query( _("Delete and rebuild the system file? (y/n) ")))
> + goto out_good;
> + check_metatree(ip, &pass2_fxns_delete);
> + fsck_inode_put(&ip);
> + gfs2_dirent_del(pernode, fn, strlen(fn));
> + goto build_it;
> + }
> +out_good:
> + fsck_inode_put(&ip);
> + return 0;
> +
> +build_it:
> + if (builder(pernode, x)) {
> + log_err(_("Error building %s\n"), fn);
> + return -1;
> + }
> + error = gfs2_lookupi(pernode, fn, strlen(fn), &ip);
> + if (error) {
> + log_err(_("Error rebuilding %s.\n"), fn);
> + return -1;
> + }
> + fsck_blockmap_set(ip, ip->i_di.di_num.no_addr, fn, gfs2_inode_file);
> + reprocess_inode(ip, fn);
> + log_err(_("System file %s rebuilt.\n"), fn);
> + goto out_good;
> +}
> +
> /* Check system directory inode */
> /* Should work for all system directories: root, master, jindex, per_node */
> static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
> @@ -1707,7 +1817,26 @@ static int check_system_dir(struct gfs2_inode *sysinode, const char *dirname,
> sysinode->i_di.di_num.no_addr);
> }
> }
> - return 0;
> + error = 0;
> + if (sysinode == sysinode->i_sbd->md.pinode) {
> + int j;
> + char fn[64];
> +
> + /* Make sure all the per_node files are there, and valid */
> + for (j = 0; j < sysinode->i_sbd->md.journals; j++) {
> + sprintf(fn, "inum_range%d", j);
> + error += check_pernode_for(j, sysinode, fn, 16, 0,
> + NULL, build_inum_range);
> + sprintf(fn, "statfs_change%d", j);
> + error += check_pernode_for(j, sysinode, fn, 24, 0,
> + NULL, build_statfs_change);
> + sprintf(fn, "quota_change%d", j);
> + error += check_pernode_for(j, sysinode, fn, 1048576, 1,
> + "a_change_fxns,
> + build_quota_change);
> + }
> + }
> + return error;
> }
>
> /**
> diff --git a/gfs2/libgfs2/libgfs2.h b/gfs2/libgfs2/libgfs2.h
> index 1548cf3..f864a08 100644
> --- a/gfs2/libgfs2/libgfs2.h
> +++ b/gfs2/libgfs2/libgfs2.h
> @@ -770,6 +770,10 @@ extern int do_init_statfs(struct gfs2_sbd *sdp);
> extern int gfs2_check_meta(struct gfs2_buffer_head *bh, int type);
> extern unsigned lgfs2_bm_scan(struct rgrp_tree *rgd, unsigned idx,
> uint64_t *buf, uint8_t state);
> +extern int build_inum_range(struct gfs2_inode *per_node, unsigned int j);
> +extern int build_statfs_change(struct gfs2_inode *per_node, unsigned int j);
> +extern int build_quota_change(struct gfs2_inode *per_node, unsigned int j);
> +
> /* super.c */
> extern int check_sb(struct gfs2_sb *sb);
> extern int read_sb(struct gfs2_sbd *sdp);
> diff --git a/gfs2/libgfs2/structures.c b/gfs2/libgfs2/structures.c
> index 2a8c6f7..e888f1e 100644
> --- a/gfs2/libgfs2/structures.c
> +++ b/gfs2/libgfs2/structures.c
> @@ -180,7 +180,7 @@ int build_jindex(struct gfs2_sbd *sdp)
> return 0;
> }
>
> -static int build_inum_range(struct gfs2_inode *per_node, unsigned int j)
> +int build_inum_range(struct gfs2_inode *per_node, unsigned int j)
> {
> struct gfs2_sbd *sdp = per_node->i_sbd;
> char name[256];
> @@ -204,7 +204,7 @@ static int build_inum_range(struct gfs2_inode *per_node, unsigned int j)
> return 0;
> }
>
> -static int build_statfs_change(struct gfs2_inode *per_node, unsigned int j)
> +int build_statfs_change(struct gfs2_inode *per_node, unsigned int j)
> {
> struct gfs2_sbd *sdp = per_node->i_sbd;
> char name[256];
> @@ -228,7 +228,7 @@ static int build_statfs_change(struct gfs2_inode *per_node, unsigned int j)
> return 0;
> }
>
> -static int build_quota_change(struct gfs2_inode *per_node, unsigned int j)
> +int build_quota_change(struct gfs2_inode *per_node, unsigned int j)
> {
> struct gfs2_sbd *sdp = per_node->i_sbd;
> struct gfs2_meta_header mh;
> diff --git a/gfs2/libgfs2/super.c b/gfs2/libgfs2/super.c
> index eb97c40..f87734a 100644
> --- a/gfs2/libgfs2/super.c
> +++ b/gfs2/libgfs2/super.c
> @@ -119,6 +119,7 @@ int read_sb(struct gfs2_sbd *sdp)
> sdp->sb_addr = GFS2_SB_ADDR * GFS2_BASIC_BLOCK / sdp->bsize;
> sdp->sd_blocks_per_bitmap = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header))
> * GFS2_NBBY;
> + sdp->qcsize = GFS2_DEFAULT_QCSIZE;
>
> return 0;
> }
>
prev parent reply other threads:[~2013-09-05 15:30 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1437915058.9265143.1378394433338.JavaMail.root@redhat.com>
2013-09-05 15:25 ` [Cluster-devel] [gfs2-utils PATCH] fsck.gfs2: Check and repair per_node contents such as quota_changeX Bob Peterson
2013-09-05 15:30 ` Steven Whitehouse [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1378395003.2698.8.camel@menhir \
--to=swhiteho@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).