diff options
author | David Woodhouse <dwmw2@infradead.org> | 2005-04-13 09:22:38 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@mtd.linutronix.de> | 2005-05-23 07:17:49 -0400 |
commit | 7d200960d4f3d1b50c3b9e9688408d9f81c66ff4 (patch) | |
tree | 0faf7439968a955f55871048448abb36fa44c090 | |
parent | 0a18cde60f384d1f7aa012aba004766fb633a31d (diff) |
[JFFS2] Fix inode allocation race
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r-- | fs/jffs2/README.Locking | 6 | ||||
-rw-r--r-- | fs/jffs2/nodelist.c | 6 | ||||
-rw-r--r-- | fs/jffs2/write.c | 7 |
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 | |||
108 | correspondent jffs2_inode_cache object). So, the inocache_lock | 108 | correspondent jffs2_inode_cache object). So, the inocache_lock |
109 | has to be locked while walking the c->inocache_list hash buckets. | 109 | has to be locked while walking the c->inocache_list hash buckets. |
110 | 110 | ||
111 | This spinlock also covers allocation of new inode numbers, which is | ||
112 | currently just '++->highest_ino++', but might one day get more complicated | ||
113 | if we need to deal with wrapping after 4 milliard inode numbers are used. | ||
114 | |||
111 | Note, the f->sem guarantees that the correspondent jffs2_inode_cache | 115 | Note, the f->sem guarantees that the correspondent jffs2_inode_cache |
112 | will not be removed. So, it is allowed to access it without locking | 116 | will not be removed. So, it is allowed to access it without locking |
113 | the inocache_lock spinlock. | 117 | the 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); |