From: alebre <al...@us...> - 2010-10-02 12:55:57
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "kdfs". The branch, make_kdfs_compile has been updated via 93feb2aa398019d78a5e95bd501ee47eb82e5031 (commit) via b626068cf8bf47e0c962b6d764d61370d8d83f1c (commit) from c97311254a567ed0ead630ce8f2e681c81c70478 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 93feb2aa398019d78a5e95bd501ee47eb82e5031 Author: ad <leb...@fr...> Date: Sat Oct 2 06:00:40 2010 +0000 Fix implicit striping for meta-data, please note that page management is still unstable diff --git a/fs/kdfs/address_space.c b/fs/kdfs/address_space.c index 008b62b..79ddff4 100644 --- a/fs/kdfs/address_space.c +++ b/fs/kdfs/address_space.c @@ -63,6 +63,17 @@ int kdfs_content_writephyspage(struct content_iolinker_data *content_data, return 0; } +int kdfs_content_readphyspage(struct content_iolinker_data *content_data, + char *page_addr, loff_t pos) +{ + int res = 0; + + kdfs_phys_read(content_data->phys_file, page_addr, PAGE_CACHE_SIZE, &pos); + + PRINT_FUNCTION_EXIT; + return res; +} + /*****************************************************************************/ /* */ /* ADDRESS SPACE OPERATIONS */ @@ -259,7 +270,7 @@ void kdfs_invalidatepage(struct page *page, unsigned long offset) DEBUG(DBG_INFO, "Gonna invalidate page %ld (objid %ld from set %ld)\n", page->index, k_page->obj_id,k_page->set_id); kddm_remove_object(kddm_def_ns, k_page->set_id, k_page->obj_id); - set_page_private(page, NULL); + set_page_private(page, 0); ClearPagePrivate(page); } PRINT_FUNCTION_EXIT; @@ -283,7 +294,7 @@ int kdfs_releasepage(struct page *page, gfp_t mask) /* There is only one copy, so we should exploit remove instead of flush */ kddm_remove_object(kddm_def_ns, k_page->set_id, k_page->obj_id); - set_page_private(page, NULL); + set_page_private(page, 0); ClearPagePrivate(page); PRINT_FUNCTION_EXIT; @@ -374,7 +385,6 @@ struct kdfs_page *kdfs_grab_distpage(struct kdfs_inode *k_inode, pgoff_t page_id return k_newpage; } - struct kdfs_page *kdfs_grab_page(kddm_set_id_t set_id, objid_t obj_id) { @@ -460,71 +470,35 @@ kddm_set_t *__create_content_kddm_set(kddm_set_id_t set_id, return kddm_set; } -int __kddm_set_local_destroy(int nsid, int setid) -{ - struct kddm_ns *ns; - struct kddm_set *kddm_set; - - /* Remove the kddm set from the name space */ - ns = kddm_ns_get (nsid); - if (ns == NULL) - return -EINVAL; - - kddm_set = hashtable_remove(ns->kddm_set_table, setid); - kddm_ns_put (ns); - - if (kddm_set == NULL) - return -EINVAL; - - put_kddm_set(kddm_set); - return 0; -} +/*****************************************************************************/ +/* */ +/* ADDRESS IO LINKER PART */ +/* (exploited for dir and file io-linkers) */ +/* (Latest code verification - April, 2010 - Adrien) */ +/*****************************************************************************/ /* - * Destroy the local instance of a content kddm_set (internal function) - * @author Adrien Lebre + * Determine the owner for a particular page. + * If the page has not been yet allocated, the page will be stored locally. + * @author Adrien Lebre * - * @param k_inode Inode associated with this 'content' set - * @return O if everything was ok + * @param kddm_set Container descriptor + * @param objid inode Id. */ -int __local_destroy_content_kddm_set(struct kdfs_inode *k_inode) +kerrighed_node_t kdfs_iol_page_default_owner (kddm_set_t *kddm_set, + objid_t objid, + const krgnodemask_t *nodes, + int nr_nodes) { - kddm_set_t *kddm_set = NULL; - - PRINT_FUNCTION_NAME; - - kddm_set = _local_get_kddm_set(kddm_def_ns, k_inode->content_setid); - if (!kddm_set) - DEBUG(DBG_INFO, "The associated kddm_set for inode %ld hasn't been instantiated\n", k_inode->inode->i_ino); - else{ - /* - * TODO PRIORITY 1, Adrien / (Renaud kDDM stuff) - * According to the function __handle_req_kddm_set_destroy - * http://lxr.kerlabs.com/kerrighed/source/modules/ctnr/kddm_set.c#650 - * I have to first remove the set from the local namespace and then - * free the kddm_set struct. - * Currently, I implemented the following function - * which is approximately a copy/paste of the __handle_req_kddm_set_destroy - * function. - */ - __kddm_set_local_destroy(KDDM_DEF_NS_ID, k_inode->content_setid); - - /* - * Free the kddm set structure (second call, count will reach 0 - * and the set structure will be freed) - */ - put_kddm_set(kddm_set); - } - PRINT_FUNCTION_EXIT; - return 0; + kerrighed_node_t ret_val; + + // check who's the default owner of the object !!! + ret_val = page_linked_node(objid); + + DEBUG(DBG_DBG, "######### /\\/\\/\\/ page owner ::: %d\n", ret_val); + return ret_val; } -/*****************************************************************************/ -/* */ -/* ADDRESS IO LINKER PART */ -/* (exploited for dir and file io-linkers) */ -/* (Latest code verification - April, 2010 - Adrien) */ -/*****************************************************************************/ /* * Allocate a kdfs_page object @@ -776,7 +750,7 @@ int kdfs_iol_page_invalidate(kddm_obj_t *objEntry, kddm_set_t *set, trylock_page(k_page->page); remove_from_page_cache(k_page->page); - set_page_private(page, NULL); + set_page_private(k_page->page, 0); ClearPagePrivate(k_page->page); unlock_page(k_page->page); page_cache_release(k_page->page); @@ -878,7 +852,7 @@ int kdfs_iol_page_put(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) } /* - * I/O linker function called when a page is removed + * I/O linker function called when a page is remove from the cache * @author Pierre Riteau * * @param objEntry page to remove @@ -919,7 +893,7 @@ int kdfs_iol_page_remove(void *object, struct kddm_set *set, objid_t objid) * * @return error code or 0 if everything was ok. */ -int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) +int kdfs_iol_content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) { struct content_iolinker_data *content_data = NULL; struct inode *inode = NULL; @@ -982,17 +956,12 @@ int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) content_data->phys_file = NULL; } - /* TODO PRIORITY 2, Adrien, we could have some issue if the kernel tries to remove the inode during this code */ /* Retrieve the local ref to the k_mapping object */ inode = ilookup(k_sb->sb, content_data->ino); if (inode) { DEBUG(DBG_INFO, "K_mapping from the cache\n"); content_data->k_mapping = inode->i_mapping; iput(inode); - } else if (inode_linked_node(content_data->ino) == kerrighed_node_id){ - DEBUG(DBG_PANIC, "K_mapping will be retrieve from iget, however this should not occur\n"); -// inode = kdfs_getinode(k_sb->sb, content_data->ino); - content_data->k_mapping = inode->i_mapping; } else { /* do dummy stuff */ DEBUG(DBG_INFO, "K_mapping exploits a dummy inode\n"); @@ -1016,31 +985,24 @@ int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) * * @param kddm_set kddm_set to uninstantiate */ -void content_uninstantiate(kddm_set_t *kddm_set, int destroy) +void kdfs_iol_content_uninstantiate(kddm_set_t *kddm_set, int destroy) { struct content_iolinker_data *content_data; - PRINT_FUNCTION_NAME; ASSERT(kddm_set != NULL); ASSERT(kddm_set->private_data != NULL); content_data = (struct content_iolinker_data *) kddm_set->private_data; - if (content_data->phys_dirname != NULL) - kfree(content_data->phys_dirname); + if (content_data->phys_dirname != NULL) { + DEBUG (DBG_TRACE, "uninstantiate content kddm_set link to inode %ld (physical file:%s)", + content_data->ino,content_data->phys_dirname); + kfree(content_data->phys_dirname); + } if (content_data->phys_file != NULL) close_phys_file(content_data->phys_file); PRINT_FUNCTION_EXIT; } -int kdfs_content_readphyspage(struct content_iolinker_data *content_data, - char *page_addr, loff_t pos) -{ - int res = 0; - - kdfs_phys_read(content_data->phys_file, page_addr, PAGE_CACHE_SIZE, &pos); - PRINT_FUNCTION_EXIT; - return res; -} diff --git a/fs/kdfs/address_space.h b/fs/kdfs/address_space.h index fd06436..ccc332a 100644 --- a/fs/kdfs/address_space.h +++ b/fs/kdfs/address_space.h @@ -135,6 +135,7 @@ void __kdfs_put_page(kddm_set_id_t set_id, objid_t obj_id); void kdfs_distmark_page_dirty(struct kdfs_inode *k_inode, pgoff_t page_id); void kdfs_mark_page_dirty(kddm_set_id_t set_id, objid_t obj_id); +kerrighed_node_t kdfs_iol_page_default_owner (kddm_set_t *kddm_set, objid_t objid, const krgnodemask_t *nodes, int nr_nodes); int kdfs_iol_page_alloc(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid); int kdfs_iol_page_first_touch(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid, int flags); int kdfs_iol_page_insert(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid); @@ -144,14 +145,14 @@ int kdfs_iol_page_import (struct rpc_desc *desc, struct kddm_set *set, struct kd int kdfs_iol_page_sync(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid); int kdfs_iol_page_put(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid); int kdfs_iol_page_remove(void *object, struct kddm_set *set, objid_t objid); + kddm_set_t *__create_content_kddm_set(kddm_set_id_t set_id, kerrighed_node_t linked_node, struct kdfs_inode *k_inode, iolinker_id_t type); -int __local_destroy_content_kddm_set(struct kdfs_inode *k_inode); -int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master); -void content_uninstantiate(kddm_set_t *kddm_set, int destroy); +int kdfs_iol_content_instantiate(kddm_set_t *kddm_set, void *private_data, int master); +void kdfs_iol_content_uninstantiate(kddm_set_t *kddm_set, int destroy); /*--------------------------------------------------------------------------* * * diff --git a/fs/kdfs/dir.c b/fs/kdfs/dir.c index c0d0e0b..b378577 100644 --- a/fs/kdfs/dir.c +++ b/fs/kdfs/dir.c @@ -778,8 +778,9 @@ kddm_set_t *create_dir_kddm_set(struct kdfs_inode *dir) ASSERT(dir != NULL); ASSERT(dir->inode != NULL); - - kddm_set = __create_content_kddm_set(0, inode_linked_node(dir->inode->i_ino), dir, DIR_LINKER); +// Enable distributed directory management - Adrien +// kddm_set = __create_content_kddm_set(0, inode_linked_node(dir->inode->i_ino), dir, DIR_LINKER); + kddm_set = __create_content_kddm_set(0, KDDM_CUSTOM_DEF_OWNER, dir, DIR_LINKER); if (!IS_ERR(kddm_set)) { dir->content_setid = kddm_set->id; DEBUG(DBG_TRACE, @@ -811,24 +812,15 @@ kddm_set_t *create_dir_kddm_set(struct kdfs_inode *dir) */ int dir_instantiate (kddm_set_t *kddm_set, void *private_data, int master) { - return content_instantiate(kddm_set, private_data, master); -} - -/* - * Uninstantiate a directory container. - * @author Adrien Lebre - * - * @param kddm_set kddm_set to uninstantiate - * @param destroy ??? - */ -void dir_uninstantiate (kddm_set_t *kddm_set, int destroy) -{ - content_uninstantiate(kddm_set, destroy); + return kdfs_iol_content_instantiate(kddm_set, private_data, master); } /* Init the dir IO linker */ struct iolinker_struct dir_io_linker = { .alloc_object = kdfs_iol_page_alloc, +#if KDFS_FILE_STRIPING + .default_owner = kdfs_iol_page_default_owner, +#endif .export_object = kdfs_iol_page_export, .first_touch = kdfs_iol_page_first_touch, .import_object = kdfs_iol_page_import, @@ -840,5 +832,5 @@ struct iolinker_struct dir_io_linker = { // .put_object = kdfs_iol_page_put, .remove_object = kdfs_iol_page_remove, .sync_object = kdfs_iol_page_sync, - .uninstantiate = dir_uninstantiate, + .uninstantiate = kdfs_iol_content_uninstantiate, }; diff --git a/fs/kdfs/file.c b/fs/kdfs/file.c index 1fe9e23..4f6b131 100644 --- a/fs/kdfs/file.c +++ b/fs/kdfs/file.c @@ -250,28 +250,6 @@ kddm_set_t *create_file_kddm_set(struct kdfs_inode *k_inode) /*****************************************************************************/ /* - * Determine the owner for a particular page. - * If the page has not been yet allocated, the page will be stored locally. - * @author Adrien Lebre - * - * @param kddm_set Container descriptor - * @param objid inode Id. - */ -kerrighed_node_t kdfs_iol_file_default_owner (kddm_set_t *kddm_set, - objid_t objid, - const krgnodemask_t *nodes, - int nr_nodes) -{ - kerrighed_node_t ret_val; - - // check who's the default owner of the object !!! - ret_val = page_linked_node(objid); - - DEBUG(DBG_DBG, "######### /\\/\\/\\/ page owner ::: %d\n", ret_val); - return ret_val; -} - -/* * Instantiate a container with a file linker. * @author Adrien Lebre * @@ -282,24 +260,14 @@ kerrighed_node_t kdfs_iol_file_default_owner (kddm_set_t *kddm_set, */ int kdfs_iol_file_instantiate (kddm_set_t *kddm_set, void *private_data, int master) { - return content_instantiate(kddm_set, private_data, master); -} - -/** Uninstantiate a file container. - * @author Adrien Lebre - * - * @param kddm_set kddm_set to uninstantiate - */ -void kdfs_iol_file_uninstantiate (kddm_set_t *kddm_set, int destroy) -{ - content_uninstantiate(kddm_set, destroy); + return kdfs_iol_content_instantiate(kddm_set, private_data, master); } /* Init the file I/O linker */ struct iolinker_struct file_io_linker = { .alloc_object = kdfs_iol_page_alloc, #if KDFS_FILE_STRIPING - .default_owner = kdfs_iol_file_default_owner, + .default_owner = kdfs_iol_page_default_owner, #endif .export_object = kdfs_iol_page_export, .first_touch = kdfs_iol_page_first_touch, @@ -312,5 +280,5 @@ struct iolinker_struct file_io_linker = { // .put_object = kdfs_iol_page_put, .remove_object = kdfs_iol_page_remove, .sync_object = kdfs_iol_page_sync, - .uninstantiate = kdfs_iol_file_uninstantiate, + .uninstantiate = kdfs_iol_content_uninstantiate, }; diff --git a/fs/kdfs/file_extent.c b/fs/kdfs/file_extent.c index ae9f811..f3c0279 100644 --- a/fs/kdfs/file_extent.c +++ b/fs/kdfs/file_extent.c @@ -19,11 +19,24 @@ void kdfs_file_extent_init(struct kdfs_inode *k_inode) { - DEBUG(DBG_INFO, "INIT LIST\n"); + DEBUG(DBG_TRACE, "INIT LIST\n"); /* initialise the extents list */ INIT_LIST_HEAD(&k_inode->extents_list); } +void kdfs_file_extent_free(struct kdfs_inode *k_inode){ + struct kdfs_file_extent *curr, *next; + + DEBUG(DBG_TRACE, "FREE LIST\n"); + + if (!list_empty(&k_inode->extents_list)) { + list_for_each_entry_safe(curr,next, &k_inode->extents_list, list_item) { + kfree(curr); + } + } +} + + struct kdfs_file_extent *kdfs_file_extent_alloc(pgoff_t page_start, pgoff_t page_end, kdfs_node_t owner_id) { struct kdfs_file_extent *extent; diff --git a/fs/kdfs/file_extent.h b/fs/kdfs/file_extent.h index 6b2ea31..c55e5e8 100644 --- a/fs/kdfs/file_extent.h +++ b/fs/kdfs/file_extent.h @@ -17,6 +17,8 @@ void kdfs_file_extent_init(struct kdfs_inode *k_inode); +void kdfs_file_extent_free(struct kdfs_inode *k_inode); + struct kdfs_file_extent *kdfs_file_extent_alloc(pgoff_t page_start, pgoff_t page_end, kdfs_node_t owner_id); int kdfs_file_extent_find(struct list_head *extents, pgoff_t page_no, struct kdfs_file_extent **ext_before, struct kdfs_file_extent **ext_in, struct kdfs_file_extent **ext_after); diff --git a/fs/kdfs/inode.c b/fs/kdfs/inode.c index 18d557e..c1e21dd 100644 --- a/fs/kdfs/inode.c +++ b/fs/kdfs/inode.c @@ -961,31 +961,17 @@ struct kdfs_inode *kdfs_ilocalfind(unsigned long ino) } /* - * Flush the object somewhere else in the cluster or remove + * Flush the object locally or remove * the object from the kddm set if this is the last copy. */ void kdfs_idrop(unsigned long ino) { - kddm_obj_t *obj_entry; - PRINT_FUNCTION_NAME; - /* - * TODO NOW: Adrien & Pierre - * This test maybe should be done before, in super.c - * Check if the object is locked or not (from kddm point of view) - */ - - obj_entry = __get_kddm_obj_entry(kdfs_inode_kddm, ino); - if (OBJ_EXCLUSIVE2(COPYSET(obj_entry))) { - put_kddm_obj_entry(kdfs_inode_kddm, obj_entry, ino); - kddm_remove_frozen_object(kddm_def_ns, KDFS_INODE_KDDM_ID, ino); - } - else { - put_kddm_obj_entry(kdfs_inode_kddm, obj_entry, ino); - kddm_flush_object(kddm_def_ns, KDFS_INODE_KDDM_ID, ino, KERRIGHED_NODE_ID_NONE); - } - + if(kddm_flush_object(kddm_def_ns, KDFS_INODE_KDDM_ID, ino, KERRIGHED_NODE_ID_NONE) == -ENOSPC) + /* There is only one copy, so we should exploit remove instead of flush */ + kddm_remove_object(kddm_def_ns,KDFS_INODE_KDDM_ID, ino); + PRINT_FUNCTION_EXIT; } @@ -1026,7 +1012,6 @@ kerrighed_node_t kdfs_iol_inode_default_owner(kddm_set_t *kddm_set, objid_t obji /* * Allocate an object - * @author Renaud Lottiaux */ int kdfs_iol_inode_alloc_object (kddm_obj_t *objEntry, kddm_set_t *kddm_set, @@ -1066,7 +1051,7 @@ int kdfs_iol_inode_alloc_object (kddm_obj_t *objEntry, else { k_inode->inode = new_inode(k_sb->sb); k_inode->inode->i_ino = objid; - insert_inode_hash(k_inode->inode); +// insert_inode_hash(k_inode->inode); } k_inode->flags = K_INODE_INITIALIZING; @@ -1080,25 +1065,8 @@ int kdfs_iol_inode_alloc_object (kddm_obj_t *objEntry, } else { /* Object id has been already allocated so reused the same structure */ DEBUG(DBG_PANIC, "Object %ld was already allocated \n", objid); - //kdfs_inode = (struct kdfs_inode*) objEntry->object; // seems to be useless since we do not have to return the object } - /* TODO PRIORITY 3: Adrien - * interest of the following code inside the alloc function - */ -// if (inode_linked_node(objid) == kerrighed_node_id) { -// char *phys_dirname; -// /* Find the physical path corresponding to the KDFS inode */ -// phys_dirname = kmalloc(PATH_MAX, GFP_KERNEL); -// ASSERT(phys_dirname != NULL); -// -// kdfs_getphysicalpath(k_sb, objid, phys_dirname); -// if (check_create_phys_dir(phys_dirname, 0777, 0, 0) != 0) -// BUG(); -// -// kfree(phys_dirname); -// } -// __kdfs_twice_putsb(k_sb); PRINT_FUNCTION_EXIT; return 0; @@ -1143,12 +1111,15 @@ int kdfs_iol_inode_first_touch(kddm_obj_t *objEntry, */ // Case 1: it's a new file, so a new inode if (flags & KDDM_CREATE_ON_FT) { + // new_inode allocates a new inode and adds it into the list of + // used inodes for the related superblock + // Adding the inode into the local inode cache is done later into the kddm_iol_insert function k_inode->inode = new_inode (k_sb->sb); k_inode->flags = K_INODE_CREATING|K_INODE_INITIALIZING; if (k_inode->inode == NULL) DEBUG(DBG_PANIC, "Cannot find inode %ld\n", objid); k_inode->inode->i_ino = objid; - insert_inode_hash(k_inode->inode); + // insert_inode_hash(k_inode->inode); } // Case 2: the inode already exists, so fill it from the HDD else { @@ -1161,24 +1132,81 @@ int kdfs_iol_inode_first_touch(kddm_obj_t *objEntry, objEntry->object = (void *) k_inode; DEBUG(DBG_INFO, "inode count %d\n", atomic_read(&k_inode->inode->i_count)); -// if (inode_linked_node(objid) == kerrighed_node_id) { -// char *phys_dirname; -// /* Find the physical path corresponding to the KDFS inode */ -// phys_dirname = kmalloc(PATH_MAX, GFP_KERNEL); -// ASSERT(phys_dirname != NULL); -// -// kdfs_getphysicalpath(k_sb, objid, phys_dirname); -// if (check_create_phys_dir(phys_dirname, 0777, 0, 0) != 0) -// BUG(); -// kfree(phys_dirname); -// - __kdfs_twice_putsb(k_sb); PRINT_FUNCTION_EXIT; return 0; } /* + * Insert a copy of an inode. Update the inode struct. + * @author Adrien Lebre + * + * @param objEntry descriptor of the k_inode to insert. + * @param set kddm set descriptor + * @param objid Id of the k_inode object to insert. + */ +int kdfs_iol_inode_insert_object(kddm_obj_t *objEntry, + kddm_set_t *set, + objid_t objid) +{ + struct kdfs_inode *k_inode = (struct kdfs_inode *) objEntry->object; + + DEBUG(DBG_INFO, "Insert inode (%ld;%ld)\n", set->id, objid); + + /* + * If this is the first insert in the set (just called after the first_touch) + * k_inode->inode->i_mode has not been yet assigned. So we cannot assign the + * right references for the operations + */ + if (!(k_inode->flags & K_INODE_CREATING)) { + /* According to the mode, set the right operations */ + switch (k_inode->inode->i_mode & S_IFMT) { + case S_IFREG: + DEBUG(DBG_TRACE, "Set file operations %o\n", k_inode->inode->i_mode & S_IFMT); + k_inode->inode->i_op = &kdfs_file_inode_operations; + k_inode->inode->i_fop = &kdfs_file_fops; + k_inode->inode->i_mapping->a_ops = &kdfs_aops; + break; + case S_IFDIR: + DEBUG (DBG_TRACE, "Set dir operations %o\n", k_inode->inode->i_mode & S_IFMT); + k_inode->inode->i_op = &kdfs_dir_inode_operations; + k_inode->inode->i_fop = &kdfs_dir_fops; + k_inode->inode->i_mapping->a_ops = &kdfs_aops; + break; + case S_IFLNK: + k_inode->inode->i_op = &kdfs_symlink_inode_operations; + k_inode->inode->i_mapping->a_ops = &kdfs_aops; + break; + case S_IFBLK: + case S_IFCHR: + case S_IFIFO: + case S_IFSOCK: + init_special_inode(k_inode->inode, k_inode->inode->i_mode, k_inode->inode->i_sb->s_dev); + break; + default: + DEBUG(DBG_PANIC, + "Cannot set kdfs inode operations %o (ino %ld)\n", + k_inode->inode->i_mode & S_IFMT, k_inode->inode->i_ino); + DEBUG(DBG_PANIC, "filename %s\n", + list_entry(k_inode->inode->i_dentry.next, struct dentry, d_alias)->d_name.name); + break; + } + } + k_inode->inode->i_flags |= S_NOATIME; + insert_inode_hash(k_inode->inode); + PRINT_FUNCTION_EXIT; + return 0; + + /* TODO PRIORITY 1, Adrien: + * A bug can occur for the case where a remote node access to one object for the first time (get) + * This object is then inserted in the local set without setting its right reference according to its mode.... + * Is it possible ? + */ +} + + + +/* * Export an object * * @author Adrien Lebre @@ -1199,6 +1227,8 @@ int kdfs_iol_inode_export_object(struct rpc_desc *desc, int res = 0; PRINT_FUNCTION_NAME; + + /* export the inode part*/ kdfs_export_kdfs_inode(&net_dest, src); /* export the extents part */ @@ -1230,6 +1260,8 @@ int kdfs_iol_inode_import_object(struct rpc_desc *desc, PRINT_FUNCTION_NAME; res = rpc_unpack_type(desc, net_src); + + /* import the inode part*/ kdfs_import_kdfs_inode(inode_dst, &net_src); /* import the extents part */ @@ -1279,73 +1311,6 @@ int kdfs_iol_inode_invalidate_object(kddm_obj_t *objEntry, PRINT_FUNCTION_EXIT; return KDDM_IO_KEEP_OBJECT; // in order to keep the object } - -/* - * Receive a fresh copy of an inode. Update the inode struct. - * @author Adrien Lebre - * - * @param objEntry descriptor of the k_inode to insert. - * @param set kddm set descriptor - * @param objid Id of the k_inode object to insert. - */ -int kdfs_iol_inode_insert_object(kddm_obj_t *objEntry, - kddm_set_t *set, - objid_t objid) -{ - struct kdfs_inode *k_inode = (struct kdfs_inode *) objEntry->object; - - DEBUG(DBG_INFO, "Insert inode (%ld;%ld)\n", set->id, objid); - - /* - * If this is the first insert in the set (just called after the first_touch) - * k_inode->inode->i_mode has not been yet assigned. So we cannot assign the - * right references for the operations - */ - if (!(k_inode->flags & K_INODE_CREATING)) { - /* According to the mode, set the right operations */ - switch (k_inode->inode->i_mode & S_IFMT) { - case S_IFREG: - DEBUG(DBG_TRACE, "Set file operations %o\n", k_inode->inode->i_mode & S_IFMT); - k_inode->inode->i_op = &kdfs_file_inode_operations; - k_inode->inode->i_fop = &kdfs_file_fops; - k_inode->inode->i_mapping->a_ops = &kdfs_aops; - break; - case S_IFDIR: - DEBUG (DBG_TRACE, "Set dir operations %o\n", k_inode->inode->i_mode & S_IFMT); - k_inode->inode->i_op = &kdfs_dir_inode_operations; - k_inode->inode->i_fop = &kdfs_dir_fops; - k_inode->inode->i_mapping->a_ops = &kdfs_aops; - break; - case S_IFLNK: - k_inode->inode->i_op = &kdfs_symlink_inode_operations; - k_inode->inode->i_mapping->a_ops = &kdfs_aops; - break; - case S_IFBLK: - case S_IFCHR: - case S_IFIFO: - case S_IFSOCK: - init_special_inode(k_inode->inode, k_inode->inode->i_mode, k_inode->inode->i_sb->s_dev); - break; - default: - DEBUG(DBG_PANIC, - "Cannot set kdfs inode operations %o (ino %ld)\n", - k_inode->inode->i_mode & S_IFMT, k_inode->inode->i_ino); - DEBUG(DBG_PANIC, "filename %s\n", - list_entry(k_inode->inode->i_dentry.next, struct dentry, d_alias)->d_name.name); - break; - } - } - k_inode->inode->i_flags |= S_NOATIME; - PRINT_FUNCTION_EXIT; - return 0; - - /* TODO PRIORITY 1, Adrien: - * A bug can occur for the case where a remote node access to one object for the first time (get) - * This object is then inserted in the local set without setting its right reference according to its mode.... - * Is it possible ? - */ -} - /* * Sync an inode struct (mark at dirty on the right node). * @author Adrien Lebre @@ -1379,37 +1344,9 @@ int kdfs_iol_inode_sync_object(kddm_obj_t *objEntry, int kdfs_iol_inode_remove_object(void *object, kddm_set_t *set, objid_t objid) { struct kdfs_inode *k_inode = (struct kdfs_inode *)object; - struct kddm_set *associated_set; - /* - * We are on the object linked node and the inode has to be deleted; - * otherwise, it's just a kddm_flush_object which should - * only remove the inode information from the local cache. - */ - if ((inode_linked_node(objid) == kerrighed_node_id) && (k_inode->flags & K_INODE_TODELETE)) { - /* Destroy locally */ - ASSERT(k_inode->inode->i_nlink == 0); - DEBUG(DBG_INFO, "We are on the linked node and the file has to be deleted\n"); - /* Actually file is currently deleted in the super.c: kdfs_delete_inode */ - kfree(object); - } - else { - /* Set associated content set reference to null */ - if (k_inode->content_setid != KDDM_SET_UNUSED) { - associated_set = _local_get_kddm_set(kddm_def_ns, k_inode->content_setid); - if (associated_set) { - //TODO NOW: Should we destroy? -#if 0 - put_associated_set(kddm_set); - DEBUG (DBG_INFO,"\n\n\n\n REMOVE KDDM SET\n\n\n"); - _destroy_associated_set(kddm_set); - kdfs_inode->content_setid = KDDM_SET_UNUSED; -#endif - ((struct content_iolinker_data *) associated_set->private_data)->k_mapping = NULL; - put_kddm_set(associated_set); - } - } - kfree(object); - } + // Free memory previously allocated. + kdfs_file_extent_free(k_inode); + kfree(k_inode); return 0; } diff --git a/fs/kdfs/physical_fs.c b/fs/kdfs/physical_fs.c index 05c0302..66b65e9 100644 --- a/fs/kdfs/physical_fs.c +++ b/fs/kdfs/physical_fs.c @@ -13,6 +13,7 @@ #include <asm/ia32.h> #endif +#include <linux/file.h> #include <asm/uaccess.h> #include <linux/namei.h> #include <linux/fs_struct.h> @@ -144,6 +145,8 @@ long remove_phys_dir(const char *pathname, uid_t uid, gid_t gid) dentry = file->f_dentry; dir = dentry->d_parent->d_inode; + filp_close(file,current->files); + DEBUG(DBG_INFO, "Remove dir %s from dir %s\n", dentry->d_name.name, dentry->d_parent->d_name.name); @@ -154,9 +157,9 @@ long remove_phys_dir(const char *pathname, uid_t uid, gid_t gid) dentry->d_parent->d_name.name); // TODO PRIORITY 3, Adrien Usefull / Useless ? - //dput(dentry); - // put_filp(file); - filp_close(file,current->files); + // Check Renaud code from kerrighed/fs/physical_fs.c + dput(dentry); + put_filp(file); out: __revert_old_creds(overridden_creds, old_creds); @@ -412,7 +415,7 @@ int kdfs_phys_write(struct file *file, char *addr, size_t len, loff_t *pos) int ret; mm_segment_t old_fs; - DEBUG(DBG_INFO, "Write Native file %s to position %ld (size %ld)\n", file->f_dentry->d_name.name, *pos, len); + DEBUG(DBG_INFO, "Write Native file %s to position %lld (size %ld )\n", file->f_dentry->d_name.name, *pos, len); old_fs = get_fs(); set_fs(KERNEL_DS); /* Enable to read in kernel memory */ @@ -465,15 +468,18 @@ int remove_phys_file(const char *filename, uid_t uid, gid_t gid) dir = dentry->d_parent->d_inode; filp_close(file,current->files); - // TODO PRIORITY 3, Adrien Useful / Useless ? - //dput(dentry); - // put_filp(file); DEBUG(DBG_INFO, "Remove file %s from dir %s\n", dentry->d_name.name, dentry->d_parent->d_name.name); res = vfs_unlink(dir, dentry); + // TODO PRIORITY 3, Adrien Useful / Useless ? + // Check Renaud code from kerrighed/fs/physical_fs.c + dput(dentry); + put_filp(file); + + DEBUG(DBG_INFO, "After vfs_unlink res = %d\n", res); diff --git a/fs/kdfs/super.c b/fs/kdfs/super.c index cb5d069..0314574 100644 --- a/fs/kdfs/super.c +++ b/fs/kdfs/super.c @@ -9,6 +9,7 @@ * @maintainer Adrien Lebre * * Copyright (C) 2006-2007, XtreemOS Consortium. + * Copyright (C) 2008-20xx, Mines Nantes - INRIA Rennes Bretagne Atlantique - LINA . */ #include <linux/module.h> @@ -333,6 +334,7 @@ void kdfs_remove_local_ino(struct kdfs_super_block *k_sb, unsigned long ino) kdfs_getphysicalpath(k_sb, ino, phys_dirname); sprintf(phys_dirname, "%s/" KDFS_CONTENT_FILENAME, phys_dirname); DEBUG(DBG_INFO, "Try to remove phys_file %s\n", phys_dirname); +// UNE LIGNE IMPORTANTE QUI POSE UN PROBLEME PUISQU'IL EN DECOULE une inode a null et donc un fichier qui ne pourra etre fermé proprement dans kdfs_iol_content_uninstantiate remove_phys_file(phys_dirname, 0, 0); #if 0 @@ -1100,7 +1102,7 @@ int __kdfs_write_inode(struct kdfs_inode *k_inode) /* * Drop a kdfs inode from the inode cache * This function is called by the VFS when someone calls iput_final() - * + * (i.e. when the i_count equals 0) * @author Adrien Lebre * * @param inode The VFS inode @@ -1108,23 +1110,21 @@ int __kdfs_write_inode(struct kdfs_inode *k_inode) */ void kdfs_drop_inode(struct inode *inode) { - struct kdfs_inode *k_inode = NULL; - DEBUG(DBG_INFO, "inode id %ld\n", inode->i_ino); + long ino = inode->i_ino; + DEBUG(DBG_INFO, "inode id %ld\n", ino); if (inode->i_nlink) { - /* Generic forget is unfortunately not exported */ - //generic_forget_inode(inode); - - /* TODO PRIORITY 1, Adrien: - * Take care about inode memory desallocation */ + /* Generic forget is unfortunately not exported unfortunately */ + /* so we have to call generic_drop_inode */ generic_drop_inode(inode); - - k_inode = kdfs_igrab(inode->i_ino); - /* Associated kddm desallocation */ - // ICI - //__local_destroy_content_kddm_set(k_inode); - - kdfs_idrop(inode->i_ino); + + // We should not remove a kDDM set locally (it can break for instance the chain owner) + // You should flush all objects and wait to remove the remaining data when someone + // is going to call kdddm_remove + // The flush of all objects is done through the truncate_inode_pages called by generic_drop_inode + + kdfs_idrop(ino); + } else generic_delete_inode(inode); @@ -1132,10 +1132,7 @@ void kdfs_drop_inode(struct inode *inode) } /* - * TODO NOW: Adrien Pierre, - * Cf. inode.c line 954. - * kdfs_idrop should be called when we want to flush an object and ONLY for a flush - * otherwise, we should call kdfs_idelete. + * WARNINGS: * Currently, there is a STRONG issue: kdfs_idelete is call whatever the i_count value * on other nodes. * The basic idea consists in adding some check in order to know if we are the last node @@ -1151,39 +1148,23 @@ void kdfs_delete_inode(struct inode *inode) * In other words, only the last node which is using this inode, has * to delete it. */ - struct kdfs_inode *kdfs_inode = NULL; - struct kddm_set *kddm_set = NULL; + struct kdfs_inode *k_inode = NULL; struct kdfs_super_block *k_sb = NULL; - struct file *phys_file = NULL; - - ASSERT(inode != NULL); + DEBUG(DBG_INFO, "Delete Inode %ld\n", inode->i_ino); k_sb = kdfs_getsb(kerrighed_node_id); -#if 0 - if ( kdfs_node_isowner(inode->i_inod) { - k_inode->flags|=K_INODE_TODELETE; - /* destroy the object with a flush */ - - } - elseif (k_inode->flags & K_INODE_TODELETE)) - /* I need to really destroy the on-disk object */ -#endif /* Get the inode and delete its associated content set and its entry in INODE KDDM Set */ - kdfs_inode = kdfs_igrab(inode->i_ino); + k_inode = kdfs_iget(inode->i_ino); + + // TODO check whether this is previously called by the vfs layer ? truncate_inode_pages(&inode->i_data, 0); - if (kdfs_inode->content_setid != KDDM_SET_UNUSED) { - kddm_set = _local_get_kddm_set(kddm_def_ns, kdfs_inode->content_setid); - //kddm_set = _find_get_kddm_set(kddm_def_ns,kdfs_inode->content_setid); - if (kddm_set) { - phys_file = ((struct content_iolinker_data *) kddm_set->private_data)->phys_file; - ((struct content_iolinker_data *) kddm_set->private_data)->phys_file = NULL; - put_kddm_set(kddm_set); - DEBUG (DBG_INFO,"\n\n\n\n REMOVE KDDM SET\n\n\n"); - _destroy_kddm_set(kddm_set); - kdfs_inode->content_setid = KDDM_SET_UNUSED; + +// ICI + if (k_inode->content_setid != KDDM_SET_UNUSED) { + destroy_kddm_set(kddm_def_ns, k_inode->content_setid); + k_inode->content_setid = KDDM_SET_UNUSED; } - } /* Cleanly remove inode from kddm inode set */ kdfs_idelete(inode->i_ino); // equivalent to kdfs_iput() and remove @@ -1192,8 +1173,6 @@ void kdfs_delete_inode(struct inode *inode) if (inode_linked_node(inode->i_ino) == kerrighed_node_id) { /* Close the physical file before it is removed in kdfs_remove_local_ino */ - if (phys_file != NULL) - close_phys_file(phys_file); kdfs_remove_local_ino(k_sb, inode->i_ino); } commit b626068cf8bf47e0c962b6d764d61370d8d83f1c Author: ad <leb...@fr...> Date: Fri Aug 20 13:09:12 2010 +0000 Partially fixed page cache management and kddm protocol interactions diff --git a/fs/kdfs/TODO b/fs/kdfs/TODO index 2c57e69..7c69c75 100644 --- a/fs/kdfs/TODO +++ b/fs/kdfs/TODO @@ -9,12 +9,6 @@ Prio. added added Type What 1 adrien 071212 bugfix superbloc: handling of clusterwide sbs (mount in any order) 2 adrien 071212 new_feature superbloc: improvements of mount (extraparemeters QoS, max) 2 adrien 071212 new_feature superbloc: improvements (several partitions on a node) -1 adrien 071212 bugfix paging: files are loaded into the kddm but the associated memory is never freed - => Bonnie on big file => out of core - => every page in a kddmset will be referenced in the local cache, this - way whenever the kernel wishes to discard a page in its local cache, - it will be discarded in the kddm set -2 adrien 071212 new_feature striping (e.g.: file .meta may contain the striping pattern and data servers) 2 adrien 071212 new_feature redundancy (e.g.: file .meta may contain the striping pattern and data servers) 3 adrien new_feature file versioning (snapshot) 4 adrien new_feature I/O probes to optimize process vs data placement @@ -40,11 +34,23 @@ Prio. added added Type What 2 pierre 080227 bugfix check about obj_entry->lock (spinlock) being locked in kddm_io_invalidate_object when calling kdfs_iol_inode_invalidate_object (which calls a sleeping function) + 2 adrien 100717 Bugfix check why we locally destroy the content kddm set the inode is dropped by the VFS (cfs. super.c kdfs_drop_inode) +2 adrien 100819 ls -al upon a directory returns a wrong size (should be 4096, however the realsize of the directory is returned) + DONE ~~~~ +1 adrien 071212 bugfix paging: files are loaded into the kddm but the associated memory is never freed + => Bonnie on big file => out of core + => every page in a kddmset will be referenced in the local cache, this + way whenever the kernel wishes to discard a page in its local cache, + it will be discarded in the kddm set +=> Done August 2010 - Adrien + +2 adrien 071212 new_feature striping (e.g.: file .meta may contain the striping pattern and data servers) +=> Done June 2010 - Adrien/Marko EOF diff --git a/fs/kdfs/address_space.c b/fs/kdfs/address_space.c index a8997fa..008b62b 100644 --- a/fs/kdfs/address_space.c +++ b/fs/kdfs/address_space.c @@ -196,6 +196,7 @@ int __kdfs_commit_write(struct file *file, kdfs_distmark_page_dirty(k_inode, page->index); _kdfs_put_page((struct kdfs_page*)page->private); + // TODO: Why synchronize the inode at each page modification, I presume that it should be done kdfs_mark_inode_dirty(k_inode); kdfs_iput(k_inode->inode->i_ino); @@ -250,20 +251,17 @@ void kdfs_invalidatepage(struct page *page, unsigned long offset) ASSERT(page->mapping != NULL); k_page = (struct kdfs_page *) page->private; + if (offset == 0) { /* The whole page is invalidated so it should be removed */ - DEBUG(DBG_INFO, "Gonna remove page %ld (objid %ld from set %ld)\n", page->index, k_page->obj_id,k_page->set_id); + /* TODO Should we really remove the page from the physical storage */ + /* Currently only the inode is updated, it seems to be sufficient */ + DEBUG(DBG_INFO, "Gonna invalidate page %ld (objid %ld from set %ld)\n", page->index, k_page->obj_id,k_page->set_id); kddm_remove_object(kddm_def_ns, k_page->set_id, k_page->obj_id); + + set_page_private(page, NULL); ClearPagePrivate(page); } - else { - //TODO Now Adrien : Fix that : sure or not sure ? - /* Not sure about this */ - ASSERT (1==0); - // kdfs_grab_distpage(k_page->set_id, k_page->obj_id); - // kddm_sync_frozen_object(kddm_def_ns, k_page->set_id, k_page->obj_id); -// __kdfs_put_page(k_page->set_id, k_page->obj_id); - } PRINT_FUNCTION_EXIT; } @@ -280,9 +278,14 @@ int kdfs_releasepage(struct page *page, gfp_t mask) k_page = (struct kdfs_page *) page->private; - kddm_flush_object(kddm_def_ns, k_page->set_id, k_page->obj_id, KERRIGHED_NODE_ID_NONE); - + DEBUG(DBG_INFO, "Gonna release page %ld (objid %ld from set %ld)\n", page->index, k_page->obj_id,k_page->set_id); + if(kddm_flush_object(kddm_def_ns, k_page->set_id, k_page->obj_id, KERRIGHED_NODE_ID_NONE) == -ENOSPC) + /* There is only one copy, so we should exploit remove instead of flush */ + kddm_remove_object(kddm_def_ns, k_page->set_id, k_page->obj_id); + + set_page_private(page, NULL); ClearPagePrivate(page); + PRINT_FUNCTION_EXIT; return 1; } @@ -624,6 +627,9 @@ int kdfs_iol_page_first_touch(kddm_obj_t *objEntry, k_page->page = find_get_page(k_mapping, pageid); if (!k_page->page) { k_page->page = find_or_create_page(k_mapping, pageid, (mapping_gfp_mask(k_mapping)|__GFP_ZERO) & ~__GFP_FS); + //k_page->page = alloc_page(mapping_gfp_mask(k_mapping)|__GFP_ZERO) & ~__GFP_FS); + //lock_page(k_page->page); + k_page->flags = K_PG_locked; page_addr = (char *) kmap(k_page->page); @@ -643,8 +649,6 @@ int kdfs_iol_page_first_touch(kddm_obj_t *objEntry, } else k_page->flags = K_PG_ok; - DEBUG(DBG_TRACE, "After find Page count=%d\n", page_count(k_page->page)); - kunmap(k_page->page); objEntry->object = (void *) k_page; @@ -676,8 +680,8 @@ int kdfs_iol_page_insert(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) * released from local cache (cf. kdfs_invalidatepage or kdfs_releasepage) */ - SetPagePrivate(k_page->page); set_page_private(k_page->page, (unsigned long) k_page); + SetPagePrivate(k_page->page); /* * if the page has been created by kDFS, we should unlock the page @@ -749,6 +753,10 @@ int kdfs_iol_page_export (struct rpc_desc *desc, * @param objid Object id of the object * * @return 0 + * + * Notes: kdfs_iol_page_invalidate can only be triggered by a KDDM event. + * As a consequence, there is no possibility to get conflict with kernel cache operations + * When a page is invalidated or remove from the cache, kdfs_iol_page_remove is invoked on the node */ int kdfs_iol_page_invalidate(kddm_obj_t *objEntry, kddm_set_t *set, objid_t objid) @@ -767,14 +775,11 @@ int kdfs_iol_page_invalidate(kddm_obj_t *objEntry, kddm_set_t *set, DEBUG(DBG_INFO, "Try to invalidate objid %ld (page id %ld page addr %p) of set %lu\n", objid, k_page->page->index, k_page->page, set->id); trylock_page(k_page->page); - // TODO Remove Useless traces - DEBUG(DBG_ALERT, "Page count before =%d\n", page_count(k_page->page)); remove_from_page_cache(k_page->page); + set_page_private(page, NULL); ClearPagePrivate(k_page->page); unlock_page(k_page->page); page_cache_release(k_page->page); - // TODO Remove Useless traces - DEBUG(DBG_ALERT, "Page after count=%d\n", page_count(k_page->page)); PRINT_FUNCTION_EXIT; @@ -885,6 +890,7 @@ int kdfs_iol_page_remove(void *object, struct kddm_set *set, objid_t objid) struct kdfs_page *k_page = (struct kdfs_page *) object; PRINT_FUNCTION_NAME; + DEBUG(DBG_INFO, "Gonna remove objid %ld from set %ld\n", k_page->obj_id,k_page->set_id); if ((!PageLocked(k_page->page))) { /* * This is not the kernel trying to remove the page but the KDDMs, @@ -917,8 +923,8 @@ int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) { struct content_iolinker_data *content_data = NULL; struct inode *inode = NULL; + char * phys_dirname; int result = 0; - char *phys_dirname; struct file *filp; /* TODO NOW: Adrien */ @@ -941,20 +947,12 @@ int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) /* Retrieve local path corresponding to kfds inode number*/ kdfs_getphysicalpath(k_sb, content_data->ino, content_data->phys_dirname); - result = check_create_phys_dir(content_data->phys_dirname, 0777, 0, 0); - if (result != 0) - DEBUG(DBG_PANIC, "Something wrong during check_create_phys_dir (error=%d)", result); + phys_dirname = content_data->phys_dirname + strlen(content_data->phys_dirname); - /* Try to open the physical associated file */ - phys_dirname = content_data->phys_dirname + strlen(content_data->phys_dirname); - // For versionning purpose: TODO add specific defines - snprintf(content_data->phys_dirname, PATH_MAX, "%s/.meta.index", content_data->phys_dirname); - filp = open_phys_file(content_data->phys_dirname, O_RDONLY, 0644, 0, 0); - *phys_dirname = '\0'; - if (IS_ERR(filp)) { + if (!KDFS_VERSIONNING) { /* This file is not checkpointed, use the standard content file. */ snprintf(content_data->phys_dirname, PATH_MAX, "%s/" KDFS_CONTENT_FILENAME, content_data->phys_dirname); - filp = open_phys_file(content_data->phys_dirname, O_CREAT|O_LARGEFILE|O_RDWR, 0644, 0,0); + filp = check_create_phys_file(content_data->phys_dirname, 0644, 0,0); BUG_ON(IS_ERR(filp)); content_data->phys_file = filp; *phys_dirname = '\0'; @@ -964,9 +962,16 @@ int content_instantiate(kddm_set_t *kddm_set, void *private_data, int master) content_data->current_meta = NULL; } else { + /* Try to open the physical associated file */ + // This code is simply useless (cf. comment below) + // phys_dirname = content_data->phys_dirname + strlen(content_data->phys_dirname); + // snprintf(content_data->phys_dirname, PATH_MAX, "%s/.meta.index", content_data->phys_dirname); + // filp = check_create_phys_file(content_data->phys_dirname, 0644, 0,0); + /* This file is checkpointed, initialization will be done on the first read/write. */ content_data->phys_file = NULL; - + *phys_dirname = '\0'; + content_data->content_readphyspage = kdfs_content_readphyspage_cow; content_data->content_writephyspage = kdfs_content_writephyspage_cow; content_data->current_meta = NULL; diff --git a/fs/kdfs/address_space.h b/fs/kdfs/address_space.h index 1a569c7..fd06436 100644 --- a/fs/kdfs/address_space.h +++ b/fs/kdfs/address_space.h @@ -33,6 +33,8 @@ /* If defined, kDFS provides local striping policy */ #define KDFS_FILE_STRIPING 1 +/* If defined, kDFS provides versionning management based on the Pierre Riteau's proposal (experimental) */ +#define KDFS_VERSIONNING 0 /*--------------------------------------------------------------------------* * * diff --git a/fs/kdfs/dir.c b/fs/kdfs/dir.c index 31a9497..c0d0e0b 100644 --- a/fs/kdfs/dir.c +++ b/fs/kdfs/dir.c @@ -204,8 +204,8 @@ struct kdfs_dir_entry *kdfs_find_entry(struct kdfs_inode *dir, /* Did we find the right entry */ DEBUG(DBG_INFO, - "filelen %d dirfilelen %d, filename %s dirname %s, dirlen %d (dirino %ld)\n", - filename_len, dir_entry->name_len, filename, dir_entry->name,dir_entry->rec_len, dir_entry->ino); + "file:%s (filename_len %d), dir:%s (dirfilename_len %d), dirlen %d (dirino %ld)\n", + filename, filename_len, dir_entry->name, dir_entry->name_len, dir_entry->rec_len, dir_entry->ino); if (dir_entry->name_len == filename_len && strncmp (dir_entry->name, filename, filename_len) == 0) goto found; @@ -837,7 +837,7 @@ struct iolinker_struct dir_io_linker = { .invalidate_object = kdfs_iol_page_invalidate, .linker_name = "dir", .linker_id = DIR_LINKER, - .put_object = kdfs_iol_page_put, +// .put_object = kdfs_iol_page_put, .remove_object = kdfs_iol_page_remove, .sync_object = kdfs_iol_page_sync, .uninstantiate = dir_uninstantiate, diff --git a/fs/kdfs/file.c b/fs/kdfs/file.c index 367c23c..1fe9e23 100644 --- a/fs/kdfs/file.c +++ b/fs/kdfs/file.c @@ -168,9 +168,12 @@ out: return r; } + +// Seems to be mandatory to cleany handle file removals. +// TODO file/dir removal process has to be tackled int kdfs_release(struct inode *inode, struct file *filp) { - struct kdfs_inode *k_inode; +// struct kdfs_inode *k_inode; DEBUG(DBG_INFO, "Release file %s (i_size %lld) (inode %p)\n", @@ -178,10 +181,11 @@ int kdfs_release(struct inode *inode, struct file *filp) filp->f_dentry->d_inode->i_size, filp->f_dentry->d_inode); - k_inode = kdfs_igrab(inode->i_ino); +// That code seems buggy +/* k_inode = kdfs_igrab(inode->i_ino); atomic_dec(&k_inode->cw_count); kdfs_iput(inode->i_ino); - +*/ return 0; } @@ -305,7 +309,7 @@ struct iolinker_struct file_io_linker = { .invalidate_object = kdfs_iol_page_invalidate, .linker_name = "file", .linker_id = FILE_LINKER, - .put_object = kdfs_iol_page_put, +// .put_object = kdfs_iol_page_put, .remove_object = kdfs_iol_page_remove, .sync_object = kdfs_iol_page_sync, .uninstantiate = kdfs_iol_file_uninstantiate, diff --git a/fs/kdfs/inode.c b/fs/kdfs/inode.c index 5a06f64..18d557e 100644 --- a/fs/kdfs/inode.c +++ b/fs/kdfs/inode.c @@ -1086,19 +1086,19 @@ int kdfs_iol_inode_alloc_object (kddm_obj_t *objEntry, /* TODO PRIORITY 3: Adrien * interest of the following code inside the alloc function */ - if (inode_linked_node(objid) == kerrighed_node_id) { - char *phys_dirname; - /* Find the physical path corresponding to the KDFS inode */ - phys_dirname = kmalloc(PATH_MAX, GFP_KERNEL); - ASSERT(phys_dirname != NULL); - - kdfs_getphysicalpath(k_sb, objid, phys_dirname); - if (check_create_phys_dir(phys_dirname, 0777, 0, 0) != 0) - BUG(); - - kfree(phys_dirname); - } - +// if (inode_linked_node(objid) == kerrighed_node_id) { +// char *phys_dirname; +// /* Find the physical path corresponding to the KDFS inode */ +// phys_dirname = kmalloc(PATH_MAX, GFP_KERNEL); +// ASSERT(phys_dirname != NULL); +// +// kdfs_getphysicalpath(k_sb, objid, phys_dirname); +// if (check_create_phys_dir(phys_dirname, 0777, 0, 0) != 0) +// BUG(); +// +// kfree(phys_dirname); +// } +// __kdfs_twice_putsb(k_sb); PRINT_FUNCTION_EXIT; return 0; diff --git a/fs/kdfs/physical_fs.c b/fs/kdfs/physical_fs.c index 8bd60c1..05c0302 100644 --- a/fs/kdfs/physical_fs.c +++ b/fs/kdfs/physical_fs.c @@ -2,9 +2,8 @@ * KDDM File System - Access to Native File System. * @file physical_fs.c based on physical_fs.c from kerrighed code * - * Copyright (C) 2001-2006, INRIA, Universite de Rennes 1, EDF. - * Copyright (C) 2006-2007, Renaud Lottiaux, Kerlabs. - * Copyright (C) 2007-, Adrien Lebre, XtreemOS Consortium. + * Copyright (C) 2006-2007, XtreemOS Consortium. + * Copyright (C) 2008-20xx, Mines Nantes - INRIA Rennes Bretagne Atlantique - LINA . * * @author Renaud Lottiaux * @author Adrien Lebre @@ -180,7 +179,7 @@ out: * @return file_ptr pointer to the opened file * NULL - err_code error opening as indicated by the error code */ -struct file *open_phys_file(char *filename, int flags, int mode, uid_t uid, gid_t gid) +struct file *open_phys_file(const char *filename, int flags, int mode, uid_t uid, gid_t gid) { int error = 0; struct file *file = NULL; @@ -230,7 +229,7 @@ int close_phys_file(struct file *file) } /* - * Check whether the given path exists + * Check whether the given directory exists * If not, create it * * @author Marko Obrovac @@ -294,6 +293,69 @@ out_close: } /* + * Check whether the given file exists + * If not, create it + * + * @author Adrien Lebre + * + * @param pathname the path that has to be checked and/or created + * @param mode mode flags to create the dir with + * @param uid owner user id + * @param gid owner group id + * + * @return file decriptor if !IS_ERR(fp) otherwise fp contains the error. + * + * @comment the function will create the whole path + * if it doesn't exist. + * Example: pathname = /path1/path2/path3 + * if only /path1 exists, /path2 + * is created inside /path1 and + * then /path3 is created inside + * /path1/path2 + */ +struct file* check_create_phys_file(const char *pathname, + int mode, + uid_t uid, + gid_t gid) +{ + int error = 0; + struct file *fp; + char *path, *buf; + path = kmalloc(PATH_MAX, GFP_KERNEL); + buf = kmalloc(PATH_MAX, GFP_KERNEL); + ASSERT(path != NULL); + ASSERT(buf != NULL); + + buf[0] = 0; + strcpy(path, pathname); + + fp = open_phys_file(path, O_CREAT|O_LARGEFILE|O_RDWR, mode, 0, 0); + if (IS_ERR(fp)){ + // Parent directory(ies) does/do not exist, so create it/them + // First, remove filename + str_move_last_block(path, buf, '/'); + buf[0] = 0; + // Second create the missing directory/ies + do { + str_move_last_block(path, buf, '/'); + fp = open_phys_file(path, O_LARGEFILE|O_RDONLY, 0644, 0, 0); + if (!IS_ERR(fp)) + break; + } while (strlen(path)); + + while (strlen(buf)) { + str_move_last_block(buf, path, '/'); + error = create_phys_dir(path, mode, uid, gid); + } while (strlen(path) && (error !=0)); + + fp = open_phys_file(pathname,O_CREAT|O_LARGEFILE|O_RDWR, mode, 0, 0); + } + kfree(path); + kfree(buf); + return fp; +} + +/* * Read from a physical file * * @author Adrien Lebre @@ -350,7 +412,7 @@ int kdfs_phys_write(struct file *file, char *addr, size_t len, loff_t *pos) int ret; mm_segment_t old_fs; - DEBUG(DBG_INFO, "Write Native file %s\n", file->f_dentry->d_name.name); + DEBUG(DBG_INFO, "Write Native file %s to position %ld (size %ld)\n", file->f_dentry->d_name.name, *pos, len); old_fs = get_fs(); set_fs(KERNEL_DS); /* Enable to read in kernel memory */ diff --git a/fs/kdfs/physical_fs.h b/fs/kdfs/physical_fs.h index 590f9fd..eb80342 100644 --- a/fs/kdfs/physical_fs.h +++ b/fs/kdfs/physical_fs.h @@ -2,10 +2,10 @@ * KDDM File System - Access to Native File System. * @file physical_fs.h based on physical_fs.h from kerrighed code * - * Copyright (C) 2001-2006, INRIA, Universite de Rennes 1, EDF. - * Copyright (C) 2006-2007, Renaud Lottiaux, Kerlabs. - * Copyright (C) 2007-, Adrien Lebre, XtreemOS Consortium. + * Copyright (C) 2006-2007, XtreemOS Consortium. + * Copyright (C) 2008-20xx, Mines Nantes - INRIA Rennes Bretagne Atlantique - LINA . * + * @author Renaud Lottiaux * @author Adrien Lebre */ @@ -60,16 +60,18 @@ static inline void str_move_last_block(char *src, char *dest, char delimiter) * * *--------------------------------------------------------------------------*/ -struct file *open_phys_file (char *filename, int flags, int mode, uid_t uid, gid_t gid); +struct file *check_create_phys_file(const char *pathname, int mode, uid_t uid, gid_t gid); +struct file *open_phys_file (const char *filename, int flags, int mode, uid_t uid, gid_t gid); int close_phys_file (struct file *file); +int remove_phys_file(const char *filename, uid_t uid, gid_t gid); int kdfs_phys_read(struct file *file, char *addr, size_t len, loff_t *pos); int kdfs_phys_write(struct file *file, char *addr, size_t len, loff_t *pos); +long check_create_phys_dir(const char *pathname,int mode, uid_t uid,gid_t gid); + long create_phys_dir(const char *pathname, int mode, uid_t uid, gid_t gid); -long check_create_phys_dir(const char *pathname, int mode, uid_t uid, gid_t gid); long remove_phys_dir(const char *pathname, uid_t uid, gid_t gid); -int remove_phys_file(const char *filename, uid_t uid, gid_t gid); #endif // __KDFS_PHYSICAL_FS__ diff --git a/fs/kdfs/super.c b/fs/kdfs/super.c index 6fa8b65..cb5d069 100644 --- a/fs/kdfs/super.c +++ b/fs/kdfs/super.c @@ -1060,7 +1060,7 @@ int __kdfs_write_inode(struct kdfs_inode *k_inode) phys_filename); strcat(phys_filename,"/" KDFS_INODE_FILENAME); - file = open_phys_file(phys_filename, O_CREAT|O_RDWR, 0644,0 ,0); + file = check_create_phys_file(phys_filename, 0644,0 ,0); if (!IS_ERR(file)) { phys_inode.size = inode->i_size; phys_inode.nlink = inode->i_nlink; @@ -1083,7 +1083,7 @@ int __kdfs_write_inode(struct kdfs_inode *k_inode) kdfs_file_extent_dump_to_file(k_inode, file); close_phys_file(file); } else { - DEBUG (DBG_ALERT, + DEBUG (DBG_PANIC, "Can't access/create the KDFS inode %ld metafile \nPlease "\ "verify type of the partition %s, it should be a KDFS one "\ " (error %ld)\n", inode->i_ino, ----------------------------------------------------------------------- Summary of changes: fs/kdfs/TODO | 18 +++- fs/kdfs/address_space.c | 187 +++++++++++++++---------------------- fs/kdfs/address_space.h | 9 +- fs/kdfs/dir.c | 30 ++---- fs/kdfs/file.c | 50 ++-------- fs/kdfs/file_extent.c | 15 +++- fs/kdfs/file_extent.h | 2 + fs/kdfs/inode.c | 235 +++++++++++++++++------------------------------ fs/kdfs/physical_fs.c | 92 ++++++++++++++++--- fs/kdfs/physical_fs.h | 14 ++- fs/kdfs/super.c | 77 ++++++---------- 11 files changed, 335 insertions(+), 394 deletions(-) hooks/post-receive -- kdfs |