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

📄 yaffs_fs.c

📁 yaffs2 lastest sourcecode~~
💻 C
📖 第 1 页 / 共 5 页
字号:
	T(YAFFS_TRACE_OS,		("yaffs_get_inode for object %d\n", obj->objectId));	inode = Y_IGET(sb, obj->objectId);	if (IS_ERR(inode))		return NULL;	/* NB Side effect: iget calls back to yaffs_read_inode(). */	/* iget also increments the inode's i_count */	/* NB You can't be holding grossLock or deadlock will happen! */	return inode;}static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,				loff_t *pos){	yaffs_Object *obj;	int nWritten, ipos;	struct inode *inode;	yaffs_Device *dev;	obj = yaffs_DentryToObject(f->f_dentry);	dev = obj->myDev;	yaffs_GrossLock(dev);	inode = f->f_dentry->d_inode;	if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)		ipos = inode->i_size;	else		ipos = *pos;	if (!obj)		T(YAFFS_TRACE_OS,			("yaffs_file_write: hey obj is null!\n"));	else		T(YAFFS_TRACE_OS,			("yaffs_file_write about to write writing %zu bytes"			"to object %d at %d\n",			n, obj->objectId, ipos));	nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0);	T(YAFFS_TRACE_OS,		("yaffs_file_write writing %zu bytes, %d written at %d\n",		n, nWritten, ipos));	if (nWritten > 0) {		ipos += nWritten;		*pos = ipos;		if (ipos > inode->i_size) {			inode->i_size = ipos;			inode->i_blocks = (ipos + 511) >> 9;			T(YAFFS_TRACE_OS,				("yaffs_file_write size updated to %d bytes, "				"%d blocks\n",				ipos, (int)(inode->i_blocks)));		}	}	yaffs_GrossUnlock(dev);	return nWritten == 0 ? -ENOSPC : nWritten;}/* Space holding and freeing is done to ensure we have space available for write_begin/end *//* For now we just assume few parallel writes and check against a small number. *//* Todo: need to do this with a counter to handle parallel reads better */static ssize_t yaffs_hold_space(struct file *f){	yaffs_Object *obj;	yaffs_Device *dev;	int nFreeChunks;	obj = yaffs_DentryToObject(f->f_dentry);	dev = obj->myDev;	yaffs_GrossLock(dev);	nFreeChunks = yaffs_GetNumberOfFreeChunks(dev);	yaffs_GrossUnlock(dev);	return (nFreeChunks > 20) ? 1 : 0;}static void yaffs_release_space(struct file *f){	yaffs_Object *obj;	yaffs_Device *dev;	obj = yaffs_DentryToObject(f->f_dentry);	dev = obj->myDev;	yaffs_GrossLock(dev);	yaffs_GrossUnlock(dev);}static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir){	yaffs_Object *obj;	yaffs_Device *dev;	struct inode *inode = f->f_dentry->d_inode;	unsigned long offset, curoffs;	struct ylist_head *i;	yaffs_Object *l;	char name[YAFFS_MAX_NAME_LENGTH + 1];	obj = yaffs_DentryToObject(f->f_dentry);	dev = obj->myDev;	yaffs_GrossLock(dev);	offset = f->f_pos;	T(YAFFS_TRACE_OS, ("yaffs_readdir: starting at %d\n", (int)offset));	if (offset == 0) {		T(YAFFS_TRACE_OS,			("yaffs_readdir: entry . ino %d \n",			(int)inode->i_ino));		if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0)			goto out;		offset++;		f->f_pos++;	}	if (offset == 1) {		T(YAFFS_TRACE_OS,			("yaffs_readdir: entry .. ino %d \n",			(int)f->f_dentry->d_parent->d_inode->i_ino));		if (filldir(dirent, "..", 2, offset,			f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)			goto out;		offset++;		f->f_pos++;	}	curoffs = 1;	/* If the directory has changed since the open or last call to	   readdir, rewind to after the 2 canned entries. */	if (f->f_version != inode->i_version) {		offset = 2;		f->f_pos = offset;		f->f_version = inode->i_version;	}	ylist_for_each(i, &obj->variant.directoryVariant.children) {		curoffs++;		if (curoffs >= offset) {			l = ylist_entry(i, yaffs_Object, siblings);			yaffs_GetObjectName(l, name,					    YAFFS_MAX_NAME_LENGTH + 1);			T(YAFFS_TRACE_OS,			  ("yaffs_readdir: %s inode %d\n", name,			   yaffs_GetObjectInode(l)));			if (filldir(dirent,					name,					strlen(name),					offset,					yaffs_GetObjectInode(l),					yaffs_GetObjectType(l)) < 0)				goto up_and_out;			offset++;			f->f_pos++;		}	}up_and_out:out:	yaffs_GrossUnlock(dev);	return 0;}/* * File creation. Allocate an inode, and we're done.. */#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)#define YCRED(x) x#else#define YCRED(x) (x->cred)#endif#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,			dev_t rdev)#elsestatic int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,			int rdev)#endif{	struct inode *inode;	yaffs_Object *obj = NULL;	yaffs_Device *dev;	yaffs_Object *parent = yaffs_InodeToObject(dir);	int error = -ENOSPC;	uid_t uid = YCRED(current)->fsuid;	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;	if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))		mode |= S_ISGID;	if (parent) {		T(YAFFS_TRACE_OS,			("yaffs_mknod: parent object %d type %d\n",			parent->objectId, parent->variantType));	} else {		T(YAFFS_TRACE_OS,			("yaffs_mknod: could not get parent object\n"));		return -EPERM;	}	T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, "			"mode %x dev %x\n",			dentry->d_name.name, mode, rdev));	dev = parent->myDev;	yaffs_GrossLock(dev);	switch (mode & S_IFMT) {	default:		/* Special (socket, fifo, device...) */		T(YAFFS_TRACE_OS, ("yaffs_mknod: making special\n"));#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))		obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,				gid, old_encode_dev(rdev));#else		obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,				gid, rdev);#endif		break;	case S_IFREG:		/* file          */		T(YAFFS_TRACE_OS, ("yaffs_mknod: making file\n"));		obj = yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,				gid);		break;	case S_IFDIR:		/* directory */		T(YAFFS_TRACE_OS,			("yaffs_mknod: making directory\n"));		obj = yaffs_MknodDirectory(parent, dentry->d_name.name, mode,					uid, gid);		break;	case S_IFLNK:		/* symlink */		T(YAFFS_TRACE_OS, ("yaffs_mknod: making symlink\n"));		obj = NULL;	/* Do we ever get here? */		break;	}	/* Can not call yaffs_get_inode() with gross lock held */	yaffs_GrossUnlock(dev);	if (obj) {		inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);		d_instantiate(dentry, inode);		T(YAFFS_TRACE_OS,			("yaffs_mknod created object %d count = %d\n",			obj->objectId, atomic_read(&inode->i_count)));		error = 0;	} else {		T(YAFFS_TRACE_OS,			("yaffs_mknod failed making object\n"));		error = -ENOMEM;	}	return error;}static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode){	int retVal;	T(YAFFS_TRACE_OS, ("yaffs_mkdir\n"));	retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);	return retVal;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,			struct nameidata *n)#elsestatic int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)#endif{	T(YAFFS_TRACE_OS, ("yaffs_create\n"));	return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);}static int yaffs_unlink(struct inode *dir, struct dentry *dentry){	int retVal;	yaffs_Device *dev;	T(YAFFS_TRACE_OS,		("yaffs_unlink %d:%s\n", (int)(dir->i_ino),		dentry->d_name.name));	dev = yaffs_InodeToObject(dir)->myDev;	yaffs_GrossLock(dev);	retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name);	if (retVal == YAFFS_OK) {		dentry->d_inode->i_nlink--;		dir->i_version++;		yaffs_GrossUnlock(dev);		mark_inode_dirty(dentry->d_inode);		return 0;	}	yaffs_GrossUnlock(dev);	return -ENOTEMPTY;}/* * Create a link... */static int yaffs_link(struct dentry *old_dentry, struct inode *dir,			struct dentry *dentry){	struct inode *inode = old_dentry->d_inode;	yaffs_Object *obj = NULL;	yaffs_Object *link = NULL;	yaffs_Device *dev;	T(YAFFS_TRACE_OS, ("yaffs_link\n"));	obj = yaffs_InodeToObject(inode);	dev = obj->myDev;	yaffs_GrossLock(dev);	if (!S_ISDIR(inode->i_mode))		/* Don't link directories */		link = yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,			obj);	if (link) {		old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj);		d_instantiate(dentry, old_dentry->d_inode);		atomic_inc(&old_dentry->d_inode->i_count);		T(YAFFS_TRACE_OS,			("yaffs_link link count %d i_count %d\n",			old_dentry->d_inode->i_nlink,			atomic_read(&old_dentry->d_inode->i_count)));	}	yaffs_GrossUnlock(dev);	if (link)		return 0;	return -EPERM;}static int yaffs_symlink(struct inode *dir, struct dentry *dentry,				const char *symname){	yaffs_Object *obj;	yaffs_Device *dev;	uid_t uid = YCRED(current)->fsuid;	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;	T(YAFFS_TRACE_OS, ("yaffs_symlink\n"));	dev = yaffs_InodeToObject(dir)->myDev;	yaffs_GrossLock(dev);	obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name,				S_IFLNK | S_IRWXUGO, uid, gid, symname);	yaffs_GrossUnlock(dev);	if (obj) {		struct inode *inode;		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);		d_instantiate(dentry, inode);		T(YAFFS_TRACE_OS, ("symlink created OK\n"));		return 0;	} else {		T(YAFFS_TRACE_OS, ("symlink not created\n"));	}	return -ENOMEM;}static int yaffs_sync_object(struct file *file, struct dentry *dentry,				int datasync){	yaffs_Object *obj;	yaffs_Device *dev;	obj = yaffs_DentryToObject(dentry);	dev = obj->myDev;	T(YAFFS_TRACE_OS, ("yaffs_sync_object\n"));	yaffs_GrossLock(dev);	yaffs_FlushFile(obj, 1);	yaffs_GrossUnlock(dev);	return 0;}/* * The VFS layer already does all the dentry stuff for rename. * * NB: POSIX says you can rename an object over an old object of the same name */static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,			struct inode *new_dir, struct dentry *new_dentry){	yaffs_Device *dev;	int retVal = YAFFS_FAIL;	yaffs_Object *target;	T(YAFFS_TRACE_OS, ("yaffs_rename\n"));	dev = yaffs_InodeToObject(old_dir)->myDev;	yaffs_GrossLock(dev);	/* Check if the target is an existing directory that is not empty. */	target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),				new_dentry->d_name.name);	if (target && target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&		!ylist_empty(&target->variant.directoryVariant.children)) {		T(YAFFS_TRACE_OS, ("target is non-empty dir\n"));		retVal = YAFFS_FAIL;	} else {		/* Now does unlinking internally using shadowing mechanism */		T(YAFFS_TRACE_OS, ("calling yaffs_RenameObject\n"));		retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),				old_dentry->d_name.name,				yaffs_InodeToObject(new_dir),				new_dentry->d_name.name);	}	yaffs_GrossUnlock(dev);	if (retVal == YAFFS_OK) {		if (target) {			new_dentry->d_inode->i_nlink--;			mark_inode_dirty(new_dentry->d_inode);		}		return 0;	} else {		return -ENOTEMPTY;	}}static int yaffs_setattr(struct dentry *dentry, struct iattr *attr){	struct inode *inode = dentry->d_inode;	int error;	yaffs_Device *dev;	T(YAFFS_TRACE_OS,		("yaffs_setattr of object %d\n",		yaffs_InodeToObject(inode)->objectId));	error = inode_change_ok(inode, attr);	if (error == 0) {		dev = yaffs_InodeToObject(inode)->myDev;		yaffs_GrossLock(dev);		if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) ==				YAFFS_OK) {			error = 0;		} else {			error = -EPERM;		}		yaffs_GrossUnlock(dev);		if (!error)			error = inode_setattr(inode, attr);	}	return error;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf){	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;

⌨️ 快捷键说明

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