fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / jffs / intrep.c
index 816f076..6dd1891 100644 (file)
  *
  */
 
-#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/jffs.h>
 #include <linux/fs.h>
 #include <linux/stat.h>
 #include <linux/pagemap.h>
-#include <asm/semaphore.h>
+#include <linux/mutex.h>
 #include <asm/byteorder.h>
 #include <linux/smp_lock.h>
 #include <linux/time.h>
 #include <linux/ctype.h>
+#include <linux/freezer.h>
 
 #include "intrep.h"
 #include "jffs_fm.h"
 
 long no_jffs_node = 0;
-long no_jffs_file = 0;
+static long no_jffs_file = 0;
 #if defined(JFFS_MEMORY_DEBUG) && JFFS_MEMORY_DEBUG
 long no_jffs_control = 0;
 long no_jffs_raw_inode = 0;
@@ -85,6 +85,32 @@ long no_name = 0;
 
 static int jffs_scan_flash(struct jffs_control *c);
 static int jffs_update_file(struct jffs_file *f, struct jffs_node *node);
+static int jffs_build_file(struct jffs_file *f);
+static int jffs_free_file(struct jffs_file *f);
+static int jffs_free_node_list(struct jffs_file *f);
+static int jffs_garbage_collect_now(struct jffs_control *c);
+static int jffs_insert_file_into_hash(struct jffs_file *f);
+static int jffs_remove_redundant_nodes(struct jffs_file *f);
+
+/* Is there enough space on the flash?  */
+static inline int JFFS_ENOUGH_SPACE(struct jffs_control *c, __u32 space)
+{
+       struct jffs_fmcontrol *fmc = c->fmc;
+
+       while (1) {
+               if ((fmc->flash_size - (fmc->used_size + fmc->dirty_size))
+                       >= fmc->min_free_size + space) {
+                       return 1;
+               }
+               if (fmc->dirty_size < fmc->sector_size)
+                       return 0;
+
+               if (jffs_garbage_collect_now(c)) {
+                 D1(printk("JFFS_ENOUGH_SPACE: jffs_garbage_collect_now() failed.\n"));
+                 return 0;
+               }
+       }
+}
 
 #if CONFIG_JFFS_FS_VERBOSE > 0
 static __u8
@@ -149,8 +175,64 @@ jffs_hexdump(struct mtd_info *mtd, loff_t pos, int size)
        }
 }
 
+/* Print the contents of a node.  */
+static void
+jffs_print_node(struct jffs_node *n)
+{
+       D(printk("jffs_node: 0x%p\n", n));
+       D(printk("{\n"));
+       D(printk("        0x%08x, /* version  */\n", n->version));
+       D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));
+       D(printk("        0x%08x, /* data_size  */\n", n->data_size));
+       D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));
+       D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));
+       D(printk("        0x%02x,       /* name_size  */\n", n->name_size));
+       D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",
+                n->fm, (n->fm ? n->fm->offset : 0)));
+       D(printk("        0x%p, /* version_prev  */\n", n->version_prev));
+       D(printk("        0x%p, /* version_next  */\n", n->version_next));
+       D(printk("        0x%p, /* range_prev  */\n", n->range_prev));
+       D(printk("        0x%p, /* range_next  */\n", n->range_next));
+       D(printk("}\n"));
+}
+
 #endif
 
+/* Print the contents of a raw inode.  */
+static void
+jffs_print_raw_inode(struct jffs_raw_inode *raw_inode)
+{
+       D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));
+       D(printk("{\n"));
+       D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));
+       D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));
+       D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));
+       D(printk("        0x%08x, /* version  */\n", raw_inode->version));
+       D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));
+       D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));
+       D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));
+       D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));
+       D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));
+       D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));
+       D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));
+       D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));
+       D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));
+       D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));
+       D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));
+       D(printk("        0x%02x,       /* spare  */\n",
+                raw_inode->spare));
+       D(printk("        %u,          /* rename  */\n",
+                raw_inode->rename));
+       D(printk("        %u,          /* deleted  */\n",
+                raw_inode->deleted));
+       D(printk("        0x%02x,       /* accurate  */\n",
+                raw_inode->accurate));
+       D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));
+       D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));
+       D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));
+       D(printk("}\n"));
+}
+
 #define flash_safe_acquire(arg)
 #define flash_safe_release(arg)
 
