patch-2.4.11-dontuse linux/fs/jffs2/scan.c
Next file: linux/fs/jffs2/super.c
Previous file: linux/fs/jffs2/pushpull.h
Back to the patch index
Back to the overall index
- Lines: 129
- Date:
Thu Oct 4 15:13:18 2001
- Orig file:
v2.4.10/linux/fs/jffs2/scan.c
- Orig date:
Sun Sep 23 11:41:00 2001
diff -u --recursive --new-file v2.4.10/linux/fs/jffs2/scan.c linux/fs/jffs2/scan.c
@@ -31,7 +31,7 @@
* provisions above, a recipient may use your version of this file
* under either the RHEPL or the GPL.
*
- * $Id: scan.c,v 1.44 2001/04/13 00:46:41 nico Exp $
+ * $Id: scan.c,v 1.51 2001/09/19 00:06:35 dwmw2 Exp $
*
*/
#include <linux/kernel.h>
@@ -76,6 +76,8 @@
int jffs2_scan_medium(struct jffs2_sb_info *c)
{
int i, ret;
+ __u32 empty_blocks = 0;
+
if (!c->blocks) {
printk(KERN_WARNING "EEEK! c->blocks is NULL!\n");
return -EINVAL;
@@ -84,13 +86,24 @@
struct jffs2_eraseblock *jeb = &c->blocks[i];
ret = jffs2_scan_eraseblock(c, jeb);
- if (ret)
+ if (ret < 0)
return ret;
ACCT_PARANOIA_CHECK(jeb);
- /* Now decide which list to put it on */
- if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
+ /* Now decide which list to put it on */
+ if (ret == 1) {
+ /*
+ * Empty block. Since we can't be sure it
+ * was entirely erased, we just queue it for erase
+ * again. It will be marked as such when the erase
+ * is complete. Meanwhile we still count it as empty
+ * for later checks.
+ */
+ list_add(&jeb->list, &c->erase_pending_list);
+ empty_blocks++;
+ c->nr_erasing_blocks++;
+ } else if (jeb->used_size == PAD(sizeof(struct jffs2_unknown_node)) && !jeb->first_node->next_in_ino) {
/* Only a CLEANMARKER node is valid */
if (!jeb->dirty_size) {
/* It's actually free */
@@ -127,11 +140,15 @@
printk(KERN_NOTICE "JFFS2: Erase block at 0x%08x is not formatted. It will be erased\n", jeb->offset);
list_add(&jeb->list, &c->erase_pending_list);
c->nr_erasing_blocks++;
- }
- }
- if (c->nr_erasing_blocks)
+ }
+ }
+ if (c->nr_erasing_blocks) {
+ if (!c->used_size && empty_blocks != c->nr_blocks) {
+ printk(KERN_NOTICE "Cowardly refusing to erase blocks on filesystem with no valid JFFS2 nodes\n");
+ return -EIO;
+ }
jffs2_erase_pending_trigger(c);
-
+ }
return 0;
}
@@ -140,13 +157,22 @@
__u32 ofs, prevofs;
__u32 hdr_crc, nodetype;
int err;
- int noise = 10;
+ int noise = 0;
ofs = jeb->offset;
prevofs = jeb->offset - 1;
D1(printk(KERN_DEBUG "jffs2_scan_eraseblock(): Scanning block at 0x%x\n", ofs));
+ err = jffs2_scan_empty(c, jeb, &ofs, &noise);
+ if (err) return err;
+ if (ofs == jeb->offset + c->sector_size) {
+ D1(printk(KERN_DEBUG "Block at 0x%08x is empty (erased)\n", jeb->offset));
+ return 1; /* special return code */
+ }
+
+ noise = 10;
+
while(ofs < jeb->offset + c->sector_size) {
ssize_t retlen;
ACCT_PARANOIA_CHECK(jeb);
@@ -272,6 +298,8 @@
case JFFS2_FEATURE_ROCOMPAT:
printk(KERN_NOTICE "Read-only compatible feature node (0x%04x) found at offset 0x%08x\n", node.nodetype, ofs);
c->flags |= JFFS2_SB_FLAG_RO;
+ if (!(OFNI_BS_2SFFJ(c)->s_flags & MS_RDONLY))
+ return -EROFS;
DIRTY_SPACE(PAD(node.totlen));
ofs += PAD(node.totlen);
continue;
@@ -306,7 +334,7 @@
__u32 scanlen = (jeb->offset + c->sector_size) - *startofs;
__u32 curofs = *startofs;
- buf = kmalloc(min(PAGE_SIZE, scanlen), GFP_KERNEL);
+ buf = kmalloc(min((__u32)PAGE_SIZE, scanlen), GFP_KERNEL);
if (!buf) {
printk(KERN_WARNING "Scan buffer allocation failed\n");
return -ENOMEM;
@@ -315,9 +343,9 @@
ssize_t retlen;
int ret, i;
- ret = c->mtd->read(c->mtd, curofs, min(PAGE_SIZE, scanlen), &retlen, (char *)buf);
+ ret = c->mtd->read(c->mtd, curofs, min((__u32)PAGE_SIZE, scanlen), &retlen, (char *)buf);
if(ret) {
- D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%lx bytes at 0x%08x returned %d\n", min(PAGE_SIZE, scanlen), curofs, ret));
+ D1(printk(KERN_WARNING "jffs2_scan_empty(): Read 0x%x bytes at 0x%08x returned %d\n", min((__u32)PAGE_SIZE, scanlen), curofs, ret));
kfree(buf);
return ret;
}
@@ -606,6 +634,8 @@
if (crc != rd.name_crc) {
printk(KERN_NOTICE "jffs2_scan_dirent_node(): Name CRC failed on node at 0x%08x: Read 0x%08x, calculated 0x%08x\n",
*ofs, rd.name_crc, crc);
+ fd->name[rd.nsize]=0;
+ D1(printk(KERN_NOTICE "Name for which CRC failed is (now) '%s', ino #%d\n", fd->name, rd.ino));
jffs2_free_full_dirent(fd);
/* FIXME: Why do we believe totlen? */
DIRTY_SPACE(PAD(rd.totlen));
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)