Chris Mason wrote:
> For reading the tail, take a look at how these functions interact:
> 
> get_block
> generic_file_read
> block_read_full_page (ext2's readpage func)
> 
> Putting the tail knowledge into ext2_file_read won't be enough, it won't
> cover mmaps.  You have to make sure your readpage/writepage functions
> keep the page and buffer caches in sync.  Reiserfs does most of this from
> get_block...
> [...]
> You have two real choices.  Unpack the tail before any writes to it, then
> repack later (file close, whatever).  This allows you to use all the
> generic functions for writing data, and keeps the synchronization down
> (only write to shared data on pack/unpack).

Yesssss.  Here is the beginning of a detailed design:

proposed ext2 file write:
  writing past tail?
    if so, unmerge tail block
  generic file write
  
additions to write full page:
  (within the per-buffer write)
    is the file tailmerged? 
      if so, does this part map the tail block?
        if so, get the tail block and copy the tail to the page

additions to read full page:
  (within the per-buffer read)
    is the file tailmerged?
      if so, does this part map the tail block?
        if so, get the tail block, copy in the tail and dirty it

This doesn't attempt to do the tail merge incrementally - instead it's
going to be done at mount time, just for the prototype.

Implications of sharing tail blocks between files:
  - must unmerge on truncate (except when truncate is within tail)
  - must unmerge before any write past tail
  - must not free shared tail block
  - races galore if not careful

Synchronization:
  - This is considerably simplified by not having incremental
    merging in the equation.  This is only a temporary 
    reprieve.  When the incremental algoritm is added to the 
    soup the possibilities for races will be multiplied.

  - I'm not clear yet on the locking strategy in the existing 
    code, so I'll assume for the moment that nothing is locked, 
    and that all my new additions have to take care of that 
    themselves.  It will be easier to relax the requirements 
    later than to hunt down mysterious races.

  - Two processes attempting to unmerge at the same time could 
    deadlock, as each of them might attempts to lock the same 
    two inodes to perform a ring delete, and each succeed in 
    getting only one of them.  This impasse has to be resolved 
    in some deterministic way.

-- 
Daniel

Reply via email to