Update disk cache usage tracking to handle sparse files.
authorMichael Vrable <mvrable@cs.ucsd.edu>
Thu, 4 Nov 2010 22:09:54 +0000 (15:09 -0700)
committerMichael Vrable <mvrable@cs.ucsd.edu>
Thu, 4 Nov 2010 22:09:54 +0000 (15:09 -0700)
bluesky/bluesky-private.h
bluesky/cache.c
bluesky/log.c

index b064465..7735a91 100644 (file)
@@ -382,6 +382,7 @@ struct BlueSkyCacheFile {
     gint mapcount;              // References to the mmaped data
     const char *addr;           // May be null if data is not mapped in memory
     size_t len;
+    int disk_used;
     BlueSkyFS *fs;
     BlueSkyLog *log;
     gboolean fetching, ready;   // Cloud data: downloading or ready for use
index 12b8be7..fd4797d 100644 (file)
@@ -328,9 +328,9 @@ void bluesky_cachefile_gc(BlueSkyFS *fs)
          * then we'll just skip the file on this pass. */
         if (g_mutex_trylock(cachefile->lock)) {
             int64_t age = bluesky_get_current_time() - cachefile->atime;
-            g_print("%s addr=%p mapcount=%d refcount=%d atime_age=%f",
+            g_print("%s addr=%p mapcount=%d refcount=%d size=%d atime_age=%f",
                     cachefile->filename, cachefile->addr, cachefile->mapcount,
-                    cachefile->refcount, age / 1e6);
+                    cachefile->refcount, cachefile->disk_used, age / 1e6);
             if (cachefile->fetching)
                 g_print(" (fetching)");
             g_print("\n");
@@ -359,7 +359,7 @@ void bluesky_cachefile_gc(BlueSkyFS *fs)
                             cachefile->filename);
                 }
 
-                g_atomic_int_add(&fs->log->disk_used, -(cachefile->len / 1024));
+                g_atomic_int_add(&fs->log->disk_used, -cachefile->disk_used);
                 g_hash_table_remove(fs->log->mmap_cache, cachefile->filename);
                 bluesky_rangeset_free(cachefile->items);
                 g_mutex_unlock(cachefile->lock);
index d9ad11b..9455058 100644 (file)
@@ -62,6 +62,16 @@ static void log_commit(BlueSkyLog *log)
         return;
 
     fdatasync(log->fd);
+
+    /* Update disk-space usage statistics for the journal file. */
+    g_atomic_int_add(&log->disk_used, -log->current_log->disk_used);
+    struct stat statbuf;
+    if (fstat(log->fd, &statbuf) >= 0) {
+        /* Convert from 512-byte blocks to 1-kB units */
+        log->current_log->disk_used = (statbuf.st_blocks + 1) / 2;
+    }
+    g_atomic_int_add(&log->disk_used, log->current_log->disk_used);
+
     while (log->committed != NULL) {
         BlueSkyCloudLog *item = (BlueSkyCloudLog *)log->committed->data;
         g_mutex_lock(item->lock);
@@ -514,6 +524,16 @@ static void cloudlog_partial_fetch_complete(BlueSkyStoreAsync *async,
         cloudlog_partial_fetch_start(cachefile, async->start, async->len);
     }
 
+    /* Update disk-space usage statistics, since the writes above may have
+     * consumed more space. */
+    g_atomic_int_add(&cachefile->log->disk_used, -cachefile->disk_used);
+    struct stat statbuf;
+    if (fstatat(cachefile->log->dirfd, cachefile->filename, &statbuf, 0) >= 0) {
+        /* Convert from 512-byte blocks to 1-kB units */
+        cachefile->disk_used = (statbuf.st_blocks + 1) / 2;
+    }
+    g_atomic_int_add(&cachefile->log->disk_used, cachefile->disk_used);
+
     bluesky_cachefile_unref(cachefile);
     g_cond_broadcast(cachefile->cond);
     g_mutex_unlock(cachefile->lock);
@@ -618,9 +638,7 @@ BlueSkyRCStr *bluesky_log_map_object(BlueSkyCloudLog *item, gboolean map_data)
         off_t length = lseek(fd, 0, SEEK_END);
         map->addr = (const char *)mmap(NULL, length, PROT_READ, MAP_SHARED,
                                        fd, 0);
-        g_atomic_int_add(&log->disk_used, -(map->len / 1024));
         map->len = length;
-        g_atomic_int_add(&log->disk_used, map->len / 1024);
 
         g_atomic_int_inc(&map->refcount);