On Tue, Jul 08, 2003 at 05:11:43PM +0100, lou wrote:
> In some email I received from Jan Harkes <[EMAIL PROTECTED]> on Tue, 8 Jul 2003
> 11:39:45 -0400, wrote:
> > On Tue, Jul 08, 2003 at 03:27:41PM +0100, lou wrote:
> [...]
> > AFS3 concurrent O_RDWR scenario
> >
> > client2
> > foo = open('foo', O_RDWR);
> > write(foo, "a");
> >
> > client1
> > foo = open('foo', O_RDWR);
> > write(foo, "test");
> > close(foo);
> > /* foo now contains "test" */
> >
> > client2
> > close(foo);
> > /* surprise! foo now contains "t" */
>
> You mean 'a' not 't' right?
No, I'm serious. The way AFS3 implemented partial file fetches, client 2
fetches 'test' into memory as soon as it receives the callback from the
server. It then writes out 'test', but with an i_size of 1 (i.e. the
size of whatever it had written itself earlier. So the file ends up with
't', which is surprisingly different from what either client has
actually written to the file.
It works fine when the client opens the file O_WRONLY, probably because
the partial file fetch logic isn't triggered.
> > I actually like it that Coda gives me a conflict in these situations, at
> > least I get to keep both pieces.
>
> That's good enough, but wont it be more sensible instead of taking a
> whole volume into a disconnect write mode to happen something like:
Well, the solution would probably be the 'application specific
resolvers', or 'Coda-sidekick'. It hasn't been seriously used, but the
idea is that whenever the client hits a conflict it notifies a helper
process which is given a chance to resolve the conflict before we return
a failure to the user.
The sidekick could (should) be taught to do things like,
case $file in
# object files can be rebuilt
*.o) removeinc $file
make $file
;;
# C files can be merged successfully most of the time
*.c) cfs br $file
merge $file/local $file/global /tmp/merged
cfs er $file
removeinc $file
cp /tmp/merged $file
;;
# important files, try to keep both pieces
important/*)
cfs br $file
cp $file/local /tmp/local_copy
cp $file/global /tmp/global_copy
cfs er $file
removeinc $file
cp /tmp/global_copy $file
cp /tmp/local_copy [EMAIL PROTECTED]
;;
# all other files simply get last_writer_wins semantics
*) cfs br $file
cp $file/local /tmp/last_writer_wins
cfs er $file
removeinc $file
cp /tmp/last_writer_wins $file
;;
esac
Jan