Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67e345d1 authored by David Woodhouse's avatar David Woodhouse Committed by Thomas Gleixner
Browse files

[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: default avatarDavid Woodhouse <dwmw2@infradead.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 002fa301
Loading
Loading
Loading
Loading
+2 −5
Original line number Diff line number Diff line
@@ -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)
+10 −3
Original line number Diff line number Diff line
@@ -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;
		}
+2 −1
Original line number Diff line number Diff line
@@ -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

+2 −5
Original line number Diff line number Diff line
@@ -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);
	}
+8 −2
Original line number Diff line number Diff line
@@ -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);
}