Commit 4a20a573 authored by Kirill Smelkov's avatar Kirill Smelkov

X Settled on what should happen after writeout for wcfs case

parent 034b05b8
...@@ -425,18 +425,53 @@ int fileh_dirty_writeout(BigFileH *fileh, enum WriteoutFlags flags) ...@@ -425,18 +425,53 @@ int fileh_dirty_writeout(BigFileH *fileh, enum WriteoutFlags flags)
goto out; goto out;
} }
/* page.state -> PAGE_LOADED and correct mappings RW -> R */ /* wcfs: remmap RW pages to base layer
// XXX wcfs: just remmap base file? (but it does not yet have stored changes) * !wcfs: page.state -> PAGE_LOADED and correct mappings RW -> R
// XXX -> vma_remove_readonly_overlay()? *
* NOTE for transaction storage (ZODB and ZBigFile) storeblk creates
* new transaction on database side, but does not update current DB
* connection to view that transaction. Thus if loadblk will be loaded
* with not-yet-resynced DB connection, it will return old - not stored
* - data. For !wcfs case this is partly mitigated by the fact that
* stored pages are kept as PAGE_LOADED in ram, but it cannot be
* relied as ram_reclaim can drop those pages and read access to them
* will trigger loadblk from database which will return old data.
* For wcfs case remapping to base layer will always return old data
* until wcfs mapping is updated to view database at newer state.
*
* In general it is a bug to access data pages in between transactions,
* so we accept those corner case difference in between wcfs and !wcfs.
*/
if (flags & WRITEOUT_MARKSTORED) { if (flags & WRITEOUT_MARKSTORED) {
page->state = PAGE_LOADED; page->state = PAGE_LOADED;
list_del_init(&page->in_dirty); list_del_init(&page->in_dirty);
list_for_each(hmmap, &fileh->mmaps) { list_for_each(hmmap, &fileh->mmaps) {
VMA *vma = list_entry(hmmap, typeof(*vma), same_fileh); VMA *vma = list_entry(hmmap, typeof(*vma), same_fileh);
if (vma->mmap_overlay) {
/* wcfs: RW -> base layer */
vma_page_ensure_unmapped(vma, page);
} else {
/* !wcfs: RW -> R*/
vma_page_ensure_notmappedrw(vma, page); vma_page_ensure_notmappedrw(vma, page);
} }
} }
// XXX just relying on page->refcnt==0 is wrong - for !wcfs case
// when there are no mappings it will unnecessarily drop fileh cache.
// -> move mmap_overlay from vma to fileh and check:
// if (fileh->mmap_overlay) {
// ASSERT(page->refcnt == 0);
// page_drop(page);
// }
#if 0
/* if noone is using the page (ex all vmas use base layer) - drop
* it completely without unnecessarily growing RSS and relying on reclaim. */
if (page->refcnt == 0) {
}
#endif
}
} }
......
...@@ -29,6 +29,8 @@ ...@@ -29,6 +29,8 @@
* Read access to mapped pages cause their on-demand loading, and write access * Read access to mapped pages cause their on-demand loading, and write access
* marks modified pages as dirty. Dirty pages then can be on request either * marks modified pages as dirty. Dirty pages then can be on request either
* written out back to file or discarded. * written out back to file or discarded.
*
* XXX update for wcfs.
*/ */
#include <stdint.h> #include <stdint.h>
...@@ -205,8 +207,9 @@ enum WriteoutFlags { ...@@ -205,8 +207,9 @@ enum WriteoutFlags {
/* mark dirty pages as stored to file ok /* mark dirty pages as stored to file ok
* *
* pages state becomes PAGE_LOADED and all mmaps are updated to map pages as * wcfs: all mmaps are updated to map read-only to base layer.
* R/O to track further writes. * !wcfs: pages state becomes PAGE_LOADED and all mmaps are updated to map
* pages as R/O to track further writes.
*/ */
WRITEOUT_MARKSTORED = 1 << 1, WRITEOUT_MARKSTORED = 1 << 1,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment