Notes 3/5/12


Surviving power failures:


Idea 1: Commit record – have an atomic low level write that commits the new write.

  1. write blocks to copy area

  2. wait for blocks to hit disk

  3. write to separate commit record

  4. copy from copy area to original area

  5. wait for data to hit disk

  6. clear commit record


This process can be described as completing a transaction:

  1. Precommit phase: (can still back out at this point w/ no change)

  2. COMMIT / ABORT

  3. Postcommit phase: for fs to clean up after write


Idea 2: Journaling












Journal (ideally infinitely long, practically ~2x size main memory)


















Cells


Advantages:


Journal Logging:

Write ahead logs

  1. log all writes you plan to do

  2. COMMIT

  3. install new values to cell data

Write behind logs

  1. log old values in journal

  2. install new values to cell

  3. COMMIT


A more complicated approach with journaling for better performance:


Virtual Memory:


Problem: Unreliable programs have bad memory references and can potentially crash other applications (or the kernel) if they access an incorrect address.


Solutions:


Page # (20 bits)

Page offset ( 12 bits)

Master table (10 bits)

Intermediate table (10 bits)

Data index (12 bits)



size_t pmap(size_t va){


int offset = va & (1<<12) - 1;

int lo = va >> 12 & (1<<10) – 1;

int hi = va >> 22;


size_t *l0page = PAGETABLE[hi];


if(l0page == FAULT)

return FAULT;


size_t *l1page = PAGETABLE[lo];


if(*l1page == FAULT)

return FAULT;


return *l1page + offset;

}


(PAGETABLE is register %cr3, a privileged register)