aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2005-04-13 09:22:38 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-05-23 07:17:49 -0400
commit7d200960d4f3d1b50c3b9e9688408d9f81c66ff4 (patch)
tree0faf7439968a955f55871048448abb36fa44c090 /fs/jffs2
parent0a18cde60f384d1f7aa012aba004766fb633a31d (diff)
[JFFS2] Fix inode allocation race
Signed-off-by: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/README.Locking6
-rw-r--r--fs/jffs2/nodelist.c6
-rw-r--r--fs/jffs2/write.c7
3 files changed, 13 insertions, 6 deletions
diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
index 49771cf8513a..b7943439b6ec 100644
--- a/fs/jffs2/README.Locking
+++ b/fs/jffs2/README.Locking
@@ -1,4 +1,4 @@
1 $Id: README.Locking,v 1.9 2004/11/20 10:35:40 dwmw2 Exp $ 1 $Id: README.Locking,v 1.12 2005/04/13 13:22:35 dwmw2 Exp $
2 2
3 JFFS2 LOCKING DOCUMENTATION 3 JFFS2 LOCKING DOCUMENTATION
4 --------------------------- 4 ---------------------------
@@ -108,6 +108,10 @@ in-core jffs2_inode_cache objects (each inode in JFFS2 has the
108correspondent jffs2_inode_cache object). So, the inocache_lock 108correspondent jffs2_inode_cache object). So, the inocache_lock
109has to be locked while walking the c->inocache_list hash buckets. 109has to be locked while walking the c->inocache_list hash buckets.
110 110
111This spinlock also covers allocation of new inode numbers, which is
112currently just '++->highest_ino++', but might one day get more complicated
113if we need to deal with wrapping after 4 milliard inode numbers are used.
114
111Note, the f->sem guarantees that the correspondent jffs2_inode_cache 115Note, the f->sem guarantees that the correspondent jffs2_inode_cache
112will not be removed. So, it is allowed to access it without locking 116will not be removed. So, it is allowed to access it without locking
113the inocache_lock spinlock. 117the inocache_lock spinlock.
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index b835a8652623..c9157e1ea40a 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.93 2005/02/27 23:01:32 dwmw2 Exp $ 10 * $Id: nodelist.c,v 1.94 2005/04/13 13:22:35 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -491,6 +491,10 @@ void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new
491 struct jffs2_inode_cache **prev; 491 struct jffs2_inode_cache **prev;
492 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino)); 492 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
493 spin_lock(&c->inocache_lock); 493 spin_lock(&c->inocache_lock);
494 if (!new->ino)
495 new->ino = ++c->highest_ino;
496
497 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
494 498
495 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE]; 499 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
496 500
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index f3910dc1c2c8..69100615d9ae 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.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: write.c,v 1.91 2005/03/01 10:34:03 dedekind Exp $ 10 * $Id: write.c,v 1.92 2005/04/13 13:22:35 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -35,13 +35,12 @@ int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint
35 f->inocache = ic; 35 f->inocache = ic;
36 f->inocache->nlink = 1; 36 f->inocache->nlink = 1;
37 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; 37 f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
38 f->inocache->ino = ++c->highest_ino;
39 f->inocache->state = INO_STATE_PRESENT; 38 f->inocache->state = INO_STATE_PRESENT;
40 39
41 ri->ino = cpu_to_je32(f->inocache->ino);
42 40
43 D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
44 jffs2_add_ino_cache(c, f->inocache); 41 jffs2_add_ino_cache(c, f->inocache);
42 D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino));
43 ri->ino = cpu_to_je32(f->inocache->ino);
45 44
46 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 45 ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
47 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); 46 ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);