aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/Makefile5
-rw-r--r--fs/jffs2/README.Locking6
-rw-r--r--fs/jffs2/background.c13
-rw-r--r--fs/jffs2/build.c9
-rw-r--r--fs/jffs2/compr_zlib.c4
-rw-r--r--fs/jffs2/dir.c46
-rw-r--r--fs/jffs2/erase.c24
-rw-r--r--fs/jffs2/file.c5
-rw-r--r--fs/jffs2/fs.c24
-rw-r--r--fs/jffs2/gc.c41
-rw-r--r--fs/jffs2/nodelist.c93
-rw-r--r--fs/jffs2/nodelist.h21
-rw-r--r--fs/jffs2/nodemgmt.c31
-rw-r--r--fs/jffs2/os-linux.h60
-rw-r--r--fs/jffs2/read.c32
-rw-r--r--fs/jffs2/readinode.c96
-rw-r--r--fs/jffs2/scan.c39
-rw-r--r--fs/jffs2/super.c8
-rw-r--r--fs/jffs2/symlink.c42
-rw-r--r--fs/jffs2/wbuf.c164
-rw-r--r--fs/jffs2/write.c55
21 files changed, 524 insertions, 294 deletions
diff --git a/fs/jffs2/Makefile b/fs/jffs2/Makefile
index e3c38ccf9c7..f1afe681ecd 100644
--- a/fs/jffs2/Makefile
+++ b/fs/jffs2/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for the Linux Journalling Flash File System v2 (JFFS2) 2# Makefile for the Linux Journalling Flash File System v2 (JFFS2)
3# 3#
4# $Id: Makefile.common,v 1.7 2004/11/03 12:57:38 jwboyer Exp $ 4# $Id: Makefile.common,v 1.9 2005/02/09 09:23:53 pavlov Exp $
5# 5#
6 6
7obj-$(CONFIG_JFFS2_FS) += jffs2.o 7obj-$(CONFIG_JFFS2_FS) += jffs2.o
@@ -11,8 +11,7 @@ jffs2-y += read.o nodemgmt.o readinode.o write.o scan.o gc.o
11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o 11jffs2-y += symlink.o build.o erase.o background.o fs.o writev.o
12jffs2-y += super.o 12jffs2-y += super.o
13 13
14jffs2-$(CONFIG_JFFS2_FS_NAND) += wbuf.o 14jffs2-$(CONFIG_JFFS2_FS_WRITEBUFFER) += wbuf.o
15jffs2-$(CONFIG_JFFS2_FS_NOR_ECC) += wbuf.o
16jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o 15jffs2-$(CONFIG_JFFS2_RUBIN) += compr_rubin.o
17jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o 16jffs2-$(CONFIG_JFFS2_RTIME) += compr_rtime.o
18jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o 17jffs2-$(CONFIG_JFFS2_ZLIB) += compr_zlib.o
diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
index 49771cf8513..b7943439b6e 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/background.c b/fs/jffs2/background.c
index 638836b277d..0f224384f17 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.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: background.c,v 1.50 2004/11/16 20:36:10 dwmw2 Exp $ 10 * $Id: background.c,v 1.54 2005/05/20 21:37:12 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -37,7 +37,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
37 if (c->gc_task) 37 if (c->gc_task)
38 BUG(); 38 BUG();
39 39
40 init_MUTEX_LOCKED(&c->gc_thread_start); 40 init_completion(&c->gc_thread_start);
41 init_completion(&c->gc_thread_exit); 41 init_completion(&c->gc_thread_exit);
42 42
43 pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES); 43 pid = kernel_thread(jffs2_garbage_collect_thread, c, CLONE_FS|CLONE_FILES);
@@ -48,7 +48,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
48 } else { 48 } else {
49 /* Wait for it... */ 49 /* Wait for it... */
50 D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid)); 50 D1(printk(KERN_DEBUG "JFFS2: Garbage collect thread is pid %d\n", pid));
51 down(&c->gc_thread_start); 51 wait_for_completion(&c->gc_thread_start);
52 } 52 }
53 53
54 return ret; 54 return ret;
@@ -56,13 +56,16 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
56 56
57void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c) 57void jffs2_stop_garbage_collect_thread(struct jffs2_sb_info *c)
58{ 58{
59 int wait = 0;
59 spin_lock(&c->erase_completion_lock); 60 spin_lock(&c->erase_completion_lock);
60 if (c->gc_task) { 61 if (c->gc_task) {
61 D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid)); 62 D1(printk(KERN_DEBUG "jffs2: Killing GC task %d\n", c->gc_task->pid));
62 send_sig(SIGKILL, c->gc_task, 1); 63 send_sig(SIGKILL, c->gc_task, 1);
64 wait = 1;
63 } 65 }
64 spin_unlock(&c->erase_completion_lock); 66 spin_unlock(&c->erase_completion_lock);
65 wait_for_completion(&c->gc_thread_exit); 67 if (wait)
68 wait_for_completion(&c->gc_thread_exit);
66} 69}
67 70
68static int jffs2_garbage_collect_thread(void *_c) 71static int jffs2_garbage_collect_thread(void *_c)
@@ -75,7 +78,7 @@ static int jffs2_garbage_collect_thread(void *_c)
75 allow_signal(SIGCONT); 78 allow_signal(SIGCONT);
76 79
77 c->gc_task = current; 80 c->gc_task = current;
78 up(&c->gc_thread_start); 81 complete(&c->gc_thread_start);
79 82
80 set_user_nice(current, 10); 83 set_user_nice(current, 10);
81 84
diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
index a01dd5fdbb9..3dd5394921c 100644
--- a/fs/jffs2/build.c
+++ b/fs/jffs2/build.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: build.c,v 1.69 2004/12/16 20:22:18 dmarlin Exp $ 10 * $Id: build.c,v 1.70 2005/02/28 08:21:05 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -97,14 +97,16 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
97 /* First, scan the medium and build all the inode caches with 97 /* First, scan the medium and build all the inode caches with
98 lists of physical nodes */ 98 lists of physical nodes */
99 99
100 c->flags |= JFFS2_SB_FLAG_MOUNTING; 100 c->flags |= JFFS2_SB_FLAG_SCANNING;
101 ret = jffs2_scan_medium(c); 101 ret = jffs2_scan_medium(c);
102 c->flags &= ~JFFS2_SB_FLAG_SCANNING;
102 if (ret) 103 if (ret)
103 goto exit; 104 goto exit;
104 105
105 D1(printk(KERN_DEBUG "Scanned flash completely\n")); 106 D1(printk(KERN_DEBUG "Scanned flash completely\n"));
106 D2(jffs2_dump_block_lists(c)); 107 D2(jffs2_dump_block_lists(c));
107 108
109 c->flags |= JFFS2_SB_FLAG_BUILDING;
108 /* Now scan the directory tree, increasing nlink according to every dirent found. */ 110 /* Now scan the directory tree, increasing nlink according to every dirent found. */
109 for_each_inode(i, c, ic) { 111 for_each_inode(i, c, ic) {
110 D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino)); 112 D1(printk(KERN_DEBUG "Pass 1: ino #%u\n", ic->ino));
@@ -116,7 +118,6 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
116 cond_resched(); 118 cond_resched();
117 } 119 }
118 } 120 }
119 c->flags &= ~JFFS2_SB_FLAG_MOUNTING;
120 121
121 D1(printk(KERN_DEBUG "Pass 1 complete\n")); 122 D1(printk(KERN_DEBUG "Pass 1 complete\n"));
122 123
@@ -164,6 +165,8 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
164 ic->scan_dents = NULL; 165 ic->scan_dents = NULL;
165 cond_resched(); 166 cond_resched();
166 } 167 }
168 c->flags &= ~JFFS2_SB_FLAG_BUILDING;
169
167 D1(printk(KERN_DEBUG "Pass 3 complete\n")); 170 D1(printk(KERN_DEBUG "Pass 3 complete\n"));
168 D2(jffs2_dump_block_lists(c)); 171 D2(jffs2_dump_block_lists(c));
169 172
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 078a30e406b..83f7e0788fd 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.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: compr_zlib.c,v 1.29 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: compr_zlib.c,v 1.31 2005/05/20 19:30:06 gleixner Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -17,10 +17,10 @@
17 17
18#include <linux/config.h> 18#include <linux/config.h>
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/sched.h>
20#include <linux/slab.h> 21#include <linux/slab.h>
21#include <linux/zlib.h> 22#include <linux/zlib.h>
22#include <linux/zutil.h> 23#include <linux/zutil.h>
23#include <asm/semaphore.h>
24#include "nodelist.h" 24#include "nodelist.h"
25#include "compr.h" 25#include "compr.h"
26 26
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 757306fa3ff..3ca0d25eef1 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.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: dir.c,v 1.84 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: dir.c,v 1.86 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -22,16 +22,6 @@
22#include <linux/time.h> 22#include <linux/time.h>
23#include "nodelist.h" 23#include "nodelist.h"
24 24
25/* Urgh. Please tell me there's a nicer way of doing these. */
26#include <linux/version.h>
27#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,48)
28typedef int mknod_arg_t;
29#define NAMEI_COMPAT(x) ((void *)x)
30#else
31typedef dev_t mknod_arg_t;
32#define NAMEI_COMPAT(x) (x)
33#endif
34
35static int jffs2_readdir (struct file *, void *, filldir_t); 25static int jffs2_readdir (struct file *, void *, filldir_t);
36 26
37static int jffs2_create (struct inode *,struct dentry *,int, 27static int jffs2_create (struct inode *,struct dentry *,int,
@@ -43,7 +33,7 @@ static int jffs2_unlink (struct inode *,struct dentry *);
43static int jffs2_symlink (struct inode *,struct dentry *,const char *); 33static int jffs2_symlink (struct inode *,struct dentry *,const char *);
44static int jffs2_mkdir (struct inode *,struct dentry *,int); 34static int jffs2_mkdir (struct inode *,struct dentry *,int);
45static int jffs2_rmdir (struct inode *,struct dentry *); 35static int jffs2_rmdir (struct inode *,struct dentry *);
46static int jffs2_mknod (struct inode *,struct dentry *,int,mknod_arg_t); 36static int jffs2_mknod (struct inode *,struct dentry *,int,dev_t);
47static int jffs2_rename (struct inode *, struct dentry *, 37static int jffs2_rename (struct inode *, struct dentry *,
48 struct inode *, struct dentry *); 38 struct inode *, struct dentry *);
49 39
@@ -58,8 +48,8 @@ struct file_operations jffs2_dir_operations =
58 48
59struct inode_operations jffs2_dir_inode_operations = 49struct inode_operations jffs2_dir_inode_operations =
60{ 50{
61 .create = NAMEI_COMPAT(jffs2_create), 51 .create = jffs2_create,
62 .lookup = NAMEI_COMPAT(jffs2_lookup), 52 .lookup = jffs2_lookup,
63 .link = jffs2_link, 53 .link = jffs2_link,
64 .unlink = jffs2_unlink, 54 .unlink = jffs2_unlink,
65 .symlink = jffs2_symlink, 55 .symlink = jffs2_symlink,
@@ -296,11 +286,11 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
296 struct jffs2_full_dirent *fd; 286 struct jffs2_full_dirent *fd;
297 int namelen; 287 int namelen;
298 uint32_t alloclen, phys_ofs; 288 uint32_t alloclen, phys_ofs;
299 int ret; 289 int ret, targetlen = strlen(target);
300 290
301 /* FIXME: If you care. We'd need to use frags for the target 291 /* FIXME: If you care. We'd need to use frags for the target
302 if it grows much more than this */ 292 if it grows much more than this */
303 if (strlen(target) > 254) 293 if (targetlen > 254)
304 return -EINVAL; 294 return -EINVAL;
305 295
306 ri = jffs2_alloc_raw_inode(); 296 ri = jffs2_alloc_raw_inode();
@@ -314,7 +304,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
314 * Just the node will do for now, though 304 * Just the node will do for now, though
315 */ 305 */
316 namelen = dentry->d_name.len; 306 namelen = dentry->d_name.len;
317 ret = jffs2_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL); 307 ret = jffs2_reserve_space(c, sizeof(*ri) + targetlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
318 308
319 if (ret) { 309 if (ret) {
320 jffs2_free_raw_inode(ri); 310 jffs2_free_raw_inode(ri);
@@ -333,16 +323,16 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
333 323
334 f = JFFS2_INODE_INFO(inode); 324 f = JFFS2_INODE_INFO(inode);
335 325
336 inode->i_size = strlen(target); 326 inode->i_size = targetlen;
337 ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size); 327 ri->isize = ri->dsize = ri->csize = cpu_to_je32(inode->i_size);
338 ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size); 328 ri->totlen = cpu_to_je32(sizeof(*ri) + inode->i_size);
339 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); 329 ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4));
340 330
341 ri->compr = JFFS2_COMPR_NONE; 331 ri->compr = JFFS2_COMPR_NONE;
342 ri->data_crc = cpu_to_je32(crc32(0, target, strlen(target))); 332 ri->data_crc = cpu_to_je32(crc32(0, target, targetlen));
343 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8)); 333 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
344 334
345 fn = jffs2_write_dnode(c, f, ri, target, strlen(target), phys_ofs, ALLOC_NORMAL); 335 fn = jffs2_write_dnode(c, f, ri, target, targetlen, phys_ofs, ALLOC_NORMAL);
346 336
347 jffs2_free_raw_inode(ri); 337 jffs2_free_raw_inode(ri);
348 338
@@ -353,6 +343,20 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
353 jffs2_clear_inode(inode); 343 jffs2_clear_inode(inode);
354 return PTR_ERR(fn); 344 return PTR_ERR(fn);
355 } 345 }
346
347 /* We use f->dents field to store the target path. */
348 f->dents = kmalloc(targetlen + 1, GFP_KERNEL);
349 if (!f->dents) {
350 printk(KERN_WARNING "Can't allocate %d bytes of memory\n", targetlen + 1);
351 up(&f->sem);
352 jffs2_complete_reservation(c);
353 jffs2_clear_inode(inode);
354 return -ENOMEM;
355 }
356
357 memcpy(f->dents, target, targetlen + 1);
358 D1(printk(KERN_DEBUG "jffs2_symlink: symlink's target '%s' cached\n", (char *)f->dents));
359
356 /* No data here. Only a metadata node, which will be 360 /* No data here. Only a metadata node, which will be
357 obsoleted by the first data write 361 obsoleted by the first data write
358 */ 362 */
@@ -564,7 +568,7 @@ static int jffs2_rmdir (struct inode *dir_i, struct dentry *dentry)
564 return ret; 568 return ret;
565} 569}
566 570
567static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mknod_arg_t rdev) 571static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, dev_t rdev)
568{ 572{
569 struct jffs2_inode_info *f, *dir_f; 573 struct jffs2_inode_info *f, *dir_f;
570 struct jffs2_sb_info *c; 574 struct jffs2_sb_info *c;
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index 41451e8bf36..6a4c0a3685d 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.66 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: erase.c,v 1.76 2005/05/03 15:11:40 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -48,6 +48,7 @@ static void jffs2_erase_block(struct jffs2_sb_info *c,
48#else /* Linux */ 48#else /* Linux */
49 struct erase_info *instr; 49 struct erase_info *instr;
50 50
51 D1(printk(KERN_DEBUG "jffs2_erase_block(): erase block %#x (range %#x-%#x)\n", jeb->offset, jeb->offset, jeb->offset + c->sector_size));
51 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL); 52 instr = kmalloc(sizeof(struct erase_info) + sizeof(struct erase_priv_struct), GFP_KERNEL);
52 if (!instr) { 53 if (!instr) {
53 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n"); 54 printk(KERN_WARNING "kmalloc for struct erase_info in jffs2_erase_block failed. Refiling block for later\n");
@@ -233,7 +234,7 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
233 continue; 234 continue;
234 } 235 }
235 236
236 if (((*prev)->flash_offset & ~(c->sector_size -1)) == jeb->offset) { 237 if (SECTOR_ADDR((*prev)->flash_offset) == jeb->offset) {
237 /* It's in the block we're erasing */ 238 /* It's in the block we're erasing */
238 struct jffs2_raw_node_ref *this; 239 struct jffs2_raw_node_ref *this;
239 240
@@ -277,11 +278,8 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
277 printk("\n"); 278 printk("\n");
278 }); 279 });
279 280
280 if (ic->nodes == (void *)ic) { 281 if (ic->nodes == (void *)ic && ic->nlink == 0)
281 D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
282 jffs2_del_ino_cache(c, ic); 282 jffs2_del_ino_cache(c, ic);
283 jffs2_free_inode_cache(ic);
284 }
285} 283}
286 284
287static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 285static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
@@ -310,7 +308,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
310 int ret; 308 int ret;
311 uint32_t bad_offset; 309 uint32_t bad_offset;
312 310
313 if (!jffs2_cleanmarker_oob(c)) { 311 if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0)) {
314 marker_ref = jffs2_alloc_raw_node_ref(); 312 marker_ref = jffs2_alloc_raw_node_ref();
315 if (!marker_ref) { 313 if (!marker_ref) {
316 printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n"); 314 printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");
@@ -335,7 +333,8 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
335 333
336 bad_offset = ofs; 334 bad_offset = ofs;
337 335
338 ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf); 336 ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);
337
339 if (ret) { 338 if (ret) {
340 printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret); 339 printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);
341 goto bad; 340 goto bad;
@@ -351,7 +350,7 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
351 bad_offset += i; 350 bad_offset += i;
352 printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset); 351 printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset);
353 bad: 352 bad:
354 if (!jffs2_cleanmarker_oob(c)) 353 if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0))
355 jffs2_free_raw_node_ref(marker_ref); 354 jffs2_free_raw_node_ref(marker_ref);
356 kfree(ebuf); 355 kfree(ebuf);
357 bad2: 356 bad2:
@@ -387,6 +386,13 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
387 jeb->used_size = 0; 386 jeb->used_size = 0;
388 jeb->dirty_size = 0; 387 jeb->dirty_size = 0;
389 jeb->wasted_size = 0; 388 jeb->wasted_size = 0;
389 } else if (c->cleanmarker_size == 0) {
390 jeb->first_node = jeb->last_node = NULL;
391
392 jeb->free_size = c->sector_size;
393 jeb->used_size = 0;
394 jeb->dirty_size = 0;
395 jeb->wasted_size = 0;
390 } else { 396 } else {
391 struct kvec vecs[1]; 397 struct kvec vecs[1];
392 struct jffs2_unknown_node marker = { 398 struct jffs2_unknown_node marker = {
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index 771a554701d..bd9ed9b0247 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -7,11 +7,10 @@
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: file.c,v 1.99 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: file.c,v 1.102 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
14#include <linux/version.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/slab.h> 15#include <linux/slab.h>
17#include <linux/fs.h> 16#include <linux/fs.h>
@@ -51,9 +50,7 @@ struct file_operations jffs2_file_operations =
51 .ioctl = jffs2_ioctl, 50 .ioctl = jffs2_ioctl,
52 .mmap = generic_file_readonly_mmap, 51 .mmap = generic_file_readonly_mmap,
53 .fsync = jffs2_fsync, 52 .fsync = jffs2_fsync,
54#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,29)
55 .sendfile = generic_file_sendfile 53 .sendfile = generic_file_sendfile
56#endif
57}; 54};
58 55
59/* jffs2_file_inode_operations */ 56/* jffs2_file_inode_operations */
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 30ab233fe42..5687c3f4200 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -7,11 +7,10 @@
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: fs.c,v 1.51 2004/11/28 12:19:37 dedekind Exp $ 10 * $Id: fs.c,v 1.56 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
14#include <linux/version.h>
15#include <linux/config.h> 14#include <linux/config.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
@@ -450,11 +449,15 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
450 449
451 c = JFFS2_SB_INFO(sb); 450 c = JFFS2_SB_INFO(sb);
452 451
453#ifndef CONFIG_JFFS2_FS_NAND 452#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
454 if (c->mtd->type == MTD_NANDFLASH) { 453 if (c->mtd->type == MTD_NANDFLASH) {
455 printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n"); 454 printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n");
456 return -EINVAL; 455 return -EINVAL;
457 } 456 }
457 if (c->mtd->type == MTD_DATAFLASH) {
458 printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
459 return -EINVAL;
460 }
458#endif 461#endif
459 462
460 c->flash_size = c->mtd->size; 463 c->flash_size = c->mtd->size;
@@ -522,9 +525,7 @@ int jffs2_do_fill_super(struct super_block *sb, void *data, int silent)
522 if (!sb->s_root) 525 if (!sb->s_root)
523 goto out_root_i; 526 goto out_root_i;
524 527
525#if LINUX_VERSION_CODE >= 0x20403
526 sb->s_maxbytes = 0xFFFFFFFF; 528 sb->s_maxbytes = 0xFFFFFFFF;
527#endif
528 sb->s_blocksize = PAGE_CACHE_SIZE; 529 sb->s_blocksize = PAGE_CACHE_SIZE;
529 sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 530 sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
530 sb->s_magic = JFFS2_SUPER_MAGIC; 531 sb->s_magic = JFFS2_SUPER_MAGIC;
@@ -661,6 +662,14 @@ static int jffs2_flash_setup(struct jffs2_sb_info *c) {
661 if (ret) 662 if (ret)
662 return ret; 663 return ret;
663 } 664 }
665
666 /* and Dataflash */
667 if (jffs2_dataflash(c)) {
668 ret = jffs2_dataflash_setup(c);
669 if (ret)
670 return ret;
671 }
672
664 return ret; 673 return ret;
665} 674}
666 675
@@ -674,4 +683,9 @@ void jffs2_flash_cleanup(struct jffs2_sb_info *c) {
674 if (jffs2_nor_ecc(c)) { 683 if (jffs2_nor_ecc(c)) {
675 jffs2_nor_ecc_flash_cleanup(c); 684 jffs2_nor_ecc_flash_cleanup(c);
676 } 685 }
686
687 /* and DataFlash */
688 if (jffs2_dataflash(c)) {
689 jffs2_dataflash_cleanup(c);
690 }
677} 691}
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 87ec74ff593..7086cd63450 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.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: gc.c,v 1.144 2004/12/21 11:18:50 dwmw2 Exp $ 10 * $Id: gc.c,v 1.148 2005/04/09 10:47:00 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -50,6 +50,7 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
50 put the clever wear-levelling algorithms. Eventually. */ 50 put the clever wear-levelling algorithms. Eventually. */
51 /* We possibly want to favour the dirtier blocks more when the 51 /* We possibly want to favour the dirtier blocks more when the
52 number of free blocks is low. */ 52 number of free blocks is low. */
53again:
53 if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) { 54 if (!list_empty(&c->bad_used_list) && c->nr_free_blocks > c->resv_blocks_gcbad) {
54 D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n")); 55 D1(printk(KERN_DEBUG "Picking block from bad_used_list to GC next\n"));
55 nextlist = &c->bad_used_list; 56 nextlist = &c->bad_used_list;
@@ -79,6 +80,13 @@ static struct jffs2_eraseblock *jffs2_find_gc_block(struct jffs2_sb_info *c)
79 D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n")); 80 D1(printk(KERN_DEBUG "Picking block from erasable_list to GC next (clean_list and {very_,}dirty_list were empty)\n"));
80 81
81 nextlist = &c->erasable_list; 82 nextlist = &c->erasable_list;
83 } else if (!list_empty(&c->erasable_pending_wbuf_list)) {
84 /* There are blocks are wating for the wbuf sync */
85 D1(printk(KERN_DEBUG "Synching wbuf in order to reuse erasable_pending_wbuf_list blocks\n"));
86 spin_unlock(&c->erase_completion_lock);
87 jffs2_flush_wbuf_pad(c);
88 spin_lock(&c->erase_completion_lock);
89 goto again;
82 } else { 90 } else {
83 /* Eep. All were empty */ 91 /* Eep. All were empty */
84 D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n")); 92 D1(printk(KERN_NOTICE "jffs2: No clean, dirty _or_ erasable blocks to GC from! Where are they all?\n"));
@@ -661,9 +669,10 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
661{ 669{
662 struct jffs2_full_dnode *new_fn; 670 struct jffs2_full_dnode *new_fn;
663 struct jffs2_raw_inode ri; 671 struct jffs2_raw_inode ri;
672 struct jffs2_node_frag *last_frag;
664 jint16_t dev; 673 jint16_t dev;
665 char *mdata = NULL, mdatalen = 0; 674 char *mdata = NULL, mdatalen = 0;
666 uint32_t alloclen, phys_ofs; 675 uint32_t alloclen, phys_ofs, ilen;
667 int ret; 676 int ret;
668 677
669 if (S_ISBLK(JFFS2_F_I_MODE(f)) || 678 if (S_ISBLK(JFFS2_F_I_MODE(f)) ||
@@ -699,6 +708,14 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
699 goto out; 708 goto out;
700 } 709 }
701 710
711 last_frag = frag_last(&f->fragtree);
712 if (last_frag)
713 /* Fetch the inode length from the fragtree rather then
714 * from i_size since i_size may have not been updated yet */
715 ilen = last_frag->ofs + last_frag->size;
716 else
717 ilen = JFFS2_F_I_SIZE(f);
718
702 memset(&ri, 0, sizeof(ri)); 719 memset(&ri, 0, sizeof(ri));
703 ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 720 ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
704 ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); 721 ri.nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE);
@@ -710,7 +727,7 @@ static int jffs2_garbage_collect_metadata(struct jffs2_sb_info *c, struct jffs2_
710 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); 727 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
711 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); 728 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
712 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); 729 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
713 ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); 730 ri.isize = cpu_to_je32(ilen);
714 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); 731 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
715 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); 732 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
716 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); 733 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
@@ -816,8 +833,7 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
816 833
817 /* Doesn't matter if there's one in the same erase block. We're going to 834 /* Doesn't matter if there's one in the same erase block. We're going to
818 delete it too at the same time. */ 835 delete it too at the same time. */
819 if ((raw->flash_offset & ~(c->sector_size-1)) == 836 if (SECTOR_ADDR(raw->flash_offset) == SECTOR_ADDR(fd->raw->flash_offset))
820 (fd->raw->flash_offset & ~(c->sector_size-1)))
821 continue; 837 continue;
822 838
823 D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw))); 839 D1(printk(KERN_DEBUG "Check potential deletion dirent at %08x\n", ref_offset(raw)));
@@ -891,7 +907,7 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
891 struct jffs2_raw_inode ri; 907 struct jffs2_raw_inode ri;
892 struct jffs2_node_frag *frag; 908 struct jffs2_node_frag *frag;
893 struct jffs2_full_dnode *new_fn; 909 struct jffs2_full_dnode *new_fn;
894 uint32_t alloclen, phys_ofs; 910 uint32_t alloclen, phys_ofs, ilen;
895 int ret; 911 int ret;
896 912
897 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n", 913 D1(printk(KERN_DEBUG "Writing replacement hole node for ino #%u from offset 0x%x to 0x%x\n",
@@ -951,10 +967,19 @@ static int jffs2_garbage_collect_hole(struct jffs2_sb_info *c, struct jffs2_eras
951 ri.csize = cpu_to_je32(0); 967 ri.csize = cpu_to_je32(0);
952 ri.compr = JFFS2_COMPR_ZERO; 968 ri.compr = JFFS2_COMPR_ZERO;
953 } 969 }
970
971 frag = frag_last(&f->fragtree);
972 if (frag)
973 /* Fetch the inode length from the fragtree rather then
974 * from i_size since i_size may have not been updated yet */
975 ilen = frag->ofs + frag->size;
976 else
977 ilen = JFFS2_F_I_SIZE(f);
978
954 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f)); 979 ri.mode = cpu_to_jemode(JFFS2_F_I_MODE(f));
955 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f)); 980 ri.uid = cpu_to_je16(JFFS2_F_I_UID(f));
956 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f)); 981 ri.gid = cpu_to_je16(JFFS2_F_I_GID(f));
957 ri.isize = cpu_to_je32(JFFS2_F_I_SIZE(f)); 982 ri.isize = cpu_to_je32(ilen);
958 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f)); 983 ri.atime = cpu_to_je32(JFFS2_F_I_ATIME(f));
959 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f)); 984 ri.ctime = cpu_to_je32(JFFS2_F_I_CTIME(f));
960 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f)); 985 ri.mtime = cpu_to_je32(JFFS2_F_I_MTIME(f));
@@ -1161,7 +1186,7 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
1161 D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n", 1186 D1(printk(KERN_DEBUG "Expanded dnode to write from (0x%x-0x%x) to (0x%x-0x%x)\n",
1162 orig_start, orig_end, start, end)); 1187 orig_start, orig_end, start, end));
1163 1188
1164 BUG_ON(end > JFFS2_F_I_SIZE(f)); 1189 D1(BUG_ON(end > frag_last(&f->fragtree)->ofs + frag_last(&f->fragtree)->size));
1165 BUG_ON(end < orig_end); 1190 BUG_ON(end < orig_end);
1166 BUG_ON(start > orig_start); 1191 BUG_ON(start > orig_start);
1167 } 1192 }
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index cd6a8bd13e0..c7bbdeec93a 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.90 2004/12/08 17:59:20 dwmw2 Exp $ 10 * $Id: nodelist.c,v 1.97 2005/07/06 15:18:41 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -58,27 +58,60 @@ void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new
58/* Put a new tmp_dnode_info into the list, keeping the list in 58/* Put a new tmp_dnode_info into the list, keeping the list in
59 order of increasing version 59 order of increasing version
60*/ 60*/
61static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct jffs2_tmp_dnode_info **list) 61
62static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)
62{ 63{
63 struct jffs2_tmp_dnode_info **prev = list; 64 struct rb_node **p = &list->rb_node;
64 65 struct rb_node * parent = NULL;
65 while ((*prev) && (*prev)->version < tn->version) { 66 struct jffs2_tmp_dnode_info *this;
66 prev = &((*prev)->next); 67
67 } 68 while (*p) {
68 tn->next = (*prev); 69 parent = *p;
69 *prev = tn; 70 this = rb_entry(parent, struct jffs2_tmp_dnode_info, rb);
71
72 /* There may actually be a collision here, but it doesn't
73 actually matter. As long as the two nodes with the same
74 version are together, it's all fine. */
75 if (tn->version < this->version)
76 p = &(*p)->rb_left;
77 else
78 p = &(*p)->rb_right;
79 }
80
81 rb_link_node(&tn->rb, parent, p);
82 rb_insert_color(&tn->rb, list);
70} 83}
71 84
72static void jffs2_free_tmp_dnode_info_list(struct jffs2_tmp_dnode_info *tn) 85static void jffs2_free_tmp_dnode_info_list(struct rb_root *list)
73{ 86{
74 struct jffs2_tmp_dnode_info *next; 87 struct rb_node *this;
88 struct jffs2_tmp_dnode_info *tn;
89
90 this = list->rb_node;
91
92 /* Now at bottom of tree */
93 while (this) {
94 if (this->rb_left)
95 this = this->rb_left;
96 else if (this->rb_right)
97 this = this->rb_right;
98 else {
99 tn = rb_entry(this, struct jffs2_tmp_dnode_info, rb);
100 jffs2_free_full_dnode(tn->fn);
101 jffs2_free_tmp_dnode_info(tn);
102
103 this = this->rb_parent;
104 if (!this)
105 break;
75 106
76 while (tn) { 107 if (this->rb_left == &tn->rb)
77 next = tn; 108 this->rb_left = NULL;
78 tn = tn->next; 109 else if (this->rb_right == &tn->rb)
79 jffs2_free_full_dnode(next->fn); 110 this->rb_right = NULL;
80 jffs2_free_tmp_dnode_info(next); 111 else BUG();
112 }
81 } 113 }
114 list->rb_node = NULL;
82} 115}
83 116
84static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd) 117static void jffs2_free_full_dirent_list(struct jffs2_full_dirent *fd)
@@ -108,12 +141,13 @@ static struct jffs2_raw_node_ref *jffs2_first_valid_node(struct jffs2_raw_node_r
108 with this ino, returning the former in order of version */ 141 with this ino, returning the former in order of version */
109 142
110int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 143int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
111 struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp, 144 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
112 uint32_t *highest_version, uint32_t *latest_mctime, 145 uint32_t *highest_version, uint32_t *latest_mctime,
113 uint32_t *mctime_ver) 146 uint32_t *mctime_ver)
114{ 147{
115 struct jffs2_raw_node_ref *ref, *valid_ref; 148 struct jffs2_raw_node_ref *ref, *valid_ref;
116 struct jffs2_tmp_dnode_info *tn, *ret_tn = NULL; 149 struct jffs2_tmp_dnode_info *tn;
150 struct rb_root ret_tn = RB_ROOT;
117 struct jffs2_full_dirent *fd, *ret_fd = NULL; 151 struct jffs2_full_dirent *fd, *ret_fd = NULL;
118 union jffs2_node_union node; 152 union jffs2_node_union node;
119 size_t retlen; 153 size_t retlen;
@@ -127,7 +161,7 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
127 161
128 valid_ref = jffs2_first_valid_node(f->inocache->nodes); 162 valid_ref = jffs2_first_valid_node(f->inocache->nodes);
129 163
130 if (!valid_ref) 164 if (!valid_ref && (f->inocache->ino != 1))
131 printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino); 165 printk(KERN_WARNING "Eep. No valid nodes for ino #%u\n", f->inocache->ino);
132 166
133 while (valid_ref) { 167 while (valid_ref) {
@@ -450,7 +484,7 @@ int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
450 return 0; 484 return 0;
451 485
452 free_out: 486 free_out:
453 jffs2_free_tmp_dnode_info_list(ret_tn); 487 jffs2_free_tmp_dnode_info_list(&ret_tn);
454 jffs2_free_full_dirent_list(ret_fd); 488 jffs2_free_full_dirent_list(ret_fd);
455 return err; 489 return err;
456} 490}
@@ -489,9 +523,13 @@ struct jffs2_inode_cache *jffs2_get_ino_cache(struct jffs2_sb_info *c, uint32_t
489void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new) 523void jffs2_add_ino_cache (struct jffs2_sb_info *c, struct jffs2_inode_cache *new)
490{ 524{
491 struct jffs2_inode_cache **prev; 525 struct jffs2_inode_cache **prev;
492 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino)); 526
493 spin_lock(&c->inocache_lock); 527 spin_lock(&c->inocache_lock);
494 528 if (!new->ino)
529 new->ino = ++c->highest_ino;
530
531 D2(printk(KERN_DEBUG "jffs2_add_ino_cache: Add %p (ino #%u)\n", new, new->ino));
532
495 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE]; 533 prev = &c->inocache_list[new->ino % INOCACHE_HASHSIZE];
496 534
497 while ((*prev) && (*prev)->ino < new->ino) { 535 while ((*prev) && (*prev)->ino < new->ino) {
@@ -506,7 +544,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) 544void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
507{ 545{
508 struct jffs2_inode_cache **prev; 546 struct jffs2_inode_cache **prev;
509 D2(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino)); 547 D1(printk(KERN_DEBUG "jffs2_del_ino_cache: Del %p (ino #%u)\n", old, old->ino));
510 spin_lock(&c->inocache_lock); 548 spin_lock(&c->inocache_lock);
511 549
512 prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE]; 550 prev = &c->inocache_list[old->ino % INOCACHE_HASHSIZE];
@@ -518,6 +556,14 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
518 *prev = old->next; 556 *prev = old->next;
519 } 557 }
520 558
559 /* Free it now unless it's in READING or CLEARING state, which
560 are the transitions upon read_inode() and clear_inode(). The
561 rest of the time we know nobody else is looking at it, and
562 if it's held by read_inode() or clear_inode() they'll free it
563 for themselves. */
564 if (old->state != INO_STATE_READING && old->state != INO_STATE_CLEARING)
565 jffs2_free_inode_cache(old);
566
521 spin_unlock(&c->inocache_lock); 567 spin_unlock(&c->inocache_lock);
522} 568}
523 569
@@ -530,7 +576,6 @@ void jffs2_free_ino_caches(struct jffs2_sb_info *c)
530 this = c->inocache_list[i]; 576 this = c->inocache_list[i];
531 while (this) { 577 while (this) {
532 next = this->next; 578 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); 579 jffs2_free_inode_cache(this);
535 this = next; 580 this = next;
536 } 581 }
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index a4864d05ea9..b34c397909e 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.126 2004/11/19 15:06:29 dedekind Exp $ 10 * $Id: nodelist.h,v 1.131 2005/07/05 21:03:07 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
@@ -160,7 +161,7 @@ struct jffs2_full_dnode
160*/ 161*/
161struct jffs2_tmp_dnode_info 162struct jffs2_tmp_dnode_info
162{ 163{
163 struct jffs2_tmp_dnode_info *next; 164 struct rb_node rb;
164 struct jffs2_full_dnode *fn; 165 struct jffs2_full_dnode *fn;
165 uint32_t version; 166 uint32_t version;
166}; 167};
@@ -362,6 +363,18 @@ static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
362 node = node->rb_left; 363 node = node->rb_left;
363 return rb_entry(node, struct jffs2_node_frag, rb); 364 return rb_entry(node, struct jffs2_node_frag, rb);
364} 365}
366
367static inline struct jffs2_node_frag *frag_last(struct rb_root *root)
368{
369 struct rb_node *node = root->rb_node;
370
371 if (!node)
372 return NULL;
373 while(node->rb_right)
374 node = node->rb_right;
375 return rb_entry(node, struct jffs2_node_frag, rb);
376}
377
365#define rb_parent(rb) ((rb)->rb_parent) 378#define rb_parent(rb) ((rb)->rb_parent)
366#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb) 379#define frag_next(frag) rb_entry(rb_next(&(frag)->rb), struct jffs2_node_frag, rb)
367#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb) 380#define frag_prev(frag) rb_entry(rb_prev(&(frag)->rb), struct jffs2_node_frag, rb)
@@ -374,7 +387,7 @@ static inline struct jffs2_node_frag *frag_first(struct rb_root *root)
374D2(void jffs2_print_frag_list(struct jffs2_inode_info *f)); 387D2(void jffs2_print_frag_list(struct jffs2_inode_info *f));
375void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list); 388void jffs2_add_fd_to_list(struct jffs2_sb_info *c, struct jffs2_full_dirent *new, struct jffs2_full_dirent **list);
376int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f, 389int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
377 struct jffs2_tmp_dnode_info **tnp, struct jffs2_full_dirent **fdp, 390 struct rb_root *tnp, struct jffs2_full_dirent **fdp,
378 uint32_t *highest_version, uint32_t *latest_mctime, 391 uint32_t *highest_version, uint32_t *latest_mctime,
379 uint32_t *mctime_ver); 392 uint32_t *mctime_ver);
380void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state); 393void jffs2_set_inocache_state(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic, int state);
@@ -462,7 +475,7 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c);
462/* erase.c */ 475/* erase.c */
463void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count); 476void jffs2_erase_pending_blocks(struct jffs2_sb_info *c, int count);
464 477
465#ifdef CONFIG_JFFS2_FS_NAND 478#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
466/* wbuf.c */ 479/* wbuf.c */
467int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino); 480int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
468int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); 481int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index 2651135bdf4..c1d8b5ed9ab 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.115 2004/11/22 11:07:21 dwmw2 Exp $ 10 * $Id: nodemgmt.c,v 1.122 2005/05/06 09:30:27 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -75,7 +75,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
75 dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size; 75 dirty = c->dirty_size + c->erasing_size - c->nr_erasing_blocks * c->sector_size + c->unchecked_size;
76 if (dirty < c->nospc_dirty_size) { 76 if (dirty < c->nospc_dirty_size) {
77 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { 77 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
78 printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n"); 78 D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on dirty space to GC, but it's a deletion. Allowing...\n"));
79 break; 79 break;
80 } 80 }
81 D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n", 81 D1(printk(KERN_DEBUG "dirty size 0x%08x + unchecked_size 0x%08x < nospc_dirty_size 0x%08x, returning -ENOSPC\n",
@@ -98,7 +98,7 @@ int jffs2_reserve_space(struct jffs2_sb_info *c, uint32_t minsize, uint32_t *ofs
98 avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size; 98 avail = c->free_size + c->dirty_size + c->erasing_size + c->unchecked_size;
99 if ( (avail / c->sector_size) <= blocksneeded) { 99 if ( (avail / c->sector_size) <= blocksneeded) {
100 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) { 100 if (prio == ALLOC_DELETION && c->nr_free_blocks + c->nr_erasing_blocks >= c->resv_blocks_deletion) {
101 printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n"); 101 D1(printk(KERN_NOTICE "jffs2_reserve_space(): Low on possibly available space, but it's a deletion. Allowing...\n"));
102 break; 102 break;
103 } 103 }
104 104
@@ -308,7 +308,10 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
308 308
309 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len)); 309 D1(printk(KERN_DEBUG "jffs2_add_physical_node_ref(): Node at 0x%x(%d), size 0x%x\n", ref_offset(new), ref_flags(new), len));
310#if 1 310#if 1
311 if (jeb != c->nextblock || (ref_offset(new)) != jeb->offset + (c->sector_size - jeb->free_size)) { 311 /* we could get some obsolete nodes after nextblock was refiled
312 in wbuf.c */
313 if ((c->nextblock || !ref_obsolete(new))
314 &&(jeb != c->nextblock || ref_offset(new) != jeb->offset + (c->sector_size - jeb->free_size))) {
312 printk(KERN_WARNING "argh. node added in wrong place\n"); 315 printk(KERN_WARNING "argh. node added in wrong place\n");
313 jffs2_free_raw_node_ref(new); 316 jffs2_free_raw_node_ref(new);
314 return -EINVAL; 317 return -EINVAL;
@@ -332,7 +335,7 @@ int jffs2_add_physical_node_ref(struct jffs2_sb_info *c, struct jffs2_raw_node_r
332 c->used_size += len; 335 c->used_size += len;
333 } 336 }
334 337
335 if (!jeb->free_size && !jeb->dirty_size) { 338 if (!jeb->free_size && !jeb->dirty_size && !ISDIRTY(jeb->wasted_size)) {
336 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */ 339 /* If it lives on the dirty_list, jffs2_reserve_space will put it there */
337 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n", 340 D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
338 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size)); 341 jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
@@ -400,7 +403,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
400 jeb = &c->blocks[blocknr]; 403 jeb = &c->blocks[blocknr];
401 404
402 if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) && 405 if (jffs2_can_mark_obsolete(c) && !jffs2_is_readonly(c) &&
403 !(c->flags & JFFS2_SB_FLAG_MOUNTING)) { 406 !(c->flags & (JFFS2_SB_FLAG_SCANNING | JFFS2_SB_FLAG_BUILDING))) {
404 /* Hm. This may confuse static lock analysis. If any of the above 407 /* Hm. This may confuse static lock analysis. If any of the above
405 three conditions is false, we're going to return from this 408 three conditions is false, we're going to return from this
406 function without actually obliterating any nodes or freeing 409 function without actually obliterating any nodes or freeing
@@ -434,7 +437,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
434 437
435 // Take care, that wasted size is taken into concern 438 // Take care, that wasted size is taken into concern
436 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) { 439 if ((jeb->dirty_size || ISDIRTY(jeb->wasted_size + ref_totlen(c, jeb, ref))) && jeb != c->nextblock) {
437 D1(printk("Dirtying\n")); 440 D1(printk(KERN_DEBUG "Dirtying\n"));
438 addedsize = ref_totlen(c, jeb, ref); 441 addedsize = ref_totlen(c, jeb, ref);
439 jeb->dirty_size += ref_totlen(c, jeb, ref); 442 jeb->dirty_size += ref_totlen(c, jeb, ref);
440 c->dirty_size += ref_totlen(c, jeb, ref); 443 c->dirty_size += ref_totlen(c, jeb, ref);
@@ -456,7 +459,7 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
456 } 459 }
457 } 460 }
458 } else { 461 } else {
459 D1(printk("Wasting\n")); 462 D1(printk(KERN_DEBUG "Wasting\n"));
460 addedsize = 0; 463 addedsize = 0;
461 jeb->wasted_size += ref_totlen(c, jeb, ref); 464 jeb->wasted_size += ref_totlen(c, jeb, ref);
462 c->wasted_size += ref_totlen(c, jeb, ref); 465 c->wasted_size += ref_totlen(c, jeb, ref);
@@ -467,8 +470,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
467 470
468 D1(ACCT_PARANOIA_CHECK(jeb)); 471 D1(ACCT_PARANOIA_CHECK(jeb));
469 472
470 if (c->flags & JFFS2_SB_FLAG_MOUNTING) { 473 if (c->flags & JFFS2_SB_FLAG_SCANNING) {
471 /* Mount in progress. Don't muck about with the block 474 /* Flash scanning is in progress. Don't muck about with the block
472 lists because they're not ready yet, and don't actually 475 lists because they're not ready yet, and don't actually
473 obliterate nodes that look obsolete. If they weren't 476 obliterate nodes that look obsolete. If they weren't
474 marked obsolete on the flash at the time they _became_ 477 marked obsolete on the flash at the time they _became_
@@ -527,7 +530,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
527 530
528 spin_unlock(&c->erase_completion_lock); 531 spin_unlock(&c->erase_completion_lock);
529 532
530 if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c)) { 533 if (!jffs2_can_mark_obsolete(c) || jffs2_is_readonly(c) ||
534 (c->flags & JFFS2_SB_FLAG_BUILDING)) {
531 /* We didn't lock the erase_free_sem */ 535 /* We didn't lock the erase_free_sem */
532 return; 536 return;
533 } 537 }
@@ -590,11 +594,8 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
590 *p = ref->next_in_ino; 594 *p = ref->next_in_ino;
591 ref->next_in_ino = NULL; 595 ref->next_in_ino = NULL;
592 596
593 if (ic->nodes == (void *)ic) { 597 if (ic->nodes == (void *)ic && ic->nlink == 0)
594 D1(printk(KERN_DEBUG "inocache for ino #%u is all gone now. Freeing\n", ic->ino));
595 jffs2_del_ino_cache(c, ic); 598 jffs2_del_ino_cache(c, ic);
596 jffs2_free_inode_cache(ic);
597 }
598 599
599 spin_unlock(&c->erase_completion_lock); 600 spin_unlock(&c->erase_completion_lock);
600 } 601 }
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 03b0acc37b7..7bf72e012c9 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -7,41 +7,24 @@
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: os-linux.h,v 1.51 2004/11/16 20:36:11 dwmw2 Exp $ 10 * $Id: os-linux.h,v 1.57 2005/07/06 12:13:09 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
14#ifndef __JFFS2_OS_LINUX_H__ 14#ifndef __JFFS2_OS_LINUX_H__
15#define __JFFS2_OS_LINUX_H__ 15#define __JFFS2_OS_LINUX_H__
16#include <linux/version.h>
17 16
18/* JFFS2 uses Linux mode bits natively -- no need for conversion */ 17/* JFFS2 uses Linux mode bits natively -- no need for conversion */
19#define os_to_jffs2_mode(x) (x) 18#define os_to_jffs2_mode(x) (x)
20#define jffs2_to_os_mode(x) (x) 19#define jffs2_to_os_mode(x) (x)
21 20
22#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,73)
23#define kstatfs statfs
24#endif
25
26struct kstatfs; 21struct kstatfs;
27struct kvec; 22struct kvec;
28 23
29#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
30#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode)) 24#define JFFS2_INODE_INFO(i) (list_entry(i, struct jffs2_inode_info, vfs_inode))
31#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode) 25#define OFNI_EDONI_2SFFJ(f) (&(f)->vfs_inode)
32#define JFFS2_SB_INFO(sb) (sb->s_fs_info) 26#define JFFS2_SB_INFO(sb) (sb->s_fs_info)
33#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv) 27#define OFNI_BS_2SFFJ(c) ((struct super_block *)c->os_priv)
34#elif defined(JFFS2_OUT_OF_KERNEL)
35#define JFFS2_INODE_INFO(i) ((struct jffs2_inode_info *) &(i)->u)
36#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
37#define JFFS2_SB_INFO(sb) ((struct jffs2_sb_info *) &(sb)->u)
38#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
39#else
40#define JFFS2_INODE_INFO(i) (&i->u.jffs2_i)
41#define OFNI_EDONI_2SFFJ(f) ((struct inode *) ( ((char *)f) - ((char *)(&((struct inode *)NULL)->u)) ) )
42#define JFFS2_SB_INFO(sb) (&sb->u.jffs2_sb)
43#define OFNI_BS_2SFFJ(c) ((struct super_block *) ( ((char *)c) - ((char *)(&((struct super_block *)NULL)->u)) ) )
44#endif
45 28
46 29
47#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size) 30#define JFFS2_F_I_SIZE(f) (OFNI_EDONI_2SFFJ(f)->i_size)
@@ -49,28 +32,14 @@ struct kvec;
49#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid) 32#define JFFS2_F_I_UID(f) (OFNI_EDONI_2SFFJ(f)->i_uid)
50#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid) 33#define JFFS2_F_I_GID(f) (OFNI_EDONI_2SFFJ(f)->i_gid)
51 34
52#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,1)
53#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f))) 35#define JFFS2_F_I_RDEV_MIN(f) (iminor(OFNI_EDONI_2SFFJ(f)))
54#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f))) 36#define JFFS2_F_I_RDEV_MAJ(f) (imajor(OFNI_EDONI_2SFFJ(f)))
55#else
56#define JFFS2_F_I_RDEV_MIN(f) (MINOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
57#define JFFS2_F_I_RDEV_MAJ(f) (MAJOR(to_kdev_t(OFNI_EDONI_2SFFJ(f)->i_rdev)))
58#endif
59 37
60/* Urgh. The things we do to keep the 2.4 build working */
61#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,47)
62#define ITIME(sec) ((struct timespec){sec, 0}) 38#define ITIME(sec) ((struct timespec){sec, 0})
63#define I_SEC(tv) ((tv).tv_sec) 39#define I_SEC(tv) ((tv).tv_sec)
64#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec) 40#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec)
65#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec) 41#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec)
66#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec) 42#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec)
67#else
68#define ITIME(x) (x)
69#define I_SEC(x) (x)
70#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime)
71#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime)
72#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime)
73#endif
74 43
75#define sleep_on_spinunlock(wq, s) \ 44#define sleep_on_spinunlock(wq, s) \
76 do { \ 45 do { \
@@ -84,23 +53,21 @@ struct kvec;
84 53
85static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) 54static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
86{ 55{
87#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)
88 f->highest_version = 0; 56 f->highest_version = 0;
89 f->fragtree = RB_ROOT; 57 f->fragtree = RB_ROOT;
90 f->metadata = NULL; 58 f->metadata = NULL;
91 f->dents = NULL; 59 f->dents = NULL;
92 f->flags = 0; 60 f->flags = 0;
93 f->usercompr = 0; 61 f->usercompr = 0;
94#else
95 memset(f, 0, sizeof(*f));
96 init_MUTEX_LOCKED(&f->sem);
97#endif
98} 62}
99 63
64
100#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY) 65#define jffs2_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
101 66
102#if (!defined CONFIG_JFFS2_FS_NAND && !defined CONFIG_JFFS2_FS_NOR_ECC) 67#ifndef CONFIG_JFFS2_FS_WRITEBUFFER
68#define SECTOR_ADDR(x) ( ((unsigned long)(x) & ~(c->sector_size-1)) )
103#define jffs2_can_mark_obsolete(c) (1) 69#define jffs2_can_mark_obsolete(c) (1)
70#define jffs2_is_writebuffered(c) (0)
104#define jffs2_cleanmarker_oob(c) (0) 71#define jffs2_cleanmarker_oob(c) (0)
105#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO) 72#define jffs2_write_nand_cleanmarker(c,jeb) (-EIO)
106 73
@@ -116,11 +83,14 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
116#define jffs2_wbuf_timeout NULL 83#define jffs2_wbuf_timeout NULL
117#define jffs2_wbuf_process NULL 84#define jffs2_wbuf_process NULL
118#define jffs2_nor_ecc(c) (0) 85#define jffs2_nor_ecc(c) (0)
86#define jffs2_dataflash(c) (0)
119#define jffs2_nor_ecc_flash_setup(c) (0) 87#define jffs2_nor_ecc_flash_setup(c) (0)
120#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) 88#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)
121 89
122#else /* NAND and/or ECC'd NOR support present */ 90#else /* NAND and/or ECC'd NOR support present */
123 91
92#define jffs2_is_writebuffered(c) (c->wbuf != NULL)
93#define SECTOR_ADDR(x) ( ((unsigned long)(x) / (unsigned long)(c->sector_size)) * c->sector_size )
124#define jffs2_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM) 94#define jffs2_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM)
125#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH) 95#define jffs2_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
126 96
@@ -142,16 +112,16 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino);
142int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c); 112int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c);
143int jffs2_nand_flash_setup(struct jffs2_sb_info *c); 113int jffs2_nand_flash_setup(struct jffs2_sb_info *c);
144void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c); 114void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c);
145#ifdef CONFIG_JFFS2_FS_NOR_ECC 115
146#define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC)) 116#define jffs2_nor_ecc(c) (c->mtd->type == MTD_NORFLASH && (c->mtd->flags & MTD_ECC))
147int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c); 117int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c);
148void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c); 118void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c);
149#else 119
150#define jffs2_nor_ecc(c) (0) 120#define jffs2_dataflash(c) (c->mtd->type == MTD_DATAFLASH)
151#define jffs2_nor_ecc_flash_setup(c) (0) 121int jffs2_dataflash_setup(struct jffs2_sb_info *c);
152#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0) 122void jffs2_dataflash_cleanup(struct jffs2_sb_info *c);
153#endif /* NOR ECC */ 123
154#endif /* NAND */ 124#endif /* WRITEBUFFER */
155 125
156/* erase.c */ 126/* erase.c */
157static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c) 127static inline void jffs2_erase_pending_trigger(struct jffs2_sb_info *c)
diff --git a/fs/jffs2/read.c b/fs/jffs2/read.c
index eb493dc06db..c7f9068907c 100644
--- a/fs/jffs2/read.c
+++ b/fs/jffs2/read.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: read.c,v 1.38 2004/11/16 20:36:12 dwmw2 Exp $ 10 * $Id: read.c,v 1.39 2005/03/01 10:34:03 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -214,33 +214,3 @@ int jffs2_read_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
214 return 0; 214 return 0;
215} 215}
216 216
217/* Core function to read symlink target. */
218char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
219{
220 char *buf;
221 int ret;
222
223 down(&f->sem);
224
225 if (!f->metadata) {
226 printk(KERN_NOTICE "No metadata for symlink inode #%u\n", f->inocache->ino);
227 up(&f->sem);
228 return ERR_PTR(-EINVAL);
229 }
230 buf = kmalloc(f->metadata->size+1, GFP_USER);
231 if (!buf) {
232 up(&f->sem);
233 return ERR_PTR(-ENOMEM);
234 }
235 buf[f->metadata->size]=0;
236
237 ret = jffs2_read_dnode(c, f, f->metadata, buf, 0, f->metadata->size);
238
239 up(&f->sem);
240
241 if (ret) {
242 kfree(buf);
243 return ERR_PTR(ret);
244 }
245 return buf;
246}
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index aca4a0b17bc..081656c1d49 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.120 2005/07/05 21:03:07 dwmw2 Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -500,7 +500,9 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
500 struct jffs2_inode_info *f, 500 struct jffs2_inode_info *f,
501 struct jffs2_raw_inode *latest_node) 501 struct jffs2_raw_inode *latest_node)
502{ 502{
503 struct jffs2_tmp_dnode_info *tn_list, *tn; 503 struct jffs2_tmp_dnode_info *tn = NULL;
504 struct rb_root tn_list;
505 struct rb_node *rb, *repl_rb;
504 struct jffs2_full_dirent *fd_list; 506 struct jffs2_full_dirent *fd_list;
505 struct jffs2_full_dnode *fn = NULL; 507 struct jffs2_full_dnode *fn = NULL;
506 uint32_t crc; 508 uint32_t crc;
@@ -522,9 +524,10 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
522 } 524 }
523 f->dents = fd_list; 525 f->dents = fd_list;
524 526
525 while (tn_list) { 527 rb = rb_first(&tn_list);
526 tn = tn_list;
527 528
529 while (rb) {
530 tn = rb_entry(rb, struct jffs2_tmp_dnode_info, rb);
528 fn = tn->fn; 531 fn = tn->fn;
529 532
530 if (f->metadata) { 533 if (f->metadata) {
@@ -556,7 +559,30 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
556 mdata_ver = tn->version; 559 mdata_ver = tn->version;
557 } 560 }
558 next_tn: 561 next_tn:
559 tn_list = tn->next; 562 BUG_ON(rb->rb_left);
563 repl_rb = NULL;
564 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {
565 /* We were then left-hand child of our parent. We need
566 to move our own right-hand child into our place. */
567 repl_rb = rb->rb_right;
568 if (repl_rb)
569 repl_rb->rb_parent = rb->rb_parent;
570 } else
571 repl_rb = NULL;
572
573 rb = rb_next(rb);
574
575 /* Remove the spent tn from the tree; don't bother rebalancing
576 but put our right-hand child in our own place. */
577 if (tn->rb.rb_parent) {
578 if (tn->rb.rb_parent->rb_left == &tn->rb)
579 tn->rb.rb_parent->rb_left = repl_rb;
580 else if (tn->rb.rb_parent->rb_right == &tn->rb)
581 tn->rb.rb_parent->rb_right = repl_rb;
582 else BUG();
583 } else if (tn->rb.rb_right)
584 tn->rb.rb_right->rb_parent = NULL;
585
560 jffs2_free_tmp_dnode_info(tn); 586 jffs2_free_tmp_dnode_info(tn);
561 } 587 }
562 D1(jffs2_sanitycheck_fragtree(f)); 588 D1(jffs2_sanitycheck_fragtree(f));
@@ -623,6 +649,40 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
623 case. */ 649 case. */
624 if (!je32_to_cpu(latest_node->isize)) 650 if (!je32_to_cpu(latest_node->isize))
625 latest_node->isize = latest_node->dsize; 651 latest_node->isize = latest_node->dsize;
652
653 if (f->inocache->state != INO_STATE_CHECKING) {
654 /* Symlink's inode data is the target path. Read it and
655 * keep in RAM to facilitate quick follow symlink operation.
656 * We use f->dents field to store the target path, which
657 * is somewhat ugly. */
658 f->dents = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
659 if (!f->dents) {
660 printk(KERN_WARNING "Can't allocate %d bytes of memory "
661 "for the symlink target path cache\n",
662 je32_to_cpu(latest_node->csize));
663 up(&f->sem);
664 jffs2_do_clear_inode(c, f);
665 return -ENOMEM;
666 }
667
668 ret = jffs2_flash_read(c, ref_offset(fn->raw) + sizeof(*latest_node),
669 je32_to_cpu(latest_node->csize), &retlen, (char *)f->dents);
670
671 if (ret || retlen != je32_to_cpu(latest_node->csize)) {
672 if (retlen != je32_to_cpu(latest_node->csize))
673 ret = -EIO;
674 kfree(f->dents);
675 f->dents = NULL;
676 up(&f->sem);
677 jffs2_do_clear_inode(c, f);
678 return -ret;
679 }
680
681 ((char *)f->dents)[je32_to_cpu(latest_node->csize)] = '\0';
682 D1(printk(KERN_DEBUG "jffs2_do_read_inode(): symlink's target '%s' cached\n",
683 (char *)f->dents));
684 }
685
626 /* fall through... */ 686 /* fall through... */
627 687
628 case S_IFBLK: 688 case S_IFBLK:
@@ -672,6 +732,9 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
672 down(&f->sem); 732 down(&f->sem);
673 deleted = f->inocache && !f->inocache->nlink; 733 deleted = f->inocache && !f->inocache->nlink;
674 734
735 if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
736 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
737
675 if (f->metadata) { 738 if (f->metadata) {
676 if (deleted) 739 if (deleted)
677 jffs2_mark_node_obsolete(c, f->metadata->raw); 740 jffs2_mark_node_obsolete(c, f->metadata->raw);
@@ -680,16 +743,27 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
680 743
681 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 744 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL);
682 745
683 fds = f->dents; 746 /* For symlink inodes we us f->dents to store the target path name */
747 if (S_ISLNK(OFNI_EDONI_2SFFJ(f)->i_mode)) {
748 if (f->dents) {
749 kfree(f->dents);
750 f->dents = NULL;
751 }
752 } else {
753 fds = f->dents;
684 754
685 while(fds) { 755 while(fds) {
686 fd = fds; 756 fd = fds;
687 fds = fd->next; 757 fds = fd->next;
688 jffs2_free_full_dirent(fd); 758 jffs2_free_full_dirent(fd);
759 }
689 } 760 }
690 761
691 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) 762 if (f->inocache && f->inocache->state != INO_STATE_CHECKING) {
692 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT); 763 jffs2_set_inocache_state(c, f->inocache, INO_STATE_CHECKEDABSENT);
764 if (f->inocache->nodes == (void *)f->inocache)
765 jffs2_del_ino_cache(c, f->inocache);
766 }
693 767
694 up(&f->sem); 768 up(&f->sem);
695} 769}
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index ded53584a89..b63160f83ba 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.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: scan.c,v 1.115 2004/11/17 12:59:08 dedekind Exp $ 10 * $Id: scan.c,v 1.119 2005/02/17 17:51:13 dedekind Exp $
11 * 11 *
12 */ 12 */
13#include <linux/kernel.h> 13#include <linux/kernel.h>
@@ -19,7 +19,7 @@
19#include <linux/compiler.h> 19#include <linux/compiler.h>
20#include "nodelist.h" 20#include "nodelist.h"
21 21
22#define EMPTY_SCAN_SIZE 1024 22#define DEFAULT_EMPTY_SCAN_SIZE 1024
23 23
24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \ 24#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
25 c->free_size -= _x; c->dirty_size += _x; \ 25 c->free_size -= _x; c->dirty_size += _x; \
@@ -68,13 +68,21 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo
68static inline int min_free(struct jffs2_sb_info *c) 68static inline int min_free(struct jffs2_sb_info *c)
69{ 69{
70 uint32_t min = 2 * sizeof(struct jffs2_raw_inode); 70 uint32_t min = 2 * sizeof(struct jffs2_raw_inode);
71#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC 71#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
72 if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize) 72 if (!jffs2_can_mark_obsolete(c) && min < c->wbuf_pagesize)
73 return c->wbuf_pagesize; 73 return c->wbuf_pagesize;
74#endif 74#endif
75 return min; 75 return min;
76 76
77} 77}
78
79static inline uint32_t EMPTY_SCAN_SIZE(uint32_t sector_size) {
80 if (sector_size < DEFAULT_EMPTY_SCAN_SIZE)
81 return sector_size;
82 else
83 return DEFAULT_EMPTY_SCAN_SIZE;
84}
85
78int jffs2_scan_medium(struct jffs2_sb_info *c) 86int jffs2_scan_medium(struct jffs2_sb_info *c)
79{ 87{
80 int i, ret; 88 int i, ret;
@@ -220,7 +228,7 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
220 c->dirty_size -= c->nextblock->dirty_size; 228 c->dirty_size -= c->nextblock->dirty_size;
221 c->nextblock->dirty_size = 0; 229 c->nextblock->dirty_size = 0;
222 } 230 }
223#if defined CONFIG_JFFS2_FS_NAND || defined CONFIG_JFFS2_FS_NOR_ECC 231#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
224 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) { 232 if (!jffs2_can_mark_obsolete(c) && c->nextblock && (c->nextblock->free_size & (c->wbuf_pagesize-1))) {
225 /* If we're going to start writing into a block which already 233 /* If we're going to start writing into a block which already
226 contains data, and the end of the data isn't page-aligned, 234 contains data, and the end of the data isn't page-aligned,
@@ -286,7 +294,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
286 uint32_t hdr_crc, buf_ofs, buf_len; 294 uint32_t hdr_crc, buf_ofs, buf_len;
287 int err; 295 int err;
288 int noise = 0; 296 int noise = 0;
289#ifdef CONFIG_JFFS2_FS_NAND 297#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
290 int cleanmarkerfound = 0; 298 int cleanmarkerfound = 0;
291#endif 299#endif
292 300
@@ -295,7 +303,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
295 303
296 D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs)); 304 D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
297 305
298#ifdef CONFIG_JFFS2_FS_NAND 306#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
299 if (jffs2_cleanmarker_oob(c)) { 307 if (jffs2_cleanmarker_oob(c)) {
300 int ret = jffs2_check_nand_cleanmarker(c, jeb); 308 int ret = jffs2_check_nand_cleanmarker(c, jeb);
301 D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret)); 309 D2(printk(KERN_NOTICE "jffs_check_nand_cleanmarker returned %d\n",ret));
@@ -316,7 +324,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
316 if (!buf_size) { 324 if (!buf_size) {
317 buf_len = c->sector_size; 325 buf_len = c->sector_size;
318 } else { 326 } else {
319 buf_len = EMPTY_SCAN_SIZE; 327 buf_len = EMPTY_SCAN_SIZE(c->sector_size);
320 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len); 328 err = jffs2_fill_scan_buf(c, buf, buf_ofs, buf_len);
321 if (err) 329 if (err)
322 return err; 330 return err;
@@ -326,11 +334,11 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
326 ofs = 0; 334 ofs = 0;
327 335
328 /* Scan only 4KiB of 0xFF before declaring it's empty */ 336 /* Scan only 4KiB of 0xFF before declaring it's empty */
329 while(ofs < EMPTY_SCAN_SIZE && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF) 337 while(ofs < EMPTY_SCAN_SIZE(c->sector_size) && *(uint32_t *)(&buf[ofs]) == 0xFFFFFFFF)
330 ofs += 4; 338 ofs += 4;
331 339
332 if (ofs == EMPTY_SCAN_SIZE) { 340 if (ofs == EMPTY_SCAN_SIZE(c->sector_size)) {
333#ifdef CONFIG_JFFS2_FS_NAND 341#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
334 if (jffs2_cleanmarker_oob(c)) { 342 if (jffs2_cleanmarker_oob(c)) {
335 /* scan oob, take care of cleanmarker */ 343 /* scan oob, take care of cleanmarker */
336 int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound); 344 int ret = jffs2_check_oob_empty(c, jeb, cleanmarkerfound);
@@ -343,7 +351,10 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
343 } 351 }
344#endif 352#endif
345 D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset)); 353 D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
346 return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */ 354 if (c->cleanmarker_size == 0)
355 return BLK_STATE_CLEANMARKER; /* don't bother with re-erase */
356 else
357 return BLK_STATE_ALLFF; /* OK to erase if all blocks are like this */
347 } 358 }
348 if (ofs) { 359 if (ofs) {
349 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset, 360 D1(printk(KERN_DEBUG "Free space at %08x ends at %08x\n", jeb->offset,
@@ -422,8 +433,8 @@ scan_more:
422 /* If we're only checking the beginning of a block with a cleanmarker, 433 /* If we're only checking the beginning of a block with a cleanmarker,
423 bail now */ 434 bail now */
424 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) && 435 if (buf_ofs == jeb->offset && jeb->used_size == PAD(c->cleanmarker_size) &&
425 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_in_ino) { 436 c->cleanmarker_size && !jeb->dirty_size && !jeb->first_node->next_phys) {
426 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE)); 437 D1(printk(KERN_DEBUG "%d bytes at start of block seems clean... assuming all clean\n", EMPTY_SCAN_SIZE(c->sector_size)));
427 return BLK_STATE_CLEANMARKER; 438 return BLK_STATE_CLEANMARKER;
428 } 439 }
429 440
@@ -618,7 +629,7 @@ scan_more:
618 } 629 }
619 630
620 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size 631 if ((jeb->used_size + jeb->unchecked_size) == PAD(c->cleanmarker_size) && !jeb->dirty_size
621 && (!jeb->first_node || !jeb->first_node->next_in_ino) ) 632 && (!jeb->first_node || !jeb->first_node->next_phys) )
622 return BLK_STATE_CLEANMARKER; 633 return BLK_STATE_CLEANMARKER;
623 634
624 /* move blocks with max 4 byte dirty space to cleanlist */ 635 /* move blocks with max 4 byte dirty space to cleanlist */
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 6b2a441d276..2cf14cf8b35 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.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: super.c,v 1.104 2004/11/23 15:37:31 gleixner Exp $ 10 * $Id: super.c,v 1.106 2005/05/18 11:37:25 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -270,8 +270,6 @@ static void jffs2_put_super (struct super_block *sb)
270 270
271 D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n")); 271 D2(printk(KERN_DEBUG "jffs2: jffs2_put_super()\n"));
272 272
273 if (!(sb->s_flags & MS_RDONLY))
274 jffs2_stop_garbage_collect_thread(c);
275 down(&c->alloc_sem); 273 down(&c->alloc_sem);
276 jffs2_flush_wbuf_pad(c); 274 jffs2_flush_wbuf_pad(c);
277 up(&c->alloc_sem); 275 up(&c->alloc_sem);
@@ -292,6 +290,8 @@ static void jffs2_put_super (struct super_block *sb)
292static void jffs2_kill_sb(struct super_block *sb) 290static void jffs2_kill_sb(struct super_block *sb)
293{ 291{
294 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 292 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
293 if (!(sb->s_flags & MS_RDONLY))
294 jffs2_stop_garbage_collect_thread(c);
295 generic_shutdown_super(sb); 295 generic_shutdown_super(sb);
296 put_mtd_device(c->mtd); 296 put_mtd_device(c->mtd);
297 kfree(c); 297 kfree(c);
@@ -309,7 +309,7 @@ static int __init init_jffs2_fs(void)
309 int ret; 309 int ret;
310 310
311 printk(KERN_INFO "JFFS2 version 2.2." 311 printk(KERN_INFO "JFFS2 version 2.2."
312#ifdef CONFIG_JFFS2_FS_NAND 312#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
313 " (NAND)" 313 " (NAND)"
314#endif 314#endif
315 " (C) 2001-2003 Red Hat, Inc.\n"); 315 " (C) 2001-2003 Red Hat, Inc.\n");
diff --git a/fs/jffs2/symlink.c b/fs/jffs2/symlink.c
index 7b1820d1371..65ab6b001dc 100644
--- a/fs/jffs2/symlink.c
+++ b/fs/jffs2/symlink.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: symlink.c,v 1.14 2004/11/16 20:36:12 dwmw2 Exp $ 10 * $Id: symlink.c,v 1.16 2005/03/01 10:50:48 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -19,27 +19,45 @@
19#include "nodelist.h" 19#include "nodelist.h"
20 20
21static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd); 21static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd);
22static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd);
23 22
24struct inode_operations jffs2_symlink_inode_operations = 23struct inode_operations jffs2_symlink_inode_operations =
25{ 24{
26 .readlink = generic_readlink, 25 .readlink = generic_readlink,
27 .follow_link = jffs2_follow_link, 26 .follow_link = jffs2_follow_link,
28 .put_link = jffs2_put_link,
29 .setattr = jffs2_setattr 27 .setattr = jffs2_setattr
30}; 28};
31 29
32static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd) 30static int jffs2_follow_link(struct dentry *dentry, struct nameidata *nd)
33{ 31{
34 unsigned char *buf; 32 struct jffs2_inode_info *f = JFFS2_INODE_INFO(dentry->d_inode);
35 buf = jffs2_getlink(JFFS2_SB_INFO(dentry->d_inode->i_sb), JFFS2_INODE_INFO(dentry->d_inode)); 33
36 nd_set_link(nd, buf); 34 /*
35 * We don't acquire the f->sem mutex here since the only data we
36 * use is f->dents which in case of the symlink inode points to the
37 * symlink's target path.
38 *
39 * 1. If we are here the inode has already built and f->dents has
40 * to point to the target path.
41 * 2. Nobody uses f->dents (if the inode is symlink's inode). The
42 * exception is inode freeing function which frees f->dents. But
43 * it can't be called while we are here and before VFS has
44 * stopped using our f->dents string which we provide by means of
45 * nd_set_link() call.
46 */
47
48 if (!f->dents) {
49 printk(KERN_ERR "jffs2_follow_link(): can't find symlink taerget\n");
50 return -EIO;
51 }
52 D1(printk(KERN_DEBUG "jffs2_follow_link(): target path is '%s'\n", (char *) f->dents));
53
54 nd_set_link(nd, (char *)f->dents);
55
56 /*
57 * We unlock the f->sem mutex but VFS will use the f->dents string. This is safe
58 * since the only way that may cause f->dents to be changed is iput() operation.
59 * But VFS will not use f->dents after iput() has been called.
60 */
37 return 0; 61 return 0;
38} 62}
39 63
40static void jffs2_put_link(struct dentry *dentry, struct nameidata *nd)
41{
42 char *s = nd_get_link(nd);
43 if (!IS_ERR(s))
44 kfree(s);
45}
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index c8128069ecf..996d922e503 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -9,7 +9,7 @@
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
12 * $Id: wbuf.c,v 1.82 2004/11/20 22:08:31 dwmw2 Exp $ 12 * $Id: wbuf.c,v 1.92 2005/04/05 12:51:54 dedekind Exp $
13 * 13 *
14 */ 14 */
15 15
@@ -83,7 +83,7 @@ static void jffs2_wbuf_dirties_inode(struct jffs2_sb_info *c, uint32_t ino)
83 struct jffs2_inodirty *new; 83 struct jffs2_inodirty *new;
84 84
85 /* Mark the superblock dirty so that kupdated will flush... */ 85 /* Mark the superblock dirty so that kupdated will flush... */
86 OFNI_BS_2SFFJ(c)->s_dirt = 1; 86 jffs2_erase_pending_trigger(c);
87 87
88 if (jffs2_wbuf_pending_for_ino(c, ino)) 88 if (jffs2_wbuf_pending_for_ino(c, ino))
89 return; 89 return;
@@ -130,7 +130,10 @@ static inline void jffs2_refile_wbuf_blocks(struct jffs2_sb_info *c)
130 } 130 }
131} 131}
132 132
133static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 133#define REFILE_NOTEMPTY 0
134#define REFILE_ANYWAY 1
135
136static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, int allow_empty)
134{ 137{
135 D1(printk("About to refile bad block at %08x\n", jeb->offset)); 138 D1(printk("About to refile bad block at %08x\n", jeb->offset));
136 139
@@ -144,7 +147,7 @@ static void jffs2_block_refile(struct jffs2_sb_info *c, struct jffs2_eraseblock
144 D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset)); 147 D1(printk("Refiling block at %08x to bad_used_list\n", jeb->offset));
145 list_add(&jeb->list, &c->bad_used_list); 148 list_add(&jeb->list, &c->bad_used_list);
146 } else { 149 } else {
147 BUG(); 150 BUG_ON(allow_empty == REFILE_NOTEMPTY);
148 /* It has to have had some nodes or we couldn't be here */ 151 /* It has to have had some nodes or we couldn't be here */
149 D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset)); 152 D1(printk("Refiling block at %08x to erase_pending_list\n", jeb->offset));
150 list_add(&jeb->list, &c->erase_pending_list); 153 list_add(&jeb->list, &c->erase_pending_list);
@@ -179,7 +182,7 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
179 182
180 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 183 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
181 184
182 jffs2_block_refile(c, jeb); 185 jffs2_block_refile(c, jeb, REFILE_NOTEMPTY);
183 186
184 /* Find the first node to be recovered, by skipping over every 187 /* Find the first node to be recovered, by skipping over every
185 node which ends before the wbuf starts, or which is obsolete. */ 188 node which ends before the wbuf starts, or which is obsolete. */
@@ -264,17 +267,16 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
264 ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len); 267 ret = jffs2_reserve_space_gc(c, end-start, &ofs, &len);
265 if (ret) { 268 if (ret) {
266 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n"); 269 printk(KERN_WARNING "Failed to allocate space for wbuf recovery. Data loss ensues.\n");
267 if (buf) 270 kfree(buf);
268 kfree(buf);
269 return; 271 return;
270 } 272 }
271 if (end-start >= c->wbuf_pagesize) { 273 if (end-start >= c->wbuf_pagesize) {
272 /* Need to do another write immediately. This, btw, 274 /* Need to do another write immediately, but it's possible
273 means that we'll be writing from 'buf' and not from 275 that this is just because the wbuf itself is completely
274 the wbuf. Since if we're writing from the wbuf there 276 full, and there's nothing earlier read back from the
275 won't be more than a wbuf full of data, now will 277 flash. Hence 'buf' isn't necessarily what we're writing
276 there? :) */ 278 from. */
277 279 unsigned char *rewrite_buf = buf?:c->wbuf;
278 uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize); 280 uint32_t towrite = (end-start) - ((end-start)%c->wbuf_pagesize);
279 281
280 D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n", 282 D1(printk(KERN_DEBUG "Write 0x%x bytes at 0x%08x in wbuf recover\n",
@@ -292,9 +294,9 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
292#endif 294#endif
293 if (jffs2_cleanmarker_oob(c)) 295 if (jffs2_cleanmarker_oob(c))
294 ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen, 296 ret = c->mtd->write_ecc(c->mtd, ofs, towrite, &retlen,
295 buf, NULL, c->oobinfo); 297 rewrite_buf, NULL, c->oobinfo);
296 else 298 else
297 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, buf); 299 ret = c->mtd->write(c->mtd, ofs, towrite, &retlen, rewrite_buf);
298 300
299 if (ret || retlen != towrite) { 301 if (ret || retlen != towrite) {
300 /* Argh. We tried. Really we did. */ 302 /* Argh. We tried. Really we did. */
@@ -321,10 +323,10 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c)
321 323
322 c->wbuf_len = (end - start) - towrite; 324 c->wbuf_len = (end - start) - towrite;
323 c->wbuf_ofs = ofs + towrite; 325 c->wbuf_ofs = ofs + towrite;
324 memcpy(c->wbuf, buf + towrite, c->wbuf_len); 326 memmove(c->wbuf, rewrite_buf + towrite, c->wbuf_len);
325 /* Don't muck about with c->wbuf_inodes. False positives are harmless. */ 327 /* Don't muck about with c->wbuf_inodes. False positives are harmless. */
326 328 if (buf)
327 kfree(buf); 329 kfree(buf);
328 } else { 330 } else {
329 /* OK, now we're left with the dregs in whichever buffer we're using */ 331 /* OK, now we're left with the dregs in whichever buffer we're using */
330 if (buf) { 332 if (buf) {
@@ -413,9 +415,9 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
413 int ret; 415 int ret;
414 size_t retlen; 416 size_t retlen;
415 417
416 /* Nothing to do if not NAND flash. In particular, we shouldn't 418 /* Nothing to do if not write-buffering the flash. In particular, we shouldn't
417 del_timer() the timer we never initialised. */ 419 del_timer() the timer we never initialised. */
418 if (jffs2_can_mark_obsolete(c)) 420 if (!jffs2_is_writebuffered(c))
419 return 0; 421 return 0;
420 422
421 if (!down_trylock(&c->alloc_sem)) { 423 if (!down_trylock(&c->alloc_sem)) {
@@ -424,7 +426,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
424 BUG(); 426 BUG();
425 } 427 }
426 428
427 if(!c->wbuf || !c->wbuf_len) 429 if (!c->wbuf_len) /* already checked c->wbuf above */
428 return 0; 430 return 0;
429 431
430 /* claim remaining space on the page 432 /* claim remaining space on the page
@@ -433,7 +435,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
433 if we have a switch to next page, we will not have 435 if we have a switch to next page, we will not have
434 enough remaining space for this. 436 enough remaining space for this.
435 */ 437 */
436 if (pad) { 438 if (pad && !jffs2_dataflash(c)) {
437 c->wbuf_len = PAD(c->wbuf_len); 439 c->wbuf_len = PAD(c->wbuf_len);
438 440
439 /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR 441 /* Pad with JFFS2_DIRTY_BITMASK initially. this helps out ECC'd NOR
@@ -484,7 +486,7 @@ static int __jffs2_flush_wbuf(struct jffs2_sb_info *c, int pad)
484 spin_lock(&c->erase_completion_lock); 486 spin_lock(&c->erase_completion_lock);
485 487
486 /* Adjust free size of the block if we padded. */ 488 /* Adjust free size of the block if we padded. */
487 if (pad) { 489 if (pad && !jffs2_dataflash(c)) {
488 struct jffs2_eraseblock *jeb; 490 struct jffs2_eraseblock *jeb;
489 491
490 jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; 492 jeb = &c->blocks[c->wbuf_ofs / c->sector_size];
@@ -532,6 +534,9 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
532 534
533 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino)); 535 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() called for ino #%u...\n", ino));
534 536
537 if (!c->wbuf)
538 return 0;
539
535 down(&c->alloc_sem); 540 down(&c->alloc_sem);
536 if (!jffs2_wbuf_pending_for_ino(c, ino)) { 541 if (!jffs2_wbuf_pending_for_ino(c, ino)) {
537 D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino)); 542 D1(printk(KERN_DEBUG "Ino #%d not pending in wbuf. Returning\n", ino));
@@ -547,6 +552,10 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
547 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n")); 552 D1(printk(KERN_DEBUG "jffs2_flush_wbuf_gc() padding. Not finished checking\n"));
548 down_write(&c->wbuf_sem); 553 down_write(&c->wbuf_sem);
549 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); 554 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
555 /* retry flushing wbuf in case jffs2_wbuf_recover
556 left some data in the wbuf */
557 if (ret)
558 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
550 up_write(&c->wbuf_sem); 559 up_write(&c->wbuf_sem);
551 } else while (old_wbuf_len && 560 } else while (old_wbuf_len &&
552 old_wbuf_ofs == c->wbuf_ofs) { 561 old_wbuf_ofs == c->wbuf_ofs) {
@@ -561,6 +570,10 @@ int jffs2_flush_wbuf_gc(struct jffs2_sb_info *c, uint32_t ino)
561 down(&c->alloc_sem); 570 down(&c->alloc_sem);
562 down_write(&c->wbuf_sem); 571 down_write(&c->wbuf_sem);
563 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING); 572 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
573 /* retry flushing wbuf in case jffs2_wbuf_recover
574 left some data in the wbuf */
575 if (ret)
576 ret = __jffs2_flush_wbuf(c, PAD_ACCOUNTING);
564 up_write(&c->wbuf_sem); 577 up_write(&c->wbuf_sem);
565 break; 578 break;
566 } 579 }
@@ -578,15 +591,27 @@ int jffs2_flush_wbuf_pad(struct jffs2_sb_info *c)
578{ 591{
579 int ret; 592 int ret;
580 593
594 if (!c->wbuf)
595 return 0;
596
581 down_write(&c->wbuf_sem); 597 down_write(&c->wbuf_sem);
582 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT); 598 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
599 /* retry - maybe wbuf recover left some data in wbuf. */
600 if (ret)
601 ret = __jffs2_flush_wbuf(c, PAD_NOACCOUNT);
583 up_write(&c->wbuf_sem); 602 up_write(&c->wbuf_sem);
584 603
585 return ret; 604 return ret;
586} 605}
587 606
607#ifdef CONFIG_JFFS2_FS_WRITEBUFFER
608#define PAGE_DIV(x) ( ((unsigned long)(x) / (unsigned long)(c->wbuf_pagesize)) * (unsigned long)(c->wbuf_pagesize) )
609#define PAGE_MOD(x) ( (unsigned long)(x) % (unsigned long)(c->wbuf_pagesize) )
610#else
588#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) ) 611#define PAGE_DIV(x) ( (x) & (~(c->wbuf_pagesize - 1)) )
589#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) ) 612#define PAGE_MOD(x) ( (x) & (c->wbuf_pagesize - 1) )
613#endif
614
590int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino) 615int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsigned long count, loff_t to, size_t *retlen, uint32_t ino)
591{ 616{
592 struct kvec outvecs[3]; 617 struct kvec outvecs[3];
@@ -601,7 +626,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
601 uint32_t outvec_to = to; 626 uint32_t outvec_to = to;
602 627
603 /* If not NAND flash, don't bother */ 628 /* If not NAND flash, don't bother */
604 if (!c->wbuf) 629 if (!jffs2_is_writebuffered(c))
605 return jffs2_flash_direct_writev(c, invecs, count, to, retlen); 630 return jffs2_flash_direct_writev(c, invecs, count, to, retlen);
606 631
607 down_write(&c->wbuf_sem); 632 down_write(&c->wbuf_sem);
@@ -630,7 +655,7 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
630 erase block. Anything else, and you die. 655 erase block. Anything else, and you die.
631 New block starts at xxx000c (0-b = block header) 656 New block starts at xxx000c (0-b = block header)
632 */ 657 */
633 if ( (to & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) { 658 if (SECTOR_ADDR(to) != SECTOR_ADDR(c->wbuf_ofs)) {
634 /* It's a write to a new block */ 659 /* It's a write to a new block */
635 if (c->wbuf_len) { 660 if (c->wbuf_len) {
636 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs)); 661 D1(printk(KERN_DEBUG "jffs2_flash_writev() to 0x%lx causes flush of wbuf at 0x%08x\n", (unsigned long)to, c->wbuf_ofs));
@@ -762,9 +787,18 @@ int jffs2_flash_writev(struct jffs2_sb_info *c, const struct kvec *invecs, unsig
762 787
763 if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) { 788 if (ret < 0 || wbuf_retlen != PAGE_DIV(totlen)) {
764 /* At this point we have no problem, 789 /* At this point we have no problem,
765 c->wbuf is empty. 790 c->wbuf is empty. However refile nextblock to avoid
791 writing again to same address.
766 */ 792 */
767 *retlen = donelen; 793 struct jffs2_eraseblock *jeb;
794
795 spin_lock(&c->erase_completion_lock);
796
797 jeb = &c->blocks[outvec_to / c->sector_size];
798 jffs2_block_refile(c, jeb, REFILE_ANYWAY);
799
800 *retlen = 0;
801 spin_unlock(&c->erase_completion_lock);
768 goto exit; 802 goto exit;
769 } 803 }
770 804
@@ -819,7 +853,7 @@ int jffs2_flash_write(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *r
819{ 853{
820 struct kvec vecs[1]; 854 struct kvec vecs[1];
821 855
822 if (jffs2_can_mark_obsolete(c)) 856 if (!jffs2_is_writebuffered(c))
823 return c->mtd->write(c->mtd, ofs, len, retlen, buf); 857 return c->mtd->write(c->mtd, ofs, len, retlen, buf);
824 858
825 vecs[0].iov_base = (unsigned char *) buf; 859 vecs[0].iov_base = (unsigned char *) buf;
@@ -835,39 +869,38 @@ int jffs2_flash_read(struct jffs2_sb_info *c, loff_t ofs, size_t len, size_t *re
835 loff_t orbf = 0, owbf = 0, lwbf = 0; 869 loff_t orbf = 0, owbf = 0, lwbf = 0;
836 int ret; 870 int ret;
837 871
838 /* Read flash */ 872 if (!jffs2_is_writebuffered(c))
839 if (!jffs2_can_mark_obsolete(c)) {
840 down_read(&c->wbuf_sem);
841
842 if (jffs2_cleanmarker_oob(c))
843 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
844 else
845 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
846
847 if ( (ret == -EBADMSG) && (*retlen == len) ) {
848 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
849 len, ofs);
850 /*
851 * We have the raw data without ECC correction in the buffer, maybe
852 * we are lucky and all data or parts are correct. We check the node.
853 * If data are corrupted node check will sort it out.
854 * We keep this block, it will fail on write or erase and the we
855 * mark it bad. Or should we do that now? But we should give him a chance.
856 * Maybe we had a system crash or power loss before the ecc write or
857 * a erase was completed.
858 * So we return success. :)
859 */
860 ret = 0;
861 }
862 } else
863 return c->mtd->read(c->mtd, ofs, len, retlen, buf); 873 return c->mtd->read(c->mtd, ofs, len, retlen, buf);
864 874
875 /* Read flash */
876 down_read(&c->wbuf_sem);
877 if (jffs2_cleanmarker_oob(c))
878 ret = c->mtd->read_ecc(c->mtd, ofs, len, retlen, buf, NULL, c->oobinfo);
879 else
880 ret = c->mtd->read(c->mtd, ofs, len, retlen, buf);
881
882 if ( (ret == -EBADMSG) && (*retlen == len) ) {
883 printk(KERN_WARNING "mtd->read(0x%zx bytes from 0x%llx) returned ECC error\n",
884 len, ofs);
885 /*
886 * We have the raw data without ECC correction in the buffer, maybe
887 * we are lucky and all data or parts are correct. We check the node.
888 * If data are corrupted node check will sort it out.
889 * We keep this block, it will fail on write or erase and the we
890 * mark it bad. Or should we do that now? But we should give him a chance.
891 * Maybe we had a system crash or power loss before the ecc write or
892 * a erase was completed.
893 * So we return success. :)
894 */
895 ret = 0;
896 }
897
865 /* if no writebuffer available or write buffer empty, return */ 898 /* if no writebuffer available or write buffer empty, return */
866 if (!c->wbuf_pagesize || !c->wbuf_len) 899 if (!c->wbuf_pagesize || !c->wbuf_len)
867 goto exit; 900 goto exit;
868 901
869 /* if we read in a different block, return */ 902 /* if we read in a different block, return */
870 if ( (ofs & ~(c->sector_size-1)) != (c->wbuf_ofs & ~(c->sector_size-1)) ) 903 if (SECTOR_ADDR(ofs) != SECTOR_ADDR(c->wbuf_ofs))
871 goto exit; 904 goto exit;
872 905
873 if (ofs >= c->wbuf_ofs) { 906 if (ofs >= c->wbuf_ofs) {
@@ -1161,7 +1194,27 @@ void jffs2_nand_flash_cleanup(struct jffs2_sb_info *c)
1161 kfree(c->wbuf); 1194 kfree(c->wbuf);
1162} 1195}
1163 1196
1164#ifdef CONFIG_JFFS2_FS_NOR_ECC 1197int jffs2_dataflash_setup(struct jffs2_sb_info *c) {
1198 c->cleanmarker_size = 0; /* No cleanmarkers needed */
1199
1200 /* Initialize write buffer */
1201 init_rwsem(&c->wbuf_sem);
1202 c->wbuf_pagesize = c->sector_size;
1203 c->wbuf_ofs = 0xFFFFFFFF;
1204
1205 c->wbuf = kmalloc(c->wbuf_pagesize, GFP_KERNEL);
1206 if (!c->wbuf)
1207 return -ENOMEM;
1208
1209 printk(KERN_INFO "JFFS2 write-buffering enabled (%i)\n", c->wbuf_pagesize);
1210
1211 return 0;
1212}
1213
1214void jffs2_dataflash_cleanup(struct jffs2_sb_info *c) {
1215 kfree(c->wbuf);
1216}
1217
1165int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) { 1218int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
1166 /* Cleanmarker is actually larger on the flashes */ 1219 /* Cleanmarker is actually larger on the flashes */
1167 c->cleanmarker_size = 16; 1220 c->cleanmarker_size = 16;
@@ -1181,4 +1234,3 @@ int jffs2_nor_ecc_flash_setup(struct jffs2_sb_info *c) {
1181void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) { 1234void jffs2_nor_ecc_flash_cleanup(struct jffs2_sb_info *c) {
1182 kfree(c->wbuf); 1235 kfree(c->wbuf);
1183} 1236}
1184#endif
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 80a5db54262..69100615d9a 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.87 2004/11/16 20:36:12 dwmw2 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);
@@ -136,6 +135,15 @@ struct jffs2_full_dnode *jffs2_write_dnode(struct jffs2_sb_info *c, struct jffs2
136 raw->__totlen = PAD(sizeof(*ri)+datalen); 135 raw->__totlen = PAD(sizeof(*ri)+datalen);
137 raw->next_phys = NULL; 136 raw->next_phys = NULL;
138 137
138 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(ri->version) < f->highest_version)) {
139 BUG_ON(!retried);
140 D1(printk(KERN_DEBUG "jffs2_write_dnode : dnode_version %d, "
141 "highest version %d -> updating dnode\n",
142 je32_to_cpu(ri->version), f->highest_version));
143 ri->version = cpu_to_je32(++f->highest_version);
144 ri->node_crc = cpu_to_je32(crc32(0, ri, sizeof(*ri)-8));
145 }
146
139 ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen, 147 ret = jffs2_flash_writev(c, vecs, cnt, flash_ofs, &retlen,
140 (alloc_mode==ALLOC_GC)?0:f->inocache->ino); 148 (alloc_mode==ALLOC_GC)?0:f->inocache->ino);
141 149
@@ -280,6 +288,16 @@ struct jffs2_full_dirent *jffs2_write_dirent(struct jffs2_sb_info *c, struct jff
280 raw->__totlen = PAD(sizeof(*rd)+namelen); 288 raw->__totlen = PAD(sizeof(*rd)+namelen);
281 raw->next_phys = NULL; 289 raw->next_phys = NULL;
282 290
291 if ((alloc_mode!=ALLOC_GC) && (je32_to_cpu(rd->version) < f->highest_version)) {
292 BUG_ON(!retried);
293 D1(printk(KERN_DEBUG "jffs2_write_dirent : dirent_version %d, "
294 "highest version %d -> updating dirent\n",
295 je32_to_cpu(rd->version), f->highest_version));
296 rd->version = cpu_to_je32(++f->highest_version);
297 fd->version = je32_to_cpu(rd->version);
298 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
299 }
300
283 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen, 301 ret = jffs2_flash_writev(c, vecs, 2, flash_ofs, &retlen,
284 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino)); 302 (alloc_mode==ALLOC_GC)?0:je32_to_cpu(rd->pino));
285 if (ret || (retlen != sizeof(*rd) + namelen)) { 303 if (ret || (retlen != sizeof(*rd) + namelen)) {
@@ -625,20 +643,23 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
625 643
626 down(&dead_f->sem); 644 down(&dead_f->sem);
627 645
628 while (dead_f->dents) { 646 if (S_ISDIR(OFNI_EDONI_2SFFJ(dead_f)->i_mode)) {
629 /* There can be only deleted ones */ 647 while (dead_f->dents) {
630 fd = dead_f->dents; 648 /* There can be only deleted ones */
631 649 fd = dead_f->dents;
632 dead_f->dents = fd->next; 650
633 651 dead_f->dents = fd->next;
634 if (fd->ino) { 652
635 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n", 653 if (fd->ino) {
636 dead_f->inocache->ino, fd->name, fd->ino); 654 printk(KERN_WARNING "Deleting inode #%u with active dentry \"%s\"->ino #%u\n",
637 } else { 655 dead_f->inocache->ino, fd->name, fd->ino);
638 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n", fd->name, dead_f->inocache->ino)); 656 } else {
657 D1(printk(KERN_DEBUG "Removing deletion dirent for \"%s\" from dir ino #%u\n",
658 fd->name, dead_f->inocache->ino));
659 }
660 jffs2_mark_node_obsolete(c, fd->raw);
661 jffs2_free_full_dirent(fd);
639 } 662 }
640 jffs2_mark_node_obsolete(c, fd->raw);
641 jffs2_free_full_dirent(fd);
642 } 663 }
643 664
644 dead_f->inocache->nlink--; 665 dead_f->inocache->nlink--;