All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

Commit af74008b authored by Charlie Jacobsen's avatar Charlie Jacobsen Committed by Vikram Narayanan

PMFS isolation: full init operational (minus function pointers).

bdi init/destroy in place. Fixed some data store bugs.

file system type function pointers not set up yet. Need to figure out
strategy for handling them (during mount).
parent 9e842950
......@@ -10,6 +10,7 @@
#include <linux/kernel.h>
#include <asm/page.h>
#include <linux/bug.h>
/* CPTRs -------------------------------------------------- */
......@@ -98,6 +99,50 @@ static inline unsigned long lcd_cptr_level(cptr_t c)
return i;
}
static inline cptr_t lcd_cptr_set_slot(cptr_t c, unsigned slot)
{
BUG_ON(slot >= (1 << LCD_CPTR_SLOT_BITS));
return __cptr(cptr_val(c) | slot);
}
static inline cptr_t lcd_cptr_set_fanout(cptr_t c, unsigned fanout_idx,
int lvl)
{
BUG_ON(lvl >= (1 << LCD_CPTR_DEPTH_BITS));
BUG_ON(fanout_idx >= (1 << LCD_CPTR_FANOUT_BITS));
return __cptr(cptr_val(c) |
(fanout_idx << (LCD_CPTR_SLOT_BITS +
lvl * LCD_CPTR_FANOUT_BITS)));
}
static inline cptr_t lcd_cptr_set_lvl(cptr_t c, int lvl)
{
BUG_ON(lvl >= (1 << LCD_CPTR_DEPTH_BITS));
return __cptr(cptr_val(c) | (lvl << LCD_CPTR_LEVEL_SHIFT));
}
static inline cptr_t mk_cptr(unsigned long lvl,
unsigned long fanouts[(1 << LCD_CPTR_DEPTH_BITS) - 1],
unsigned long slot)
{
unsigned long result = 0;
int i;
result |= lvl << LCD_CPTR_LEVEL_SHIFT;
for (i = 0; i < lvl; i++) {
result |=
(fanouts[i] <<
(lvl * LCD_CPTR_FANOUT_BITS +
LCD_CPTR_SLOT_BITS));
}
result |= slot;
return __cptr(result);
}
/* CPTR CACHE -------------------------------------------------- */
struct cptr_cache {
......
......@@ -338,6 +338,12 @@ static void lcd_free_dptr(struct dptr_cache *dptr_cache, dptr_t d)
/* DATA STORE -------------------------------------------------- */
/*
* This is used in a hack to make the cnode table slab caches
* work. See init cspace routine.
*/
static u64 dstore_id = 0;
static int make_empty_dstore_node_table(struct dstore *dstore,
uint8_t level,
struct dstore_node_table **new_out)
......@@ -385,6 +391,7 @@ int lcd_dstore_init_dstore(struct dstore **out)
{
int ret;
struct dstore *dstore;
char name[32];
/*
* Alloc
......@@ -410,9 +417,20 @@ int lcd_dstore_init_dstore(struct dstore **out)
INIT_LIST_HEAD(&dstore->table_list);
/*
* Initialize the dstore node table cache
* Initialize the dstore node table cache. We can't use the
* KMEM_CACHE macro because we need to use unique names. This
* is kind of hacky right now. (If you don't use a unique name,
* you might get an error/crash when you destroy the kmem cache
* for multiple lcd's. This is because slabs are tied to sysfs, and
* it complains when it tries to remove slabs with the same name.)
*/
dstore->dstore_node_table_cache = KMEM_CACHE(dstore_node_table, 0);
snprintf(name, 32, "dstore%llu", dstore_id);
dstore->dstore_node_table_cache = kmem_cache_create(
name,
sizeof(struct dstore_node_table),
__alignof__(struct dstore_node_table),
0,
NULL);
if(!dstore->dstore_node_table_cache) {
LIBLCD_ERR("failed to allocate dstore_node_table slab");
ret = -ENOMEM;
......@@ -438,6 +456,11 @@ int lcd_dstore_init_dstore(struct dstore **out)
}
*out = dstore;
/*
* Inc dstore id for next time
*/
dstore_id++;
return 0;
......
......@@ -14,8 +14,9 @@ static int boot_main(void)
struct lcd_info *mi;
cptr_t lcd;
cptr_t vfs;
cptr_t endpoint;
cptr_t dest1, dest2;
cptr_t vfs_chnl, bdi_chnl;
cptr_t pmfs_dest1, pmfs_dest2;
cptr_t vfs_dest1, vfs_dest2;
/*
* Enter lcd mode
......@@ -23,17 +24,25 @@ static int boot_main(void)
ret = lcd_enter();
if (ret) {
LIBLCD_ERR("enter");
goto fail1;
goto out;
}
/*
* Create VFS channel
*/
ret = lcd_create_sync_endpoint(&endpoint);
ret = lcd_create_sync_endpoint(&vfs_chnl);
if (ret) {
LIBLCD_ERR("create endpoint");
goto fail2;
LIBLCD_ERR("create vfs endpoint");
goto lcd_exit;
}
/*
* Create bdi channel
*/
ret = lcd_create_sync_endpoint(&bdi_chnl);
if (ret) {
LIBLCD_ERR("create bdi endpoint");
goto lcd_exit;
}
/* CREATE LCDS -------------------------------------------------- */
/*
......@@ -42,7 +51,7 @@ static int boot_main(void)
ret = klcd_create_module_klcd(&vfs, "lcd_test_mod_pmfs_vfs");
if (ret) {
LIBLCD_ERR("create vfs klcd");
goto fail2;
goto lcd_exit;
}
/*
* Create pmfs lcd
......@@ -51,38 +60,61 @@ static int boot_main(void)
LCD_CPTR_NULL, &mi);
if (ret) {
LIBLCD_ERR("create module lcd");
goto fail3;
goto destroy_vfs;
}
/* GRANT ENDPOINT TO PMFS ------------------------------ */
/* GRANT ENDPOINTS TO PMFS ------------------------------ */
/*
* Alloc dest slot
*/
ret = __lcd_alloc_cptr(mi->cache, &dest1);
ret = __lcd_alloc_cptr(mi->cache, &pmfs_dest1);
if (ret) {
LIBLCD_ERR("failed to alloc cptr");
goto fail4;
goto destroy_both;
}
/*
* Grant
*/
ret = lcd_cap_grant(lcd, endpoint, dest1);
ret = lcd_cap_grant(lcd, vfs_chnl, pmfs_dest1);
if (ret) {
LIBLCD_ERR("failed to grant endpoint to lcd1");
goto fail5;
LIBLCD_ERR("failed to grant vfs endpoint to pmfs");
goto destroy_both;
}
/*
* Alloc dest slot
*/
ret = __lcd_alloc_cptr(mi->cache, &pmfs_dest2);
if (ret) {
LIBLCD_ERR("failed to alloc cptr");
goto destroy_both;
}
/*
* Grant
*/
ret = lcd_cap_grant(lcd, bdi_chnl, pmfs_dest2);
if (ret) {
LIBLCD_ERR("failed to grant bdi endpoint to pmfs");
goto destroy_both;
}
/* GRANT ENDPOINT TO VFS ------------------------------ */
/* GRANT ENDPOINTS TO VFS ------------------------------ */
dest2 = __cptr(3);
ret = lcd_cap_grant(vfs, endpoint, dest2);
vfs_dest1 = __cptr(3);
ret = lcd_cap_grant(vfs, vfs_chnl, vfs_dest1);
if (ret) {
LIBLCD_ERR("failed to grant endpoint to vfs");
goto fail6;
LIBLCD_ERR("failed to grant vfs endpoint to vfs");
goto destroy_both;
}
vfs_dest2 = lcd_cptr_set_lvl(__cptr(0), 1);
vfs_dest2 = lcd_cptr_set_fanout(vfs_dest2, 0, 0);
vfs_dest2 = lcd_cptr_set_slot(vfs_dest2, 0);
ret = lcd_cap_grant(vfs, bdi_chnl, vfs_dest2);
if (ret) {
LIBLCD_ERR("failed to grant bdi endpoint to vfs");
goto destroy_both;
}
/* DUMP BOOT INFO FOR PMFS ------------------------------ */
/*
......@@ -91,9 +123,10 @@ static int boot_main(void)
ret = lcd_dump_boot_info(mi);
if (ret) {
LIBLCD_ERR("dump boot info");
goto fail7;
goto destroy_both;
}
to_boot_info(mi)->cptrs[0] = dest1;
to_boot_info(mi)->cptrs[0] = pmfs_dest1;
to_boot_info(mi)->cptrs[1] = pmfs_dest2;
/* RUN -------------------------------------------------- */
......@@ -103,7 +136,7 @@ static int boot_main(void)
ret = lcd_run(vfs);
if (ret) {
LIBLCD_ERR("run vfs");
goto fail8;
goto destroy_both;
}
/*
* Run pmfs
......@@ -111,7 +144,7 @@ static int boot_main(void)
ret = lcd_run(lcd);
if (ret) {
LIBLCD_ERR("run pmfs");
goto fail9;
goto destroy_both;
}
/*
* Wait for 2 seconds
......@@ -121,22 +154,16 @@ static int boot_main(void)
* Tear everything down
*/
ret = 0;
goto out;
goto destroy_both;
out:
fail9:
fail8:
fail7:
fail6:
fail5:
fail4:
destroy_both:
lcd_destroy_module_lcd(lcd, mi, LCD_CPTR_NULL);
fail3:
destroy_vfs:
klcd_destroy_module_klcd(vfs, "lcd_test_mod_pmfs_vfs");
fail2:
lcd_exit:
/* frees endpoint */
lcd_exit(0);
fail1:
out:
return ret;
}
......
/*
* bdi_caller.c - caller side of bdi interface
*/
#include <linux/backing-dev.h>
#include <lcd-domains/liblcd.h>
#include "../internal.h"
int bdi_init(struct backing_dev_info *bdi)
static cptr_t bdi_chnl;
static struct dstore *bdi_dstore;
//static struct dispatch_ctx *loop_ctx;
/* INIT/EXIT -------------------------------------------------- */
int glue_bdi_init(cptr_t _bdi_channel, struct dispatch_ctx *ctx)
{
int ret;
/* Store a reference to the dispatch loop context, so we
* can dynamically add channels to the loop later. */
// loop_ctx = ctx;
/* Store reference to bdi channel so we can invoke functions
* on it later. */
bdi_chnl = _bdi_channel;
/* Initialize data store. */
ret = lcd_dstore_init_dstore(&bdi_dstore);
if (ret) {
LIBLCD_ERR("dstore init");
return ret;
}
return 0;
}
void glue_bdi_exit(void)
{
/*
* Free bdi data store
*/
lcd_dstore_destroy(bdi_dstore);
}
/* CALLER FUNCTIONS -------------------------------------------------- */
int bdi_init(struct backing_dev_info *bdi)
{
struct backing_dev_info_container *bdi_container;
int ret;
/*
* Get container
*/
bdi_container = container_of(bdi,
struct backing_dev_info_container,
backing_dev_info);
/*
* INSERT INTO DATA STORE ------------------------------
*
*/
ret = lcd_dstore_insert(bdi_dstore,
bdi_container,
STRUCT_BACKING_DEV_INFO_TAG,
&bdi_container->my_ref);
if (ret) {
LIBLCD_ERR("lcd_dstore_insert");
lcd_exit(ret); /* abort */
}
/*
* IPC MARSHALING --------------------------------------------------
*
*/
lcd_set_r1(dptr_val(bdi_container->my_ref));
lcd_set_r2(bdi_container->backing_dev_info.ra_pages);
lcd_set_r3(bdi_container->backing_dev_info.capabilities);
/*
* IPC CALL ----------------------------------------
*/
lcd_set_r0(BDI_INIT);
ret = lcd_call(bdi_chnl);
if (ret) {
LIBLCD_ERR("lcd_call");
lcd_exit(ret);
}
/* IPC UNMARSHALING ---------------------------------------- */
/*
* We expect a remote ref coming back
*/
bdi_container->bdi_ref = __dptr(lcd_r1());
/* Clear capability register */
lcd_set_cr1(LCD_CPTR_NULL);
/*
* Pass back return value
*/
return lcd_r0();
}
void bdi_destroy(struct backing_dev_info *bdi)
{
return;
int ret;
struct backing_dev_info_container *bdi_container;
bdi_container = container_of(bdi,
struct backing_dev_info_container,
backing_dev_info);
/* IPC MARSHALING ---------------------------------------- */
/*
* Pass remote ref to bdi's copy
*/
lcd_set_r1(dptr_val(bdi_container->bdi_ref));
/* IPC CALL ---------------------------------------- */
lcd_set_r0(BDI_DESTROY);
ret = lcd_call(bdi_chnl);
if (ret) {
LIBLCD_ERR("lcd_call");
lcd_exit(ret);
}
/* POST-IPC ---------------------------------------- */
/*
* Remove bdi from data store
*/
lcd_dstore_delete(bdi_dstore, bdi_container->my_ref);
/*
* (no return value)
*/
}
......@@ -143,8 +143,6 @@ int unregister_filesystem(struct file_system_type *fs)
/* IPC CALL ---------------------------------------- */
LIBLCD_MSG("calling unregister fs");
lcd_set_r0(UNREGISTER_FS);
ret = lcd_call(vfs_chnl);
if (ret) {
......@@ -152,8 +150,6 @@ int unregister_filesystem(struct file_system_type *fs)
lcd_exit(ret);
}
LIBLCD_MSG("done");
/* POST-IPC ---------------------------------------- */
/*
......
......@@ -7,6 +7,7 @@
#include <lcd-domains/liblcd-config.h>
#include <linux/fs.h>
#include <linux/backing-dev.h>
#include <lcd-domains/liblcd.h>
#include <lcd-domains/dispatch_loop.h>
......@@ -18,10 +19,13 @@
/* Data store flags */
#define STRUCT_FILE_SYSTEM_TYPE_TAG 2
#define STRUCT_BACKING_DEV_INFO_TAG 3
/* Function flags */
#define REGISTER_FS 1
#define UNREGISTER_FS 2
#define BDI_INIT 3
#define BDI_DESTROY 4
/* STRUCT DEFS -------------------------------------------------- */
......@@ -32,11 +36,22 @@ struct file_system_type_container {
struct ipc_channel chnl;
};
struct backing_dev_info_container {
struct backing_dev_info backing_dev_info;
dptr_t my_ref;
dptr_t bdi_ref;
/* no channel since pmfs doesn't implement function ptrs */
};
/* FUNCTIONS -------------------------------------------------- */
int glue_vfs_init(cptr_t _vfs_channel, struct dispatch_ctx *ctx);
void glue_vfs_exit(void);
int glue_bdi_init(cptr_t _bdi_channel, struct dispatch_ctx *ctx);
void glue_bdi_exit(void);
#endif /* PMFS_LCD_INTERNAL_H */
......@@ -86,6 +86,7 @@ static int __noreturn __init pmfs_lcd_init(void)
{
int r = 0;
cptr_t vfs_chnl;
// cptr_t bdi_chnl;
r = lcd_enter();
if (r)
......@@ -95,27 +96,38 @@ static int __noreturn __init pmfs_lcd_init(void)
*/
init_dispatch_ctx(&ctx);
/*
* Get the vfs channel cptr from boot info
* Get the vfs and bdi channel cptrs from boot info
*/
vfs_chnl = lcd_get_boot_info()->cptrs[0];
// bdi_chnl = lcd_get_boot_info()->cptrs[1];
/*
* Initialize vfs glue
*/
r = glue_vfs_init(vfs_chnl, &ctx);
if (r) {
LIBLCD_ERR("vfs init");
goto fail1;
goto fail2;
}
/*
* Initialize bdi glue
*/
r = glue_bdi_init(vfs_chnl, &ctx);
if (r) {
LIBLCD_ERR("bdi init");
goto fail3;
}
/* EXECUTE REAL CODE ---------------------------------------- */
/*
* Initialize pmfs
*/
r = init_pmfs_fs();
if (r)
goto fail1;
goto fail4;
LIBLCD_ERR("SUCCESSFULLY REGISTERED PMFS!");
LIBLCD_MSG("SUCCESSFULLY REGISTERED PMFS!");
// loop(&ctx);
......@@ -125,8 +137,20 @@ static int __noreturn __init pmfs_lcd_init(void)
exit_pmfs_fs();
LIBLCD_ERR("SUCCESSFULLY UNREGISTERED PMFS!");
LIBLCD_MSG("SUCCESSFULLY UNREGISTERED PMFS!");
/* REAL CODE DONE; CLEAN UP ---------------------------------------- */
glue_vfs_exit();
glue_bdi_exit();
lcd_exit(0); /* doesn't return */
fail4:
glue_bdi_exit();
fail3:
glue_vfs_exit();
fail2:
fail1:
lcd_exit(r);
}
......
......@@ -25,11 +25,25 @@
#include "pmfs.h"
#include "xip.h"
#ifdef LCD_ISOLATE
struct backing_dev_info_container
pmfs_backing_dev_info_container __read_mostly = {
.backing_dev_info = {
.ra_pages = 0, /* No readahead */
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
},
};
#else /* !LCD_ISOLATE */
struct backing_dev_info pmfs_backing_dev_info __read_mostly = {
.ra_pages = 0, /* No readahead */
.capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK,
};
#endif /* LCD_ISOLATE */
unsigned int blk_type_to_shift[PMFS_BLOCK_TYPE_MAX] = {12, 21, 30};
uint32_t blk_type_to_size[PMFS_BLOCK_TYPE_MAX] = {0x1000, 0x200000, 0x40000000};
......@@ -857,8 +871,18 @@ static int pmfs_read_inode(struct inode *inode, struct pmfs_inode *pi)
inode->i_blocks = le64_to_cpu(pi->i_blocks);
inode->i_mapping->a_ops = &pmfs_aops_xip;
#ifdef LCD_ISOLATE
inode->i_mapping->backing_dev_info =
&pmfs_backing_dev_info_container.backing_dev_info;
#else /* !LCD_ISOLATE */
inode->i_mapping->backing_dev_info = &pmfs_backing_dev_info;
#endif /* LCD_ISOLATE */
switch (inode->i_mode & S_IFMT) {
case S_IFREG:
inode->i_op = &pmfs_file_inode_operations;
......
......@@ -21,6 +21,7 @@
#include <linux/pagemap.h>
#include <linux/rcupdate.h>
#include <linux/types.h>
#include <linux/backing-dev.h>
#include "journal.h"
......@@ -601,8 +602,22 @@ extern const struct inode_operations pmfs_special_inode_operations;
/* symlink.c */
extern const struct inode_operations pmfs_symlink_inode_operations;
#ifdef LCD_ISOLATE
struct backing_dev_info_container {
struct backing_dev_info backing_dev_info;
u64 ref1;
u64 ref2;
};
extern struct backing_dev_info_container pmfs_backing_dev_info_container;
#else /* !LCD_ISOLATE */
extern struct backing_dev_info pmfs_backing_dev_info;
#endif /* LCD_ISOLATE */