@@ -165,7 +247,7 @@ flash_safe_read(struct mtd_info *mtd, loff_t from,
        D3(printk(KERN_NOTICE "flash_safe_read(%p, %08x, %p, %08x)\n",
                  mtd, (unsigned int) from, buf, count));
 
-       res = MTD_READ(mtd, from, count, &retlen, buf);
+       res = mtd->read(mtd, from, count, &retlen, buf);
        if (retlen != count) {
                panic("Didn't read all bytes in flash_safe_read(). Returned %d\n", res);
        }
@@ -180,7 +262,7 @@ flash_read_u32(struct mtd_info *mtd, loff_t from)
        __u32 ret;
        int res;
 
-       res = MTD_READ(mtd, from, 4, &retlen, (unsigned char *)&ret);
+       res = mtd->read(mtd, from, 4, &retlen, (unsigned char *)&ret);
        if (retlen != 4) {
                printk("Didn't read all bytes in flash_read_u32(). Returned %d\n", res);
                return 0;
@@ -200,7 +282,7 @@ flash_safe_write(struct mtd_info *mtd, loff_t to,
        D3(printk(KERN_NOTICE "flash_safe_write(%p, %08x, %p, %08x)\n",
                  mtd, (unsigned int) to, buf, count));
 
-       res = MTD_WRITE(mtd, to, count, &retlen, buf);
+       res = mtd->write(mtd, to, count, &retlen, buf);
        if (retlen != count) {
                printk("Didn't write all bytes in flash_safe_write(). Returned %d\n", res);
        }
@@ -209,7 +291,7 @@ flash_safe_write(struct mtd_info *mtd, loff_t to,
 
 
 static int
-flash_safe_writev(struct mtd_info *mtd, const struct iovec *vecs,
+flash_safe_writev(struct mtd_info *mtd, const struct kvec *vecs,
                        unsigned long iovec_cnt, loff_t to)
 {
        size_t retlen, retlen_a;
@@ -218,9 +300,9 @@ flash_safe_writev(struct mtd_info *mtd, const struct iovec *vecs,
 
        D3(printk(KERN_NOTICE "flash_safe_writev(%p, %08x, %p)\n",
                  mtd, (unsigned int) to, vecs));
-       
+
        if (mtd->writev) {
-               res = MTD_WRITEV(mtd, vecs, iovec_cnt, to, &retlen);
+               res = mtd->writev(mtd, vecs, iovec_cnt, to, &retlen);
                return res ? res : retlen;
        }
        /* Not implemented writev. Repeatedly use write - on the not so
@@ -230,7 +312,8 @@ flash_safe_writev(struct mtd_info *mtd, const struct iovec *vecs,
        retlen=0;
 
        for (i=0; !res && i<iovec_cnt; i++) {
-               res = MTD_WRITE(mtd, to, vecs[i].iov_len, &retlen_a, vecs[i].iov_base);
+               res = mtd->write(mtd, to, vecs[i].iov_len, &retlen_a,
+                                vecs[i].iov_base);
                if (retlen_a != vecs[i].iov_len) {
                        printk("Didn't write all bytes in flash_safe_writev(). Returned %d\n", res);
                        if (i != iovec_cnt-1)
@@ -311,7 +394,7 @@ flash_erase_region(struct mtd_info *mtd, loff_t start,
        set_current_state(TASK_UNINTERRUPTIBLE);
        add_wait_queue(&wait_q, &wait);
 
-       if (MTD_ERASE(mtd, erase) < 0) {
+       if (mtd->erase(mtd, erase) < 0) {
                set_current_state(TASK_RUNNING);
                remove_wait_queue(&wait_q, &wait);
                kfree(erase);
@@ -331,7 +414,7 @@ flash_erase_region(struct mtd_info *mtd, loff_t start,
 }
 
 /* This routine calculates checksums in JFFS.  */
-__u32
+static __u32
 jffs_checksum(const void *data, int size)
 {
        __u32 sum = 0;
@@ -344,7 +427,7 @@ jffs_checksum(const void *data, int size)
 }
 
 
-int
+static int
 jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
 {
        __u32 sum = 0;
@@ -353,7 +436,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
        int i, length;
 
        /* Allocate read buffer */
-       read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+       read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
        if (!read_buf) {
                printk(KERN_NOTICE "kmalloc failed in jffs_checksum_flash()\n");
                return -ENOMEM;
@@ -380,7 +463,7 @@ jffs_checksum_flash(struct mtd_info *mtd, loff_t start, int size, __u32 *result)
        }
 
        /* Free read buffer */
-       kfree (read_buf);
+       kfree(read_buf);
 
        /* Return result */
        D3(printk("checksum result: 0x%08x\n", sum));
@@ -406,13 +489,11 @@ jffs_create_file(struct jffs_control *c,
 {
        struct jffs_file *f;
 
-       if (!(f = (struct jffs_file *)kmalloc(sizeof(struct jffs_file),
-                                             GFP_KERNEL))) {
+       if (!(f = kzalloc(sizeof(*f), GFP_KERNEL))) {
                D(printk("jffs_create_file(): Failed!\n"));
-               return 0;
+               return NULL;
        }
        no_jffs_file++;
-       memset(f, 0, sizeof(struct jffs_file));
        f->ino = raw_inode->ino;
        f->pino = raw_inode->pino;
        f->nlink = raw_inode->nlink;
@@ -434,15 +515,15 @@ jffs_create_control(struct super_block *sb)
 
        D2(printk("jffs_create_control()\n"));
 
-       if (!(c = (struct jffs_control *)kmalloc(s, GFP_KERNEL))) {
+       if (!(c = kmalloc(s, GFP_KERNEL))) {
                goto fail_control;
        }
        DJM(no_jffs_control++);
-       c->root = 0;
-       c->gc_task = 0;
+       c->root = NULL;
+       c->gc_task = NULL;
        c->hash_len = JFFS_HASH_SIZE;
        s = sizeof(struct list_head) * c->hash_len;
-       if (!(c->hash = (struct list_head *)kmalloc(s, GFP_KERNEL))) {
+       if (!(c->hash = kmalloc(s, GFP_KERNEL))) {
                goto fail_hash;
        }
        DJM(no_hash++);
@@ -511,8 +592,7 @@ jffs_add_virtual_root(struct jffs_control *c)
        D2(printk("jffs_add_virtual_root(): "
                  "Creating a virtual root directory.\n"));
 
-       if (!(root = (struct jffs_file *)kmalloc(sizeof(struct jffs_file),
-                                                GFP_KERNEL))) {
+       if (!(root = kzalloc(sizeof(struct jffs_file), GFP_KERNEL))) {
                return -ENOMEM;
        }
        no_jffs_file++;
@@ -524,7 +604,6 @@ jffs_add_virtual_root(struct jffs_control *c)
        DJM(no_jffs_node++);
        memset(node, 0, sizeof(struct jffs_node));
        node->ino = JFFS_MIN_INO;
-       memset(root, 0, sizeof(struct jffs_file));
        root->ino = JFFS_MIN_INO;
        root->mode = S_IFDIR | S_IRWXU | S_IRGRP
                     | S_IXGRP | S_IROTH | S_IXOTH;
@@ -646,7 +725,7 @@ jffs_build_fs_fail:
   a (even) higher degree of confidence in your mount process. 
   A higher number would of course slow down your mount.
 */
-int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){
+static int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){
 
 #define NUM_REREADS             4 /* see note above */
 #define READ_AHEAD_BYTES        4096 /* must be a multiple of 4, 
@@ -665,11 +744,11 @@ int check_partly_erased_sectors(struct jffs_fmcontrol *fmc){
 
 
        /* Allocate read buffers */
-       read_buf1 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+       read_buf1 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
        if (!read_buf1)
                return -ENOMEM;
 
-       read_buf2 = (__u8 *) kmalloc (sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
+       read_buf2 = kmalloc(sizeof(__u8) * READ_AHEAD_BYTES, GFP_KERNEL);
        if (!read_buf2) {
                kfree(read_buf1);
                return -ENOMEM;
@@ -752,7 +831,7 @@ jffs_scan_flash(struct jffs_control *c)
 {
        char name[JFFS_MAX_NAME_LEN + 2];
        struct jffs_raw_inode raw_inode;
-       struct jffs_node *node = 0;
+       struct jffs_node *node = NULL;
        struct jffs_fmcontrol *fmc = c->fmc;
        __u32 checksum;
        __u8 tmp_accurate;
@@ -797,7 +876,7 @@ jffs_scan_flash(struct jffs_control *c)
        }
 
        /* Allocate read buffer */
-       read_buf = (__u8 *) kmalloc (sizeof(__u8) * 4096, GFP_KERNEL);
+       read_buf = kmalloc(sizeof(__u8) * 4096, GFP_KERNEL);
        if (!read_buf) {
                flash_safe_release(fmc->mtd);
                return -ENOMEM;
@@ -904,7 +983,7 @@ jffs_scan_flash(struct jffs_control *c)
                                        D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
                                                  (unsigned int) start, (unsigned int) (pos - start)));
                                        jffs_fmalloced(fmc, (__u32) start,
-                                                      (__u32) (pos - start), 0);
+                                                      (__u32) (pos - start), NULL);
                                }else{
                                        /* "Flipping bits" detected. This means that our scan for them
                                           did not catch this offset. See check_partly_erased_sectors() for
@@ -929,12 +1008,12 @@ jffs_scan_flash(struct jffs_control *c)
                                                       offset , fmc->sector_size);
 
                                                flash_safe_release(fmc->mtd);
-                                               kfree (read_buf);
+                                               kfree(read_buf);
                                                return -1; /* bad, bad, bad! */
 
                                        }
                                        flash_safe_release(fmc->mtd);
-                                       kfree (read_buf);
+                                       kfree(read_buf);
 
                                        return -EAGAIN; /* erased offending sector. Try mount one more time please. */
                                }
@@ -964,7 +1043,7 @@ jffs_scan_flash(struct jffs_control *c)
                                         D1(printk("Dirty space: Starting 0x%x for 0x%x bytes\n",
                                                   (unsigned int) start, (unsigned int) (pos - start)));
                                         jffs_fmalloced(fmc, (__u32) start,
-                                                       (__u32) (pos - start), 0);                                         
+                                                       (__u32) (pos - start), NULL);                                      
                                 }
                                 
                        }
@@ -986,7 +1065,7 @@ jffs_scan_flash(struct jffs_control *c)
                        D1(printk("jffs_scan_flash(): 0x00 ended at "
                                  "pos 0x%lx.\n", (long)pos));
                        jffs_fmalloced(fmc, (__u32) start,
-                                      (__u32) (pos - start), 0);
+                                      (__u32) (pos - start), NULL);
                        continue;
 
                case JFFS_MAGIC_BITMASK:
@@ -1020,7 +1099,7 @@ jffs_scan_flash(struct jffs_control *c)
                           which really does contain crap. */
                        jffs_fmalloced(fmc, (__u32) start,
                                       (__u32) (pos - start),
-                                      0);
+                                      NULL);
                        
                        continue;
                }/* switch */
@@ -1030,7 +1109,7 @@ jffs_scan_flash(struct jffs_control *c)
                if (!node) {
                        if (!(node = jffs_alloc_node())) {
                                /* Free read buffer */
-                               kfree (read_buf);
+                               kfree(read_buf);
 
                                /* Release the flash device */
                                flash_safe_release(fmc->mtd);
@@ -1067,7 +1146,7 @@ jffs_scan_flash(struct jffs_control *c)
                                  checksum, raw_inode.chksum));
                        pos += sizeof(struct jffs_raw_inode);
                        jffs_fmalloced(fmc, (__u32) start,
-                                      (__u32) (pos - start), 0);
+                                      (__u32) (pos - start), NULL);
                        /* Reuse this unused struct jffs_node.  */
                        continue;
                }
@@ -1121,7 +1200,7 @@ jffs_scan_flash(struct jffs_control *c)
                                          "raw_inode.nchksum = %u\n",
                                          checksum, raw_inode.nchksum));
                                jffs_fmalloced(fmc, (__u32) start,
-                                              (__u32) (pos - start), 0);
+                                              (__u32) (pos - start), NULL);
                                /* Reuse this unused struct jffs_node.  */
                                continue;
                        }
@@ -1139,7 +1218,7 @@ jffs_scan_flash(struct jffs_control *c)
                        if (jffs_checksum_flash(fmc->mtd, pos, raw_inode.dsize, &checksum)) {
                                printk("jffs_checksum_flash() failed to calculate a checksum\n");
                                jffs_fmalloced(fmc, (__u32) start,
-                                              (__u32) (pos - start), 0);
+                                              (__u32) (pos - start), NULL);
                                /* Reuse this unused struct jffs_node.  */
                                continue;
                        }                               
