lockd: Add helper to sanity check incoming NOTIFY requests
[safe/jmp/linux-2.6] / fs / jffs2 / readinode.c
index 6c1ba35..6ca08ad 100644 (file)
@@ -37,23 +37,24 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
 
        BUG_ON(tn->csize == 0);
 
-       if (!jffs2_is_writebuffered(c))
-               goto adj_acc;
-
        /* Calculate how many bytes were already checked */
        ofs = ref_offset(ref) + sizeof(struct jffs2_raw_inode);
-       len = ofs % c->wbuf_pagesize;
-       if (likely(len))
-               len = c->wbuf_pagesize - len;
-
-       if (len >= tn->csize) {
-               dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
-                       ref_offset(ref), tn->csize, ofs);
-               goto adj_acc;
-       }
+       len = tn->csize;
 
-       ofs += len;
-       len = tn->csize - len;
+       if (jffs2_is_writebuffered(c)) {
+               int adj = ofs % c->wbuf_pagesize;
+               if (likely(adj))
+                       adj = c->wbuf_pagesize - adj;
+
+               if (adj >= tn->csize) {
+                       dbg_readinode("no need to check node at %#08x, data length %u, data starts at %#08x - it has already been checked.\n",
+                                     ref_offset(ref), tn->csize, ofs);
+                       goto adj_acc;
+               }
+
+               ofs += adj;
+               len -= adj;
+       }
 
        dbg_readinode("check node at %#08x, data length %u, partial CRC %#08x, correct CRC %#08x, data starts at %#08x, start checking from %#08x - %u bytes.\n",
                ref_offset(ref), tn->csize, tn->partial_crc, tn->data_crc, ofs - len, ofs, len);
