[JFFS2] Prevent ino cache removal for inodes in use

Don't remove inocache for inodes which are in read_inode() or
clear_inode() until they're done.

Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
David Woodhouse 2005-02-27 23:01:36 +00:00 committed by Thomas Gleixner
parent 002fa30170
commit 67e345d17f
5 changed files with 24 additions and 16 deletions

View File

@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: erase.c,v 1.71 2005/02/09 09:17:40 pavlov Exp $
* $Id: erase.c,v 1.72 2005/02/27 23:01:32 dwmw2 Exp $
*
*/
@ -277,11 +277,8 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
printk("\n");
});
if (ic->nodes == (void *)ic) {
D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
if (ic->nodes == (void *)ic)
jffs2_del_ino_cache(c, ic);
jffs2_free_inode_cache(ic);
}
}
static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)

View File

@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: nodelist.c,v 1.92 2005/01/19 19:22:00 tpoynor Exp $
* $Id: nodelist.c,v 1.93 2005/02/27 23:01:32 dwmw2 Exp $
*
*/
@ -506,7 +506,7 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
{
struct jffs2_inode_cache **prev;
D2(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
D1(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
spin_lock(&c->inocache_lock);
prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
@ -518,6 +518,14 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
*prev = old->next;
}
/* Free it now unless it's in READING or CLEARING state, which
are the transitions upon read_inode() and clear_inode(). The
rest of the time we know nobody else is looking at it, and
if it's held by read_inode() or clear_inode() they'll free it
for themselves. */
if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
jffs2_free_inode_cache(old);
spin_unlock(&c->inocache_lock);
}
@ -530,7 +538,6 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
this = c->inocache_list[i];
while (this) {
next = this->next;
D2(printk(KERN_DEBUG "jffs2_free_ino_caches: Freeing ino #%u at %p\n", this->ino, this));
jffs2_free_inode_cache(this);
this = next;
}

View File

@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: nodelist.h,v 1.127 2005/02/09 09:23:53 pavlov Exp $
* $Id: nodelist.h,v 1.128 2005/02/27 23:01:32 dwmw2 Exp $
*
*/
@ -135,6 +135,7 @@ struct jffs2_inode_cache {
#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */
#define INO_STATE_GC 4 /* GCing a 'pristine' node */
#define INO_STATE_READING 5 /* In read_inode() */
#define INO_STATE_CLEARING 6 /* In clear_inode() */
#define INOCACHE_HASHSIZE 128

View File

@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: nodemgmt.c,v 1.117 2005/01/25 20:11:11 hammache Exp $
* $Id: nodemgmt.c,v 1.118 2005/02/27 23:01:32 dwmw2 Exp $
*
*/
@ -593,11 +593,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
*p = ref->next_in_ino;
ref->next_in_ino = NULL;
if (ic->nodes == (void *)ic) {
D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
if (ic->nodes == (void *)ic)
jffs2_del_ino_cache(c, ic);
jffs2_free_inode_cache(ic);
}
spin_unlock(&c->erase_completion_lock);
}

View File

@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: readinode.c,v 1.117 2004/11/20 18:06:54 dwmw2 Exp $
* $Id: readinode.c,v 1.118 2005/02/27 23:01:33 dwmw2 Exp $
*
*/
@ -672,6 +672,9 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
down(&f->sem);
deleted = f->inocache && !f->inocache->nlink;
if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
if (f->metadata) {
if (deleted)
jffs2_mark_node_obsolete(c, f->metadata->raw);
@ -688,8 +691,11 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
jffs2_free_full_dirent(fd);
}
if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
if (f->inocache->nodes == (void *)f->inocache)
jffs2_del_ino_cache(c, f->inocache);
}
up(&f->sem);
}