From: Eric Sandeen <sandeen@redhat.com>
To: linux-xfs <linux-xfs@vger.kernel.org>
Subject: [PATCH] xfsdump: find root inode, not first inode
Date: Wed, 21 Aug 2019 17:14:51 -0500 [thread overview]
Message-ID: <f66f26f7-5e29-80fc-206c-9a53cf4640fa@redhat.com> (raw)
The prior effort to identify the actual root inode in a filesystem
failed in the (rare) case where inodes were allocated with a lower
number than the root. As a result, the wrong root inode number
went into the dump, and restore would fail with:
xfsrestore: tree.c:757: tree_begindir: Assertion `ino != persp->p_rootino || hardh == persp->p_rooth' failed.
Fix this by iterating over a chunk's worth of inodes until we find
a directory inode with generation 0, which should only be true
for the real root inode.
Fixes: 25195ebf107 ("xfsdump: handle bind mount targets")
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
diff --git a/dump/content.c b/dump/content.c
index 30232d4..9f9c03b 100644
--- a/dump/content.c
+++ b/dump/content.c
@@ -1384,7 +1384,7 @@ baseuuidbypass:
/* figure out the ino for the root directory of the fs
* and get its struct xfs_bstat for inomap_build(). This could
* be a bind mount; don't ask for the mount point inode,
- * find the actual lowest inode number in the filesystem.
+ * actually find the root inode number in the filesystem.
*/
{
stat64_t rootstat;
@@ -1404,20 +1404,36 @@ baseuuidbypass:
(struct xfs_bstat *)calloc(1, sizeof(struct xfs_bstat));
assert(sc_rootxfsstatp);
- /* Get the first valid (i.e. root) inode in this fs */
- bulkreq.lastip = (__u64 *)&lastino;
- bulkreq.icount = 1;
- bulkreq.ubuffer = sc_rootxfsstatp;
- bulkreq.ocount = &ocount;
- if (ioctl(sc_fsfd, XFS_IOC_FSBULKSTAT, &bulkreq) < 0) {
- mlog(MLOG_ERROR,
- _("failed to get bulkstat information for root inode\n"));
+ /*
+ * Find the root inode in this fs. It is (rarely) possible to
+ * have a non-root inode come before the root inode, so iterate
+ * over a chunk's worth looking for the first dir inode with
+ * bs_gen == 0, which should only be true for the root inode.
+ */
+ for (i = 0; i < 64; i++) {
+ bulkreq.lastip = (__u64 *)&lastino;
+ bulkreq.icount = 1;
+ bulkreq.ubuffer = sc_rootxfsstatp;
+ bulkreq.ocount = &ocount;
+ if (ioctl(sc_fsfd, XFS_IOC_FSBULKSTAT, &bulkreq) < 0) {
+ mlog(MLOG_ERROR,
+_("failed to get bulkstat information for root inode\n"));
+ return BOOL_FALSE;
+ }
+ /* found it? */
+ if ((sc_rootxfsstatp->bs_mode & S_IFMT) == S_IFDIR &&
+ sc_rootxfsstatp->bs_gen == 0)
+ break;
+ }
+
+ if (i == 64) {
+ mlog(MLOG_ERROR, _("failed to find root inode\n"));
return BOOL_FALSE;
}
if (sc_rootxfsstatp->bs_ino != rootstat.st_ino)
mlog (MLOG_NORMAL | MLOG_NOTE,
- _("root ino %lld differs from mount dir ino %lld, bind mount?\n"),
+_("root ino %lld differs from mount dir ino %lld, bind mount?\n"),
sc_rootxfsstatp->bs_ino, rootstat.st_ino);
}
next reply other threads:[~2019-08-21 22:14 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-21 22:14 Eric Sandeen [this message]
2019-08-22 6:01 ` [PATCH] xfsdump: find root inode, not first inode Dave Chinner
2019-08-22 14:48 ` Eric Sandeen
2019-08-22 19:13 ` Eric Sandeen
2019-08-22 19:19 ` Eric Sandeen
2019-08-22 19:39 ` [PATCH] xfsdump: reject bind mounted subdir targets Eric Sandeen
2019-08-22 20:54 ` Eric Sandeen
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=f66f26f7-5e29-80fc-206c-9a53cf4640fa@redhat.com \
--to=sandeen@redhat.com \
--cc=linux-xfs@vger.kernel.org \
/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