+ if (page_size == 0) {
+ page_size = getpagesize();
+ }
+
+ BlueSkyLog *log = fs->log;
+ BlueSkyCacheFile *map = bluesky_cachefile_lookup(fs, log_dir, log_seq);
+
+ if (map == NULL) {
+ return NULL;
+ }
+
+ if (map->addr == NULL) {
+ while (!map->ready && map->fetching) {
+ g_print("Waiting for log segment to be fetched from cloud...\n");
+ g_cond_wait(map->cond, map->lock);
+ }
+
+ int fd = openat(log->dirfd, map->filename, O_RDONLY);
+
+ if (fd < 0) {
+ fprintf(stderr, "Error opening logfile %s: %m\n", map->filename);
+ bluesky_cachefile_unref(map);
+ g_mutex_unlock(map->lock);
+ return NULL;
+ }
+
+ off_t length = lseek(fd, 0, SEEK_END);
+ map->addr = (const char *)mmap(NULL, length, PROT_READ, MAP_SHARED,
+ fd, 0);
+ map->len = length;
+
+ g_print("Re-mapped log segment %d...\n", log_seq);
+ g_atomic_int_inc(&map->refcount);
+
+ close(fd);
+ }
+
+ g_mutex_unlock(log->mmap_lock);
+
+ BlueSkyRCStr *str;
+ map->atime = bluesky_get_current_time();
+ str = bluesky_string_new_from_mmap(map, log_offset, log_size);
+ bluesky_cachefile_unref(map);
+ g_mutex_unlock(map->lock);
+ return str;
+}
+
+void bluesky_mmap_unref(BlueSkyCacheFile *mmap)
+{
+ if (mmap == NULL)
+ return;
+
+ if (g_atomic_int_dec_and_test(&mmap->mapcount)) {
+ g_mutex_lock(mmap->lock);
+ if (g_atomic_int_get(&mmap->mapcount) == 0) {
+ g_print("Unmapped log segment %d...\n", mmap->log_seq);
+ munmap((void *)mmap->addr, mmap->len);
+ mmap->addr = NULL;
+ g_atomic_int_add(&mmap->refcount, -1);
+ }
+ g_mutex_unlock(mmap->lock);
+ }