diff options
author | David Woodhouse <dwmw2@infradead.org> | 2005-02-27 18:01:36 -0500 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-05-23 06:46:14 -0400 |
commit | 67e345d17ff8c2085a54c293001ae548f7be7b21 (patch) | |
tree | 07f2829e98c22c5d1edd8832a06a11cbdde85f24 | |
parent | 002fa30170f9500ac31fa22931c689029af7f27b (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.c | 7 | ||||
-rw-r--r-- | fs/jffs2/nodelist.c | 13 | ||||
-rw-r--r-- | fs/jffs2/nodelist.h | 3 | ||||
-rw-r--r-- | fs/jffs2/nodemgmt.c | 7 | ||||
-rw-r--r-- | fs/jffs2/readinode.c | 10 |
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 | ||
287 | static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) | 284 | static 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 | |||
506 | void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old) | 506 | void 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 | } |