Julian Foad wrote on Tue, Dec 07, 2010 at 09:40:07 +0000:
> On Mon, 2010-12-06 at 18:44 +0000, Philip Martin wrote:
> > Julian Foad <julian.f...@wandisco.com> writes:
> > 
> > > I'm going to drop this "Remove the re-try logic from
> > > svn_fs_fs__path_rev_absolute()" follow-up patch, as I don't want to get
> > > into checking or messing with the txn-correctness of FSFS now.  If
> > > Daniel or anyone else wants to pursue it, I'd be glad to help.
> > 
> > I thought the patch was an improvement.  The existing retry in
> > svn_fs_fs__path_rev_absolute doesn't fix the race, it simply makes the
> > window smaller.  As the patch makes the window larger we are more likely
> > to see and fix any places where the caller doesn't handle the race.
> 
> I *think* the problem is that a caller may use this function within a
> transaction and depend on this internal re-try logic simply to update a
> stale cached min-unpacked-foo value.  "Stale" in the sense that *this*
> transaction has changed the real value and hasn't updated the cached
> value.
> 

Yes, it's conceivable that a caller might do:

  for (int i = 0; i < 2; i++)
    {
      ...
      SVN_ERR(svn_fs_fs__path_rev_absolute());
      ...
      if (i == 0)
        /* other process runs svn_fs_pack(); */;
      ...
      err = foo();
      if (err)
        {
          svn_error_clear(err);
          continue;
        }
      ...
    }

and rely on the call to svn_fs_fs__path_rev_absolute() in the second
iteration to update ffd->min_unpacked_rev.

I do not know that any of the current callers behave this way ---
I think that other than open_pack_or_rev_file(), all callers always have
the write lock --- but it's conceivable.  And if we ever add such
a caller, we will have to make them call update_min_unpacked_rev() by
themselves.

. o O [It should be fun to build with 
printf("-DSVN_FS_FS_DEFAULT_MAX_FILES_PER_DIR=%d -DPACK_AFTER_EVERY_COMMIT", 
1).]

> Daniel, you wrote:
> > But is it strictly *necessary* to do so?  I think not: by not calling
> > update_min_unpacked_rev(), we cause ffd->min_unpacked_rev to become
> > stale --- a situation which the code has to account for anyway.
> 
> That was true, then, and it meant that every place that used this value
> had to account for it possibly being stale.  But now we have realized
> that the code shouldn't need to account for the possibility of the value
> being stale if it is running within a transaction (with the write lock).
> 
> Now, I think it would be better to change this.  Whenever the code
> updates the min-foo on disk, it should also update the cached value.
> That style of coding would be easier to reason about (to use an in-vogue
> phrase), and then we would be able to remove the re-try in
> svn_fs_fs__path_rev_absolute() without a concern.
> 

Making ffd->min_unpacked_rev stale less often does not mean that we will
have less places to account for it *possibly* being stale: it could
become stale due to other processes who write to the repository.
(except for "pack runs under the write lock" considerations)

To borrow Philip's point: making ffd->min_unpacked_rev stale less often
might hide bugs.

> Does that make sense?
> 
> - Julian
> 
> 

Daniel
(ffd->min_unpacked_rev could be renamed ffd->min_unpacked_rev_cache...)

Reply via email to