int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) { struct jffs2_raw_inode n; struct jffs2_inode_info *f = kzalloc(sizeof(*f), GFP_KERNEL); int ret; if (!f) return -ENOMEM; init_MUTEX_LOCKED(&f->sem); f->inocache = ic; ret = jffs2_do_read_inode_internal(c, f, &n); if (!ret) { up(&f->sem); jffs2_do_clear_inode(c, f); } kfree (f); return ret; }
int jffs2_do_crccheck_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) { struct jffs2_raw_inode n; struct jffs2_inode_info *f = kzalloc(sizeof(*f), GFP_KERNEL); int ret; if (!f) return -ENOMEM; mutex_init(&f->sem); mutex_lock(&f->sem); f->inocache = ic; ret = jffs2_do_read_inode_internal(c, f, &n); if (!ret) { mutex_unlock(&f->sem); jffs2_do_clear_inode(c, f); } jffs2_xattr_do_crccheck_inode(c, ic); kfree (f); return ret; }
/* Scan the list of all nodes present for this ino, build map of versions, etc. */ int jffs2_do_read_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t ino, struct jffs2_raw_inode *latest_node) { dbg_readinode("read inode #%u\n", ino); retry_inocache: spin_lock(&c->inocache_lock); f->inocache = jffs2_get_ino_cache(c, ino); if (f->inocache) { /* Check its state. We may need to wait before we can use it */ switch(f->inocache->state) { case INO_STATE_UNCHECKED: case INO_STATE_CHECKEDABSENT: f->inocache->state = INO_STATE_READING; break; case INO_STATE_CHECKING: case INO_STATE_GC: /* If it's in either of these states, we need to wait for whoever's got it to finish and put it back. */ dbg_readinode("waiting for ino #%u in state %d\n", ino, f->inocache->state); sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock); goto retry_inocache; case INO_STATE_READING: case INO_STATE_PRESENT: /* Eep. This should never happen. It can happen if Linux calls read_inode() again before clear_inode() has finished though. */ JFFS2_ERROR("Eep. Trying to read_inode #%u when it's already in state %d!\n", ino, f->inocache->state); /* Fail. That's probably better than allowing it to succeed */ f->inocache = NULL; break; default: BUG(); } } spin_unlock(&c->inocache_lock); if (!f->inocache && ino == 1) { /* Special case - no root inode on medium */ f->inocache = jffs2_alloc_inode_cache(); if (!f->inocache) { JFFS2_ERROR("cannot allocate inocache for root inode\n"); return -ENOMEM; } 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->nodes = (struct jffs2_raw_node_ref *)f->inocache; f->inocache->state = INO_STATE_READING; jffs2_add_ino_cache(c, f->inocache); } if (!f->inocache) { JFFS2_ERROR("requestied to read an nonexistent ino %u\n", ino); return -ENOENT; } return jffs2_do_read_inode_internal(c, f, latest_node); }