Skip to content

Commit

Permalink
[LibOS] Introduce refresh_mappings_on_file() convenience func
Browse files Browse the repository at this point in the history
This commit refactors repetitive invocations of file-mapping related
functions `prot_refresh_mmaped_from_file_handle()` and
`reload_mmaped_from_file_handle()` into a new convenience function.

Signed-off-by: Dmitrii Kuvaiskii <dmitrii.kuvaiskii@intel.com>
  • Loading branch information
Dmitrii Kuvaiskii committed Aug 5, 2024
1 parent 79ce80f commit a9d08fd
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 88 deletions.
9 changes: 4 additions & 5 deletions libos/include/libos_vma.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,10 @@ int msync_range(uintptr_t begin, uintptr_t end);
/* Call `msync` for file mappings of `hdl` */
int msync_handle(struct libos_handle* hdl);

/* Reload file mappings of `hdl` */
int reload_mmaped_from_file_handle(struct libos_handle* hdl);

/* Refresh page protections of file mappings of `hdl` when the file size has changed */
int prot_refresh_mmaped_from_file_handle(struct libos_handle* hdl, size_t file_size);
/* Refresh page protections and optionally reload file contents of file mappings of `hdl`. Reloading
* of file contents is performed by reading data from `hdl` and only on MAP_SHARED mappings. */
void refresh_mappings_on_file(struct libos_handle* hdl, size_t new_file_size,
bool reload_file_contents);

void debug_print_all_vmas(void);

