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

Reply via email to