mtd/fs/jffs3 summary.c, NONE, 3.1 summary.h, NONE,
3.1 Makefile.common, 3.2, 3.3 build.c, 3.3, 3.4 debug.h, 1.10,
1.11 dir.c, 3.4, 3.5 file.c, 3.4, 3.5 fs.c, 3.3, 3.4 gc.c, 3.6,
3.7 jffs3.h, 3.3, 3.4 nodelist.h, 3.4, 3.5 nodemgmt.c, 3.2,
3.3 os-linux.h, 3.1, 3.2 scan.c, 3.4, 3.5 super-v24.c, 3.1,
3.2 super.c, 3.4, 3.5 wbuf.c, 3.4, 3.5 write.c, 3.3, 3.4
havasi at infradead.org
havasi at infradead.org
Tue Dec 21 10:18:54 EST 2004
Update of /home/cvs/mtd/fs/jffs3
In directory phoenix.infradead.org:/tmp/cvs-serv24573/fs/jffs3
Modified Files:
Makefile.common build.c debug.h dir.c file.c fs.c gc.c jffs3.h
nodelist.h nodemgmt.c os-linux.h scan.c super-v24.c super.c
wbuf.c write.c
Added Files:
summary.c summary.h
Log Message:
Summary support for JFFS3.
***** Error reading new file: [Errno 2] No such file or directory: 'summary.c'
***** Error reading new file: [Errno 2] No such file or directory: 'summary.h'
Index: Makefile.common
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/Makefile.common,v
retrieving revision 3.2
retrieving revision 3.3
diff -u -r3.2 -r3.3
--- Makefile.common 13 Dec 2004 15:25:12 -0000 3.2
+++ Makefile.common 21 Dec 2004 15:18:50 -0000 3.3
@@ -17,3 +17,4 @@
jffs3-$(CONFIG_JFFS3_RUBIN) += compr_rubin.o
jffs3-$(CONFIG_JFFS3_RTIME) += compr_rtime.o
jffs3-$(CONFIG_JFFS3_ZLIB) += compr_zlib.o
+jffs3-$(CONFIG_JFFS3_SUMMARY) += summary.o
Index: build.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/build.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- build.c 21 Dec 2004 14:11:19 -0000 3.3
+++ build.c 21 Dec 2004 15:18:50 -0000 3.4
@@ -335,6 +335,9 @@
c->blocks[i].first_node = NULL;
c->blocks[i].last_node = NULL;
c->blocks[i].bad_count = 0;
+#ifdef CONFIG_JFFS3_SUMMARY
+ c->blocks[i].sum_collected = NULL;
+#endif
}
init_MUTEX(&c->alloc_sem);
Index: debug.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/debug.h,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- debug.h 21 Dec 2004 14:47:57 -0000 1.10
+++ debug.h 21 Dec 2004 15:18:50 -0000 1.11
@@ -35,6 +35,7 @@
#define JFFS3_DBG_VFS 9 /* VFS callback handlers */
#define JFFS3_DBG_BLD 10 /* File system build (on mount) */
#define JFFS3_DBG_COMPR 11 /* Compression */
+#define JFFS3_DBG_SUMMARY 12 /* Summary info */
#if CONFIG_JFFS3_FS_DEBUG > 0
#define JFFS3_DBG_PARANOIA_CHECKS 1
@@ -50,6 +51,7 @@
#define JFFS3_DBG_SUBSYS_VFS_PRINT 1
#define JFFS3_DBG_SUBSYS_BLD_PRINT 1
#define JFFS3_DBG_SUBSYS_COMPR_PRINT 1
+#define JFFS3_DBG_SUBSYS_SUMMARY_PRINT 1
#else
#define JFFS3_DBG_SUBSYS_OTHER_PRINT 0
#define JFFS3_DBG_SUBSYS_SCAN_PRINT 0
@@ -62,6 +64,7 @@
#define JFFS3_DBG_SUBSYS_VFS_PRINT 0
#define JFFS3_DBG_SUBSYS_BLD_PRINT 0
#define JFFS3_DBG_SUBSYS_COMPR_PRINT 0
+#define JFFS3_DBG_SUBSYS_SUMMARY_PRINT 0
#endif
/*
@@ -109,13 +112,19 @@
case JFFS3_DBG_GC: \
if (JFFS3_DBG_SUBSYS_GC_PRINT) \
subsysname = "GC"; \
+ break; \
case JFFS3_DBG_WBUF: \
if (JFFS3_DBG_SUBSYS_GC_PRINT) \
subsysname = "wbuf"; \
+ break; \
case JFFS3_DBG_OTHER: \
if (JFFS3_DBG_SUBSYS_OTHER_PRINT) \
subsysname = ""; \
break; \
+ case JFFS3_DBG_SUMMARY: \
+ if (JFFS3_DBG_SUBSYS_SUMMARY_PRINT) \
+ subsysname = "Summary"; \
+ break; \
default: \
BUG(); \
} \
@@ -163,6 +172,10 @@
#define DBG_COMPR(debug_level, args...) \
JFFS3DBG_SUBSYSTEM(JFFS3_DBG_COMPR, debug_level, args)
+
+#define DBG_SUMMARY(debug_level, args...) \
+ JFFS3DBG_SUBSYSTEM(JFFS3_DBG_SUMMARY, debug_level, args)
+
#define ERROR_MSG(args...) \
do { \
Index: dir.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/dir.c,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- dir.c 21 Dec 2004 14:11:19 -0000 3.4
+++ dir.c 21 Dec 2004 15:18:50 -0000 3.5
@@ -314,7 +314,7 @@
* Just the node will do for now, though
*/
namelen = dentry->d_name.len;
- ret = jffs3_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*ri) + strlen(target), &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
jffs3_free_raw_inode(ri);
@@ -360,7 +360,7 @@
up(&f->sem);
jffs3_complete_reservation(c);
- ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
/* Eep. */
jffs3_clear_inode(inode);
@@ -445,7 +445,7 @@
* Just the node will do for now, though
*/
namelen = dentry->d_name.len;
- ret = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
jffs3_free_raw_inode(ri);
@@ -488,7 +488,7 @@
up(&f->sem);
jffs3_complete_reservation(c);
- ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
/* Eep. */
jffs3_clear_inode(inode);
@@ -597,7 +597,7 @@
* Just the node will do for now, though
*/
namelen = dentry->d_name.len;
- ret = jffs3_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*ri) + devlen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
jffs3_free_raw_inode(ri);
@@ -642,7 +642,7 @@
up(&f->sem);
jffs3_complete_reservation(c);
- ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
/* Eep. */
jffs3_clear_inode(inode);
@@ -796,4 +796,3 @@
return 0;
}
-
Index: file.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/file.c,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- file.c 21 Dec 2004 14:11:19 -0000 3.4
+++ file.c 21 Dec 2004 15:18:50 -0000 3.5
@@ -136,7 +136,7 @@
DBG_VFS(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
(unsigned int)inode->i_size, pageofs);
- ret = jffs3_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
if (ret)
return ret;
Index: fs.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/fs.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- fs.c 21 Dec 2004 14:11:19 -0000 3.3
+++ fs.c 21 Dec 2004 15:18:50 -0000 3.4
@@ -77,7 +77,7 @@
return -ENOMEM;
}
- ret = jffs3_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*ri) + mdatalen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
jffs3_free_raw_inode(ri);
if (S_ISLNK(inode->i_mode & S_IFMT))
Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/gc.c,v
retrieving revision 3.6
retrieving revision 3.7
diff -u -r3.6 -r3.7
--- gc.c 21 Dec 2004 11:45:06 -0000 3.6
+++ gc.c 21 Dec 2004 15:18:50 -0000 3.7
@@ -509,7 +509,7 @@
don't want to force wastage of the end of a block if splitting would
work. */
ret = jffs3_reserve_space_gc(c, min_t(uint32_t, sizeof(struct jffs3_raw_inode) + JFFS3_MIN_DATA_LEN,
- rawlen), &phys_ofs, &alloclen);
+ rawlen), &phys_ofs, &alloclen, rawlen); /* this is not optimal yet */
if (ret)
return ret;
@@ -618,7 +618,7 @@
jffs3_dbg_acct_sanity_check(c, jeb);
jffs3_dbg_acct_paranoia_check(c, jeb);
- ret = jffs3_reserve_space_gc(c, rawlen, &phys_ofs, &dummy);
+ ret = jffs3_reserve_space_gc(c, rawlen, &phys_ofs, &dummy, rawlen); /* this is not optimal yet */
if (!ret) {
DBG_GC(1, "Allocated space at %#08x to retry failed write.\n", phys_ofs);
@@ -696,7 +696,7 @@
}
- ret = jffs3_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen);
+ ret = jffs3_reserve_space_gc(c, sizeof(ri) + mdatalen, &phys_ofs, &alloclen, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
WARNING_MSG("Reserve space of %zd bytes for garbage_collect_metadata failed: %d\n",
sizeof(ri)+ mdatalen, ret);
@@ -763,7 +763,7 @@
rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
- ret = jffs3_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen);
+ ret = jffs3_reserve_space_gc(c, sizeof(rd)+rd.nsize, &phys_ofs, &alloclen, JFFS3_SUMMARY_DIRENT_SIZE(rd.nsize));
if (ret) {
WARNING_MSG("Reserve space of %zd bytes for garbage_collect_dirent failed: %d\n",
sizeof(rd)+rd.nsize, ret);
@@ -963,7 +963,7 @@
ri.data_crc = cpu_to_je32(0);
ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
- ret = jffs3_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen);
+ ret = jffs3_reserve_space_gc(c, sizeof(ri), &phys_ofs, &alloclen, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
WARNING_MSG("Reserve space of %zd bytes for garbage_collect_hole failed: %d\n",
sizeof(ri), ret);
@@ -1183,7 +1183,7 @@
uint32_t cdatalen;
uint16_t comprtype = JFFS3_COMPR_NONE;
- ret = jffs3_reserve_space_gc(c, sizeof(ri) + JFFS3_MIN_DATA_LEN, &phys_ofs, &alloclen);
+ ret = jffs3_reserve_space_gc(c, sizeof(ri) + JFFS3_MIN_DATA_LEN, &phys_ofs, &alloclen, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
WARNING_MSG("Reserve space of %zd bytes for garbage_collect_dnode failed: %d\n",
@@ -1240,4 +1240,3 @@
jffs3_gc_release_page(c, pg_ptr, &pg);
return ret;
}
-
Index: jffs3.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/jffs3.h,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- jffs3.h 13 Dec 2004 11:33:37 -0000 3.3
+++ jffs3.h 21 Dec 2004 15:18:50 -0000 3.4
@@ -41,6 +41,9 @@
#define JFFS3_EMPTY_BITMASK 0xffff
#define JFFS3_DIRTY_BITMASK 0x0000
+/* Summary node MAGIC marker */
+#define JFFS3_SUM_MAGIC 0x02851885
+
/*
* We only allow a single char for length, and 0xFF is empty flash so
* we don't want it confused with a real length. Hence max 254.
@@ -78,6 +81,8 @@
#define JFFS3_NODETYPE_CLEANMARKER (JFFS3_FEATURE_RWCOMPAT_DELETE | JFFS3_NODE_ACCURATE | 3)
#define JFFS3_NODETYPE_PADDING (JFFS3_FEATURE_RWCOMPAT_DELETE | JFFS3_NODE_ACCURATE | 4)
+#define JFFS3_NODETYPE_SUMMARY (JFFS3_FEATURE_RWCOMPAT_DELETE | JFFS3_NODE_ACCURATE | 6)
+
#define JFFS3_SB_FLAG_RO 1
#define JFFS3_SB_FLAG_MOUNTING 2
@@ -155,10 +160,24 @@
uint8_t data[0];
} __attribute__((packed));
+struct jffs3_summary_node{
+ jint16_t magic;
+ jint16_t nodetype; /* = JFFS3_NODETYPE_INODE_SUM */
+ jint32_t totlen;
+ jint32_t hdr_crc;
+ jint16_t sum_num; /* number of sum entries*/
+ jint32_t cln_mkr; /* clean marker size, 0 = no cleanmarker */
+ jint32_t padded; /* sum of the size of padding nodes */
+ jint32_t sum_crc; /* summary information crc */
+ jint32_t node_crc; /* node crc */
+ jint32_t sum[0]; /* inode summary info */
+} __attribute__((packed));
+
union jffs3_node_union {
struct jffs3_raw_inode i;
struct jffs3_raw_dirent d;
struct jffs3_unknown_node u;
+ struct jffs3_summary_node s;
};
@@ -289,6 +308,9 @@
uint32_t fsdata_pos;
uint32_t fsdata_len;
#endif
+#ifdef CONFIG_JFFS3_SUMMARY
+ jint32_t *summary_buf;
+#endif
/* OS-private pointer for getting back to master superblock info */
void *os_priv;
Index: nodelist.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/nodelist.h,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- nodelist.h 13 Dec 2004 15:30:33 -0000 3.4
+++ nodelist.h 21 Dec 2004 15:18:50 -0000 3.5
@@ -19,6 +19,7 @@
#include <linux/fs.h>
#include <linux/types.h>
#include "jffs3.h"
+#include "summary.h"
#ifdef __ECOS
#include "os-ecos.h"
@@ -192,7 +193,11 @@
struct list_head list;
int bad_count;
uint32_t offset; /* of this block in the MTD */
-
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ struct jffs3_sum_info *sum_collected;
+#endif
+
uint32_t unchecked_size;
uint32_t used_size;
uint32_t dirty_size;
@@ -333,8 +338,8 @@
/* nodemgmt.c */
int jffs3_thread_should_wake(struct jffs3_sb_info *c);
-int jffs3_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio);
-int jffs3_reserve_space_gc(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
+int jffs3_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio, uint32_t sumsize);
+int jffs3_reserve_space_gc(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize);
int jffs3_add_physical_node_ref(struct jffs3_sb_info *c, struct jffs3_raw_node_ref *new);
void jffs3_complete_reservation(struct jffs3_sb_info *c);
void jffs3_mark_node_obsolete(struct jffs3_sb_info *c, struct jffs3_raw_node_ref *raw);
@@ -395,6 +400,9 @@
/* scan.c */
int jffs3_scan_medium(struct jffs3_sb_info *c);
void jffs3_rotate_lists(struct jffs3_sb_info *c);
+int jffs3_fill_scan_buf (struct jffs3_sb_info *c, unsigned char *buf,
+ uint32_t ofs, uint32_t len);
+struct jffs3_inode_cache *jffs3_scan_make_ino_cache(struct jffs3_sb_info *c, uint32_t ino);
/* build.c */
int jffs3_do_mount_fs(struct jffs3_sb_info *c);
@@ -414,4 +422,3 @@
#endif /* __JFFS3_NODELIST_H__ */
#include "debug.h"
-
Index: nodemgmt.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/nodemgmt.c,v
retrieving revision 3.2
retrieving revision 3.3
diff -u -r3.2 -r3.3
--- nodemgmt.c 13 Dec 2004 15:34:49 -0000 3.2
+++ nodemgmt.c 21 Dec 2004 15:18:50 -0000 3.3
@@ -39,9 +39,9 @@
* for the requested allocation.
*/
-static int jffs3_do_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len);
+static int jffs3_do_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize);
-int jffs3_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio)
+int jffs3_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, int prio, uint32_t sumsize)
{
int ret = -EAGAIN;
int blocksneeded = c->resv_blocks_write;
@@ -130,7 +130,7 @@
spin_lock(&c->erase_completion_lock);
}
- ret = jffs3_do_reserve_space(c, minsize, ofs, len);
+ ret = jffs3_do_reserve_space(c, minsize, ofs, len, sumsize);
if (ret) {
D1(printk(KERN_DEBUG "jffs3_reserve_space: ret is %d\n", ret));
}
@@ -141,7 +141,7 @@
return ret;
}
-int jffs3_reserve_space_gc(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
+int jffs3_reserve_space_gc(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize)
{
int ret = -EAGAIN;
minsize = PAD(minsize);
@@ -150,7 +150,7 @@
spin_lock(&c->erase_completion_lock);
while(ret == -EAGAIN) {
- ret = jffs3_do_reserve_space(c, minsize, ofs, len);
+ ret = jffs3_do_reserve_space(c, minsize, ofs, len, sumsize);
if (ret) {
D1(printk(KERN_DEBUG "jffs3_reserve_space_gc: looping, ret is %d\n", ret));
}
@@ -160,49 +160,115 @@
}
/* Called with alloc sem _and_ erase_completion_lock */
-static int jffs3_do_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len)
+static int jffs3_do_reserve_space(struct jffs3_sb_info *c, uint32_t minsize, uint32_t *ofs, uint32_t *len, uint32_t sumsize)
{
struct jffs3_eraseblock *jeb = c->nextblock;
+ uint32_t nofree_size;
restart:
- if (jeb && minsize > jeb->free_size) {
- /* Skip the end of this block and file it as having some dirty space */
- /* If there's a pending write to it, flush now */
- if (jffs3_wbuf_dirty(c)) {
- spin_unlock(&c->erase_completion_lock);
- D1(printk(KERN_DEBUG "jffs3_do_reserve_space: Flushing write buffer\n"));
- jffs3_flush_wbuf_pad(c);
- spin_lock(&c->erase_completion_lock);
- jeb = c->nextblock;
- goto restart;
- }
- c->wasted_size += jeb->free_size;
- c->free_size -= jeb->free_size;
- jeb->wasted_size += jeb->free_size;
- jeb->free_size = 0;
+ nofree_size = 0;
+
+#ifdef CONFIG_JFFS3_SUMMARY
+
+ if (sumsize != JFFS3_SUMMARY_NOSUM_SIZE) {
- /* Check, if we have a dirty block now, or if it was dirty already */
- if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
- c->dirty_size += jeb->wasted_size;
- c->wasted_size -= jeb->wasted_size;
- jeb->dirty_size += jeb->wasted_size;
- jeb->wasted_size = 0;
- if (VERYDIRTY(c, jeb->dirty_size)) {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->very_dirty_list);
- } else {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->dirty_list);
+ int ret;
+
+ if (jeb) {
+ if ((ret=jffs3_sum_care_sum_collected(jeb))) return ret;
+ nofree_size = sumsize + jeb->sum_collected->sum_size + JFFS3_SUMMARY_FRAME_SIZE;
+ }
+
+ DBG_SUMMARY(1,"JFFS3: minsize %d , jeb->free(%d) , sum_collected->size(%d) , sumsize(%d)\n",
+ minsize,jeb->free_size,jeb->sum_collected->sum_size,sumsize);
+
+ if (jeb && (minsize + jeb->sum_collected->sum_size + sumsize + JFFS3_SUMMARY_FRAME_SIZE > jeb->free_size)) {
+ DBG_SUMMARY(1,"JFFS3: generating summary for 0x%08x.\n", jeb->offset);
+ if (jeb->sum_collected->sum_size == JFFS3_SUMMARY_NOSUM_SIZE) {
+ sumsize = JFFS3_SUMMARY_NOSUM_SIZE;
+ jffs3_sum_clean_collected(jeb);
+ goto restart;
}
- } else {
- D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
- jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
- list_add_tail(&jeb->list, &c->clean_list);
+
+ ret = jffs3_sum_write_sumnode(c);
+
+ if (ret)
+ return ret;
+
+ if (jeb->sum_collected->sum_size == JFFS3_SUMMARY_NOSUM_SIZE) { //jffs3_write_sumnode can't write out the summary information
+ sumsize = JFFS3_SUMMARY_NOSUM_SIZE;
+ jffs3_sum_clean_collected(jeb);
+ goto restart;
+ }
+
+ /* Check, if we have a dirty block now, or if it was dirty already */
+ if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
+ c->dirty_size += jeb->wasted_size;
+ c->wasted_size -= jeb->wasted_size;
+ jeb->dirty_size += jeb->wasted_size;
+ jeb->wasted_size = 0;
+ if (VERYDIRTY(c, jeb->dirty_size)) {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->very_dirty_list);
+ } else {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->dirty_list);
+ }
+ } else {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->clean_list);
+ }
+ c->nextblock = jeb = NULL;
}
- c->nextblock = jeb = NULL;
}
+ else {
+#endif
+
+ if (jeb && minsize > jeb->free_size) {
+ /* Skip the end of this block and file it as having some dirty space */
+ /* If there's a pending write to it, flush now */
+ if (jffs3_wbuf_dirty(c)) {
+ spin_unlock(&c->erase_completion_lock);
+ D1(printk(KERN_DEBUG "jffs3_do_reserve_space: Flushing write buffer\n"));
+ jffs3_flush_wbuf_pad(c);
+ spin_lock(&c->erase_completion_lock);
+ jeb = c->nextblock;
+ goto restart;
+ }
+ c->wasted_size += jeb->free_size;
+ c->free_size -= jeb->free_size;
+ jeb->wasted_size += jeb->free_size;
+ jeb->free_size = 0;
+
+ /* Check, if we have a dirty block now, or if it was dirty already */
+ if (ISDIRTY (jeb->wasted_size + jeb->dirty_size)) {
+ c->dirty_size += jeb->wasted_size;
+ c->wasted_size -= jeb->wasted_size;
+ jeb->dirty_size += jeb->wasted_size;
+ jeb->wasted_size = 0;
+ if (VERYDIRTY(c, jeb->dirty_size)) {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to very_dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->very_dirty_list);
+ } else {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to dirty_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->dirty_list);
+ }
+ } else {
+ D1(printk(KERN_DEBUG "Adding full erase block at 0x%08x to clean_list (free 0x%08x, dirty 0x%08x, used 0x%08x\n",
+ jeb->offset, jeb->free_size, jeb->dirty_size, jeb->used_size));
+ list_add_tail(&jeb->list, &c->clean_list);
+ }
+ c->nextblock = jeb = NULL;
+ }
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ }
+#endif
if (!jeb) {
struct list_head *next;
@@ -267,7 +333,7 @@
/* OK, jeb (==c->nextblock) is now pointing at a block which definitely has
enough space */
*ofs = jeb->offset + (c->sector_size - jeb->free_size);
- *len = jeb->free_size;
+ *len = jeb->free_size - nofree_size;
if (c->cleanmarker_size && jeb->used_size == c->cleanmarker_size &&
!jeb->first_node->next_in_ino) {
Index: os-linux.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/os-linux.h,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- os-linux.h 9 Dec 2004 16:05:06 -0000 3.1
+++ os-linux.h 21 Dec 2004 15:18:51 -0000 3.2
@@ -101,7 +101,12 @@
#define jffs3_is_readonly(c) (OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY)
#if (!defined CONFIG_JFFS3_FS_NAND && !defined CONFIG_JFFS3_FS_NOR_ECC)
+#ifndef CONFIG_JFFS3_SUMMARY
#define jffs3_can_mark_obsolete(c) (1)
+#else
+#define jffs3_can_mark_obsolete(c) (0)
+#endif
+
#define jffs3_cleanmarker_oob(c) (0)
#define jffs3_write_nand_cleanmarker(c,jeb) (-EIO)
@@ -122,7 +127,12 @@
#else /* NAND and/or ECC'd NOR support present */
+#ifndef CONFIG_JFFS3_SUMMARY
#define jffs3_can_mark_obsolete(c) ((c->mtd->type == MTD_NORFLASH && !(c->mtd->flags & MTD_ECC)) || c->mtd->type == MTD_RAM)
+#else
+#define jffs3_can_mark_obsolete(c) (0)
+#endif
+
#define jffs3_cleanmarker_oob(c) (c->mtd->type == MTD_NANDFLASH)
#define jffs3_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
@@ -219,5 +229,3 @@
#endif /* __JFFS3_OS_LINUX_H__ */
-
-
Index: scan.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/scan.c,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- scan.c 14 Dec 2004 16:14:32 -0000 3.4
+++ scan.c 21 Dec 2004 15:18:51 -0000 3.5
@@ -19,22 +19,10 @@
#include <linux/crc32.h>
#include <linux/compiler.h>
#include "nodelist.h"
+#include "summary.h"
#define EMPTY_SCAN_SIZE 1024
-#define DIRTY_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->dirty_size += _x; \
- jeb->free_size -= _x ; jeb->dirty_size += _x; \
- }while(0)
-#define USED_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->used_size += _x; \
- jeb->free_size -= _x ; jeb->used_size += _x; \
- }while(0)
-#define UNCHECKED_SPACE(x) do { typeof(x) _x = (x); \
- c->free_size -= _x; c->unchecked_size += _x; \
- jeb->free_size -= _x ; jeb->unchecked_size += _x; \
- }while(0)
-
#define DBG_NOISY(noise, args...) do { \
if (*(noise)) { \
NOTICE_MSG(args); \
@@ -57,14 +45,7 @@
struct jffs3_raw_inode *ri, uint32_t ofs);
static int jffs3_scan_dirent_node(struct jffs3_sb_info *c, struct jffs3_eraseblock *jeb,
struct jffs3_raw_dirent *rd, uint32_t ofs);
-
-#define BLK_STATE_ALLFF 0
-#define BLK_STATE_CLEAN 1
-#define BLK_STATE_PARTDIRTY 2
-#define BLK_STATE_CLEANMARKER 3
-#define BLK_STATE_ALLDIRTY 4
-#define BLK_STATE_BADBLOCK 5
-
+
static inline int min_free(struct jffs3_sb_info *c)
{
uint32_t min = 2 * sizeof(struct jffs3_raw_inode);
@@ -261,7 +242,7 @@
return ret;
}
-static int jffs3_fill_scan_buf (struct jffs3_sb_info *c, unsigned char *buf,
+int jffs3_fill_scan_buf (struct jffs3_sb_info *c, unsigned char *buf,
uint32_t ofs, uint32_t len)
{
int ret;
@@ -293,6 +274,11 @@
uint32_t hdr_crc, buf_ofs, buf_len;
int err;
int noise = 0;
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ struct jffs3_sum_marker *sm;
+#endif
+
#ifdef CONFIG_JFFS3_FS_NAND
int cleanmarkerfound = 0;
#endif
@@ -318,10 +304,55 @@
}
}
#endif
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ sm = (struct jffs3_sum_marker *)kmalloc(sizeof(struct jffs3_sum_marker), GFP_KERNEL);
+ if (!sm) {
+ return -ENOMEM;
+ }
+
+ err = jffs3_fill_scan_buf(c, (unsigned char *) sm, jeb->offset + c->sector_size - sizeof(struct jffs3_sum_marker), sizeof(struct jffs3_sum_marker));
+
+ if (err) {
+ kfree(sm);
+ return err;
+ }
+
+ if (je32_to_cpu(sm->magic) == JFFS3_SUM_MAGIC ) {
+
+ if(je32_to_cpu(sm->erase_size) == c->sector_size) {
+ int ret = jffs3_sum_scan_sumnode(c,jeb,je32_to_cpu(sm->offset),&pseudo_random);
+
+ if (ret) {
+ kfree(sm);
+ return ret;
+ }
+ }
+
+ WARNING_MSG("FS erase_block_size != JFFS3 erase_block_size => skipping summary information\n");
+
+ }
+
+ kfree(sm);
+
+ ofs = jeb->offset;
+ prevofs = jeb->offset - 1;
+
+#endif
+
+
buf_ofs = jeb->offset;
if (!buf_size) {
buf_len = c->sector_size;
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ /* must reread because of summary test */
+ err = jffs3_fill_scan_buf(c, buf, buf_ofs, buf_len);
+ if (err)
+ return err;
+#endif
+
} else {
buf_len = EMPTY_SCAN_SIZE;
err = jffs3_fill_scan_buf(c, buf, buf_ofs, buf_len);
@@ -363,6 +394,10 @@
noise = 10;
+#ifdef CONFIG_JFFS3_SUMMARY
+ DBG_SUMMARY(1,"JFFS3: no summary found in jeb 0x%08x. Apply original scan.\n",jeb->offset);
+#endif
+
scan_more:
while(ofs < jeb->offset + c->sector_size) {
@@ -584,6 +619,9 @@
break;
case JFFS3_NODETYPE_PADDING:
+#ifdef CONFIG_JFFS3_SUMMARY
+ jffs3_sum_add_padding_mem(jeb,je32_to_cpu(node->totlen));
+#endif
DIRTY_SPACE(PAD(je32_to_cpu(node->totlen)));
ofs += PAD(je32_to_cpu(node->totlen));
break;
@@ -651,7 +689,7 @@
return BLK_STATE_ALLDIRTY;
}
-static struct jffs3_inode_cache *jffs3_scan_make_ino_cache(struct jffs3_sb_info *c, uint32_t ino)
+struct jffs3_inode_cache *jffs3_scan_make_ino_cache(struct jffs3_sb_info *c, uint32_t ino)
{
struct jffs3_inode_cache *ic;
@@ -744,6 +782,11 @@
pseudo_random += je32_to_cpu(ri->version);
UNCHECKED_SPACE(PAD(je32_to_cpu(ri->totlen)));
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ jffs3_sum_add_inode_mem(jeb,ri,ofs);
+#endif
+
return 0;
}
@@ -823,6 +866,10 @@
USED_SPACE(PAD(je32_to_cpu(rd->totlen)));
jffs3_add_fd_to_list(c, fd, &ic->scan_dents);
+#ifdef CONFIG_JFFS3_SUMMARY
+ jffs3_sum_add_dirent_mem(jeb,rd,ofs);
+#endif
+
return 0;
}
Index: super-v24.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/super-v24.c,v
retrieving revision 3.1
retrieving revision 3.2
diff -u -r3.1 -r3.2
--- super-v24.c 9 Dec 2004 16:05:07 -0000 3.1
+++ super-v24.c 21 Dec 2004 15:18:51 -0000 3.2
@@ -25,6 +25,7 @@
#include <linux/mtd/mtd.h>
#include "compr.h"
#include "nodelist.h"
+#include "summary.h"
#ifndef MTD_BLOCK_MAJOR
#define MTD_BLOCK_MAJOR 31
@@ -73,7 +74,9 @@
put_mtd_device(c->mtd);
return NULL;
}
-
+#ifdef CONFIG_JFFS3_SUMMARY
+ jffs3_sum_init(c);
+#endif
return sb;
}
@@ -89,6 +92,10 @@
down(&c->alloc_sem);
jffs3_flush_wbuf_pad(c);
up(&c->alloc_sem);
+#ifdef CONFIG_JFFS3_SUMMARY
+ jffs3_sum_clean_all_info(c);
+ jffs3_sum_exit(c);
+#endif
jffs3_free_ino_caches(c);
jffs3_free_raw_node_refs(c);
kfree(c->blocks);
@@ -111,6 +118,9 @@
#ifdef CONFIG_JFFS3_FS_NAND
" (NAND)"
#endif
+#ifdef CONFIG_JFFS3_SUMMARY
+ " (SUMMARY)"
+#endif
" (C) 2001-2004 Red Hat, Inc.\n");
#ifdef JFFS3_OUT_OF_KERNEL
Index: super.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/super.c,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- super.c 21 Dec 2004 14:14:48 -0000 3.4
+++ super.c 21 Dec 2004 15:18:51 -0000 3.5
@@ -152,7 +152,10 @@
deactivate_super(sb);
return ERR_PTR(ret);
}
-
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ jffs3_sum_init(c);
+#endif
sb->s_flags |= MS_ACTIVE;
return sb;
@@ -274,6 +277,10 @@
down(&c->alloc_sem);
jffs3_flush_wbuf_pad(c);
up(&c->alloc_sem);
+#ifdef CONFIG_JFFS3_SUMMARY
+ jffs3_sum_clean_all_info(c);
+ jffs3_sum_exit(c);
+#endif
jffs3_free_ino_caches(c);
jffs3_free_raw_node_refs(c);
if (c->mtd->flags & MTD_NO_VIRTBLOCKS)
@@ -311,6 +318,9 @@
#ifdef CONFIG_JFFS3_FS_NAND
" (NAND)"
#endif
+#ifdef CONFIG_JFFS3_SUMMARY
+ " (SUMMARY) "
+#endif
" (C) 2001-2004 Red Hat, Inc.\n");
jffs3_inode_cachep = kmem_cache_create("jffs3_i",
Index: wbuf.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/wbuf.c,v
retrieving revision 3.4
retrieving revision 3.5
diff -u -r3.4 -r3.5
--- wbuf.c 17 Dec 2004 15:02:52 -0000 3.4
+++ wbuf.c 21 Dec 2004 15:18:51 -0000 3.5
@@ -260,7 +260,7 @@
/* ... and get an allocation of space from a shiny new block instead */
- ret = jffs3_reserve_space_gc(c, end-start, &ofs, &len);
+ ret = jffs3_reserve_space_gc(c, end-start, &ofs, &len, JFFS3_SUMMARY_NOSUM_SIZE);
if (ret) {
WARNING_MSG("Failed to allocate space for wbuf recovery. Data loss ensues.\n");
if (buf)
@@ -590,8 +590,15 @@
uint32_t outvec_to = to;
/* If not NAND flash, don't bother */
- if (!c->wbuf)
+ if (!c->wbuf){
+#ifdef CONFIG_JFFS3_SUMMARY
+ DBG_SUMMARY(1,"JFFS3.summary: NOT NAND MEMORY\n");
+ if(jffs3_sum_add_kvec(c,invecs,count,(uint32_t) to)){
+ ERROR_MSG("jffs3_sum_add_kvec(): MEMORY ALLOCATION ERROR!");
+ }
+#endif
return jffs3_flash_direct_writev(c, invecs, count, to, retlen);
+ }
down_write(&c->wbuf_sem);
@@ -789,6 +796,12 @@
remember that the wbuf affects this ino */
alldone:
*retlen = donelen;
+
+#ifdef CONFIG_JFFS3_SUMMARY
+ if(jffs3_sum_add_kvec(c,invecs,count,(uint32_t) to)){
+ ERROR_MSG("jffs3_sum_add_kvec(): MEMORY ALLOCATION ERROR!");
+ }
+#endif
if (c->wbuf_len && ino)
jffs3_wbuf_dirties_inode(c, ino);
Index: write.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs3/write.c,v
retrieving revision 3.3
retrieving revision 3.4
diff -u -r3.3 -r3.4
--- write.c 13 Dec 2004 17:15:46 -0000 3.3
+++ write.c 21 Dec 2004 15:18:51 -0000 3.4
@@ -145,13 +145,13 @@
jffs3_dbg_acct_paranoia_check(c, jeb);
if (alloc_mode == ALLOC_GC) {
- ret = jffs3_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy);
+ ret = jffs3_reserve_space_gc(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, JFFS3_SUMMARY_INODE_SIZE);
} else {
/* Locking pain */
up(&f->sem);
jffs3_complete_reservation(c);
- ret = jffs3_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode);
+ ret = jffs3_reserve_space(c, sizeof(*ri) + datalen, &flash_ofs, &dummy, alloc_mode, JFFS3_SUMMARY_INODE_SIZE);
down(&f->sem);
}
@@ -280,13 +280,13 @@
jffs3_dbg_acct_paranoia_check(c, jeb);
if (alloc_mode == ALLOC_GC) {
- ret = jffs3_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy);
+ ret = jffs3_reserve_space_gc(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
} else {
/* Locking pain */
up(&f->sem);
jffs3_complete_reservation(c);
- ret = jffs3_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode);
+ ret = jffs3_reserve_space(c, sizeof(*rd) + namelen, &flash_ofs, &dummy, alloc_mode, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
down(&f->sem);
}
@@ -343,7 +343,7 @@
retry:
D2(printk(KERN_DEBUG "jffs3_commit_write() loop: 0x%x to write to 0x%x\n", writelen, offset));
- ret = jffs3_reserve_space(c, sizeof(*ri) + JFFS3_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*ri) + JFFS3_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
if (ret) {
D1(printk(KERN_DEBUG "jffs3_reserve_space returned %d\n", ret));
break;
@@ -430,7 +430,7 @@
/* Try to reserve enough space for both node and dirent.
* Just the node will do for now, though
*/
- ret = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*ri), &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_INODE_SIZE);
D1(printk(KERN_DEBUG "jffs3_do_create(): reserved 0x%x bytes\n", alloclen));
if (ret) {
up(&f->sem);
@@ -459,7 +459,7 @@
up(&f->sem);
jffs3_complete_reservation(c);
- ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
/* Eep. */
@@ -529,7 +529,7 @@
if (!rd)
return -ENOMEM;
- ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION);
+ ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_DELETION, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
jffs3_free_raw_dirent(rd);
return ret;
@@ -635,7 +635,7 @@
if (!rd)
return -ENOMEM;
- ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL);
+ ret = jffs3_reserve_space(c, sizeof(*rd)+namelen, &phys_ofs, &alloclen, ALLOC_NORMAL, JFFS3_SUMMARY_DIRENT_SIZE(namelen));
if (ret) {
jffs3_free_raw_dirent(rd);
return ret;
More information about the linux-mtd-cvs
mailing list