From 1ff95dce46dcb5b0358db1fd4fa9698daeb326d7 Mon Sep 17 00:00:00 2001 From: Michael Vrable Date: Thu, 4 Nov 2010 15:09:54 -0700 Subject: [PATCH] Update disk cache usage tracking to handle sparse files. --- bluesky/bluesky-private.h | 1 + bluesky/cache.c | 6 +++--- bluesky/log.c | 22 ++++++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/bluesky/bluesky-private.h b/bluesky/bluesky-private.h index b064465..7735a91 100644 --- a/bluesky/bluesky-private.h +++ b/bluesky/bluesky-private.h @@ -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 diff --git a/bluesky/cache.c b/bluesky/cache.c index 12b8be7..fd4797d 100644 --- a/bluesky/cache.c +++ b/bluesky/cache.c @@ -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); diff --git a/bluesky/log.c b/bluesky/log.c index d9ad11b..9455058 100644 --- a/bluesky/log.c +++ b/bluesky/log.c @@ -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); -- 2.20.1