mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
[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:
parent
002fa30170
commit
67e345d17f
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user