Expand Down
29 changes: 27 additions & 2 deletions libos/src/bookkeep/libos_vma.c
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,7 @@ static int reload_vma(struct libos_vma_info* vma_info) {
* `mmap(MAP_FIXED_NOREPLACE)` and `msync()`) via the `msync` callback, so blindly reloading the VMA
* contents on e.g. `munmap()` can be inefficient (but unmapping file-backed memory regions
* shouldn't be a frequent operation). */
int reload_mmaped_from_file_handle(struct libos_handle* hdl) {
static int reload_mmaped_from_file_handle(struct libos_handle* hdl) {
struct libos_vma_info* vma_infos;
size_t count;

Expand Down Expand Up @@ -1617,7 +1617,7 @@ static int prot_refresh_vma(struct libos_vma_info* vma_info) {

/* This helper function is to refresh access protections on the VMA pages of a given file handle on
* file-extend operations (`write` and `ftruncate`). */
int prot_refresh_mmaped_from_file_handle(struct libos_handle* hdl, size_t file_size) {
static int prot_refresh_mmaped_from_file_handle(struct libos_handle* hdl, size_t file_size) {
struct libos_vma_info* vma_infos;
size_t count;

Expand Down Expand Up @@ -1709,6 +1709,31 @@ int msync_handle(struct libos_handle* hdl) {
return msync_all(/*begin=*/0, /*end=*/UINTPTR_MAX, hdl);
}

void refresh_mappings_on_file(struct libos_handle* hdl, size_t new_file_size,
bool reload_file_contents) {
assert(hdl->type == TYPE_TMPFS || hdl->type == TYPE_SHM || hdl->type == TYPE_CHROOT
|| hdl->type == TYPE_CHROOT_ENCRYPTED);

if (__atomic_load_n(&hdl->inode->num_mmapped, __ATOMIC_ACQUIRE) == 0)
return;

int refresh_ret = prot_refresh_mmaped_from_file_handle(hdl, new_file_size);
if (refresh_ret < 0) {
log_error("refreshing page protections of mmapped regions of file failed: %s",
unix_strerror(refresh_ret));
BUG();
}

if (!reload_file_contents)
return;

int reload_ret = reload_mmaped_from_file_handle(hdl);
if (reload_ret < 0) {
log_error("reload mmapped regions of file failed: %s", unix_strerror(reload_ret));
BUG();
}
}

BEGIN_CP_FUNC(vma) {
__UNUSED(size);
assert(size == sizeof(struct libos_vma_info));
Expand Down
29 changes: 2 additions & 27 deletions libos/src/fs/chroot/encrypted.c
Original file line number Diff line number Diff line change
Expand Up @@ -491,23 +491,7 @@ static ssize_t chroot_encrypted_write(struct libos_handle* hdl, const void* buf,
size_t new_size = hdl->inode->size;
unlock(&hdl->inode->lock);

if (__atomic_load_n(&hdl->inode->num_mmapped, __ATOMIC_ACQUIRE) != 0) {
/* There are mappings for the file, refresh their access protections. */
ret = prot_refresh_mmaped_from_file_handle(hdl, new_size);
if (ret < 0) {
log_error("refreshing page protections of mmapped regions of file failed: %s",
unix_strerror(ret));
BUG();
}

/* There are mappings for the file, read data from `enc` (only for MAP_SHARED mappings). */
ret = reload_mmaped_from_file_handle(hdl);
if (ret < 0) {
log_error("reload mmapped regions of file failed: %s", unix_strerror(ret));
BUG();
}
}

refresh_mappings_on_file(hdl, new_size, /*reload_file_contents=*/true);
return (ssize_t)actual_count;
}

Expand All @@ -532,16 +516,7 @@ static int chroot_encrypted_truncate(struct libos_handle* hdl, file_off_t size)
hdl->inode->size = size;
unlock(&hdl->inode->lock);

if (__atomic_load_n(&hdl->inode->num_mmapped, __ATOMIC_ACQUIRE) != 0) {
/* There are mappings for the file, refresh their access protections. */
ret = prot_refresh_mmaped_from_file_handle(hdl, size);
if (ret < 0) {
log_error("refreshing page protections of mmapped regions of file failed: %s",
unix_strerror(ret));
BUG();
}
}

refresh_mappings_on_file(hdl, size, /*reload_file_contents=*/false);
return 0;
}

Expand Down
18 changes: 1 addition & 17 deletions libos/src/fs/chroot/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,23 +246,7 @@ static ssize_t chroot_write(struct libos_handle* hdl, const void* buf, size_t co
unlock(&hdl->inode->lock);
}

if (__atomic_load_n(&hdl->inode->num_mmapped, __ATOMIC_ACQUIRE) != 0) {
/* There are mappings for the file, refresh their access protections. */
ret = prot_refresh_mmaped_from_file_handle(hdl, new_size);
if (ret < 0) {
log_error("refreshing page protections of mmapped regions of file failed: %s",
unix_strerror(ret));
BUG();
}

/* There are mappings for the file, read data from `hdl` (only for MAP_SHARED mappings). */
ret = reload_mmaped_from_file_handle(hdl);
if (ret < 0) {
log_error("reload mmapped regions of file failed: %s", unix_strerror(ret));
BUG();
}
}

refresh_mappings_on_file(hdl, new_size, /*reload_file_contents=*/true);
return (ssize_t)actual_count;
}

Expand Down
11 changes: 1 addition & 10 deletions libos/src/fs/libos_fs_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -270,15 +270,6 @@ int generic_truncate(struct libos_handle* hdl, file_off_t size) {
hdl->inode->size = size;
unlock(&hdl->inode->lock);

if (__atomic_load_n(&hdl->inode->num_mmapped, __ATOMIC_ACQUIRE) != 0) {
/* There are mappings for the file, refresh their access protections. */
ret = prot_refresh_mmaped_from_file_handle(hdl, size);
if (ret < 0) {
log_error("refreshing page protections of mmapped regions of file failed: %s",
unix_strerror(ret));
BUG();
}
}

refresh_mappings_on_file(hdl, size, /*reload_file_contents=*/false);
return 0;
}
29 changes: 2 additions & 27 deletions libos/src/fs/tmpfs/fs.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,23 +274,7 @@ static ssize_t tmpfs_write(struct libos_handle* hdl, const void* buf, size_t siz
size_t new_size = inode->size;
unlock(&inode->lock);

if (__atomic_load_n(&hdl->inode->num_mmapped, __ATOMIC_ACQUIRE) != 0) {
/* There are mappings for the file, refresh their access protections. */
int refresh_ret = prot_refresh_mmaped_from_file_handle(hdl, new_size);
if (refresh_ret < 0) {
log_error("refreshing page protections of mmapped regions of file failed: %s",
unix_strerror(refresh_ret));
BUG();
}

/* There are mappings for the file, read data from `hdl` (only for MAP_SHARED mappings). */
int reload_ret = reload_mmaped_from_file_handle(hdl);
if (reload_ret < 0) {
log_error("reload mmapped regions of file failed: %s", unix_strerror(reload_ret));
BUG();
}
}

refresh_mappings_on_file(hdl, new_size, /*reload_file_contents=*/true);
return ret;
}

Expand All @@ -314,16 +298,7 @@ static int tmpfs_truncate(struct libos_handle* hdl, file_off_t size) {
hdl->inode->size = size;
unlock(&hdl->inode->lock);

if (__atomic_load_n(&hdl->inode->num_mmapped, __ATOMIC_ACQUIRE) != 0) {
/* There are mappings for the file, refresh their access protections. */
ret = prot_refresh_mmaped_from_file_handle(hdl, size);
if (ret < 0) {
log_error("refreshing page protections of mmapped regions of file failed: %s",
unix_strerror(ret));
BUG();
}
}

refresh_mappings_on_file(hdl, size, /*reload_file_contents=*/false);
return 0;
}

Expand Down

0 comments on commit a9d08fd

Please sign in to comment.