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

📄 yaffs_fs.c

📁 yaffs2 source code for linux2.4/2.6. include the utile
💻 C
📖 第 1 页 / 共 5 页
字号:
{	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,		  (KERN_DEBUG "yaffs_file_write: hey obj is null!\n"));	} else {		T(YAFFS_TRACE_OS,		  (KERN_DEBUG		   "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,	  (KERN_DEBUG "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,			  (KERN_DEBUG			   "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,		  (KERN_DEBUG "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,		  (KERN_DEBUG "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,			  (KERN_DEBUG "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,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 = current->fsuid;	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;	if((dir->i_mode & S_ISGID) && S_ISDIR(mode))		mode |= S_ISGID;	if (parent) {		T(YAFFS_TRACE_OS,		  (KERN_DEBUG "yaffs_mknod: parent object %d type %d\n",		   parent->objectId, parent->variantType));	} else {		T(YAFFS_TRACE_OS,		  (KERN_DEBUG "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, (KERN_DEBUG				   "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, (KERN_DEBUG "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,		  (KERN_DEBUG "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, (KERN_DEBUG "yaffs_mknod: making file\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,		  (KERN_DEBUG "yaffs_mknod created object %d count = %d\n",		   obj->objectId, atomic_read(&inode->i_count)));		error = 0;	} else {		T(YAFFS_TRACE_OS,		  (KERN_DEBUG "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, (KERN_DEBUG "yaffs_mkdir\n"));	retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);#if 0	/* attempt to fix dir bug - didn't work */	if (!retVal) {		dget(dentry);	}#endif	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, (KERN_DEBUG "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,	  (KERN_DEBUG "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, (KERN_DEBUG "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,		  (KERN_DEBUG "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 = current->fsuid;	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;	T(YAFFS_TRACE_OS, (KERN_DEBUG "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, (KERN_DEBUG "symlink created OK\n"));		return 0;	} else {		T(YAFFS_TRACE_OS, (KERN_DEBUG "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, (KERN_DEBUG "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, (KERN_DEBUG "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, (KERN_DEBUG "target is non-empty dir\n"));		retVal = YAFFS_FAIL;	} else {		/* Now does unlinking internally using shadowing mechanism */	        T(YAFFS_TRACE_OS, (KERN_DEBUG "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,	  (KERN_DEBUG "yaffs_setattr of object %d\n",	   yaffs_InodeToObject(inode)->objectId));	if ((error = inode_change_ok(inode, attr)) == 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;}

⌨️ 快捷键说明

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