Fixed LSN flushing typo.
[captive.git] / src / libcaptive / cc / sharedcachemap.c
index db4e1dc..b278008 100644 (file)
@@ -195,21 +195,25 @@ size_new_big:
                        }
                }
 
-       if (size_new > captive_shared_cache_map_object->alloc_length) {
+       if (!size_new || size_new > captive_shared_cache_map_object->alloc_length) {
+size_t alloc_new;
+guint64 alloc64_new;
 gpointer buffer_new;
 
-               size_new*=2;
-               size64_new*=2;
-               if (size_new!=size64_new)
+               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 (size_new) {
+               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_NORESERVE, /* At least ext2fsd maps the whole disk. */
@@ -222,13 +226,11 @@ int errint;
                        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));
@@ -243,6 +245,7 @@ int errint;
                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;
 
@@ -255,14 +258,15 @@ 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=size_new;
+               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;
@@ -343,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);
@@ -726,7 +734,7 @@ guint64 captive_shared_cache_map_flush(CaptiveSharedCacheMapObject *captive_shar
 {
 guint64 flushed;
 guint64 now;
-gint lsn_target;
+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;