@@ -62,10 +63,11 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
        /* TODO: instead, incapsulate point() stuff to jffs2_flash_read(),
         * adding and jffs2_flash_read_end() interface. */
        if (c->mtd->point) {
-               err = c->mtd->point(c->mtd, ofs, len, &retlen, &buffer);
-               if (!err && retlen < tn->csize) {
+               err = c->mtd->point(c->mtd, ofs, len, &retlen,
+                                   (void **)&buffer, NULL);
+               if (!err && retlen < len) {
                        JFFS2_WARNING("MTD point returned len too short: %zu instead of %u.\n", retlen, tn->csize);
-                       c->mtd->unpoint(c->mtd, buffer, ofs, retlen);
+                       c->mtd->unpoint(c->mtd, ofs, retlen);
                } else if (err)
                        JFFS2_WARNING("MTD point failed: error code %d.\n", err);
                else
@@ -99,7 +101,7 @@ static int check_node_data(struct jffs2_sb_info *c, struct jffs2_tmp_dnode_info
                kfree(buffer);
 #ifndef __ECOS
        else
-               c->mtd->unpoint(c->mtd, buffer, ofs, len);
+               c->mtd->unpoint(c->mtd, ofs, len);
 #endif
 
        if (crc != tn->data_crc) {
@@ -135,7 +137,7 @@ free_out:
                kfree(buffer);
 #ifndef __ECOS
        else
-               c->mtd->unpoint(c->mtd, buffer, ofs, len);
+               c->mtd->unpoint(c->mtd, ofs, len);
 #endif
        return err;
 }
@@ -824,8 +826,9 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
        else // normal case...
                tn->fn->size = je32_to_cpu(rd->dsize);
 
-       dbg_readinode("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n",
-                 ref_offset(ref), je32_to_cpu(rd->version), je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize);
+       dbg_readinode2("dnode @%08x: ver %u, offset %#04x, dsize %#04x, csize %#04x\n",
+                      ref_offset(ref), je32_to_cpu(rd->version),
+                      je32_to_cpu(rd->offset), je32_to_cpu(rd->dsize), csize);
 
        ret = jffs2_add_tn_to_tree(c, rii, tn);
 
@@ -835,13 +838,13 @@ static inline int read_dnode(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
                jffs2_free_tmp_dnode_info(tn);
                return ret;
        }
-#ifdef JFFS2_DBG_READINODE_MESSAGES
-       dbg_readinode("After adding ver %d:\n", je32_to_cpu(rd->version));
+#ifdef JFFS2_DBG_READINODE2_MESSAGES
+       dbg_readinode2("After adding ver %d:\n", je32_to_cpu(rd->version));
        tn = tn_first(&rii->tn_root);
        while (tn) {
-               dbg_readinode("%p: v %d r 0x%x-0x%x ov %d\n",
-                            tn, tn->version, tn->fn->ofs,
-                            tn->fn->ofs+tn->fn->size, tn->overlapped);
+               dbg_readinode2("%p: v %d r 0x%x-0x%x ov %d\n",
+                              tn, tn->version, tn->fn->ofs,
+                              tn->fn->ofs+tn->fn->size, tn->overlapped);
                tn = tn_next(tn);
        }
 #endif
@@ -1121,7 +1124,8 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
        size_t retlen;
        int ret;
 
-       dbg_readinode("ino #%u nlink is %d\n", f->inocache->ino, f->inocache->nlink);
+       dbg_readinode("ino #%u pino/nlink is %d\n", f->inocache->ino,
+                     f->inocache->pino_nlink);
 
        memset(&rii, 0, sizeof(rii));
 
@@ -1192,7 +1196,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
                JFFS2_ERROR("failed to read from flash: error %d, %zd of %zd bytes read\n",
                        ret, retlen, sizeof(*latest_node));
                /* FIXME: If this fails, there seems to be a memory leak. Find it. */
-               up(&f->sem);
+               mutex_unlock(&f->sem);
                jffs2_do_clear_inode(c, f);
                return ret?ret:-EIO;
        }
@@ -1201,7 +1205,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
        if (crc != je32_to_cpu(latest_node->node_crc)) {
                JFFS2_ERROR("CRC failed for read_inode of inode %u at physical location 0x%x\n",
                        f->inocache->ino, ref_offset(rii.latest_ref));
-               up(&f->sem);
+               mutex_unlock(&f->sem);
                jffs2_do_clear_inode(c, f);
                return -EIO;
        }
@@ -1241,7 +1245,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
                        f->target = kmalloc(je32_to_cpu(latest_node->csize) + 1, GFP_KERNEL);
                        if (!f->target) {
                                JFFS2_ERROR("can't allocate %d bytes of memory for the symlink target path cache\n", je32_to_cpu(latest_node->csize));
-                               up(&f->sem);
+                               mutex_unlock(&f->sem);
                                jffs2_do_clear_inode(c, f);
                                return -ENOMEM;
                        }
@@ -1254,7 +1258,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
                                        ret = -EIO;
                                kfree(f->target);
                                f->target = NULL;
-                               up(&f->sem);
+                               mutex_unlock(&f->sem);
                                jffs2_do_clear_inode(c, f);
                                return -ret;
                        }
@@ -1272,14 +1276,14 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
                if (f->metadata) {
                        JFFS2_ERROR("Argh. Special inode #%u with mode 0%o had metadata node\n",
                               f->inocache->ino, jemode_to_cpu(latest_node->mode));
-                       up(&f->sem);
+                       mutex_unlock(&f->sem);
                        jffs2_do_clear_inode(c, f);
                        return -EIO;
                }
                if (!frag_first(&f->fragtree)) {
                        JFFS2_ERROR("Argh. Special inode #%u with mode 0%o has no fragments\n",
                               f->inocache->ino, jemode_to_cpu(latest_node->mode));
-                       up(&f->sem);
+                       mutex_unlock(&f->sem);
                        jffs2_do_clear_inode(c, f);
                        return -EIO;
                }
@@ -1288,7 +1292,7 @@ static int jffs2_do_read_inode_internal(struct jffs2_sb_info *c,
                        JFFS2_ERROR("Argh. Special inode #%u with mode 0x%x had more than one node\n",
                               f->inocache->ino, jemode_to_cpu(latest_node->mode));
                        /* FIXME: Deal with it - check crc32, check for duplicate node, check times and discard the older one */
-                       up(&f->sem);
+                       mutex_unlock(&f->sem);
                        jffs2_do_clear_inode(c, f);
                        return -EIO;
                }
@@ -1356,7 +1360,7 @@ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
                }
                dbg_readinode("creating inocache for root inode\n");
                memset(f->inocache, 0, sizeof(struct jffs2_inode_cache));
-               f->inocache->ino = f->inocache->nlink = 1;
+               f->inocache->ino = f->inocache->pino_nlink = 1;
                f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache;
                f->inocache->state = INO_STATE_READING;
                jffs2_add_ino_cache(c, f->inocache);
@@ -1378,12 +1382,13 @@ int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
        if (!f)
                return -ENOMEM;
 
-       init_MUTEX_LOCKED(&f->sem);
+       mutex_init(&f->sem);
+       mutex_lock(&f->sem);
        f->inocache = ic;
 
        ret = jffs2_do_read_inode_internal(c, f, &n);
        if (!ret) {
-               up(&f->sem);
+               mutex_unlock(&f->sem);
                jffs2_do_clear_inode(c, f);
        }
        kfree (f);
@@ -1397,8 +1402,8 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
 
        jffs2_clear_acl(f);
        jffs2_xattr_delete_inode(c, f->inocache);
-       down(&f->sem);
-       deleted = f->inocache && !f->inocache->nlink;
+       mutex_lock(&f->sem);
+       deleted = f->inocache && !f->inocache->pino_nlink;
 
        if (f->inocache && f->inocache->state != INO_STATE_CHECKING)
                jffs2_set_inocache_state(c, f->inocache, INO_STATE_CLEARING);
@@ -1429,5 +1434,5 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
                        jffs2_del_ino_cache(c, f->inocache);
        }
 
-       up(&f->sem);
+       mutex_unlock(&f->sem);
 }