From: alebre <al...@us...> - 2010-12-23 15:13:05
|
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 98833b0b5cbed6daebe10dc95fec43b7e02216e1 (commit) via 2ce817f4d32527927caf84e043349ff34d0c61a0 (commit) from e022fc85cfe0f7df2194c7591e7fbd5e2ff624e2 (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 98833b0b5cbed6daebe10dc95fec43b7e02216e1 Merge: 2ce817f e022fc8 Author: ad <leb...@fr...> Date: Thu Dec 23 09:34:48 2010 +0000 Fix Conflict with last pull diff --cc fs/kdfs/address_space.c index c4c3b71,33bd7f9..4a90d2d --- a/fs/kdfs/address_space.c +++ b/fs/kdfs/address_space.c @@@ -615,17 -618,21 +615,11 @@@ int kdfs_iol_page_first_touch(kddm_obj_ } else k_page->flags = K_PG_ok; + page_addr = (char *) kmap(k_page->page); + pos = (loff_t)pageid * PAGE_SIZE; + - - /* The page should be filled only if it was not handled - * by another node before (i.e if the page is already in - * the cache, it means that the page has been inserted - * throught another kddm object call) - */ + iolinker_data->content_readphyspage(iolinker_data, page_addr, pos); + kunmap(k_page->page); objEntry->object = (void *) k_page; diff --cc fs/kdfs/inode.c index ca2405a,53bde96..c89111e --- a/fs/kdfs/inode.c +++ b/fs/kdfs/inode.c @@@ -1109,8 -1109,9 +1109,8 @@@ int kdfs_iol_inode_first_touch(kddm_obj 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); + DEBUG(DBG_PANIC, "Cannot find inode %lu\n", objid); k_inode->inode->i_ino = objid; - // insert_inode_hash(k_inode->inode); } // Case 2: the inode already exists, so fill it from the HDD else { diff --cc fs/kdfs/super.c index fd268c3,b52cc3d..c3e877f --- a/fs/kdfs/super.c +++ b/fs/kdfs/super.c @@@ -1183,13 -1160,38 +1183,12 @@@ void kdfs_drop_inode(struct inode *inod PRINT_FUNCTION_EXIT; } -/* - * 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 - * handling the object or not. - */ -void kdfs_delete_inode(struct inode *inode) +// Warning the k_inode should be locked (get/grab) +void destroy_content_kddmset(struct kdfs_inode *k_inode) { - /* - * If we are there, that's mean inode->i_nlink and inode->i_count - * have reached 0. So for this node, the inode is not more used. - * We have to take into account, potential access to this inode - * from remote nodes. - * In other words, only the last node which is using this inode, has - * to delete it. - */ - struct kdfs_inode *k_inode = NULL; - struct kdfs_super_block *k_sb = NULL; - - DEBUG(DBG_INFO, "Delete Inode %lu\n", inode->i_ino); - - k_sb = kdfs_getsb(kerrighed_node_id); + DEBUG(DBG_INFO, "Destroy the contentset associated to inode %ld\n", k_inode->inode->i_ino); - /* Get the inode and delete its associated content set and its entry in INODE KDDM Set */ - 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 (k_inode->content_setid != KDDM_SET_UNUSED) { - DEBUG(DBG_INFO, "kdfs gonna uninstantiate the set"); // WARNING, the set should exist somewhere in the cluster // Otherwise, we do not know what can happen from the kddm layer viewpoint // cf. kddm_set.h - Adrien December 2010 commit 2ce817f4d32527927caf84e043349ff34d0c61a0 Author: ad <leb...@fr...> Date: Thu Dec 23 09:29:57 2010 +0000 Fix kddm set destruction when inode is drop from the cache. Fix inode synchronization (my previous commit removed the synchronization of the inode each time (before the inode synchronization was performed at each page modification, now it is based on write operation (maybe too dangerous) diff --git a/fs/kdfs/address_space.c b/fs/kdfs/address_space.c index 0b10c46..c4c3b71 100644 --- a/fs/kdfs/address_space.c +++ b/fs/kdfs/address_space.c @@ -611,27 +611,20 @@ 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; + } else + k_page->flags = K_PG_ok; - page_addr = (char *) kmap(k_page->page); - pos = (loff_t)pageid * PAGE_SIZE; + page_addr = (char *) kmap(k_page->page); + pos = (loff_t)pageid * PAGE_SIZE; - DEBUG(DBG_TRACE, "The page for file/directory = %ld and " \ - "page id = %ld is not in the cache. So created/locked and read from HDD (kmap page address %p, page address %p)\n", iolinker_data->ino, - pageid,page_addr, k_page->page); - - /* The page should be filled only if it was not handled - * by another node before (i.e if the page is already in - * the cache, it means that the page has been inserted - * throught another kddm object call) - */ - iolinker_data->content_readphyspage(iolinker_data, page_addr, pos); - } else - k_page->flags = K_PG_ok; + /* The page should be filled only if it was not handled + * by another node before (i.e if the page is already in + * the cache, it means that the page has been inserted + * throught another kddm object call) + */ + iolinker_data->content_readphyspage(iolinker_data, page_addr, pos); kunmap(k_page->page); objEntry->object = (void *) k_page; diff --git a/fs/kdfs/address_space.h b/fs/kdfs/address_space.h index 7fd9901..ab11551 100644 --- a/fs/kdfs/address_space.h +++ b/fs/kdfs/address_space.h @@ -154,6 +154,7 @@ kddm_set_t *__create_content_kddm_set(kddm_set_id_t set_id, 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); +void destroy_content_kddmset(struct kdfs_inode *k_inode); /*--------------------------------------------------------------------------* * * * EXTERN VARIABLES * diff --git a/fs/kdfs/file.c b/fs/kdfs/file.c index 74fd1a1..f7e02b6 100644 --- a/fs/kdfs/file.c +++ b/fs/kdfs/file.c @@ -100,6 +100,8 @@ ssize_t kdfs_write(struct file *filp, const char *buf, size_t count, loff_t *ppo /* Call generic_file_aio_write */ r = do_sync_write(filp, buf, count, ppos); + // WARNING, synchronizing inode right now can be dangerous + kdfs_mark_inode_dirty(kdfs_inode); kdfs_iput(filp->f_dentry->d_inode->i_ino); DEBUG(DBG_INFO, diff --git a/fs/kdfs/inode.c b/fs/kdfs/inode.c index 5ebc699..ca2405a 100644 --- a/fs/kdfs/inode.c +++ b/fs/kdfs/inode.c @@ -1111,7 +1111,6 @@ int kdfs_iol_inode_first_touch(kddm_obj_t *objEntry, 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); } // Case 2: the inode already exists, so fill it from the HDD else { @@ -1336,9 +1335,31 @@ 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 dentry *dentry, *dchild; + + PRINT_FUNCTION_NAME ; + /* Invalidate local dentries */ + /* We could have several dentries for a same inode due to the hardlink */ + list_for_each_entry(dentry, &k_inode->inode->i_dentry, d_alias) { + if ((k_inode->inode->i_mode & S_IFMT) == S_IFDIR) { + /* + * Invalidate negative child dentries for a directory, because of the following problem: + * Node B has a negative dentry for file /foo, + * Node A creates /foo (so invalidates inode /) + * the negative dentry on node B should be invalidated. + */ + list_for_each_entry(dchild, &dentry->d_subdirs, d_u.d_child) + if (!dchild->d_inode) + d_drop(dchild); /* Should we revalidate instead? */ + } + DEBUG(DBG_INFO, "drop dentry\n"); + d_drop(dentry); + } + // Free memory previously allocated. kdfs_file_extent_free(k_inode); kfree(k_inode); + PRINT_FUNCTION_EXIT; return 0; } diff --git a/fs/kdfs/super.c b/fs/kdfs/super.c index 66ba12d..fd268c3 100644 --- a/fs/kdfs/super.c +++ b/fs/kdfs/super.c @@ -1140,82 +1140,62 @@ int __kdfs_write_inode(struct kdfs_inode *k_inode) void kdfs_drop_inode(struct inode *inode) { long ino = inode->i_ino; - DEBUG(DBG_INFO, "inode id %ld\n", ino); + struct kdfs_inode *k_inode; + struct kdfs_super_block *k_sb; + + DEBUG(DBG_INFO, "Drop inode id %ld\n", ino); + k_inode = kdfs_iget(ino); if (inode->i_nlink) { - /* Generic forget is unfortunately not exported unfortunately */ + /* Generic forget is unfortunately not exported */ /* so we have to call generic_drop_inode */ generic_drop_inode(inode); - - // 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 - + // TODO PRIORITY 2: Please note, destroying the kddm set is not effficient clusterwide + // However, there is no way to locallly flush a set since it can break the probably owner chain + destroy_content_kddmset(k_inode); + kdfs_iput(ino); kdfs_idrop(ino); - } else - generic_delete_inode(inode); + } else{ + /* + * 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 + * handling the object or not. + */ + generic_delete_inode(inode); + /* Cleanly remove inode from kddm inode set */ + destroy_content_kddmset(k_inode); + kdfs_idelete(ino); // equivalent to kdfs_iput() and remove + + DEBUG(DBG_INFO, "Freeing i_ino %ld from the bitmap\n", inode->i_ino); + + if (inode_linked_node(ino) == kerrighed_node_id) { + k_sb = kdfs_getsb(kerrighed_node_id); + /* Close the physical file before it is removed in kdfs_remove_local_ino */ + /* TODO PRIORITY 1: if the file is deleted on another node that the one where it has been created, we do not remove the local_ino from the bitmap */ + kdfs_remove_local_ino(k_sb, inode->i_ino); + __kdfs_putsb(k_sb); + } + } PRINT_FUNCTION_EXIT; } -/* - * 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 - * handling the object or not. - */ -void kdfs_delete_inode(struct inode *inode) +// Warning the k_inode should be locked (get/grab) +void destroy_content_kddmset(struct kdfs_inode *k_inode) { - /* - * If we are there, that's mean inode->i_nlink and inode->i_count - * have reached 0. So for this node, the inode is not more used. - * We have to take into account, potential access to this inode - * from remote nodes. - * In other words, only the last node which is using this inode, has - * to delete it. - */ - struct kdfs_inode *k_inode = NULL; - struct kdfs_super_block *k_sb = NULL; - - DEBUG(DBG_INFO, "Delete Inode %ld\n", inode->i_ino); + DEBUG(DBG_INFO, "Destroy the contentset associated to inode %ld\n", k_inode->inode->i_ino); - k_sb = kdfs_getsb(kerrighed_node_id); /* Get the inode and delete its associated content set and its entry in INODE KDDM Set */ - 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 (k_inode->content_setid != KDDM_SET_UNUSED) { - DEBUG(DBG_INFO, "kdfs gonna uninstantiate the set"); // WARNING, the set should exist somewhere in the cluster // Otherwise, we do not know what can happen from the kddm layer viewpoint // cf. kddm_set.h - Adrien December 2010 __destroy_kddm_set(kddm_def_ns, k_inode->content_setid); k_inode->content_setid = KDDM_SET_UNUSED; } - -DEBUG(DBG_INFO, "kdfs uninstantiate has been called now it idelete\n"); - - /* Cleanly remove inode from kddm inode set */ - kdfs_idelete(inode->i_ino); // equivalent to kdfs_iput() and remove - - DEBUG(DBG_INFO, "Freeing i_ino %ld from the bitmap\n", inode->i_ino); - - if (inode_linked_node(inode->i_ino) == kerrighed_node_id) { - /* Close the physical file before it is removed in kdfs_remove_local_ino */ - /* TODO PRIORITY 1: if the file is deleted on another node that the one where it has been created, we do not remove the local_ino from the bitmap */ - kdfs_remove_local_ino(k_sb, inode->i_ino); - } - - clear_inode(inode); - // destroy inode is done in generic_delete_inode - - __kdfs_putsb(k_sb); PRINT_FUNCTION_EXIT; } @@ -1323,7 +1303,6 @@ out: } static struct super_operations kdfs_sops = { - .delete_inode = kdfs_delete_inode, .drop_inode = kdfs_drop_inode, .show_options = kdfs_show_options, .statfs = kdfs_statfs, diff --git a/fs/namei.c b/fs/namei.c index 60835a8..bcdfa4d 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -2209,6 +2209,7 @@ static long do_rmdir(int dfd, const char __user *pathname) nd.flags &= ~LOOKUP_PARENT; mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT); + dentry = lookup_hash(&nd); error = PTR_ERR(dentry); if (IS_ERR(dentry)) ----------------------------------------------------------------------- Summary of changes: fs/kdfs/address_space.c | 23 ++--------- fs/kdfs/address_space.h | 1 + fs/kdfs/file.c | 2 + fs/kdfs/inode.c | 23 +++++++++++- fs/kdfs/super.c | 94 ++++++++++++++++++----------------------------- fs/namei.c | 1 + 6 files changed, 67 insertions(+), 77 deletions(-) hooks/post-receive -- kdfs |