@@ -1152,7 +1231,7 @@ jffs_scan_flash(struct jffs_control *c)
                                          "raw_inode.dchksum = %u\n",
                                          checksum, raw_inode.dchksum));
                                jffs_fmalloced(fmc, (__u32) start,
-                                              (__u32) (pos - start), 0);
+                                              (__u32) (pos - start), NULL);
                                /* Reuse this unused struct jffs_node.  */
                                continue;
                        }
@@ -1187,14 +1266,14 @@ jffs_scan_flash(struct jffs_control *c)
                                DJM(no_jffs_node--);
 
                                /* Free read buffer */
-                               kfree (read_buf);
+                               kfree(read_buf);
 
                                /* Release the flash device */
                                flash_safe_release(fmc->mtd);
 
                                return -ENOMEM;
                        }
-                       if ((err = jffs_insert_node(c, 0, &raw_inode,
+                       if ((err = jffs_insert_node(c, NULL, &raw_inode,
                                                    name, node)) < 0) {
                                printk("JFFS: Failed to handle raw inode. "
                                       "(err = %d)\n", err);
@@ -1214,7 +1293,7 @@ jffs_scan_flash(struct jffs_control *c)
                                        flash_safe_release(fmc->flash_part);
 
                                        /* Free read buffer */
-                                       kfree (read_buf);
+                                       kfree(read_buf);
 
                                        return -ENOMEM;
                                }
@@ -1224,11 +1303,11 @@ jffs_scan_flash(struct jffs_control *c)
                                node->data_size = 0;
                        }
                        D3(jffs_print_node(node));
-                       node = 0; /* Don't free the node!  */
+                       node = NULL; /* Don't free the node!  */
                }
                else {
                        jffs_fmalloced(fmc, (__u32) start,
-                                      (__u32) (pos - start), 0);
+                                      (__u32) (pos - start), NULL);
                        D3(printk("jffs_scan_flash(): Just found an obsolete "
                                  "raw_inode. Continuing the scan...\n"));
                        /* Reuse this unused struct jffs_node.  */
@@ -1242,7 +1321,7 @@ jffs_scan_flash(struct jffs_control *c)
        jffs_build_end(fmc);
 
        /* Free read buffer */
-       kfree (read_buf);
+       kfree(read_buf);
 
        if(!num_free_space){
                printk(KERN_WARNING "jffs_scan_flash(): Did not find even a single "
@@ -1312,8 +1391,8 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
                /* This is the first node.  */
                f->version_head = node;
                f->version_tail = node;
-               node->version_prev = 0;
-               node->version_next = 0;
+               node->version_prev = NULL;
+               node->version_next = NULL;
                f->highest_version = node->version;
                update_name = 1;
                f->mode = raw_inode->mode;
@@ -1328,7 +1407,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
                /* Insert at the end of the list.  I.e. this node is the
                   newest one so far.  */
                node->version_prev = f->version_tail;
-               node->version_next = 0;
+               node->version_next = NULL;
                f->version_tail->version_next = node;
                f->version_tail = node;
                f->highest_version = node->version;
@@ -1343,7 +1422,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
        }
        else if (f->version_head->version > node->version) {
                /* Insert at the bottom of the list.  */
-               node->version_prev = 0;
+               node->version_prev = NULL;
                node->version_next = f->version_head;
                f->version_head->version_prev = node;
                f->version_head = node;
@@ -1384,7 +1463,7 @@ jffs_insert_node(struct jffs_control *c, struct jffs_file *f,
                        kfree(f->name);
                        DJM(no_name--);
                }
-               if (!(f->name = (char *) kmalloc(raw_inode->nsize + 1,
+               if (!(f->name = kmalloc(raw_inode->nsize + 1,
                                                 GFP_KERNEL))) {
                        return -ENOMEM;
                }
@@ -1478,7 +1557,7 @@ jffs_classify_node(struct jffs_node *node)
 
 /* Remove redundant nodes from a file.  Mark the on-flash memory
    as dirty.  */
-int
+static int
 jffs_remove_redundant_nodes(struct jffs_file *f)
 {
        struct jffs_node *newest_node;
@@ -1532,7 +1611,7 @@ jffs_remove_redundant_nodes(struct jffs_file *f)
 
 
 /* Insert a file into the hash table.  */
-int
+static int
 jffs_insert_file_into_hash(struct jffs_file *f)
 {
        int i = f->ino % f->c->hash_len;
@@ -1556,9 +1635,9 @@ jffs_insert_file_into_tree(struct jffs_file *f)
        if (!(parent = jffs_find_file(f->c, f->pino))) {
                if (f->pino == 0) {
                        f->c->root = f;
-                       f->parent = 0;
-                       f->sibling_prev = 0;
-                       f->sibling_next = 0;
+                       f->parent = NULL;
+                       f->sibling_prev = NULL;
+                       f->sibling_next = NULL;
                        return 0;
                }
                else {
@@ -1573,14 +1652,14 @@ jffs_insert_file_into_tree(struct jffs_file *f)
        if (f->sibling_next) {
                f->sibling_next->sibling_prev = f;
        }
-       f->sibling_prev = 0;
+       f->sibling_prev = NULL;
        parent->children = f;
        return 0;
 }
 
 
 /* Remove a file from the hash table.  */
-int
+static int
 jffs_unlink_file_from_hash(struct jffs_file *f)
 {
        D3(printk("jffs_unlink_file_from_hash(): f: 0x%p, "
@@ -1619,12 +1698,10 @@ jffs_find_file(struct jffs_control *c, __u32 ino)
 {
        struct jffs_file *f;
        int i = ino % c->hash_len;
-       struct list_head *tmp;
 
        D3(printk("jffs_find_file(): ino: %u\n", ino));
 
-       for (tmp = c->hash[i].next; tmp != &c->hash[i]; tmp = tmp->next) {
-               f = list_entry(tmp, struct jffs_file, hash);
+       list_for_each_entry(f, &c->hash[i], hash) {
                if (ino != f->ino)
                        continue;
                D3(printk("jffs_find_file(): Found file with ino "
@@ -1660,16 +1737,14 @@ jffs_find_child(struct jffs_file *dir, const char *name, int len)
                printk("jffs_find_child(): Found \"%s\".\n", f->name);
        }
        else {
-               char *copy = (char *) kmalloc(len + 1, GFP_KERNEL);
+               char *copy = kmalloc(len + 1, GFP_KERNEL);
                if (copy) {
                        memcpy(copy, name, len);
                        copy[len] = '\0';
                }
                printk("jffs_find_child(): Didn't find the file \"%s\".\n",
                       (copy ? copy : ""));
-               if (copy) {
-                       kfree(copy);
-               }
+               kfree(copy);
        });
 
        return f;
@@ -1740,7 +1815,7 @@ jffs_write_node(struct jffs_control *c, struct jffs_node *node,
 {
        struct jffs_fmcontrol *fmc = c->fmc;
        struct jffs_fm *fm;
-       struct iovec node_iovec[4];
+       struct kvec node_iovec[4];
        unsigned long iovec_cnt;
 
        __u32 pos;
@@ -1887,7 +1962,7 @@ retry:
                iovec_cnt++;
 
                if (JFFS_GET_PAD_BYTES(raw_inode->nsize)) {
-                       static char allff[3]={255,255,255};
+                       static unsigned char allff[3]={255,255,255};
                        /* Add some extra padding if necessary */
                        node_iovec[iovec_cnt].iov_base = allff;
                        node_iovec[iovec_cnt].iov_len =
@@ -2020,13 +2095,12 @@ jffs_foreach_file(struct jffs_control *c, int (*func)(struct jffs_file *))
        int result = 0;
 
        for (pos = 0; pos < c->hash_len; pos++) {
-               struct list_head *p, *next;
-               for (p = c->hash[pos].next; p != &c->hash[pos]; p = next) {
-                       /* We need a reference to the next file in the
-                          list because `func' might remove the current
-                          file `f'.  */
-                       next = p->next;
-                       r = func(list_entry(p, struct jffs_file, hash));
+               struct jffs_file *f, *next;
+
+               /* We must do _safe, because 'func' might remove the
+                  current file 'f' from the list.  */
+               list_for_each_entry_safe(f, next, &c->hash[pos], hash) {
+                       r = func(f);
                        if (r < 0)
                                return r;
                        result += r;
@@ -2038,7 +2112,7 @@ jffs_foreach_file(struct jffs_control *c, int (*func)(struct jffs_file *))
 
 
 /* Free all nodes associated with a file.  */
-int
+static int
 jffs_free_node_list(struct jffs_file *f)
 {
        struct jffs_node *node;
@@ -2058,7 +2132,7 @@ jffs_free_node_list(struct jffs_file *f)
 
 
 /* Free a file and its name.  */
-int
+static int
 jffs_free_file(struct jffs_file *f)
 {
        D3(printk("jffs_free_file: f #%u, \"%s\"\n",
@@ -2073,7 +2147,7 @@ jffs_free_file(struct jffs_file *f)
        return 0;
 }
 
-long
+static long
 jffs_get_file_count(void)
 {
        return no_jffs_file;
@@ -2127,7 +2201,7 @@ jffs_file_count(struct jffs_file *f)
 
 /* Build up a file's range list from scratch by going through the
    version list.  */
-int
+static int
 jffs_build_file(struct jffs_file *f)
 {
        struct jffs_node *n;
@@ -2311,7 +2385,7 @@ jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
        retry:
        if (node->data_offset == f->size) {
                /* A simple append.  This is the most common operation.  */
-               node->range_next = 0;
+               node->range_next = NULL;
                node->range_prev = f->range_tail;
                if (node->range_prev) {
                        node->range_prev->range_next = node;
@@ -2389,10 +2463,10 @@ jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
                virtual_node->removed_size = 0;
                virtual_node->fm_offset = 0;
                virtual_node->name_size = 0;
-               virtual_node->fm = 0; /* This is a virtual data holder.  */
-               virtual_node->version_prev = 0;
-               virtual_node->version_next = 0;
-               virtual_node->range_next = 0;
+               virtual_node->fm = NULL; /* This is a virtual data holder.  */
+               virtual_node->version_prev = NULL;
+               virtual_node->version_next = NULL;
+               virtual_node->range_next = NULL;
 
                /* Are there any data at all in the file yet?  */
                if (f->range_head) {
@@ -2407,7 +2481,7 @@ jffs_insert_data(struct jffs_file *f, struct jffs_node *node)
                else {
                        virtual_node->data_offset = 0;
                        virtual_node->data_size = node->data_offset;
-                       virtual_node->range_prev = 0;
+                       virtual_node->range_prev = NULL;
                        f->range_head = virtual_node;
                }
 
@@ -2481,66 +2555,8 @@ jffs_update_file(struct jffs_file *f, struct jffs_node *node)
        return 0;
 }
 
-
-/* Print the contents of a node.  */
-void
-jffs_print_node(struct jffs_node *n)
-{
-       D(printk("jffs_node: 0x%p\n", n));
-       D(printk("{\n"));
-       D(printk("        0x%08x, /* version  */\n", n->version));
-       D(printk("        0x%08x, /* data_offset  */\n", n->data_offset));
-       D(printk("        0x%08x, /* data_size  */\n", n->data_size));
-       D(printk("        0x%08x, /* removed_size  */\n", n->removed_size));
-       D(printk("        0x%08x, /* fm_offset  */\n", n->fm_offset));
-       D(printk("        0x%02x,       /* name_size  */\n", n->name_size));
-       D(printk("        0x%p, /* fm,  fm->offset: %u  */\n",
-                n->fm, (n->fm ? n->fm->offset : 0)));
-       D(printk("        0x%p, /* version_prev  */\n", n->version_prev));
-       D(printk("        0x%p, /* version_next  */\n", n->version_next));
-       D(printk("        0x%p, /* range_prev  */\n", n->range_prev));
-       D(printk("        0x%p, /* range_next  */\n", n->range_next));
-       D(printk("}\n"));
-}
-
-
-/* Print the contents of a raw inode.  */
-void
-jffs_print_raw_inode(struct jffs_raw_inode *raw_inode)
-{
-       D(printk("jffs_raw_inode: inode number: %u\n", raw_inode->ino));
-       D(printk("{\n"));
-       D(printk("        0x%08x, /* magic  */\n", raw_inode->magic));
-       D(printk("        0x%08x, /* ino  */\n", raw_inode->ino));
-       D(printk("        0x%08x, /* pino  */\n", raw_inode->pino));
-       D(printk("        0x%08x, /* version  */\n", raw_inode->version));
-       D(printk("        0x%08x, /* mode  */\n", raw_inode->mode));
-       D(printk("        0x%04x,     /* uid  */\n", raw_inode->uid));
-       D(printk("        0x%04x,     /* gid  */\n", raw_inode->gid));
-       D(printk("        0x%08x, /* atime  */\n", raw_inode->atime));
-       D(printk("        0x%08x, /* mtime  */\n", raw_inode->mtime));
-       D(printk("        0x%08x, /* ctime  */\n", raw_inode->ctime));
-       D(printk("        0x%08x, /* offset  */\n", raw_inode->offset));
-       D(printk("        0x%08x, /* dsize  */\n", raw_inode->dsize));
-       D(printk("        0x%08x, /* rsize  */\n", raw_inode->rsize));
-       D(printk("        0x%02x,       /* nsize  */\n", raw_inode->nsize));
-       D(printk("        0x%02x,       /* nlink  */\n", raw_inode->nlink));
-       D(printk("        0x%02x,       /* spare  */\n",
-                raw_inode->spare));
-       D(printk("        %u,          /* rename  */\n",
-                raw_inode->rename));
-       D(printk("        %u,          /* deleted  */\n",
-                raw_inode->deleted));
-       D(printk("        0x%02x,       /* accurate  */\n",
-                raw_inode->accurate));
-       D(printk("        0x%08x, /* dchksum  */\n", raw_inode->dchksum));
-       D(printk("        0x%04x,     /* nchksum  */\n", raw_inode->nchksum));
-       D(printk("        0x%04x,     /* chksum  */\n", raw_inode->chksum));
-       D(printk("}\n"));
-}
-
-
 /* Print the contents of a file.  */
+#if 0
 int
 jffs_print_file(struct jffs_file *f)
 {
@@ -2580,7 +2596,7 @@ jffs_print_file(struct jffs_file *f)
        D(printk("}\n"));
        return 0;
 }
-
+#endif  /*  0  */
 
 void
 jffs_print_hash_table(struct jffs_control *c)
@@ -2589,9 +2605,8 @@ jffs_print_hash_table(struct jffs_control *c)
 
        printk("JFFS: Dumping the file system's hash table...\n");
        for (i = 0; i < c->hash_len; i++) {
-               struct list_head *p;
-               for (p = c->hash[i].next; p != &c->hash[i]; p = p->next) {
-                       struct jffs_file *f=list_entry(p,struct jffs_file,hash);
+               struct jffs_file *f;
+               list_for_each_entry(f, &c->hash[i], hash) {
                        printk("*** c->hash[%u]: \"%s\" "
                               "(ino: %u, pino: %u)\n",
                               i, (f->name ? f->name : ""),
@@ -2612,7 +2627,7 @@ jffs_print_tree(struct jffs_file *first_file, int indent)
                return;
        }
 
-       if (!(space = (char *) kmalloc(indent + 1, GFP_KERNEL))) {
+       if (!(space = kmalloc(indent + 1, GFP_KERNEL))) {
                printk("jffs_print_tree(): Out of memory!\n");
                return;
        }
@@ -2655,7 +2670,7 @@ jffs_print_memory_allocation_statistics(void)
 
 
 /* Rewrite `size' bytes, and begin at `node'.  */
-int
+static int
 jffs_rewrite_data(struct jffs_file *f, struct jffs_node *node, __u32 size)
 {
        struct jffs_control *c = f->c;
@@ -2858,7 +2873,7 @@ retry:
    process and is often called multiple times at each occasion of a
    garbage collect.  */
 
-int
+static int
 jffs_garbage_collect_next(struct jffs_control *c)
 {
        struct jffs_fmcontrol *fmc = c->fmc;
@@ -3097,7 +3112,7 @@ jffs_clear_end_of_node(struct jffs_control *c, __u32 erase_size)
 } /* jffs_clear_end_of_node()  */
 
 /* Try to erase as much as possible of the dirt in the flash memory.  */
-long
+static long
 jffs_try_to_erase(struct jffs_control *c)
 {
        struct jffs_fmcontrol *fmc = c->fmc;
@@ -3198,7 +3213,7 @@ jffs_try_to_erase(struct jffs_control *c)
    collection can be.  */
 
 
-int
+static int
 jffs_garbage_collect_now(struct jffs_control *c)
 {
        struct jffs_fmcontrol *fmc = c->fmc;
@@ -3373,6 +3388,9 @@ jffs_garbage_collect_thread(void *ptr)
                        siginfo_t info;
                        unsigned long signr = 0;
 
+                       if (try_to_freeze())
+                               continue;
+
                        spin_lock_irq(&current->sighand->siglock);
                        signr = dequeue_signal(current, &current->blocked, &info);
                        spin_unlock_irq(&current->sighand->siglock);
@@ -3395,7 +3413,7 @@ jffs_garbage_collect_thread(void *ptr)
                D1(printk (KERN_NOTICE "jffs_garbage_collect_thread(): collecting.\n"));
 
                D3(printk (KERN_NOTICE "g_c_thread(): down biglock\n"));
-               down(&fmc->biglock);
+               mutex_lock(&fmc->biglock);
                
                D1(printk("***jffs_garbage_collect_thread(): round #%u, "
                          "fmc->dirty_size = %u\n", i++, fmc->dirty_size));
@@ -3426,6 +3444,6 @@ jffs_garbage_collect_thread(void *ptr)
                
        gc_end:
                D3(printk (KERN_NOTICE "g_c_thread(): up biglock\n"));
-               up(&fmc->biglock);
+               mutex_unlock(&fmc->biglock);
        } /* for (;;) */
 } /* jffs_garbage_collect_thread() */