int jffs2_do_new_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f, uint32_t mode, struct jffs2_raw_inode *ri) { struct jffs2_inode_cache *ic; ic = jffs2_alloc_inode_cache(); if (!ic) { return -ENOMEM; } memset(ic, 0, sizeof(*ic)); f->inocache = ic; f->inocache->nlink = 1; f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; f->inocache->state = INO_STATE_PRESENT; jffs2_add_ino_cache(c, f->inocache); D1(printk(KERN_DEBUG "jffs2_do_new_inode(): Assigned ino# %d\n", f->inocache->ino)); ri->ino = cpu_to_je32(f->inocache->ino); ri->magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); ri->nodetype = cpu_to_je16(JFFS2_NODETYPE_INODE); ri->totlen = cpu_to_je32(PAD(sizeof(*ri))); ri->hdr_crc = cpu_to_je32(crc32(0, ri, sizeof(struct jffs2_unknown_node)-4)); ri->mode = cpu_to_jemode(mode); f->highest_version = 1; ri->version = cpu_to_je32(f->highest_version); return 0; }
static struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, __u32 ino) { struct jffs2_inode_cache *ic; ic = jffs2_get_ino_cache(c, ino); if (ic) return ic; ic = jffs2_alloc_inode_cache(); if (!ic) { printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n"); return NULL; } memset(ic, 0, sizeof(*ic)); ic->scan = kmalloc(sizeof(struct jffs2_scan_info), GFP_KERNEL); if (!ic->scan) { printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of scan info for inode cache failed\n"); jffs2_free_inode_cache(ic); return NULL; } memset(ic->scan, 0, sizeof(*ic->scan)); ic->ino = ino; ic->nodes = (void *)ic; jffs2_add_ino_cache(c, ic); if (ino == 1) ic->nlink=1; return ic; }
struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino) { struct jffs2_inode_cache *ic; ic = jffs2_get_ino_cache(c, ino); if (ic) return ic; if (ino > c->highest_ino) c->highest_ino = ino; ic = jffs2_alloc_inode_cache(); if (!ic) { printk(KERN_NOTICE "jffs2_scan_make_inode_cache(): allocation of inode cache failed\n"); return NULL; } memset(ic, 0, sizeof(*ic)); ic->ino = ino; ic->nodes = (void *)ic; jffs2_add_ino_cache(c, ic); if (ino == 1) ic->pino_nlink = 1; return ic; }
/* 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); }
/* jffs2_new_inode: allocate a new inode and inocache, add it to the hash, fill in the raw_inode while you're at it. */ struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct jffs2_raw_inode *ri) { struct inode *inode; struct super_block *sb = dir_i->i_sb; struct jffs2_inode_cache *ic; struct jffs2_sb_info *c; struct jffs2_inode_info *f; D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode)); c = JFFS2_SB_INFO(sb); memset(ri, 0, sizeof(*ri)); ic = jffs2_alloc_inode_cache(); if (!ic) { return ERR_PTR(-ENOMEM); } memset(ic, 0, sizeof(*ic)); inode = new_inode(sb); if (!inode) { jffs2_free_inode_cache(ic); return ERR_PTR(-ENOMEM); } /* Alloc jffs2_inode_info when that's split in 2.5 */ f = JFFS2_INODE_INFO(inode); memset(f, 0, sizeof(*f)); init_MUTEX_LOCKED(&f->sem); f->inocache = ic; inode->i_nlink = f->inocache->nlink = 1; f->inocache->nodes = (struct jffs2_raw_node_ref *)f->inocache; f->inocache->ino = ri->ino = inode->i_ino = ++c->highest_ino; D1(printk(KERN_DEBUG "jffs2_new_inode(): Assigned ino# %d\n", ri->ino)); jffs2_add_ino_cache(c, f->inocache); ri->magic = JFFS2_MAGIC_BITMASK; ri->nodetype = JFFS2_NODETYPE_INODE; ri->totlen = PAD(sizeof(*ri)); ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4); ri->mode = mode; f->highest_version = ri->version = 1; ri->uid = current->fsuid; if (dir_i->i_mode & S_ISGID) { ri->gid = dir_i->i_gid; if (S_ISDIR(mode)) ri->mode |= S_ISGID; } else { ri->gid = current->fsgid; } inode->i_mode = ri->mode; inode->i_gid = ri->gid; inode->i_uid = ri->uid; inode->i_atime = inode->i_ctime = inode->i_mtime = ri->atime = ri->mtime = ri->ctime = CURRENT_TIME; inode->i_blksize = PAGE_SIZE; inode->i_blocks = 0; inode->i_size = 0; insert_inode_hash(inode); return inode; }