From: alebre <al...@us...> - 2011-01-11 18:18: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 0791354f11b2d8bb6090c786e3aca225cd795f22 (commit) from b181310573abd91710fc46f94c350ebb83d46cdb (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 0791354f11b2d8bb6090c786e3aca225cd795f22 Author: ad <leb...@fr...> Date: Tue Jan 11 19:16:31 2011 +0000 Preliminary commit to test kernel compilations (Fix the management of directory entries in order to run Bonnie++) - Adrien diff --git a/fs/kdfs/dir.c b/fs/kdfs/dir.c index 022d60d..eb82fa8 100644 --- a/fs/kdfs/dir.c +++ b/fs/kdfs/dir.c @@ -469,7 +469,7 @@ int kdfs_add_dir_entry(struct kdfs_inode *kdfs_pdir, char *filename, ino_t ino, * * @return 0 If everything ok. Negative value otherwise. */ -int kdfs_del_dir_entry(struct kdfs_inode *kdfs_pdir, char *filename, ino_t ino) +int kdfs_del_and_pack_dir_entry(struct kdfs_inode *kdfs_pdir, char *filename, ino_t ino) { ino_t res = KDFS_BAD_INODEID; int err = -ENOENT; @@ -569,6 +569,61 @@ out: return err; } + + + +/* + * Delete an entry in a given directory + * and decrement i_nlink counter if the entry is found + * + * @author Adrien Lebre + * + * @param kdfs_pdir Parent directory to add the file in. + * @param filename Name of the file to add. + * @param ino Associated file's inode id. + * + * @return 0 If everything ok. Negative value otherwise. + */ +int kdfs_del_dir_entry(struct kdfs_inode *kdfs_pdir, char *filename, ino_t ino) +{ + ino_t res = KDFS_BAD_INODEID; + int err = -ENOENT; + struct kdfs_dir_entry *dir_entry = NULL; + struct kdfs_page *k_page = NULL; + void *page_addr; + + PRINT_FUNCTION_NAME; + + /* Look for direntry */ + dir_entry = kdfs_grab_entry(kdfs_pdir, filename, &k_page); + if (dir_entry == NULL) + goto out; + + /* We found the direntry, let's remove it! */ + res = le32_to_cpu(dir_entry->ino); + DEBUG(DBG_INFO, "found direntry : ino = %lu \n", res); + page_addr = page_address(k_page->page); + + // Delete the entry by setting a wrong inodeid + dir_entry->ino=KDFS_BAD_INODEID; + + /* Update timestamps */ + kdfs_pdir->inode->i_mtime = kdfs_pdir->inode->i_ctime = CURRENT_TIME_SEC; + + /* Sync kddm object to propagate change to the right partitions (clusterwide) */ + kdfs_mark_inode_dirty(kdfs_pdir); + + /* Propagate changes to the device on the righ node*/ + kdfs_mark_page_dirty(kdfs_pdir->content_setid, k_page->obj_id); + + _kdfs_put_page(k_page); + err = 0; + +out: + PRINT_FUNCTION_EXIT; + return err; +} + /* * Create the '.' and '..' directory entries * @@ -598,7 +653,7 @@ int kdfs_make_empty(struct kdfs_inode *k_pdir, struct kdfs_inode *k_dir) * * @comments k_dir has to be locked */ -int kdfs_dir_empty(struct kdfs_inode *k_dir) +int kdfs_pack_dir_empty(struct kdfs_inode *k_dir) { DEBUG(DBG_INFO, "Directory size: %llu empty if: %lu\n", k_dir->inode->i_size, KDFS_DIRENT_SIZE * 2); if (k_dir->inode->i_size > KDFS_DIRENT_SIZE * 2) @@ -606,6 +661,94 @@ int kdfs_dir_empty(struct kdfs_inode *k_dir) return 1; } +/* + * Check if a directory is empty or not + * + * @author Adrien Lebre + * @param k_dir k_inode directory to check. + * + * @return 1 If k_dir is empty. 0 otherwise. + * + * @comments k_dir has to be locked + */ +int kdfs_dir_empty(struct kdfs_inode *k_dir) +{ + struct kdfs_page *k_page = NULL; + struct kdfs_dir_entry *dir_entry = NULL; + void *direntry_addr; + unsigned long npages ; + unsigned long pageid = 0; + struct page *tmp_page = NULL; + void *page_addr = NULL ; + int res = 1 ; + + PRINT_FUNCTION_NAME; + + if (k_dir->inode->i_size > KDFS_DIRENT_SIZE * 2) { + npages = (k_dir->inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; + if (k_dir->content_setid == KDDM_SET_UNUSED) { + /* + * First access to the directory content: + * create the associated kddm_set + */ + create_dir_kddm_set(k_dir); + } + + /* Parse directory dentries */ + do { + // *k_page = kdfs_get_page(dir->content_setid, pageid); + k_page = kdfs_get_distpage(k_dir, pageid); + if (IS_ERR(k_page)) + DEBUG (DBG_PANIC, + "Can't get page %lu for the directory %lu", + pageid, k_dir->content_setid); + + tmp_page = (k_page)->page; + page_addr = kmap (tmp_page); + direntry_addr = page_addr; + /* Get the directory entry */ + dir_entry = (struct kdfs_dir_entry *) direntry_addr; + direntry_addr += dir_entry->rec_len; // '.' + dir_entry = (struct kdfs_dir_entry *) direntry_addr; + direntry_addr += dir_entry->rec_len; // '..' + // Now dir_entry points on the first real entry + + /* For each entry contained in the page */ + do { + DEBUG (DBG_INFO, + "Get page %lu:" + "page addr (mapped %p, unmapped %p), dentry_addr %p (file size %llu)\n", + pageid, page_addr, tmp_page, direntry_addr, + k_dir->inode->i_size); + /* Get the directory entry */ + dir_entry = (struct kdfs_dir_entry *) direntry_addr; + + /* Did we find the right entry */ + if (dir_entry->ino != 0 ){ + res = 0; + break; + } + /* Check if another dentry could be contained in the current page */ + if ((direntry_addr-page_addr+dir_entry->rec_len) <= (PAGE_CACHE_SIZE - KDFS_DIRENT_SIZE)) + direntry_addr += dir_entry->rec_len; + else + direntry_addr = 0; + } + while ((direntry_addr != 0) && ((pageid * PAGE_CACHE_SIZE) + (direntry_addr-page_addr) < k_dir->inode->i_size)); + + kunmap (tmp_page); + _kdfs_put_page (k_page); + pageid++; + } + while (res && (pageid < npages)); + + dir_entry = NULL; + + } // end if there are some entries + return res; +} + + /*****************************************************************************/ /* */ /* DIRECTORY OPERATIONS */ @@ -644,7 +787,7 @@ int kdfs_readdir(struct file *filp, void *dirent, filldir_t filldir) unsigned long npages = 0; unsigned long pageid = 0; void *page_addr = NULL; - void *dentry_addr = NULL; + void *direntry_addr = NULL; int res = 0; DEBUG(DBG_INFO, @@ -658,20 +801,16 @@ int kdfs_readdir(struct file *filp, void *dirent, filldir_t filldir) k_inode = kdfs_igrab(filp->f_dentry->d_inode->i_ino); if (k_inode->inode->i_size != 0) { - if (filp->f_pos >= k_inode->inode->i_size) { + if (filp->f_pos > k_inode->inode->i_size - KDFS_DIRENT_SIZE) { DEBUG(DBG_INFO, "readdir file offset is greather than file size. Nothing TODO return\n"); goto out; } if (k_inode->content_setid == KDDM_SET_UNUSED) { /* first access to the directory content: create the associated kddm_set */ - create_dir_kddm_set(k_inode); - //dir_set=create_dir_kddm_set(k_inode); // TODO: PRIORITY 1: test kddm creation + create_dir_kddm_set(k_inode); } - // else - // nsid=0=SYS_KDDM__NS_ID cf. ./ctnr/name_space.h - // dir_set = find_get_kddm_set(KDDM_DEF_NS_ID, k_inode->content_setid); DEBUG (DBG_INFO, "kDFS: readdir %s: offset = %d - dir size %d\n", @@ -679,6 +818,7 @@ int kdfs_readdir(struct file *filp, void *dirent, filldir_t filldir) /* Parse directory dentries */ DEBUG(DBG_INFO, "Start to look inside directory\n"); + pageid = filp->f_pos / PAGE_SIZE; pageoffset = filp->f_pos - (pageid * PAGE_SIZE); npages = (k_inode->inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; @@ -693,47 +833,54 @@ int kdfs_readdir(struct file *filp, void *dirent, filldir_t filldir) tmp_page = k_page->page; page_addr = kmap(tmp_page); - dentry_addr = page_addr + pageoffset; + direntry_addr = page_addr + pageoffset; /* For each entry contained in the page */ do { /* Get the directory entry */ - dir_entry = (struct kdfs_dir_entry *) dentry_addr; - DEBUG(DBG_INFO, - "dentry_addr %p (dir_len %d, dirname %s, namelen %d, file size %llu, file pos %llu PAGESIZE=%lu pageoffset=%u)\n", - dentry_addr,dir_entry->rec_len, dir_entry->name, dir_entry->name_len, k_inode->inode->i_size, filp->f_pos, PAGE_SIZE, pageoffset); - - /* Fill the buffer with the current directory entry */ - res = filldir(dirent, dir_entry->name, dir_entry->name_len, + dir_entry = (struct kdfs_dir_entry *) direntry_addr; + + if(dir_entry->ino != KDFS_BAD_INODEID){ + + DEBUG(DBG_INFO, + "direntry_addr %p (dir_len %d, dirname %s, namelen %d, file size %llu, file pos %llu PAGESIZE=%lu pageoffset=%u)\n", + direntry_addr,dir_entry->rec_len, dir_entry->name, dir_entry->name_len, k_inode->inode->i_size, filp->f_pos, PAGE_SIZE, pageoffset); + + + /* Fill the buffer with the current directory entry */ + res = filldir(dirent, dir_entry->name, dir_entry->name_len, filp->f_pos, dir_entry->ino, kdfs_dt_type(dir_entry->mode)); - if (res < 0) { - /* filldir is over (cf. ext2_readdir), so a new dirent should be allocated by the kernel */ - DEBUG(DBG_ALERT, "Can't fill dirent or dirent is full (res=%d)\n",res); - /* Get the directory entry */ - kunmap(tmp_page); - _kdfs_put_page(k_page); - goto out; - } + if (res < 0) { + /* filldir is over (cf. ext2_readdir), so a new dirent should be allocated by the kernel */ + DEBUG(DBG_ALERT, "Can't fill dirent or dirent is full (res=%d)\n",res); + /* Get the directory entry */ + kunmap(tmp_page); + _kdfs_put_page(k_page); + goto out; + } + + } else + DEBUG(DBG_INFO,"direntry_addr %p has been deleted, TODO IMPLEMENT THE GC IN ORDER TO REMOVE USELESS DIR ENTRIES\n",direntry_addr); /* Check if another dentry could be contained in the current page */ - if ((dentry_addr-page_addr+dir_entry->rec_len) <= (PAGE_CACHE_SIZE - KDFS_DIRENT_SIZE)) { - dentry_addr += dir_entry->rec_len; + if ((direntry_addr-page_addr+dir_entry->rec_len) <= (PAGE_CACHE_SIZE - KDFS_DIRENT_SIZE)) { + direntry_addr += dir_entry->rec_len; filp->f_pos += dir_entry->rec_len; } else { - filp->f_pos += (page_addr + PAGE_CACHE_SIZE - dentry_addr); - dentry_addr = 0; + filp->f_pos += (page_addr + PAGE_CACHE_SIZE - direntry_addr); + direntry_addr = 0; pageoffset = 0; - } - + } } - while ((dentry_addr != 0) && ((pageid * PAGE_CACHE_SIZE) + (dentry_addr-page_addr) < k_inode->inode->i_size)); + while ((direntry_addr != 0) && ((pageid * PAGE_CACHE_SIZE) + (direntry_addr-page_addr) < k_inode->inode->i_size)); - //kunmap_atomic(tmp_page, KM_USER0); kunmap(tmp_page); _kdfs_put_page(k_page); pageid++; } while (pageid < npages); + + // TODO If we are the last, then pack all directories entries. } else DEBUG(DBG_INFO, ----------------------------------------------------------------------- Summary of changes: fs/kdfs/dir.c | 213 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 180 insertions(+), 33 deletions(-) hooks/post-receive -- kdfs |