0x09 / hfsfuse

FUSE driver for HFS+ filesystems
Other
77 stars 13 forks source link

Argument list too long #5

Closed ctron closed 6 years ago

ctron commented 6 years ago

First of all, many thanks for this awesome driver!

I am currently trying to recover a few thousand font files using Linux from a HFS+ disk. This requires me to read the resource fork.

However for a number of files (~15%) I get the following error when reading the resource fork attribute Argument list too long:

[jreimann@localhost /]$ getfattr -d  "/media/Users/abc/Font Library/A/Avant Garde Gothic URW/Avant Garde Gothic URW"
getfattr: Removing leading '/' from absolute path names
# file: media/Users/abc/Font Library/A/Avant Garde Gothic URW/Avant Garde Gothic URW
user.com.apple.FinderInfo=0sRkZJTERNT1YAAP////8AAAAAAAAAAAAAAAAAAAAAAAA=
/media/Users/abc/Font Library/A/Avant Garde Gothic URW/Avant Garde Gothic URW: user.com.apple.ResourceFork: Argument list too long
user.hfsfuse.record.date_created=0sMjAwMS0wMy0wMlQwOTozNjowMCsAAAAA

I did compile on Fedora 26 with the following options:

CC=cc
CONFIG_CFLAGS=-O3 -std=gnu11
WITH_UBLIO=none
WITH_UTF8PROC=none
0x09 commented 6 years ago

Hi, can you unmount the disk from FUSE and post the output of hfsdump /dev/sdXX stat "/Users/abc/Font Library/A/Avant Garde Gothic URW/Avant Garde Gothic URW"

and also try running hfsdump /dev/sdXX read "/Users/abc/Font Library/A/Avant Garde Gothic URW/Avant Garde Gothic URW/rsrc" > some_resource_data (note the /rsrc at the end of the path in this one)

This should help indicate what's going wrong.

0x09 commented 6 years ago

OK, I figured out what's going on here. The maximum size extended attribute the Linux kernel can support is 64kb. If the resource fork is larger than this, hfsfuse will return a range error, which in turn getting printed as "argument list too long".

The best way to deal with these at present is to read them with hfsdump as outlined above. I'm not sure what the best solution is for making these readable on the FUSE side (adding /rsrc to the path does not work with FUSE's path resolution), but I'll try to come up with some alternate syntax for that.

ctron commented 6 years ago

Thanks for investigating this. Is there a simple command with hfsdump which will write out only the raw data into a file or stdout?

0x09 commented 6 years ago

You can do this with the second command above. hfsdump <device> read <path> will write the data at path to stdout. Appending /rsrc to the path it will write the resource fork instead.

You can find all files with an oversized resource fork on the mounted volume using attr:

find Users/ -type f -exec attr -l {} \; |\
awk '$2 = "com.apple.ResourceFork" && $5 > 65536' |\
cut -d' ' -f9- > bigforks.txt

Then the list can be fed to hfsdump in a loop. For example if you wanted to place the fork data under a mirror of the hierarchy of the original volume at "rsrc/":

while read -r path; do
  mkdir -p "rsrc/$(dirname "$path")" && hfsdump /dev/sdXX read "/$path/rsrc" > "rsrc/$path"
done < bigforks.txt

Probably hfsdump should support some kind of bulk mode like debugfs does to make operations like this more efficient.

ctron commented 6 years ago

That will work fine I guess with my small application, recovering the font files.

Thanks for all your help.

0x09 commented 6 years ago

No problem. I'd like to leave this ticket open until I have a solution for this inside the FUSE driver.

FYI, I noticed that the hfsfuse.record.date_* xattrs were being printed incorrectly on Linux due to some time formatting differences vs the BSDs and just pushed a fix, you may want to update.

0x09 commented 6 years ago

I've added two new options to facilitate accessing fork data within the FUSE driver -- one which allows setting a special file extension like .rsrc and one which mounts the entire volume as a resource fork view. I also expanded the documentation on fork and xattr handling: https://github.com/0x09/hfsfuse#extended-attributes-and-resource-forks

This should take care of any cases where extended attributes are too small to represent the fork data and make the forks easier to work with anyway. Thanks for reporting this!

ctron commented 6 years ago

This is awesome! Thanks for the changes!