From: Christoph Hellwig <hch@infradead.org>
To: "Darrick J. Wong" <darrick.wong@oracle.com>
Cc: sandeen@sandeen.net, linux-xfs@vger.kernel.org,
Christoph Hellwig <hch@infradead.org>
Subject: Re: [PATCH v2 11/8] xfs_repair: don't corrupt a attr fork da3 node when clearing forw/back
Date: Thu, 30 Jan 2020 22:03:15 -0800 [thread overview]
Message-ID: <20200131060315.GA26786@infradead.org> (raw)
In-Reply-To: <20200130184606.GC3447196@magnolia>
Looks sensible, but I think we want the helpers for both the node and
leaf case, something like this untested patch:
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-01-31 6:03 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 [this message]
2020-02-04 23:14 ` Darrick J. Wong
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=20200131060315.GA26786@infradead.org \
--to=hch@infradead.org \
--cc=darrick.wong@oracle.com \
--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