6

I copied some files to HFS+, using macOS, ensuring that it was copied exactly. On macOS these copied files have 501 as owner according to ls -han.

I then plug in the HFS+ usb stick into Ubuntu, and there the files have 1000 as owner according to ls -han. Why?

I then tried copying one of the 501 owned files in Ubuntu (to the same HFS+ volume), ensuring that it was copied exactly using cp -a.

Now macOS ls sees the new file as owned by user 1000...

Really? I don't understand — what was the point of using cp with the -a option if it doesn't even preserve the owner's user id? What did I miss?

Update: To clarify, I think my confusion here stems from that — in my mind — HFS supports Unix file permissions natively and should "just work" with them.


I recently learned that cps preserve=timestamps does not, in fact, preserve time stamps (creation dates are reset). Am I now to believe that its preserve=ownership does not preserve ownership?

3
  • In practical terms, the "birth date/time" of a file is the moment its inode was removed from the free list, and it cannot be modified again until that inode has been freed and re-used. Sep 10 at 22:18
  • 1
    @Paul_Pedant Sounds more technical than practical, at least for someone like me who just sees "creation time" and immediately thinks "time stamp" 🙂 Though if — judging by the answer below — I need to look up kernel documentation for each file system involved in a copy I imagine my chances of effectively using cp in practice are growing slim regardless. I seem to fail every time I use it.
    – Andreas
    Sep 10 at 22:53
  • 2
    The standard 3 timestamps in a Unix inode are access (last open, including read-only), modification (of the data), and change (of the inode, e.g. the link count or when renaming a directory entry for it, or chmod, or changing any of the other timestamps). None of these are creation time. Linux has an extra field in its stat struct for a birth time, which is set on file creation and can't be changed. stat /bin/cat or something to see the four timestamps on a normal file. Sep 11 at 11:57

1 Answer 1

15

From the Linux kernel documentation for the hfsplus module:

Mount options

uid=n, gid=n

Specifies the user/group that owns all files on the filesystem that have uninitialized permissions structures. Default: user/group id of the mounting process.

501 is the default UID of the first regular user on modern macOS.

So, apparently macOS does not initialize "permissions structures" for some files. Also, the Apple Technote #1150 indicates the storage of owner ID has an added wrinkle:

ownerID

The Mac OS X user ID of the owner of the file or folder. Mac OS X versions prior to 10.3 treats user ID 99 as if it was the user ID of the user currently logged in to the console. If no user is logged in to the console, user ID 99 is treated as user ID 0 (root). Mac OS X version 10.3 treats user ID 99 as if it was the user ID of the process making the call (in effect, making it owned by everyone simultaneously). These substitutions happen at run time. The actual user ID on disk is not changed.

and later:

Note:

If the S_IFMT field (upper 4 bits) of the fileMode field is zero, then Mac OS X assumes that the permissions structure is uninitialized, and internally uses default values for all of the fields. The default user and group IDs are 99, but can be changed at the time the volume is mounted. This default ownerID is then subject to substitution as described above.

This means that files created by Mac OS 8 and 9, or any other implementation that sets the permissions fields to zeroes, will behave as if the "ignore ownership" option is enabled for those files, even if "ignore ownership" is disabled for the volume as a whole.

S_IFMT referred here is the highest 4 bits of the 16-bit value that is used to store the Unix-style permission bits: 3x read/write/execute, and the setuid/setgid/sticky bits. A regular file needs those highest 4 bits to be set to a specific non-zero value (S_IFREG) or else the backwards compatibility mechanism described above will kick in.

The structure of the HFS+ filesystem clearly opens up a possibility to sometimes play "fast and loose" with the file ownerships, and your results indicate macOS seems to do exactly that in some situations.

For removable media, it would make a certain kind of sense for macOS to automatically enable the "ignore ownership" option as the system that writes the files to the media might not be the same as the one that will be reading it, and the two systems might have entirely different UID mappings, resulting in inconvenience to the user.

So this might just be macOS trying to be user friendly on removable media, and assuming that the user's physical possession of the removable media is equivalent to a proof of ownership of the data within.

Ubuntu's first regular user account is created with UID 1000, and that's apparently the account you mounted the HFS+ volume to Ubuntu as.

Since files created by Linux keep their UID 1000 into macOS, that indicates Linux will populate the HFS+ "permissions structures" with file owner UIDs, and once macOS reads them, they will work as expected.


The classic POSIX timestamps are:

  • ctime = time of last status/metadata change
  • mtime = time of last modification of contents
  • atime = time of last access.

A creation time (crtime, or birth time) is not one of them. A filesystem may or may not support creation times, and the exact semantics of it may vary between filesystem types and Unix-style operating systems.

Some filesystem drivers handle assigning the creation time internally and make it outright impossible to modify the crtime of a file afterwards: in such a filesystem, a file that's been accidentally deleted and restored from a backup may have their classic ctime and mtime restored, but the creation time will reflect the time of restoration from backup, since the file is now no longer the original, although it might be an exact copy of it.

When you copy a file, you plainly create a new file: the idea of "preserving the creation time" across a copy operation is an oxymoron.

A filesystem on its own can track the creation time of a file, but that is not necessarily the same thing as the creation time of the data within the file. If you want to track the latter, you usually need either a version control system, or a file format that can include a metadata field on data creation time... and all applications using that data format must agree on the semantics of what the "data creation time" means, or else it will become meaningless.

4
  • You're into something there I think. Thank you for the quote. As for "removable media compatible ... unless you specifically tell it otherwise" I'm fairly certain that's not the case, since I use Paste files exactly in Finder, which will fail if the volume is set to "ignore ownership" (an explicit option for removable media). Though I must admit that "uninitialized permission structures" doesn't tell me much. I would have guessed that every object had a mandatory owner on HFS+, as well as in other Unix FSes, and have never reflected upon that the field could be absent.
    – Andreas
    Sep 10 at 22:27
  • Oops, forgot to add the link to the Linux hfsplus module documentation, added.
    – telcoM
    Sep 11 at 6:16
  • Great explanation - thanks!
    – Seamus
    Sep 11 at 19:44
  • While I find it rather hard to imagine that macOS would play "fast and loose" with the files in ~/Library in particular (a single user's private application files) I still think this answer hints at the cause. A hunch tells me these files are explicitly set to 501:20, so the remaining explanation is that Ubuntu applies a mask on removable HFS media to aid interoperability. Since HFS supports unix file permissions I must have overlooked that. My conclusion has to be that Ubuntu was the one trying to be user-friendly here. I feel stupid to have been caught by this.
    – Andreas
    Sep 18 at 22:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .