X-Git-Url: http://git.jankratochvil.net/?a=blobdiff_plain;f=src%2Flibcaptive%2Fcc%2Fsharedcachemap.c;h=b278008a02f675155a159504c09831f2d383cfcd;hb=c6bf6aff6799a5504a5ebd28982b5df1e716ee61;hp=4dbd2da455a8d73f14d1885acd997dc60d0575e0;hpb=e8bcd39260e3703a633638ca125a6cc35e1dab25;p=captive.git diff --git a/src/libcaptive/cc/sharedcachemap.c b/src/libcaptive/cc/sharedcachemap.c index 4dbd2da..b278008 100644 --- a/src/libcaptive/cc/sharedcachemap.c +++ b/src/libcaptive/cc/sharedcachemap.c @@ -28,6 +28,7 @@ #include "captive/macros.h" #include #include "reactos/ddk/obfuncs.h" +#include static GHashTable *CaptiveSharedCacheMapObject_hash; @@ -74,9 +75,9 @@ CaptiveSharedCacheMapObject_page *page; captive_shared_cache_map_object->pin_hash=NULL; } g_assert(captive_shared_cache_map_object->map==NULL); - if (captive_shared_cache_map_object->SectionObjectPointers) { - g_assert(captive_shared_cache_map_object==captive_shared_cache_map_object->SectionObjectPointers->SharedCacheMap); - captive_shared_cache_map_object->SectionObjectPointers->SharedCacheMap=NULL; + if (captive_shared_cache_map_object->SectionObjectPointer) { + g_assert(captive_shared_cache_map_object==captive_shared_cache_map_object->SectionObjectPointer->SharedCacheMap); + captive_shared_cache_map_object->SectionObjectPointer->SharedCacheMap=NULL; } if (captive_shared_cache_map_object->FileObject) { @@ -99,7 +100,7 @@ static void captive_shared_cache_map_object_class_init(CaptiveSharedCacheMapObje { GObjectClass *gobject_class=G_OBJECT_CLASS(class); - captive_shared_cache_map_object_parent_class=g_type_class_ref(G_TYPE_OBJECT); + captive_shared_cache_map_object_parent_class=g_type_class_ref(g_type_parent(G_TYPE_FROM_CLASS(class))); gobject_class->finalize=(void (*)(GObject *object))captive_shared_cache_map_object_finalize; class->FileSizes_changed=captive_shared_cache_map_object_FileSizes_changed; @@ -175,52 +176,76 @@ guint64 size64_old,size64_new; g_assert(size_old==size64_old); size64_new=CAPTIVE_ROUND_UP64(AllocationSize,PAGE_SIZE); size_new=size64_new; - g_assert(size_new==size64_new); + if (size_new!=size64_new) { +size_new_big: + g_error("Mapped size %" G_GUINT64_FORMAT " is too big; FIXME: non-mmap(2)-able areas not yet supported",size64_new); + g_assert_not_reached(); + } if (size_old!=size_new) { + /* ntfs.sys of NT-5.1sp1 may extend StreamFileObject while dirty pins exist. + * How to extend SharedCacheMap size without changing the memory location? + * I hope ntfs.sys does not expect long-term absolute position of its + * StreamFileObject: + */ + if (!(captive_shared_cache_map_object->FileObject->Flags&FO_STREAM_FILE)) { + /* These two assertions should be already catched by pin/map signal handlers. */ + g_assert(!captive_shared_cache_map_object->map); + g_assert(!g_hash_table_size(captive_shared_cache_map_object->pin_hash)); + } + } + + if (!size_new || size_new > captive_shared_cache_map_object->alloc_length) { +size_t alloc_new; +guint64 alloc64_new; gpointer buffer_new; - /* These two assertions should be already catched by pin/map signal handlers. */ - g_assert(!captive_shared_cache_map_object->map); - g_assert(!g_hash_table_size(captive_shared_cache_map_object->pin_hash)); + alloc64_new=CAPTIVE_ROUND_UP64((!size64_new ? 0 : MAX(size64_new*2,0x10000)),PAGE_SIZE); + alloc_new=alloc64_new; + if (alloc_new!=alloc64_new) + goto size_new_big; - if (AllocationSize) { + if (!alloc_new) + buffer_new=NULL; + else { gpointer base; int errint; base=mmap( NULL, /* start */ - PAGE_SIZE+size_new+PAGE_SIZE, /* length; leading and trailing boundary check pages */ + PAGE_SIZE+alloc_new+PAGE_SIZE, /* length; leading and trailing boundary check pages */ PROT_READ|PROT_WRITE, /* prot; read/write must be possible although write is not guaranteed to be flushed yet */ - MAP_PRIVATE|MAP_ANONYMOUS, /* flags */ + MAP_PRIVATE|MAP_ANONYMOUS /* flags */ + |MAP_NORESERVE, /* At least ext2fsd maps the whole disk. */ -1, /* fd; ignored due to MAP_ANONYMOUS */ 0); /* offset; ignored due to MAP_ANONYMOUS */ + if (base==MAP_FAILED) + goto size_new_big; g_assert(base!=NULL); base+=PAGE_SIZE; errint=munmap(base-PAGE_SIZE,PAGE_SIZE); /* unmap leading boundary check page */ g_assert(errint==0); - errint=munmap(base+size_new,PAGE_SIZE); /* unmap trailing boundary check page */ + errint=munmap(base+alloc_new,PAGE_SIZE); /* unmap trailing boundary check page */ g_assert(errint==0); buffer_new=base; } - else - buffer_new=NULL; memcpy(buffer_new,captive_shared_cache_map_object->buffer, MIN(AllocationSize,captive_shared_cache_map_object->AllocationSize)); - if (captive_shared_cache_map_object->AllocationSize) { + if (captive_shared_cache_map_object->alloc_length) { int errint; - errint=munmap(captive_shared_cache_map_object->buffer,size_old); + errint=munmap(captive_shared_cache_map_object->buffer,captive_shared_cache_map_object->alloc_length); g_assert(errint==0); } captive_shared_cache_map_object->buffer=buffer_new; #if 0 /* It appears it is valid to squeeze out 'dirty' blocks. FIXME: Flush them? */ + /* FIXME: The code may be no longer valid with the 'alloc_new' introduction! */ if (size_old>size_new) { guint64 now; @@ -231,13 +256,17 @@ guint64 now; } } #endif + captive_shared_cache_map_object->pages=g_realloc(captive_shared_cache_map_object->pages, - size_new/PAGE_SIZE*sizeof(*captive_shared_cache_map_object->pages)); - if (size_new>size_old) /* prevent 'size_new-size_old' as it is unsigned! */ - memset(captive_shared_cache_map_object->pages+(size_old/PAGE_SIZE),0, - (size_new-size_old)/PAGE_SIZE*sizeof(*captive_shared_cache_map_object->pages)); + alloc_new/PAGE_SIZE*sizeof(*captive_shared_cache_map_object->pages)); + + captive_shared_cache_map_object->alloc_length=alloc_new; } + if (size_new>size_old) /* prevent 'size_new-size_old' as it is unsigned! */ + memset(captive_shared_cache_map_object->pages+(size_old/PAGE_SIZE),0, + (size_new-size_old)/PAGE_SIZE*sizeof(*captive_shared_cache_map_object->pages)); + captive_shared_cache_map_object->AllocationSize=AllocationSize; captive_shared_cache_map_object->FileSize=FileSize; captive_shared_cache_map_object->ValidDataLength=ValidDataLength; @@ -254,16 +283,16 @@ static void captive_shared_cache_map_object_purge(CaptiveSharedCacheMapObject *c } CaptiveSharedCacheMapObject *captive_shared_cache_map_get_ref(FILE_OBJECT *FileObject, - const CC_FILE_SIZES *FileSizes,BOOLEAN PinAccess,CACHE_MANAGER_CALLBACKS *CallBacks,VOID *LazyWriterContext) + const CC_FILE_SIZES *FileSizes,BOOLEAN PinAccess,const CACHE_MANAGER_CALLBACKS *CallBacks,VOID *LazyWriterContext) { CaptiveSharedCacheMapObject *captive_shared_cache_map_object; g_return_val_if_fail(FileObject!=NULL,NULL); - g_return_val_if_fail(FileObject->SectionObjectPointers!=NULL,NULL); + g_return_val_if_fail(FileObject->SectionObjectPointer!=NULL,NULL); g_return_val_if_fail(FileSizes!=NULL,NULL); g_return_val_if_fail(CallBacks!=NULL,NULL); - if ((captive_shared_cache_map_object=FileObject->SectionObjectPointers->SharedCacheMap)) { + if ((captive_shared_cache_map_object=FileObject->SectionObjectPointer->SharedCacheMap)) { captive_shared_cache_map_w32_ref(captive_shared_cache_map_object); } else { @@ -271,10 +300,16 @@ CaptiveSharedCacheMapObject *captive_shared_cache_map_object; CAPTIVE_SHARED_CACHE_MAP_TYPE_OBJECT, /* object_type */ NULL); /* first_property_name; FIXME: support properties */ + /* FIXME: When to drop SharedCacheMap? + * Currently we never close it. + * Fix also CcZeroData() workaround. + */ + g_object_ref(captive_shared_cache_map_object); + /* W32 references twice. */ ObReferenceObject(FileObject); captive_shared_cache_map_object->FileObject=FileObject; - captive_shared_cache_map_object->SectionObjectPointers=FileObject->SectionObjectPointers; + captive_shared_cache_map_object->SectionObjectPointer=FileObject->SectionObjectPointer; captive_shared_cache_map_object->AllocationSize=0; captive_shared_cache_map_object->FileSize=0; captive_shared_cache_map_object->ValidDataLength=0; @@ -282,12 +317,12 @@ CaptiveSharedCacheMapObject *captive_shared_cache_map_object; captive_shared_cache_map_object->CallBacks=*CallBacks; captive_shared_cache_map_object->LazyWriterContext=LazyWriterContext; - FileObject->SectionObjectPointers->SharedCacheMap=captive_shared_cache_map_object; + FileObject->SectionObjectPointer->SharedCacheMap=captive_shared_cache_map_object; } g_assert(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object)); /* FileObject may differ - we can have a different reference to the same FCB. */ - g_assert(FileObject->SectionObjectPointers==captive_shared_cache_map_object->SectionObjectPointers); + g_assert(FileObject->SectionObjectPointer==captive_shared_cache_map_object->SectionObjectPointer); g_assert(PinAccess==captive_shared_cache_map_object->PinAccess); g_assert(CallBacks->AcquireForLazyWrite==captive_shared_cache_map_object->CallBacks.AcquireForLazyWrite); g_assert(CallBacks->ReleaseFromLazyWrite==captive_shared_cache_map_object->CallBacks.ReleaseFromLazyWrite); @@ -312,8 +347,12 @@ guint64 AllocationSize,FileSize,ValidDataLength; FileSize=FileSizes->FileSize.QuadPart; ValidDataLength=FileSizes->ValidDataLength.QuadPart; - if (ValidDataLength==G_MAXINT64) - ValidDataLength=FileSize; + /* Do not: if (ValidDataLength==G_MAXINT64) + * ValidDataLength=FileSize; + * In some cases (during NTFS mount) there may be also invalid 'ValidDataLength' at all: + * CcSetFileSizes(AllocationSize=0x1000000,FileSize=0xf80208,ValidDataLength=0x23b801a0) + */ + ValidDataLength=FileSize; g_assert(AllocationSize>=0); g_assert(FileSize>=0); @@ -326,13 +365,21 @@ guint64 AllocationSize,FileSize,ValidDataLength; /* AllocationSize can be much higher: */ g_assert(FileSize<=AllocationSize); - /* Prevent signalling if not needed as signal is forbidden in captive_shared_cache_map_object_finalize() */ + /* Prevent signalling if not needed. */ if (0 || captive_shared_cache_map_object->AllocationSize!=AllocationSize || captive_shared_cache_map_object->FileSize!=FileSize - || captive_shared_cache_map_object->ValidDataLength!=ValidDataLength) - g_signal_emit(captive_shared_cache_map_object,FileSizes_changed_signal,0, - AllocationSize,FileSize,ValidDataLength); + || captive_shared_cache_map_object->ValidDataLength!=ValidDataLength) { + /* Signalling is forbidden in captive_shared_cache_map_object_finalize(). */ + if (G_OBJECT(captive_shared_cache_map_object)->ref_count==0) { + (*CAPTIVE_SHARED_CACHE_MAP_OBJECT_GET_CLASS(captive_shared_cache_map_object)->FileSizes_changed) + (captive_shared_cache_map_object,AllocationSize,FileSize,ValidDataLength); + } + else { + g_signal_emit(captive_shared_cache_map_object,FileSizes_changed_signal,0, + AllocationSize,FileSize,ValidDataLength); + } + } g_assert(captive_shared_cache_map_object->AllocationSize==AllocationSize); g_assert(captive_shared_cache_map_object->FileSize==FileSize); @@ -351,7 +398,7 @@ CaptiveSharedCacheMapObject *captive_FileObject_to_SharedCacheMap(FILE_OBJECT *F { g_return_val_if_fail(FileObject!=NULL,NULL); - return captive_SectionObjectPointers_to_SharedCacheMap(FileObject->SectionObjectPointers); + return captive_SectionObjectPointers_to_SharedCacheMap(FileObject->SectionObjectPointer); } void captive_shared_cache_map_w32_ref(CaptiveSharedCacheMapObject *captive_shared_cache_map_object) @@ -367,23 +414,17 @@ void captive_shared_cache_map_w32_unref(CaptiveSharedCacheMapObject *captive_sha g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object)); g_return_if_fail(G_OBJECT(captive_shared_cache_map_object)->ref_count>0); - if (captive_shared_cache_map_object->w32_ref_count==1) { -static const CC_FILE_SIZES FileSizes_zero; - - g_assert(G_OBJECT(captive_shared_cache_map_object)->ref_count==1); - - /* Prevent such truncation in captive_shared_cache_map_object_finalize() - * as it would do forbidden g_object_ref() there. - */ - captive_shared_cache_map_FileSizes_set(captive_shared_cache_map_object,&FileSizes_zero); - g_assert(captive_shared_cache_map_object->buffer==NULL); - g_assert(captive_shared_cache_map_object->pages==NULL); - } - captive_shared_cache_map_object->w32_ref_count--; g_object_unref(captive_shared_cache_map_object); } +gint captive_shared_cache_map_query_w32_ref(CaptiveSharedCacheMapObject *captive_shared_cache_map_object) +{ + g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),0); + + return captive_shared_cache_map_object->w32_ref_count; +} + void captive_shared_cache_map_data_validate_read(CaptiveSharedCacheMapObject *captive_shared_cache_map_object, FILE_OBJECT *FileObject,guint64 start,guint64 end) { @@ -412,6 +453,7 @@ ULONG got; g_assert(got<=PAGE_SIZE); after_eof=(gotpages[now/PAGE_SIZE].data_valid=TRUE; + captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty=FALSE; } } @@ -441,11 +483,37 @@ guint64 now; g_return_if_fail(start<=end); g_return_if_fail(end<=CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE)); + start=CAPTIVE_ROUND_UP64(start,PAGE_SIZE); + if (endFileSize) + end=CAPTIVE_ROUND_DOWN64(end,PAGE_SIZE); + else { + /* We can validate the last page of the file + * even if it does not end on PAGE_SIZE boundary. + */ + end=CAPTIVE_ROUND_UP64(end,PAGE_SIZE); + } + /* We may get endpages[now/PAGE_SIZE].data_valid=TRUE; + /* .dirty is undefined */ + } +} + +void captive_shared_cache_map_set_data_invalid(CaptiveSharedCacheMapObject *captive_shared_cache_map_object, + guint64 start,guint64 end) +{ +guint64 now; + + g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object)); + g_return_if_fail(start<=end); + g_return_if_fail(end<=CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE)); + start=CAPTIVE_ROUND_DOWN64(start,PAGE_SIZE); end=CAPTIVE_ROUND_UP64(end,PAGE_SIZE); for (now=start;nowpages[now/PAGE_SIZE].data_valid=TRUE; + captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid=FALSE; } } @@ -516,11 +584,18 @@ CaptiveSharedCacheMapObject_page *page; g_signal_emit(captive_shared_cache_map_object,purge_signal,0); + /* Needed by fastfat.sys of NT-5.1sp1 during FAT32 unmount + * otherwise it fails on: g_assert(!page->dirty); + * It corrupts the disk if the buffer is dropped instead. + */ + captive_shared_cache_map_flush(captive_shared_cache_map_object, + 0,CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE)); + for (offset=0;offsetAllocationSize,PAGE_SIZE);offset+=PAGE_SIZE) { page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE; if (!page->data_valid) continue; - g_assert(!page->dirty); /* FIXME: Is it allowed by W32? */ + g_assert(!page->dirty); page->data_valid=FALSE; } } @@ -575,14 +650,14 @@ CaptiveSharedCacheMapObject_page *page; g_return_if_fail(page->dirty); if (page->lsn_newest) { -LARGE_INTEGER lsn_newest_LargeInteger; - /* sanity check */ g_assert(!lsn_last || lsn_last<=page->lsn_newest); lsn_last=page->lsn_newest; - lsn_newest_LargeInteger.QuadPart=page->lsn_newest; - (*captive_FlushToLsnRoutine)(captive_LogHandle,lsn_newest_LargeInteger); + captive_stdcall_call_12((CaptiveStdCallFunc12)captive_FlushToLsnRoutine, + captive_LogHandle, + (gpointer)(guint32)(page->lsn_newest>> 0U), /* 'LARGE_INTEGER' argument */ + (gpointer)(guint32)(page->lsn_newest>>32U)); } offset_LargeInteger.QuadPart=offset; @@ -594,25 +669,34 @@ LARGE_INTEGER lsn_newest_LargeInteger; page->lsn_newest=0; } -typedef struct _captive_shared_cache_map_page_write_lsn_foreach_param captive_shared_cache_map_page_write_lsn_foreach_param; -struct _captive_shared_cache_map_page_write_lsn_foreach_param { +typedef struct _captive_shared_cache_map_flush_lsn_sort captive_shared_cache_map_flush_lsn_sort; +struct _captive_shared_cache_map_flush_lsn_sort { + gint64 lsn; + CaptiveSharedCacheMapObject *captive_shared_cache_map_object; + guint64 offset; + }; + +typedef struct _captive_shared_cache_map_flush_lsn_pages_foreach_param + captive_shared_cache_map_flush_lsn_pages_foreach_param; +struct _captive_shared_cache_map_flush_lsn_pages_foreach_param { gint64 lsn_target; - gint64 lsn_best; - CaptiveSharedCacheMapObject *captive_shared_cache_map_object_best; - guint64 offset_best; + guint lsn_pages_count; + captive_shared_cache_map_flush_lsn_sort *lsn_pages_pointer; /* Not filled in if NULL */ }; -static void captive_shared_cache_map_page_write_lsn_foreach( +static void captive_shared_cache_map_flush_lsn_pages_foreach( CaptiveSharedCacheMapObject *captive_shared_cache_map_object, /* key */ CaptiveSharedCacheMapObject *captive_shared_cache_map_object_value, /* value */ - captive_shared_cache_map_page_write_lsn_foreach_param *param) /* user_data */ + captive_shared_cache_map_flush_lsn_pages_foreach_param *param) /* user_data */ { guint64 now; CaptiveSharedCacheMapObject_page *page; +#if 0 /* acceleration */ g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object)); g_return_if_fail(captive_shared_cache_map_object==captive_shared_cache_map_object_value); g_return_if_fail(param!=NULL); +#endif for (now=0;nowAllocationSize;now+=PAGE_SIZE) { page=captive_shared_cache_map_object->pages+now/PAGE_SIZE; @@ -622,47 +706,27 @@ CaptiveSharedCacheMapObject_page *page; continue; if (!page->lsn_newest) continue; - if (page->lsn_newest>=param->lsn_target) + if (page->lsn_newest>param->lsn_target) continue; - if (param->lsn_best && page->lsn_newest>param->lsn_best) + param->lsn_pages_count++; + if (!param->lsn_pages_pointer) continue; - param->lsn_best=page->lsn_newest; - param->captive_shared_cache_map_object_best=captive_shared_cache_map_object; - param->offset_best=now; + param->lsn_pages_pointer->lsn=page->lsn_newest; + param->lsn_pages_pointer->captive_shared_cache_map_object=captive_shared_cache_map_object; + param->lsn_pages_pointer->offset=now; + param->lsn_pages_pointer++; } } -static void captive_shared_cache_map_page_write_lsn(CaptiveSharedCacheMapObject *captive_shared_cache_map_object, - guint64 offset) +static int captive_shared_cache_map_flush_lsn_pages_compar + (const captive_shared_cache_map_flush_lsn_sort *a,const captive_shared_cache_map_flush_lsn_sort *b) { -CaptiveSharedCacheMapObject_page *page; - - g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object)); - g_return_if_fail(captive_shared_cache_map_object->FileObject!=NULL); - g_return_if_fail(offsetAllocationSize,PAGE_SIZE)); - g_return_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE)); - page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE; - g_return_if_fail(page->data_valid); - g_return_if_fail(page->dirty); - - if (page->lsn_newest) { - CaptiveSharedCacheMapObject_hash_init(); - for (;;) { -captive_shared_cache_map_page_write_lsn_foreach_param param; - - param.lsn_target=page->lsn_newest; - param.lsn_best=0; - g_hash_table_foreach( - CaptiveSharedCacheMapObject_hash, /* hash_table */ - (GHFunc)captive_shared_cache_map_page_write_lsn_foreach, /* func */ - ¶m); /* user_data */ - if (!param.lsn_best) - break; - captive_shared_cache_map_page_write(param.captive_shared_cache_map_object_best,param.offset_best); - } - } +#if 0 /* acceleration */ + g_return_val_if_fail(a!=NULL,0); + g_return_val_if_fail(b!=NULL,0); +#endif - captive_shared_cache_map_page_write(captive_shared_cache_map_object,offset); + return (a->lsn>b->lsn)-(b->lsn>a->lsn); } guint64 captive_shared_cache_map_flush(CaptiveSharedCacheMapObject *captive_shared_cache_map_object, @@ -670,6 +734,11 @@ guint64 captive_shared_cache_map_flush(CaptiveSharedCacheMapObject *captive_shar { guint64 flushed; guint64 now; +gint64 lsn_target; +captive_shared_cache_map_flush_lsn_pages_foreach_param lsn_pages_foreach_param; +captive_shared_cache_map_flush_lsn_sort *lsn_pages_pointer; +const captive_shared_cache_map_flush_lsn_sort *lsn_page; +guint lsn_pages_count; g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),0); g_return_val_if_fail(start<=end,0); @@ -679,21 +748,77 @@ guint64 now; start=CAPTIVE_ROUND_DOWN64(start,PAGE_SIZE); end=CAPTIVE_ROUND_UP64(end,PAGE_SIZE); + lsn_target=0; + for (now=start;nowpages+now/PAGE_SIZE; + if (!page->data_valid) + continue; + if (!page->dirty) + continue; + if (!page->lsn_newest) + continue; + if (!lsn_target || lsn_targetlsn_newest) + lsn_target=page->lsn_newest; + } + + lsn_pages_foreach_param.lsn_target=lsn_target; + lsn_pages_foreach_param.lsn_pages_count=0; + lsn_pages_foreach_param.lsn_pages_pointer=NULL; /* Not yet filling */ + g_hash_table_foreach( + CaptiveSharedCacheMapObject_hash, /* hash_table */ + (GHFunc)captive_shared_cache_map_flush_lsn_pages_foreach, /* func */ + &lsn_pages_foreach_param); /* user_data */ + + lsn_pages_count=lsn_pages_foreach_param.lsn_pages_count; + captive_newn(lsn_pages_pointer,lsn_pages_count); + g_assert(lsn_pages_foreach_param.lsn_target==lsn_target); + lsn_pages_foreach_param.lsn_pages_count=0; + lsn_pages_foreach_param.lsn_pages_pointer=lsn_pages_pointer; + g_hash_table_foreach( + CaptiveSharedCacheMapObject_hash, /* hash_table */ + (GHFunc)captive_shared_cache_map_flush_lsn_pages_foreach, /* func */ + &lsn_pages_foreach_param); /* user_data */ + + g_assert(lsn_pages_foreach_param.lsn_target==lsn_target); + g_assert(lsn_pages_foreach_param.lsn_pages_count==lsn_pages_count); + g_assert(lsn_pages_foreach_param.lsn_pages_pointer==lsn_pages_pointer+lsn_pages_count); + + qsort(lsn_pages_pointer,lsn_pages_count,sizeof(*lsn_pages_pointer), + (int (*)(const void *,const void *))captive_shared_cache_map_flush_lsn_pages_compar); + flushed=0; + + for (lsn_page=lsn_pages_pointer;lsn_pagecaptive_shared_cache_map_object,lsn_page->offset); + if (lsn_page->captive_shared_cache_map_object==captive_shared_cache_map_object + && lsn_page->offset>=start && lsn_page->offsetpages[now/PAGE_SIZE].data_valid) +CaptiveSharedCacheMapObject_page *page; + + page=captive_shared_cache_map_object->pages+now/PAGE_SIZE; + if (!page->data_valid) continue; - if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty) + if (!page->dirty) continue; - captive_shared_cache_map_page_write_lsn(captive_shared_cache_map_object,now); + captive_shared_cache_map_page_write(captive_shared_cache_map_object,now); flushed+=PAGE_SIZE; } /* We were calling W32 code - recheck our task completion. */ for (now=start;nowpages[now/PAGE_SIZE].data_valid) +CaptiveSharedCacheMapObject_page *page; + + page=captive_shared_cache_map_object->pages+now/PAGE_SIZE; + if (!page->data_valid) continue; - g_assert(!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty); + g_assert(!page->dirty); } return flushed; @@ -711,9 +836,12 @@ guint64 now; g_return_if_fail(dirty_foundp!=NULL); for (now=0;nowAllocationSize;now+=PAGE_SIZE) { - if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid) +CaptiveSharedCacheMapObject_page *page; + + page=captive_shared_cache_map_object->pages+now/PAGE_SIZE; + if (!page->data_valid) continue; - if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty) + if (!page->dirty) continue; *dirty_foundp=TRUE; /* FIXME: stop the traversal. */ break;