getattrlistbulk returns [ERANGE] (34) when supplied a 16K buffer; does that make sense?

Title pretty much says it all.


I have a loop that reads attributes from a directory into a buffer until all of the enteries have been read. The buffer size is 16K, typically enough to read 100-150 directory entries at a time. I've successfully tested this code on directories with thousands of files.


However, I have one customer that's getting a ERANGE (34) error when trying to read a specific directory (/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/tests). This directory has about 90 files on my system and reads just fine.


If I interpret it correctly, the ERANGE error occurs when the buffer isn't big enough to copy even a single entry into the buffer. Is it possible for a single directory entry to consume more than 16K of data?


The attributes I'm requestion are:

ATTR_CMN_NAME

ATTR_CMN_DEVID

ATTR_CMN_OBJTYPE

ATTR_CMN_SCRIPT

ATTR_CMN_CRTIME

ATTR_CMN_MODTIME

ATTR_CMN_CHGTIME

ATTR_CMN_OWNERID

ATTR_CMN_GRPID

ATTR_CMN_ACCESSMASK

ATTR_CMN_FLAGS

ATTR_CMN_USERACCESS

ATTR_CMN_FILEID

files also get:

ATTR_FILE_LINKCOUNT

ATTR_FILE_TOTALSIZE

ATTR_FILE_ALLOCSIZE

ATTR_FILE_DATALENGTH

directories also get:

ATTR_DIR_LINKCOUNT

ATTR_DIR_ENTRYCOUNT

ATTR_DIR_MOUNTSTATUS


All of these (except for the name) are fixed size types, so how could a single entry require more than 16K? Could their directory structure be damaged?

Post not yet marked as solved Up vote post of dawn2dusk Down vote post of dawn2dusk
931 views

Replies

Follow up: The customer who is encountering this says they checked their volume and it doesn't show any problems, yet this error is still happening.

The one clearly documented case for

getattrlistbulk
failing with
ERANGE
is, as you’ve noted, a buffer so small that it can’t hold a single entry. This seems very unlikely given your 16 KiB buffer. It’s more likely that this error is coming from ‘deeper’ in the
getattrlistbulk
implementation, and that means it’s most likely file-system specific.

Is the volume HFS Plus or APFS?

Can you deploy test code to the customer? If so, it’d be interesting to see what higher-level APIs in this case, specifically

-[NSFileManager contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error:]
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Quinn,


This is APFS on an SSD.


I created a command-line tool to test the problem. It would perform an identical getattrlistbulk() to the one returning the error, and then would read the same directory using -contentsOfDirectoryURL:...


Here's the bad news: not only did the test run OK, but it's a moving problem. The customer now reports other directories that report this error (one was ~/Library ... YIKES!), and it's not repeatable. The next time the same directory reads just fine.


This is a beta of my latest product (and my customers are great about reporting and investigating bugs), so I'm going to add some extra code that looks for this problem and when it occurs perform a -contentsOfDirectoryAtURL:includingPropertiesForKeys:options:error: on the same directory and log all of the results.


So with any luck, I'll have more details within a few days...

Wow, that’s weird. My best guess right now is that there’s an OS bug in play here. Given you’re in touch with super helpful customers, you should ask them to reproduce the problem and then immediately take a sysdiagnose log (per the instructions on our Bug Reporting > Profiles and Logs). If you do eventually file a bug about this, the sysdiagnose log will be the first step in Apple Engineering investigating it.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

After much testing, I discovered what's going on.


Normally, you call getattrlistbulk() repeatedly until it returns 0, indicating that all of the entries have been read.


However, on APFS if that last call to return attribute data exactly fills the buffer, the next call to getattrlistbulk() results in an ERANGE error (instead of returning 0).


The good news is that if you call getattrlistbulk() again, it returns 0. So as a workaround I can either ignore the ERANGE error and just try again or treat the ERANGE error the same as a 0 when the previous buffer was completely filled.


Bug filed: #38491322

I just had a customer reporting the same issue with getattrlistbulk and ERANGE: Result too large. According to them, it happens on macOS 10.13 with APFS but doesn't happen on macOS 10.14 anymore.

I can also confirm that it only happens when the last call exactly fills the buffer. Running FileManager.contentsOfDirectory(atPath:) returns the cumulative amount of entries processed with getattrlistbulk and throws no error.