|
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
|