[Top] [All Lists]

Re: Files with non-ASCII names inaccessible after xfs_repair

To: Zachary Kotlarek <zach@xxxxxxxxxxxx>
Subject: Re: Files with non-ASCII names inaccessible after xfs_repair
From: Dave Chinner <david@xxxxxxxxxxxxx>
Date: Wed, 15 Jan 2014 17:37:22 +1100
Cc: xfs@xxxxxxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1E5E569C-2E11-42A1-A771-89D4800BC412@xxxxxxxxxxxx>
References: <20140113031947.GG3469@dastard> <E2EE0AEA-ED22-4D3B-8550-88F2ED1F8314@xxxxxxxxxxxx> <20140113192732.GI3469@dastard> <0E45339E-04C4-4775-B6B0-FC55245B0AED@xxxxxxxxxxxx> <20140114022414.GM3469@dastard> <BE0C947E-37DE-4CA1-B120-59B95E1E8EB8@xxxxxxxxxxxx> <20140115015350.GR3469@dastard> <61E74CEF-8244-4E90-BA7D-91D54DADC3C1@xxxxxxxxxxxx> <20140115034803.GT3469@dastard> <1E5E569C-2E11-42A1-A771-89D4800BC412@xxxxxxxxxxxx>
User-agent: Mutt/1.5.21 (2010-09-15)
On Tue, Jan 14, 2014 at 09:30:57PM -0800, Zachary Kotlarek wrote:
> On Jan 14, 2014, at 7:48 PM, Dave Chinner <david@xxxxxxxxxxxxx> wrote:
> > It's called *ASCII* Case Insensitivity for a reason: it doesn't
> > support anything other than ASCII. So your usage is not actually
> > supported at all, hence it's no surprise that it has caused
> > breakage.
> Okay. Thanks for the explanation.
> FWIW, I read âASCII-only case-insensitiveâ to mean âonly case-insensitive for 
> ASCIIâ as in à and à would not match each other. If it actually means 
> âanything other than ASCII is subject to complete breakageâ a more nuanced 
> explanation in the man page might be desirable.

Sure. Can you write a patch to add explanation that explain the
problem you've had?

> I donât suppose thereâs any way to disable that setting short of creating a 
> new file system?

Not officially. Changing it means you have to change every single
hash for every directory entry. I *think* that you could probably do
it with a bit of xfs_db magic and and xfs_repair pass.

First, A warning, some advice and a disclaimer: back up anything you
don't want to lose, because if this screws up it'll trash the
directory structure and you may *LOSE* *ALL* *YOUR* *DATA*. This is
dangerous, not recommended and I take no responsibility for what
happens if you try it and it fails.

After taking a backup, use xfs_metadump to set up for a
non-destructive trial run.  take a copy of the filesystem metadata
using xfs_metadump:

# xfs_metadump <dev> scratch.metadump

Restore the metadump to a file - this is a sparse image file we can
operate on safely.

# xfs_mdrestore scratch.metadump scratch_xfs_filesystem.img

Then point xfs_db at the image file:

# xfs_db -x -f scratch_xfs_filesystem.img

Remove the case insensitive feature bit using the version command.
First dump the current values using version:

xfs_db> version
versionnum [0xf4a4+0x8a] = 

And you'll see the ASCII_CI bit in there. That's what we want to
remove. It's value is:

#define XFS_SB_VERSION_BORGBIT          0x4000

so we need to clear that from the version field.

        0xf4a4 - 0x4000 = 0xb4a4

And we want to write that back into the version field:

xfs_db> sb 0
xfs_db> p versionnum
versionnum = 0xf4a4
xfs_db> write versionnum 0xb4a4
versionnum = 0xb4a4
xfs_db> p versionnum
versionnum = 0xb4a4
xfs_db> quit

And now run xfs_repair on the image file:

# xfs_repair -f scratch_xfs_filesystem.img

That should through lots of "bad hash table.... repairing" errors.
Once it completes, mount the filesystem image on the loopback

# mount -o loop,ro,norecovery scratch_xfs_filesystem.img /mnt/scratch

And walk around the filesystem to determine if the directory
structure is correct and intact. If you have any doubts, or anything
was left in lost+found, then it hasn't worked properly and you
should not do this to your filesystem.

Only if you are convinced that everything is OK and you can do the
conversion without stuffing up, run the same xfs_db/repair process
on the real filesystem. If you have any doubts or not confident that
it has worked, then go the long way of mkfs and restoring the backup
you've already made.

> > I suspect that the way to fix your filesystem is to run xfs_repair
> > under a "C" locale so that the glibc tolower() function behaves the
> > same way the kernel behaves and so the hashes calculated by
> > xfs_repair match the what the kernel thinks is correct.
> Neither this:
>       LC_ALL=C
> nor this:
>       LC_ALL=POSIX
> or for that matter:
>       LC_ALL=en_US.utf8
> made any difference. And my default was already POSIX.
> Any other thoughts?

$ LC_ALL=C locale

Perhaps you also need to override LANG and LANGUAGE?

> Theoretically I could find the expected hashvals and overwrite
> them with xfs_db, right?

In theory, but hashvals need to be ordered correctly and that
potentially means having to update btree node pointers and all sorts
of other complexities. xfs_db is really not designed to rewrite
directory structures manually.

> Or at least unlink the files so I can
> reclaim the disk space?

You need to be able to stat the file to be able to unlink it....


Dave Chinner

<Prev in Thread] Current Thread [Next in Thread>