mtd/fs/jffs2/ecos/src dir-ecos.c,1.5,1.6 fs-ecos.c,1.14,1.15
jffs2port.h,1.6,1.7
David Woodhouse
dwmw2 at infradead.org
Mon Nov 24 09:54:42 EST 2003
Update of /home/cvs/mtd/fs/jffs2/ecos/src
In directory phoenix.infradead.org:/tmp/cvs-serv2185
Modified Files:
dir-ecos.c fs-ecos.c jffs2port.h
Log Message:
clean up icache some more
Index: dir-ecos.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/dir-ecos.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- dir-ecos.c 24 Nov 2003 13:49:38 -0000 1.5
+++ dir-ecos.c 24 Nov 2003 14:54:39 -0000 1.6
@@ -96,8 +96,7 @@
d_name->name, d_name->len);
if (ret) {
- jffs2_clear_inode(inode);
- make_bad_inode(inode);
+ inode->i_nlink = 0;
iput(inode);
jffs2_free_raw_inode(ri);
return ret;
@@ -204,7 +203,8 @@
/* Eeek. Wave bye bye */
up(&f->sem);
jffs2_complete_reservation(c);
- jffs2_clear_inode(inode);
+ inode->i_nlink = 0;
+ iput(inode);
return PTR_ERR(fn);
}
/* No data here. Only a metadata node, which will be
@@ -217,7 +217,8 @@
ret = jffs2_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
if (ret) {
/* Eep. */
- jffs2_clear_inode(inode);
+ inode->i_nlink = 0;
+ iput(inode);
return ret;
}
@@ -225,7 +226,8 @@
if (!rd) {
/* Argh. Now we treat it like a normal delete */
jffs2_complete_reservation(c);
- jffs2_clear_inode(inode);
+ inode->i_nlink = 0;
+ iput(inode);
return -ENOMEM;
}
@@ -255,7 +257,8 @@
/* dirent failed to write. Delete the inode normally
as if it were the final unlink() */
up(&dir_f->sem);
- jffs2_clear_inode(inode);
+ inode->i_nlink = 0;
+ iput(inode);
return PTR_ERR(fd);
}
Index: fs-ecos.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/fs-ecos.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -r1.14 -r1.15
--- fs-ecos.c 24 Nov 2003 13:54:17 -0000 1.14
+++ fs-ecos.c 24 Nov 2003 14:54:39 -0000 1.15
@@ -144,7 +144,7 @@
// STATIC VARIABLES !!!
static char read_write_buffer[PAGE_CACHE_SIZE]; //avoids malloc when user may be under memory pressure
-static char gc_buffer[PAGE_CACHE_SIZE]; //avoids malloc when user may be under memory pressure
+static unsigned char gc_buffer[PAGE_CACHE_SIZE]; //avoids malloc when user may be under memory pressure
static unsigned char n_fs_mounted = 0; // a counter to track the number of jffs2 instances mounted
//==========================================================================
@@ -169,28 +169,24 @@
// right thing?
static void icache_evict(struct _inode *root_i, struct _inode *i)
{
- struct _inode *cached_inode;
- struct _inode *next_inode;
+ struct _inode *this = root_i, *next;
D2(printf("icache_evict\n"));
// If this is an absolute search path from the root,
// remove all cached inodes with i_count of zero (these are only
// held where needed for dotdot filepaths)
- if (i == root_i) {
- for (cached_inode = root_i; cached_inode != NULL;
- cached_inode = next_inode) {
- next_inode = cached_inode->i_cache_next;
- if (cached_inode->i_count == 0) {
- cached_inode->i_cache_prev->i_cache_next = cached_inode->i_cache_next; // Previous entry points ahead of us
- if (cached_inode->i_cache_next != NULL)
- cached_inode->i_cache_next->i_cache_prev = cached_inode->i_cache_prev; // Next entry points behind us
- jffs2_clear_inode(cached_inode);
- D2(printf
- ("free icache_evict inode %x $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$\n",
- cached_inode));
- free(cached_inode);
- }
+ while (this) {
+ next = this->i_cache_next;
+ if (this != i && this->i_count == 0) {
+
+ if (this->i_cache_next)
+ this->i_cache_next->i_cache_prev = this->i_cache_prev;
+ if (this->i_cache_prev)
+ this->i_cache_prev->i_cache_next = this->i_cache_next;
+ jffs2_clear_inode(this);
+ free(this);
}
+ this = next;
}
}
@@ -467,16 +463,12 @@
D1(printk(KERN_DEBUG "jffs2_read_super(): Getting root inode\n"));
sb->s_root = iget(sb, 1);
- if (!sb->s_root) {
+ if (IS_ERR(sb->s_root)) {
D1(printk(KERN_WARNING "get root inode failed\n"));
- err = -ENOMEM;
+ err = PTR_ERR(sb->s_root);
+ sb->s_root = NULL;
goto out_nodes;
}
- if (is_bad_inode(sb->s_root)) {
- D1(printk(KERN_WARNING "get root inode failed\n"));
- err = EIO;
- goto out_root_i;
- }
sb->s_blocksize = PAGE_CACHE_SIZE;
sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -484,8 +476,6 @@
return 0;
- out_root_i:
- iput(sb->s_root);
out_nodes:
jffs2_free_ino_caches(c);
jffs2_free_raw_node_refs(c);
@@ -585,7 +575,7 @@
// Only really umount if this is the only mount
if (jffs2_sb->s_mount_count == 1) {
-
+ icache_evict(root, NULL);
if (root->i_cache_next != NULL) {
struct _inode *inode = root->i_cache_next;
printf("Refuse to unmount.\n");
@@ -615,7 +605,7 @@
// That's all folks.
D2(printf("jffs2_umount No current mounts\n"));
} else {
- jffs2_sb->s_mount_count--;
+ jffs2_sb->s_mount_count--;
}
if (--n_fs_mounted == 0)
jffs2_destroy_slab_caches();
@@ -636,8 +626,6 @@
D2(printf("jffs2_open\n"));
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -735,8 +723,6 @@
D2(printf("jffs2_ops_unlink\n"));
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -787,8 +773,6 @@
D2(printf("jffs2_ops_mkdir\n"));
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -845,8 +829,6 @@
D2(printf("jffs2_ops_rmdir\n"));
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -1098,8 +1080,6 @@
D2(printf("jffs2_opendir\n"));
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -1144,8 +1124,6 @@
jffs2_dirsearch ds;
int err;
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -1187,8 +1165,6 @@
D2(printf("jffs2_stat\n"));
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -1226,8 +1202,6 @@
D2(printf("jffs2_getinfo\n"));
- icache_evict((struct _inode *) mte->root, (struct _inode *) dir);
-
init_dirsearch(&ds, (struct _inode *) dir, name);
err = jffs2_find(&ds);
@@ -1683,67 +1657,26 @@
//
//==========================================================================
-static struct page *read_cache_page(unsigned long index,
- int (*filler) (void *, struct page *), void *data)
-{
- // Only called in gc.c jffs2_garbage_collect_dnode
- // but gets a real page for the specified inode
-
- int err;
- struct page *gc_page = malloc(sizeof (struct page));
-
- printf("read_cache_page\n");
- memset(&gc_buffer, 0, PAGE_CACHE_SIZE);
-
- if (gc_page != NULL) {
- gc_page->virtual = &gc_buffer;
- gc_page->index = index;
-
- err = filler(data, gc_page);
- if (err < 0) {
- free(gc_page);
- gc_page = NULL;
- }
- }
-
- return gc_page;
-}
-
-static void page_cache_release(struct page *pg)
-{
-
- // Only called in gc.c jffs2_garbage_collect_dnode
- // but should free the page malloc'd by read_cache_page
-
- printf("page_cache_release\n");
- free(pg);
-}
-
unsigned char *jffs2_gc_fetch_page(struct jffs2_sb_info *c,
struct jffs2_inode_info *f,
unsigned long offset,
unsigned long *priv)
{
- struct _inode *inode = OFNI_EDONI_2SFFJ(f);
- struct page *pg;
+ /* FIXME: This works only with one file system mounted at a time */
+ int ret;
- pg = read_cache_page(offset >> PAGE_CACHE_SHIFT,
- (void *)jffs2_do_readpage_unlock, inode);
- if (IS_ERR(pg))
- return (void *)pg;
-
- *priv = (unsigned long)pg;
- return kmap(pg);
+ ret = jffs2_read_inode_range(c, f, gc_buffer, offset, PAGE_CACHE_SIZE);
+ if (ret)
+ return ERR_PTR(ret);
+
+ return gc_buffer;
}
void jffs2_gc_release_page(struct jffs2_sb_info *c,
unsigned char *ptr,
unsigned long *priv)
{
- struct page *pg = (void *)*priv;
-
- kunmap(pg);
- page_cache_release(pg);
+ /* Do nothing */
}
static struct _inode *new_inode(struct super_block *sb)
@@ -1785,6 +1718,7 @@
return inode;
}
+
struct _inode *ilookup(struct super_block *sb, cyg_uint32 ino)
{
struct _inode *inode = NULL;
@@ -1810,6 +1744,7 @@
// If this fails let new_inode create one
struct _inode *inode;
+ int err;
D2(printf("iget\n"));
@@ -1824,10 +1759,13 @@
inode->i_ino = ino;
inode->i_count = 1;
- if (jffs2_read_inode(inode)) {
+
+ err = jffs2_read_inode(inode);
+ if (err) {
printf("jffs2_read_inode() failed\n");
iput(inode);
inode = NULL;
+ return ERR_PTR(err);
}
return inode;
}
@@ -1844,8 +1782,6 @@
// super.c jffs2_read_super,
// and gc.c jffs2_garbage_collect_pass
- struct _inode *cached_inode;
-
if (!i) {
printf("iput() called with NULL inode\n");
// and let it fault...
@@ -1856,60 +1792,22 @@
if (i->i_count)
return;
- if (i != NULL) {
- // Remove from the icache
- for (cached_inode = i->i_sb->s_root; cached_inode != NULL;
- cached_inode = cached_inode->i_cache_next) {
- if (cached_inode == i) {
- if(cached_inode->i_cache_prev != NULL) {
- cached_inode->i_cache_prev->i_cache_next = cached_inode->i_cache_next; // Previous entry points ahead of us
- if (cached_inode->i_cache_next != NULL)
- cached_inode->i_cache_next->i_cache_prev = cached_inode->i_cache_prev; // Next entry points behind us
- }
- break;
- }
- }
- // inode has been seperated from the cache
+ if (!i->i_nlink) {
+ // Remove from the icache linked list and free immediately
+ if (i->i_cache_prev)
+ i->i_cache_prev->i_cache_next = i->i_cache_next;
+ if (i->i_cache_next)
+ i->i_cache_next->i_cache_prev = i->i_cache_prev;
+
jffs2_clear_inode(i);
free(i);
+ } else {
+ // Evict some _other_ inode with i_count zero, leaving
+ // this latest one in the cache for a while
+ icache_evict(i->i_sb->s_root, i);
}
}
-static int return_EIO(void)
-{
- return -EIO;
-}
-
-#define EIO_ERROR ((void *) (return_EIO))
-
-void make_bad_inode(struct _inode *inode)
-{
-
- // In readinode.c JFFS2 checks whether the inode has appropriate
- // content for its marked type
-
- D2(printf("make_bad_inode\n"));
-
- inode->i_mode = S_IFREG;
- inode->i_atime = inode->i_mtime = inode->i_ctime = cyg_timestamp();
- inode->i_op = EIO_ERROR;
- inode->i_fop = EIO_ERROR;
-}
-
-int is_bad_inode(struct _inode *inode)
-{
-
- // Called in super.c jffs2_read_super,
- // and gc.c jffs2_garbage_collect_pass
-
- D2(printf("is_bad_inode\n"));
-
- return (inode->i_op == EIO_ERROR);
- /*if(i == NULL)
- return 1;
- return 0; */
-}
-
cyg_bool jffs2_flash_read(struct jffs2_sb_info * c,
cyg_uint32 read_buffer_offset, const size_t size,
size_t * return_size, char *write_buffer)
@@ -2098,7 +1996,6 @@
ri->mode = cpu_to_jemode(mode);
ret = jffs2_do_new_inode (c, f, mode, ri);
if (ret) {
- make_bad_inode(inode);
iput(inode);
return ERR_PTR(ret);
}
@@ -2133,7 +2030,6 @@
ret = jffs2_do_read_inode(c, f, inode->i_ino, &latest_node);
if (ret) {
- make_bad_inode(inode);
up(&f->sem);
return ret;
}
@@ -2208,15 +2104,8 @@
Just iget() it, and if read_inode() is necessary that's OK.
*/
inode = iget(OFNI_BS_2SFFJ(c), inum);
- if (!inode)
- return ERR_PTR(-ENOMEM);
- }
- if (is_bad_inode(inode)) {
- printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. nlink %d\n",
- inum, nlink);
- /* NB. This will happen again. We need to do something appropriate here. */
- iput(inode);
- return ERR_PTR(-EIO);
+ if (IS_ERR(inode))
+ return (void *)inode;
}
return JFFS2_INODE_INFO(inode);
Index: jffs2port.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/ecos/src/jffs2port.h,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- jffs2port.h 24 Nov 2003 13:49:38 -0000 1.6
+++ jffs2port.h 24 Nov 2003 14:54:39 -0000 1.7
@@ -172,8 +172,6 @@
//static struct _inode * new_inode(struct super_block *sb);
struct _inode * iget(struct super_block *sb, cyg_uint32 ino);
void iput(struct _inode * i);
-void make_bad_inode(struct _inode * inode);
-int is_bad_inode(struct _inode * inode);
struct jffs2_sb_info;
struct jffs2_eraseblock;
More information about the linux-mtd-cvs
mailing list