aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2005-02-27 18:01:36 -0500
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-05-23 06:46:14 -0400
commit67e345d17ff8c2085a54c293001ae548f7be7b21 (patch)
tree07f2829e98c22c5d1edd8832a06a11cbdde85f24
parent002fa30170f9500ac31fa22931c689029af7f27b (diff)
[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>
-rw-r--r--fs/jffs2/erase.c7
-rw-r--r--fs/jffs2/nodelist.c13
-rw-r--r--fs/jffs2/nodelist.h3
-rw-r--r--fs/jffs2/nodemgmt.c7
-rw-r--r--fs/jffs2/readinode.c10
5 files changed, 24 insertions, 16 deletions
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index a3c6cc150497..d1ae565352a6 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: erase.c,v 1.71 2005/02/09 09:17:40 pavlov Exp $ 10 * $Id: erase.c,v 1.72 2005/02/27 23:01:32 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -277,11 +277,8 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
277 printk("\n"); 277 printk("\n");
278 }); 278 });
279 279
280 if (ic->nodes == (void *)ic) { 280 if (ic->nodes == (void *)ic)
281 D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
282 jffs2_del_ino_cache(c, ic); 281 jffs2_del_ino_cache(c, ic);
283 jffs2_free_inode_cache(ic);
284 }
285} 282}
286 283
287static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 284static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 3c6d93c8ea0a..b835a8652623 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.c,v 1.92 2005/01/19 19:22:00 tpoynor Exp $ 10 * $Id: nodelist.c,v 1.93 2005/02/27 23:01:32 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -506,7 +506,7 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
506void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old) 506void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
507{ 507{
508 struct jffs2_inode_cache **prev; 508 struct jffs2_inode_cache **prev;
509 D2(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino)); 509 D1(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
510 spin_lock(&c->inocache_lock); 510 spin_lock(&c->inocache_lock);
511 511
512 prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE]; 512 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)
518 *prev = old->next; 518 *prev = old->next;
519 } 519 }
520 520
521 /* Free it now unless it's in READING or CLEARING state, which
522 are the transitions upon read_inode() and clear_inode(). The
523 rest of the time we know nobody else is looking at it, and
524 if it's held by read_inode() or clear_inode() they'll free it
525 for themselves. */
526 if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
527 jffs2_free_inode_cache(old);
528
521 spin_unlock(&c->inocache_lock); 529 spin_unlock(&c->inocache_lock);
522} 530}
523 531
@@ -530,7 +538,6 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
530 this = c->inocache_list[i]; 538 this = c->inocache_list[i];
531 while (this) { 539 while (this) {
532 next = this->next; 540 next = this->next;
533 D2(printk(KERN_DEBUG "jffs2_free_ino_caches: Freeing ino #%u at %p\n", this->ino, this));
534 jffs2_free_inode_cache(this); 541 jffs2_free_inode_cache(this);
535 this = next; 542 this = next;
536 } 543 }
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index 8c122838bf6d..57f675c2c97f 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.h,v 1.127 2005/02/09 09:23:53 pavlov Exp $ 10 * $Id: nodelist.h,v 1.128 2005/02/27 23:01:32 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -135,6 +135,7 @@ struct jffs2_inode_cache {
135#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */ 135#define INO_STATE_CHECKEDABSENT 3 /* Checked, cleared again */
136#define INO_STATE_GC 4 /* GCing a 'pristine' node */ 136#define INO_STATE_GC 4 /* GCing a 'pristine' node */
137#define INO_STATE_READING 5 /* In read_inode() */ 137#define INO_STATE_READING 5 /* In read_inode() */
138#define INO_STATE_CLEARING 6 /* In clear_inode() */
138 139
139#define INOCACHE_HASHSIZE 128 140#define INOCACHE_HASHSIZE 128
140 141
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 5e1e8caf54e8..f9dcac1415ac 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodemgmt.c,v 1.117 2005/01/25 20:11:11 hammache Exp $ 10 * $Id: nodemgmt.c,v 1.118 2005/02/27 23:01:32 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -593,11 +593,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
593 *p = ref->next_in_ino; 593 *p = ref->next_in_ino;
594 ref->next_in_ino = NULL; 594 ref->next_in_ino = NULL;
595 595
596 if (ic->nodes == (void *)ic) { 596 if (ic->nodes == (void *)ic)
597 D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
598 jffs2_del_ino_cache(c, ic); 597 jffs2_del_ino_cache(c, ic);
599 jffs2_free_inode_cache(ic);
600 }
601 598
602 spin_unlock(&c->erase_completion_lock); 599 spin_unlock(&c->erase_completion_lock);
603 } 600 }
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index aca4a0b17bcd..a1980a9da531 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: readinode.c,v 1.117 2004/11/20 18:06:54 dwmw2 Exp $ 10 * $Id: readinode.c,v 1.118 2005/02/27 23:01:33 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -672,6 +672,9 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
672 down(&f->sem); 672 down(&f->sem);
673 deleted = f->inocache && !f->inocache->nlink; 673 deleted = f->inocache && !f->inocache->nlink;
674 674
675 if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
676 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
677
675 if (f->metadata) { 678 if (f->metadata) {
676 if (deleted) 679 if (deleted)
677 jffs2_mark_node_obsolete(c, f->metadata->raw); 680 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)
688 jffs2_free_full_dirent(fd); 691 jffs2_free_full_dirent(fd);
689 } 692 }
690 693
691 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) 694 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
692 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 695 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
696 if (f->inocache->nodes == (void *)f->inocache)
697 jffs2_del_ino_cache(c, f->inocache);
698 }
693 699
694 up(&f->sem); 700 up(&f->sem);
695} 701}