From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Christoph Hellwig <hch@infradead.org>
Cc: sandeen@sandeen.net, linux-xfs@vger.kernel.org
Subject: Re: [PATCH v2 11/8] xfs_repair: don't corrupt a attr fork da3 node when clearing forw/back
Date: Tue, 4 Feb 2020 15:14:42 -0800 [thread overview]
Message-ID: <20200204231442.GE6874@magnolia> (raw)
In-Reply-To: <20200131060315.GA26786@infradead.org>
On Thu, Jan 30, 2020 at 10:03:15PM -0800, Christoph Hellwig wrote:
> Looks sensible, but I think we want the helpers for both the node and
> leaf case, something like this untested patch:
Ok, I was about to repost with more or less the same code.
--D
> diff --git a/repair/attr_repair.c b/repair/attr_repair.c
> index 9a44f610..0c26f0e6 100644
> --- a/repair/attr_repair.c
> +++ b/repair/attr_repair.c
> @@ -952,6 +952,98 @@ _("wrong FS UUID, inode %" PRIu64 " attr block %" PRIu64 "\n"),
> return 0;
> }
>
> +static int
> +process_leaf_da_root(
> + struct xfs_mount *mp,
> + xfs_ino_t ino,
> + struct xfs_dinode *dip,
> + struct blkmap *blkmap,
> + int *repair,
> + struct xfs_buf *bp)
> +{
> + struct xfs_attr3_icleaf_hdr leafhdr;
> + xfs_dahash_t next_hashval;
> + int repairlinks = 0;
> +
> + /*
> + * Check sibling pointers in block 0 before we have to release the btree
> + * block.
> + */
> + xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, bp->b_addr);
> + if (leafhdr.forw != 0 || leafhdr.back != 0) {
> + if (!no_modify) {
> + do_warn(
> + _("clearing forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"),
> + ino);
> + repairlinks = 1;
> + leafhdr.forw = 0;
> + leafhdr.back = 0;
> + xfs_attr3_leaf_hdr_to_disk(mp->m_attr_geo, bp->b_addr,
> + &leafhdr);
> + } else {
> + do_warn(
> + _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino);
> + }
> + }
> +
> + if (process_leaf_attr_block(mp, bp->b_addr, 0, ino, blkmap, 0,
> + &next_hashval, repair)) {
> + *repair = 0;
> + /* the block is bad. lose the attribute fork. */
> + libxfs_putbuf(bp);
> + return 1;
> + }
> +
> + *repair = *repair || repairlinks;
> + return 0;
> +}
> +
> +static int
> +process_node_da_root(
> + struct xfs_mount *mp,
> + xfs_ino_t ino,
> + struct xfs_dinode *dip,
> + struct blkmap *blkmap,
> + int *repair,
> + struct xfs_buf *bp)
> +{
> + struct xfs_da3_icnode_hdr da3_hdr;
> + int repairlinks = 0;
> + int error;
> +
> + /*
> + * Check sibling pointers in block 0 before we have to release the btree
> + * block.
> + */
> + xfs_da3_node_hdr_from_disk(mp, &da3_hdr, bp->b_addr);
> + if (da3_hdr.forw != 0 || da3_hdr.back != 0) {
> + if (!no_modify) {
> + do_warn(
> +_("clearing forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"),
> + ino);
> +
> + repairlinks = 1;
> + da3_hdr.forw = 0;
> + da3_hdr.back = 0;
> + xfs_da3_node_hdr_to_disk(mp, bp->b_addr, &da3_hdr);
> + } else {
> + do_warn(
> +_("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino);
> + }
> + }
> +
> + /* must do this now, to release block 0 before the traversal */
> + if ((*repair || repairlinks) && !no_modify) {
> + *repair = 1;
> + libxfs_writebuf(bp, 0);
> + } else
> + libxfs_putbuf(bp);
> + error = process_node_attr(mp, ino, dip, blkmap); /* + repair */
> + if (error)
> + *repair = 0;
> + return error;
> +}
> +
> /*
> * Start processing for a leaf or fuller btree.
> * A leaf directory is one where the attribute fork is too big for
> @@ -963,19 +1055,15 @@ _("wrong FS UUID, inode %" PRIu64 " attr block %" PRIu64 "\n"),
> */
> static int
> process_longform_attr(
> - xfs_mount_t *mp,
> - xfs_ino_t ino,
> - xfs_dinode_t *dip,
> - blkmap_t *blkmap,
> - int *repair) /* out - 1 if something was fixed */
> + struct xfs_mount *mp,
> + xfs_ino_t ino,
> + struct xfs_dinode *dip,
> + blkmap_t *blkmap,
> + int *repair) /* out - 1 if something was fixed */
> {
> - xfs_attr_leafblock_t *leaf;
> - xfs_fsblock_t bno;
> - xfs_buf_t *bp;
> - xfs_dahash_t next_hashval;
> - int repairlinks = 0;
> - struct xfs_attr3_icleaf_hdr leafhdr;
> - int error;
> + xfs_fsblock_t bno;
> + struct xfs_buf *bp;
> + struct xfs_da_blkinfo *info;
>
> *repair = 0;
>
> @@ -1015,77 +1103,35 @@ process_longform_attr(
> return 1;
> }
>
> - /* verify leaf block */
> - leaf = bp->b_addr;
> - xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &leafhdr, leaf);
> -
> - /* check sibling pointers in leaf block or root block 0 before
> - * we have to release the btree block
> - */
> - if (leafhdr.forw != 0 || leafhdr.back != 0) {
> - if (!no_modify) {
> - do_warn(
> - _("clearing forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"),
> - ino);
> - repairlinks = 1;
> - leafhdr.forw = 0;
> - leafhdr.back = 0;
> - xfs_attr3_leaf_hdr_to_disk(mp->m_attr_geo,
> - leaf, &leafhdr);
> - } else {
> - do_warn(
> - _("would clear forw/back pointers in block 0 for attributes in inode %" PRIu64 "\n"), ino);
> - }
> - }
> -
> /*
> * use magic number to tell us what type of attribute this is.
> * it's possible to have a node or leaf attribute in either an
> * extent format or btree format attribute fork.
> */
> - switch (leafhdr.magic) {
> + info = bp->b_addr;
> + switch (be16_to_cpu(info->magic)) {
> case XFS_ATTR_LEAF_MAGIC: /* leaf-form attribute */
> case XFS_ATTR3_LEAF_MAGIC:
> - if (process_leaf_attr_block(mp, leaf, 0, ino, blkmap,
> - 0, &next_hashval, repair)) {
> - *repair = 0;
> - /* the block is bad. lose the attribute fork. */
> - libxfs_putbuf(bp);
> - return(1);
> - }
> - *repair = *repair || repairlinks;
> - break;
> -
> + return process_leaf_da_root(mp, ino, dip, blkmap, repair, bp);
> case XFS_DA_NODE_MAGIC: /* btree-form attribute */
> case XFS_DA3_NODE_MAGIC:
> - /* must do this now, to release block 0 before the traversal */
> - if ((*repair || repairlinks) && !no_modify) {
> - *repair = 1;
> - libxfs_writebuf(bp, 0);
> - } else
> - libxfs_putbuf(bp);
> - error = process_node_attr(mp, ino, dip, blkmap); /* + repair */
> - if (error)
> - *repair = 0;
> - return error;
> + return process_node_da_root(mp, ino, dip, blkmap, repair, bp);
> default:
> do_warn(
> _("bad attribute leaf magic # %#x for dir ino %" PRIu64 "\n"),
> - be16_to_cpu(leaf->hdr.info.magic), ino);
> + be16_to_cpu(info->magic), ino);
> libxfs_putbuf(bp);
> *repair = 0;
> - return(1);
> + return 1;
> }
>
> if (*repair && !no_modify)
> libxfs_writebuf(bp, 0);
> else
> libxfs_putbuf(bp);
> -
> - return(0); /* repair may be set */
> + return 0; /* repair may be set */
> }
>
> -
> static int
> xfs_acl_from_disk(
> struct xfs_mount *mp,
next prev parent reply other threads:[~2020-02-04 23:15 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-24 0:16 [PATCH 0/8] xfsprogs: random fixes Darrick J. Wong
2020-01-24 0:16 ` [PATCH 1/8] man: list xfs_io lsattr inode flag letters Darrick J. Wong
2020-01-25 23:16 ` Christoph Hellwig
2020-01-24 0:16 ` [PATCH 2/8] man: document the xfs_db btheight command Darrick J. Wong
2020-01-25 23:16 ` Christoph Hellwig
2020-01-24 0:16 ` [PATCH 3/8] man: reformat xfs_quota commands in the manpage for testing Darrick J. Wong
2020-01-25 23:16 ` Christoph Hellwig
2020-01-24 0:16 ` [PATCH 4/8] man: document some missing xfs_db commands Darrick J. Wong
2020-01-25 23:16 ` Christoph Hellwig
2020-01-24 0:17 ` [PATCH 5/8] xfs_db: dump per-AG reservations Darrick J. Wong
2020-01-25 23:17 ` Christoph Hellwig
2020-01-24 0:17 ` [PATCH 6/8] xfs_io: fix copy_file_range length argument overflow Darrick J. Wong
2020-01-25 23:18 ` Christoph Hellwig
2020-01-24 0:17 ` [PATCH 7/8] xfs_io: fix pwrite/pread length truncation on 32-bit systems Darrick J. Wong
2020-01-25 23:18 ` Christoph Hellwig
2020-01-24 0:17 ` [PATCH 8/8] xfs_repair: fix totally broken unit conversion in directory invalidation Darrick J. Wong
2020-01-25 23:19 ` Christoph Hellwig
2020-01-26 22:11 ` Darrick J. Wong
2020-01-30 18:35 ` Eric Sandeen
2020-01-28 15:56 ` [PATCH 9/8] xfs_io: fix integer over/underflow handling in timespec_from_string Darrick J. Wong
2020-01-30 18:18 ` Christoph Hellwig
2020-01-30 18:13 ` [PATCH 10/8] libxfs: remove duplicate attr function declarations Darrick J. Wong
2020-01-30 18:17 ` Christoph Hellwig
2020-01-30 18:28 ` Eric Sandeen
2020-01-30 18:40 ` Darrick J. Wong
2020-01-30 18:48 ` Eric Sandeen
2020-01-30 18:15 ` [PATCH 11/8] xfs_repair: don't corrupt a attr fork da3 node when clearing forw/back Darrick J. Wong
2020-01-30 18:22 ` Christoph Hellwig
2020-01-30 18:31 ` Darrick J. Wong
2020-01-30 18:46 ` [PATCH v2 " Darrick J. Wong
2020-01-31 6:03 ` Christoph Hellwig
2020-02-04 23:14 ` Darrick J. Wong [this message]
2020-02-05 6:07 ` Christoph Hellwig
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=20200204231442.GE6874@magnolia \
--to=darrick.wong@oracle.com \
--cc=hch@infradead.org \
--cc=linux-xfs@vger.kernel.org \
--cc=sandeen@sandeen.net \
/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).