⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 file.c

📁 这是著名的jffs2嵌入式日志文件系统的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
			pg_buf += holeend - offset;			offset = holeend;			frag = frag->next;			continue;		} else {			__u32 readlen;			readlen = min(frag->size, end - offset);			D1(printk(KERN_DEBUG "Reading %d-%d from node at 0x%x\n", frag->ofs, frag->ofs+readlen, frag->node->raw->flash_offset & ~3));			ret = jffs2_read_dnode(c, frag->node, pg_buf, frag->ofs - frag->node->ofs, readlen);			D2(printk(KERN_DEBUG "node read done\n"));			if (ret) {				D1(printk(KERN_DEBUG"jffs2_readpage error %d\n",ret));				memset(pg_buf, 0, frag->size);				ClearPageUptodate(pg);				SetPageError(pg);				kunmap(pg);				return ret;			}		}		pg_buf += frag->size;		offset += frag->size;		frag = frag->next;		D2(printk(KERN_DEBUG "node read was OK. Looping\n"));	}	D2(printk(KERN_DEBUG "readpage finishing\n"));	SetPageUptodate(pg);	ClearPageError(pg);	flush_dcache_page(pg);	kunmap(pg);	D1(printk(KERN_DEBUG "readpage finished\n"));	return 0;}int jffs2_do_readpage_unlock(struct inode *inode, struct page *pg){	int ret = jffs2_do_readpage_nolock(inode, pg);	UnlockPage(pg);	return ret;}int jffs2_readpage (struct file *filp, struct page *pg){	struct jffs2_inode_info *f = JFFS2_INODE_INFO(filp->f_dentry->d_inode);	int ret;		down(&f->sem);	ret = jffs2_do_readpage_unlock(filp->f_dentry->d_inode, pg);	up(&f->sem);	return ret;}int jffs2_prepare_write (struct file *filp, struct page *pg, unsigned start, unsigned end){	struct inode *inode = filp->f_dentry->d_inode;	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);	__u32 pageofs = pg->index << PAGE_CACHE_SHIFT;	int ret = 0;	down(&f->sem);	D1(printk(KERN_DEBUG "jffs2_prepare_write() nrpages %ld\n", inode->i_mapping->nrpages));	if (pageofs > inode->i_size) {		/* Make new hole frag from old EOF to new page */		struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);		struct jffs2_raw_inode ri;		struct jffs2_full_dnode *fn;		__u32 phys_ofs, alloc_len;				D1(printk(KERN_DEBUG "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",			  (unsigned int)inode->i_size, pageofs));		ret = jffs2_reserve_space(c, sizeof(ri), &phys_ofs, &alloc_len, ALLOC_NORMAL);		if (ret) {			up(&f->sem);			return ret;		}		memset(&ri, 0, sizeof(ri));		ri.magic = JFFS2_MAGIC_BITMASK;		ri.nodetype = JFFS2_NODETYPE_INODE;		ri.totlen = sizeof(ri);		ri.hdr_crc = crc32(0, &ri, sizeof(struct jffs2_unknown_node)-4);		ri.ino = f->inocache->ino;		ri.version = ++f->highest_version;		ri.mode = inode->i_mode;		ri.uid = inode->i_uid;		ri.gid = inode->i_gid;		ri.isize = max((__u32)inode->i_size, pageofs);		ri.atime = ri.ctime = ri.mtime = CURRENT_TIME;		ri.offset = inode->i_size;		ri.dsize = pageofs - inode->i_size;		ri.csize = 0;		ri.compr = JFFS2_COMPR_ZERO;		ri.node_crc = crc32(0, &ri, sizeof(ri)-8);		ri.data_crc = 0;				fn = jffs2_write_dnode(inode, &ri, NULL, 0, phys_ofs, NULL);		jffs2_complete_reservation(c);		if (IS_ERR(fn)) {			ret = PTR_ERR(fn);			up(&f->sem);			return ret;		}		ret = jffs2_add_full_dnode_to_inode(c, f, fn);		if (f->metadata) {			jffs2_mark_node_obsolete(c, f->metadata->raw);			jffs2_free_full_dnode(f->metadata);			f->metadata = NULL;		}		if (ret) {			D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret));			jffs2_mark_node_obsolete(c, fn->raw);			jffs2_free_full_dnode(fn);			up(&f->sem);			return ret;		}		inode->i_size = pageofs;	}		/* Read in the page if it wasn't already present */	if (!Page_Uptodate(pg) && (start || end < PAGE_SIZE))		ret = jffs2_do_readpage_nolock(inode, pg);	D1(printk(KERN_DEBUG "end prepare_write(). nrpages %ld\n", inode->i_mapping->nrpages));	up(&f->sem);	return ret;}int jffs2_commit_write (struct file *filp, struct page *pg, unsigned start, unsigned end){	/* Actually commit the write from the page cache page we're looking at.	 * For now, we write the full page out each time. It sucks, but it's simple	 */	struct inode *inode = filp->f_dentry->d_inode;	struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);	struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);	__u32 newsize = max_t(__u32, filp->f_dentry->d_inode->i_size, (pg->index << PAGE_CACHE_SHIFT) + end);	__u32 file_ofs = (pg->index << PAGE_CACHE_SHIFT);	__u32 writelen = min((__u32)PAGE_CACHE_SIZE, newsize - file_ofs);	struct jffs2_raw_inode *ri;	int ret = 0;	ssize_t writtenlen = 0;	D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, nrpages %ld\n", inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, filp->f_dentry->d_inode->i_mapping->nrpages));	ri = jffs2_alloc_raw_inode();	if (!ri)		return -ENOMEM;	while(writelen) {		struct jffs2_full_dnode *fn;		unsigned char *comprbuf = NULL;		unsigned char comprtype = JFFS2_COMPR_NONE;		__u32 phys_ofs, alloclen;		__u32 datalen, cdatalen;		D2(printk(KERN_DEBUG "jffs2_commit_write() loop: 0x%x to write to 0x%x\n", writelen, file_ofs));		ret = jffs2_reserve_space(c, sizeof(*ri) + JFFS2_MIN_DATA_LEN, &phys_ofs, &alloclen, ALLOC_NORMAL);		if (ret) {			SetPageError(pg);			D1(printk(KERN_DEBUG "jffs2_reserve_space returned %d\n", ret));			break;		}		down(&f->sem);		datalen = writelen;		cdatalen = min(alloclen - sizeof(*ri), writelen);		comprbuf = kmalloc(cdatalen, GFP_KERNEL);		if (comprbuf) {			comprtype = jffs2_compress(page_address(pg)+ (file_ofs & (PAGE_CACHE_SIZE-1)), comprbuf, &datalen, &cdatalen);		}		if (comprtype == JFFS2_COMPR_NONE) {			/* Either compression failed, or the allocation of comprbuf failed */			if (comprbuf)				kfree(comprbuf);			comprbuf = page_address(pg) + (file_ofs & (PAGE_CACHE_SIZE -1));			datalen = cdatalen;		}		/* Now comprbuf points to the data to be written, be it compressed or not.		   comprtype holds the compression type, and comprtype == JFFS2_COMPR_NONE means		   that the comprbuf doesn't need to be kfree()d. 		*/		ri->magic = JFFS2_MAGIC_BITMASK;		ri->nodetype = JFFS2_NODETYPE_INODE;		ri->totlen = sizeof(*ri) + cdatalen;		ri->hdr_crc = crc32(0, ri, sizeof(struct jffs2_unknown_node)-4);		ri->ino = inode->i_ino;		ri->version = ++f->highest_version;		ri->mode = inode->i_mode;		ri->uid = inode->i_uid;		ri->gid = inode->i_gid;		ri->isize = max((__u32)inode->i_size, file_ofs + datalen);		ri->atime = ri->ctime = ri->mtime = CURRENT_TIME;		ri->offset = file_ofs;		ri->csize = cdatalen;		ri->dsize = datalen;		ri->compr = comprtype;		ri->node_crc = crc32(0, ri, sizeof(*ri)-8);		ri->data_crc = crc32(0, comprbuf, cdatalen);		fn = jffs2_write_dnode(inode, ri, comprbuf, cdatalen, phys_ofs, NULL);		jffs2_complete_reservation(c);		if (comprtype != JFFS2_COMPR_NONE)			kfree(comprbuf);		if (IS_ERR(fn)) {			ret = PTR_ERR(fn);			up(&f->sem);			SetPageError(pg);			break;		}		ret = jffs2_add_full_dnode_to_inode(c, f, fn);		if (f->metadata) {			jffs2_mark_node_obsolete(c, f->metadata->raw);			jffs2_free_full_dnode(f->metadata);			f->metadata = NULL;		}		up(&f->sem);		if (ret) {			/* Eep */			D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in commit_write, returned %d\n", ret));			jffs2_mark_node_obsolete(c, fn->raw);			jffs2_free_full_dnode(fn);			SetPageError(pg);			break;		}		inode->i_size = ri->isize;		inode->i_blocks = (inode->i_size + 511) >> 9;		inode->i_ctime = inode->i_mtime = ri->ctime;		if (!datalen) {			printk(KERN_WARNING "Eep. We didn't actually write any bloody data\n");			ret = -EIO;			SetPageError(pg);			break;		}		D1(printk(KERN_DEBUG "increasing writtenlen by %d\n", datalen));		writtenlen += datalen;		file_ofs += datalen;		writelen -= datalen;	}	jffs2_free_raw_inode(ri);	if (writtenlen < end) {		/* generic_file_write has written more to the page cache than we've		   actually written to the medium. Mark the page !Uptodate so that 		   it gets reread */		D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n"));		SetPageError(pg);		ClearPageUptodate(pg);	}	if (writtenlen <= start) {		/* We didn't even get to the start of the affected part */		ret = ret?ret:-ENOSPC;		D1(printk(KERN_DEBUG "jffs2_commit_write(): Only %x bytes written to page. start (%x) not reached, returning %d\n", writtenlen, start, ret));	}	writtenlen = min(end-start, writtenlen-start);	D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d. nrpages is %ld\n",writtenlen?writtenlen:ret, inode->i_mapping->nrpages));	return writtenlen?writtenlen:ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -