JFFS2_DBG_READINODE("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); 
dbg_readinode("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref)); 
static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_info *f,				 struct rb_root *tnp, struct jffs2_full_dirent **fdp,				 uint32_t *highest_version, uint32_t *latest_mctime,				 uint32_t *mctime_ver){	struct jffs2_raw_node_ref *ref, *valid_ref;	struct rb_root ret_tn = RB_ROOT;	struct jffs2_full_dirent *ret_fd = NULL;	unsigned char *buf = NULL;	union jffs2_node_union *node;	size_t retlen;	int len, err;	*mctime_ver = 0;		JFFS2_DBG_READINODE("ino #%u\n", f->inocache->ino);	if (jffs2_is_writebuffered(c)) {		/*		 * If we have the write buffer, we assume the minimal I/O unit		 * is c->wbuf_pagesize. We implement some optimizations which in		 * this case and we need a temporary buffer of size =		 * 2*c->wbuf_pagesize bytes (see comments in read_dnode()).		 * Basically, we want to read not only the node header, but the		 * whole wbuf (NAND page in case of NAND) or 2, if the node		 * header overlaps the border between the 2 wbufs.		 */		len = 2*c->wbuf_pagesize;	} else {		/*		 * When there is no write buffer, the size of the temporary		 * buffer is the size of the larges node header.		 */		len = sizeof(union jffs2_node_union);	}	/* FIXME: in case of NOR and available ->point() this	 * needs to be fixed. */	buf = kmalloc(len, GFP_KERNEL);	if (!buf)		return -ENOMEM;				spin_lock(&c->erase_completion_lock);	valid_ref = jffs2_first_valid_node(f->inocache->nodes);	if (!valid_ref && f->inocache->ino != 1)		JFFS2_WARNING("Eep. No valid nodes for ino #%u.\n", f->inocache->ino);	while (valid_ref) {		unsigned char *bufstart;		/* We can hold a pointer to a non-obsolete node without the spinlock,		   but _obsolete_ nodes may disappear at any time, if the block		   they're in gets erased. So if we mark 'ref' obsolete while we're		   not holding the lock, it can go away immediately. For that reason,		   we find the next valid node first, before processing 'ref'.		*/		ref = valid_ref;		valid_ref = jffs2_first_valid_node(ref->next_in_ino);		spin_unlock(&c->erase_completion_lock);		cond_resched();		/*		 * At this point we don't know the type of the node we're going		 * to read, so we do not know the size of its header. In order		 * to minimize the amount of flash IO we assume the node has		 * size = JFFS2_MIN_NODE_HEADER.		 */		if (jffs2_is_writebuffered(c)) {			/* 			 * We treat 'buf' as 2 adjacent wbufs. We want to			 * adjust bufstart such as it points to the			 * beginning of the node within this wbuf.			 */			bufstart = buf + (ref_offset(ref) % c->wbuf_pagesize);			/* We will read either one wbuf or 2 wbufs. */			len = c->wbuf_pagesize - (bufstart - buf);			if (JFFS2_MIN_NODE_HEADER + (int)(bufstart - buf) > c->wbuf_pagesize) {				/* The header spans the border of the first wbuf */				len += c->wbuf_pagesize;			}		} else {			bufstart = buf;			len = JFFS2_MIN_NODE_HEADER;		}		JFFS2_DBG_READINODE("read %d bytes at %#08x(%d).\n", len, ref_offset(ref), ref_flags(ref));		/* FIXME: point() */		err = jffs2_flash_read(c, ref_offset(ref), len,				       &retlen, bufstart);		if (err) {			JFFS2_ERROR("can not read %d bytes from 0x%08x, " "error code: %d.\n", len, ref_offset(ref), err);			goto free_out;		}				if (retlen < len) {			JFFS2_ERROR("short read at %#08x: %d instead of %d.\n", ref_offset(ref), retlen, len);			err = -EIO;			goto free_out;		}				node = (union jffs2_node_union *)bufstart;					switch (je16_to_cpu(node->u.nodetype)) {					case JFFS2_NODETYPE_DIRENT:			if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_dirent)) {				err = read_more(c, ref, sizeof(struct jffs2_raw_dirent), &len, buf, bufstart);				if (unlikely(err))					goto free_out;			}						err = read_direntry(c, ref, &node->d, retlen, &ret_fd, latest_mctime, mctime_ver);			if (err == 1) {				jffs2_mark_node_obsolete(c, ref);				break;			} else if (unlikely(err))				goto free_out;						if (je32_to_cpu(node->d.version) > *highest_version)				*highest_version = je32_to_cpu(node->d.version);			break;		case JFFS2_NODETYPE_INODE:						if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_raw_inode)) {				err = read_more(c, ref, sizeof(struct jffs2_raw_inode), &len, buf, bufstart);				if (unlikely(err))					goto free_out;			}			err = read_dnode(c, ref, &node->i, &ret_tn, len, latest_mctime, mctime_ver);			if (err == 1) {				jffs2_mark_node_obsolete(c, ref);				break;			} else if (unlikely(err))				goto free_out;			if (je32_to_cpu(node->i.version) > *highest_version)				*highest_version = je32_to_cpu(node->i.version);						break;		default:			if (JFFS2_MIN_NODE_HEADER < sizeof(struct jffs2_unknown_node)) {				err = read_more(c, ref, sizeof(struct jffs2_unknown_node), &len, buf, bufstart);				if (unlikely(err))					goto free_out;			}						err = read_unknown(c, ref, &node->u);			if (err == 1) {				jffs2_mark_node_obsolete(c, ref);				break;			} else if (unlikely(err))				goto free_out;		}		spin_lock(&c->erase_completion_lock);	}	spin_unlock(&c->erase_completion_lock);	*tnp = ret_tn;	*fdp = ret_fd;	kfree(buf);	JFFS2_DBG_READINODE("nodes of inode #%u were read, the highest version is %u, latest_mctime %u, mctime_ver %u.\n",			f->inocache->ino, *highest_version, *latest_mctime, *mctime_ver);	return 0; free_out:	jffs2_free_tmp_dnode_info_list(&ret_tn);	jffs2_free_full_dirent_list(ret_fd);	kfree(buf);	return err;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/733802d974e5af42acb7cd61b16c0ce6dd03b7ed/readinode.c/clean/fs/jffs2/readinode.c