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

📄 yaffs_fs.c

📁 yaffs2 lastest sourcecode~~
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif/* clear is called to tell the fs to release any per-inode data it holds */static void yaffs_clear_inode(struct inode *inode){	yaffs_Object *obj;	yaffs_Device *dev;	obj = yaffs_InodeToObject(inode);	T(YAFFS_TRACE_OS,		("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino,		atomic_read(&inode->i_count),		obj ? "object exists" : "null object"));	if (obj) {		dev = obj->myDev;		yaffs_GrossLock(dev);		/* Clear the association between the inode and		 * the yaffs_Object.		 */		obj->myInode = NULL;		yaffs_InodeToObjectLV(inode) = NULL;		/* If the object freeing was deferred, then the real		 * free happens now.		 * This should fix the inode inconsistency problem.		 */		yaffs_HandleDeferedFree(obj);		yaffs_GrossUnlock(dev);	}}/* delete is called when the link count is zero and the inode * is put (ie. nobody wants to know about it anymore, time to * delete the file). * NB Must call clear_inode() */static void yaffs_delete_inode(struct inode *inode){	yaffs_Object *obj = yaffs_InodeToObject(inode);	yaffs_Device *dev;	T(YAFFS_TRACE_OS,		("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino,		atomic_read(&inode->i_count),		obj ? "object exists" : "null object"));	if (obj) {		dev = obj->myDev;		yaffs_GrossLock(dev);		yaffs_DeleteObject(obj);		yaffs_GrossUnlock(dev);	}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))	truncate_inode_pages(&inode->i_data, 0);#endif	clear_inode(inode);}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))static int yaffs_file_flush(struct file *file, fl_owner_t id)#elsestatic int yaffs_file_flush(struct file *file)#endif{	yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry);	yaffs_Device *dev = obj->myDev;	T(YAFFS_TRACE_OS,		("yaffs_file_flush object %d (%s)\n", obj->objectId,		obj->dirty ? "dirty" : "clean"));	yaffs_GrossLock(dev);	yaffs_FlushFile(obj, 1);	yaffs_GrossUnlock(dev);	return 0;}static int yaffs_readpage_nolock(struct file *f, struct page *pg){	/* Lifted from jffs2 */	yaffs_Object *obj;	unsigned char *pg_buf;	int ret;	yaffs_Device *dev;	T(YAFFS_TRACE_OS, ("yaffs_readpage at %08x, size %08x\n",			(unsigned)(pg->index << PAGE_CACHE_SHIFT),			(unsigned)PAGE_CACHE_SIZE));	obj = yaffs_DentryToObject(f->f_dentry);	dev = obj->myDev;#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))	BUG_ON(!PageLocked(pg));#else	if (!PageLocked(pg))		PAGE_BUG(pg);#endif	pg_buf = kmap(pg);	/* FIXME: Can kmap fail? */	yaffs_GrossLock(dev);	ret = yaffs_ReadDataFromFile(obj, pg_buf,				pg->index << PAGE_CACHE_SHIFT,				PAGE_CACHE_SIZE);	yaffs_GrossUnlock(dev);	if (ret >= 0)		ret = 0;	if (ret) {		ClearPageUptodate(pg);		SetPageError(pg);	} else {		SetPageUptodate(pg);		ClearPageError(pg);	}	flush_dcache_page(pg);	kunmap(pg);	T(YAFFS_TRACE_OS, ("yaffs_readpage done\n"));	return ret;}static int yaffs_readpage_unlock(struct file *f, struct page *pg){	int ret = yaffs_readpage_nolock(f, pg);	UnlockPage(pg);	return ret;}static int yaffs_readpage(struct file *f, struct page *pg){	return yaffs_readpage_unlock(f, pg);}/* writepage inspired by/stolen from smbfs */#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))static int yaffs_writepage(struct page *page, struct writeback_control *wbc)#elsestatic int yaffs_writepage(struct page *page)#endif{	struct address_space *mapping = page->mapping;	loff_t offset = (loff_t) page->index << PAGE_CACHE_SHIFT;	struct inode *inode;	unsigned long end_index;	char *buffer;	yaffs_Object *obj;	int nWritten = 0;	unsigned nBytes;	if (!mapping)		BUG();	inode = mapping->host;	if (!inode)		BUG();	if (offset > inode->i_size) {		T(YAFFS_TRACE_OS,			("yaffs_writepage at %08x, inode size = %08x!!!\n",			(unsigned)(page->index << PAGE_CACHE_SHIFT),			(unsigned)inode->i_size));		T(YAFFS_TRACE_OS,			("                -> don't care!!\n"));		unlock_page(page);		return 0;	}	end_index = inode->i_size >> PAGE_CACHE_SHIFT;	/* easy case */	if (page->index < end_index)		nBytes = PAGE_CACHE_SIZE;	else		nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1);	get_page(page);	buffer = kmap(page);	obj = yaffs_InodeToObject(inode);	yaffs_GrossLock(obj->myDev);	T(YAFFS_TRACE_OS,		("yaffs_writepage at %08x, size %08x\n",		(unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes));	T(YAFFS_TRACE_OS,		("writepag0: obj = %05x, ino = %05x\n",		(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));	nWritten = yaffs_WriteDataToFile(obj, buffer,			page->index << PAGE_CACHE_SHIFT, nBytes, 0);	T(YAFFS_TRACE_OS,		("writepag1: obj = %05x, ino = %05x\n",		(int)obj->variant.fileVariant.fileSize, (int)inode->i_size));	yaffs_GrossUnlock(obj->myDev);	kunmap(page);	SetPageUptodate(page);	UnlockPage(page);	put_page(page);	return (nWritten == nBytes) ? 0 : -ENOSPC;}#if (YAFFS_USE_WRITE_BEGIN_END > 0)static int yaffs_write_begin(struct file *filp, struct address_space *mapping,				loff_t pos, unsigned len, unsigned flags,				struct page **pagep, void **fsdata){	struct page *pg = NULL;	pgoff_t index = pos >> PAGE_CACHE_SHIFT;	uint32_t offset = pos & (PAGE_CACHE_SIZE - 1);	uint32_t to = offset + len;	int ret = 0;	int space_held = 0;	T(YAFFS_TRACE_OS, ("start yaffs_write_begin\n"));	/* Get a page */#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)	pg = grab_cache_page_write_begin(mapping, index, flags);#else	pg = __grab_cache_page(mapping, index);#endif	*pagep = pg;	if (!pg) {		ret =  -ENOMEM;		goto out;	}	/* Get fs space */	space_held = yaffs_hold_space(filp);	if (!space_held) {		ret = -ENOSPC;		goto out;	}	/* Update page if required */	if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))		ret = yaffs_readpage_nolock(filp, pg);	if (ret)		goto out;	/* Happy path return */	T(YAFFS_TRACE_OS, ("end yaffs_write_begin - ok\n"));	return 0;out:	T(YAFFS_TRACE_OS, ("end yaffs_write_begin fail returning %d\n", ret));	if (space_held)		yaffs_release_space(filp);	if (pg) {		unlock_page(pg);		page_cache_release(pg);	}	return ret;}#elsestatic int yaffs_prepare_write(struct file *f, struct page *pg,				unsigned offset, unsigned to){	T(YAFFS_TRACE_OS, ("yaffs_prepair_write\n"));	if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))		return yaffs_readpage_nolock(f, pg);	return 0;}#endif#if (YAFFS_USE_WRITE_BEGIN_END > 0)static int yaffs_write_end(struct file *filp, struct address_space *mapping,				loff_t pos, unsigned len, unsigned copied,				struct page *pg, void *fsdadata){	int ret = 0;	void *addr, *kva;	uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);	kva = kmap(pg);	addr = kva + offset_into_page;	T(YAFFS_TRACE_OS,		("yaffs_write_end addr %x pos %x nBytes %d\n",		(unsigned) addr,		(int)pos, copied));	ret = yaffs_file_write(filp, addr, copied, &pos);	if (ret != copied) {		T(YAFFS_TRACE_OS,			("yaffs_write_end not same size ret %d  copied %d\n",			ret, copied));		SetPageError(pg);		ClearPageUptodate(pg);	} else {		SetPageUptodate(pg);	}	kunmap(pg);	yaffs_release_space(filp);	unlock_page(pg);	page_cache_release(pg);	return ret;}#elsestatic int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,				unsigned to){	void *addr, *kva;	loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;	int nBytes = to - offset;	int nWritten;	unsigned spos = pos;	unsigned saddr;	kva = kmap(pg);	addr = kva + offset;	saddr = (unsigned) addr;	T(YAFFS_TRACE_OS,		("yaffs_commit_write addr %x pos %x nBytes %d\n",		saddr, spos, nBytes));	nWritten = yaffs_file_write(f, addr, nBytes, &pos);	if (nWritten != nBytes) {		T(YAFFS_TRACE_OS,			("yaffs_commit_write not same size nWritten %d  nBytes %d\n",			nWritten, nBytes));		SetPageError(pg);		ClearPageUptodate(pg);	} else {		SetPageUptodate(pg);	}	kunmap(pg);	T(YAFFS_TRACE_OS,		("yaffs_commit_write returning %d\n",		nWritten == nBytes ? 0 : nWritten));	return nWritten == nBytes ? 0 : nWritten;}#endifstatic void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj){	if (inode && obj) {		/* Check mode against the variant type and attempt to repair if broken. */		__u32 mode = obj->yst_mode;		switch (obj->variantType) {		case YAFFS_OBJECT_TYPE_FILE:			if (!S_ISREG(mode)) {				obj->yst_mode &= ~S_IFMT;				obj->yst_mode |= S_IFREG;			}			break;		case YAFFS_OBJECT_TYPE_SYMLINK:			if (!S_ISLNK(mode)) {				obj->yst_mode &= ~S_IFMT;				obj->yst_mode |= S_IFLNK;			}			break;		case YAFFS_OBJECT_TYPE_DIRECTORY:			if (!S_ISDIR(mode)) {				obj->yst_mode &= ~S_IFMT;				obj->yst_mode |= S_IFDIR;			}			break;		case YAFFS_OBJECT_TYPE_UNKNOWN:		case YAFFS_OBJECT_TYPE_HARDLINK:		case YAFFS_OBJECT_TYPE_SPECIAL:		default:			/* TODO? */			break;		}		inode->i_flags |= S_NOATIME;		inode->i_ino = obj->objectId;		inode->i_mode = obj->yst_mode;		inode->i_uid = obj->yst_uid;		inode->i_gid = obj->yst_gid;#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))		inode->i_blksize = inode->i_sb->s_blocksize;#endif#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))		inode->i_rdev = old_decode_dev(obj->yst_rdev);		inode->i_atime.tv_sec = (time_t) (obj->yst_atime);		inode->i_atime.tv_nsec = 0;		inode->i_mtime.tv_sec = (time_t) obj->yst_mtime;		inode->i_mtime.tv_nsec = 0;		inode->i_ctime.tv_sec = (time_t) obj->yst_ctime;		inode->i_ctime.tv_nsec = 0;#else		inode->i_rdev = obj->yst_rdev;		inode->i_atime = obj->yst_atime;		inode->i_mtime = obj->yst_mtime;		inode->i_ctime = obj->yst_ctime;#endif		inode->i_size = yaffs_GetObjectFileLength(obj);		inode->i_blocks = (inode->i_size + 511) >> 9;		inode->i_nlink = yaffs_GetObjectLinkCount(obj);		T(YAFFS_TRACE_OS,			("yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",			inode->i_mode, inode->i_uid, inode->i_gid,			(int)inode->i_size, atomic_read(&inode->i_count)));		switch (obj->yst_mode & S_IFMT) {		default:	/* fifo, device or socket */#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))			init_special_inode(inode, obj->yst_mode,					old_decode_dev(obj->yst_rdev));#else			init_special_inode(inode, obj->yst_mode,					(dev_t) (obj->yst_rdev));#endif			break;		case S_IFREG:	/* file */			inode->i_op = &yaffs_file_inode_operations;			inode->i_fop = &yaffs_file_operations;			inode->i_mapping->a_ops =				&yaffs_file_address_operations;			break;		case S_IFDIR:	/* directory */			inode->i_op = &yaffs_dir_inode_operations;			inode->i_fop = &yaffs_dir_operations;			break;		case S_IFLNK:	/* symlink */			inode->i_op = &yaffs_symlink_inode_operations;			break;		}		yaffs_InodeToObjectLV(inode) = obj;		obj->myInode = inode;	} else {		T(YAFFS_TRACE_OS,			("yaffs_FileInode invalid parameters\n"));	}}struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,				yaffs_Object *obj){	struct inode *inode;	if (!sb) {		T(YAFFS_TRACE_OS,			("yaffs_get_inode for NULL super_block!!\n"));		return NULL;	}	if (!obj) {		T(YAFFS_TRACE_OS,			("yaffs_get_inode for NULL object!!\n"));		return NULL;	}

⌨️ 快捷键说明

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