(Illustration by Gaich Muramatsu)
On Tue, Jul 08, 2003 at 05:11:43PM +0100, lou wrote: > In some email I received from Jan Harkes <jaharkes_at_cs.cmu.edu> 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 $file@`hostname` ;; # 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 JanReceived on 2003-07-08 12:43:25