Re: testing exchangedata
Re: testing exchangedata
- Subject: Re: testing exchangedata
- From: "Gerriet M. Denkmann" <email@hidden>
- Date: Tue, 4 Oct 2005 19:53:37 +0200
On 04.10.2005, at 18:39, glenn andreas <email@hidden> wrote:
On Oct 4, 2005, at 9:14 AM, Derrick Bass wrote:
I don't have an answer for you, but I'd like to encourage you to
file a bug report about this. I filed one over a year ago for the
same thing and nothing has been done. It seems to be the consensus
that the more people file a bug report, the more likely Apple is to
fix the problem.
It is arguable as to whether or not exchangedata() should work with
hard-linked files (I think it should) and exactly what it should it
do, but the fact that it fails if a file was EVER hard linked (even
if it is no longer hard linked) is definitely a bug!
In HFS+ " ln a b; rm b " creates a file "a" which is (not: was)
hardlinked. Only it is a bit difficult to see this fact.
But exchangedata() notices the difference and refuses to work.
Derrick
From a unix point of view, _all_ files are "hard linked" - if they
weren't, they wouldn't appear in the file system.
Basically, under UFS, a directory is a list of names and "i-node
numbers" (which refer to the actually file allocation blocks). So
when you make a file in a directory, the file is allocated, and that
name is added to the directory listing with it's inode. When you
make a "hard link", all it does is add that same inode with another
name somewhere else (which is why hard links only work within the
same volume - different volumes would reuse the inode numbers and
conflict).
Yes. But in HFS(+) a hard link pointing to a file (with no other hard
links pointing to it) is something very different to just a file.
The problem is that no (known) Unix call can distinguish between these
two situations. The only (known) exception being exchangedata which
works onl in the second case.
(And note that a file can still be allocated even if it isn't in the
file system - this is how you can open a file and get it's
descriptor, delete it from the file system, and continue to read/
write that file, since the file isn't actually deallocated until
there are no external links and no open file descriptors).
Again, in HFS+ these things _are_ in the filesystem, they are part of
HFS+ Private Data and called temp1235 (if 12345 was their file id).
Getting back to exchangedata, so suppose you have a file "a" and make
a second link to that underlying data "a1". You've got a different
file "b". Roughly:
a - inode 123 (link count 2) "abcdefg"
a1 - inode 123 (link count 2) "abcdefg"
b - inode 456 (link count 1) "hijklmno"
exchangedata "swaps the contents of the two files" (and that the
reference to the file remains unchanged - i.e., the actual inode
remains the same). So in a simple case (disregarding the open file
descriptors which the kernel needs to fix up), you basically swap
what the inode contains. But what happens for the above case for
"a1", which isn't a parameter to exchangedata, but an "innocent
bystander"? There are sevaral possible behaviors:
a - inode 123 (link count 2) "hijklmno"
a1 - inode 123 (link count 2) "hijklmno"
b - inode 456 (link count 1) "abcdefg"
There is a problem here - any application that opened file "a1" (not
caring that it was the same file as "a") now suddenly had all it's
references swapped out from under it. One could argue that this case
is no different than an application having "a" open, but "a1" appears
as a separate file entity, and one could easily see the confusing
this would cause to users.
I agree that it is a sound policy of exchangedata not to work with hard
linked files. So this confusion will never happen.
But it would be very helpful to have a function like:
BOOL exchangedataWouldWorkWithPath( NSString *path)
Another possible behavior:
a - inode 123 (link count 1) "hijklmno"
a1 - inode 456 (link count 2) "abcdefg"
b - inode 456 (link count 2) "abcdefg"
Now "a1" has the same contents, but it's inode was changed.
Disregarding that there is no "inverse inode" table to determine that
file system entry "a1" has a reference to file 123, this causes a
problem if there are open file descriptors. If two programs have "a"
and "a1" open, they are both reading/writing the same file (and may
be doing this for some form of IPC - nothing says that "a" and "a1"
have to be anywhere near each other in the file system, just the same
volume). Suddenly, that is no longer happening (since the first
program is now using the data from inode 456), so calling
"exchangedata" breaks this state. And this also will violate the
underlying condition that file references will remain unchanged.
If I understand Derrick correctly, he wants exchangedata to work in the
case of hard links with a link count of 1.
And there is absolutely no reason why this could not be done. No other
program could be confused.
You only need a function convertSingularHardLinkToNormalFileForPath(
NSString *path) which is a nop for UFS, does the right thing for HFS
and returns some error code (like EINVAL) if the link count of "path"
is ≠ 1.
So if exchangedata works, great, you're done. If it doesn't work,
you will still need provide fallback code to handle that case.
Disregarding the extra links issue, not all volumes support
exchangedata. So unless you like dealing with tech support calls
from customers complaining that your application doesn't work when
editing files on some (for example) network file server, you need to
provide a fallback (so if exchangedata doesn't work because of extra
links, you'd use that anyway).
This is not a big problem, because exchangedata sets errno to ENOTSUP
in this case.
Kind regards,
Gerriet.
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Cocoa-dev mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden