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

📄 j_inode.cpp

📁 JFFS的源代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
						  GFP_KERNEL))) {
		D(printk("jffs_file_write(): node == 0\n"));
		return -ENOMEM;
	}*/
	if ( !(node = (struct jffs_node *) malloc(sizeof(struct jffs_node))) ) {
		D(printk("jffs_file_write(): node == 0\n"));
		return -ENOMEM;
	}

	DJM(no_jffs_node++);
	node->data_offset = pos;
	node->removed_size = 0; 

	/* Initialize the raw inode.  */
	raw_inode.magic = JFFS_MAGIC_BITMASK;
	raw_inode.ino = f->ino;
	raw_inode.pino = f->pino;
	raw_inode.version = f->highest_version + 1;
	raw_inode.mode = f->mode;
	/*raw_inode.uid = current->fsuid;
	raw_inode.gid = current->fsgid;*/
	raw_inode.atime = CURRENT_TIME;
	raw_inode.mtime = raw_inode.atime;
	raw_inode.ctime = f->ctime;
	raw_inode.offset = pos;
	raw_inode.dsize = 0;
	raw_inode.rsize = count;
	raw_inode.nsize = f->nsize;
	raw_inode.nlink = f->nlink;
	raw_inode.spare = 0;
	raw_inode.rename = 0;
	raw_inode.deleted = 0;

	if (pos < f->size) {
		raw_inode.rsize = jffs_min(f->size-pos, count);
		node->removed_size = raw_inode.rsize;
	}
	else {
		printf("jffs_file_trunc(): pos < f->size\n");
		return -EINVAL;
	}	

	/* Write the new node to the flash. ??? */ 
	if ((written = jffs_write_node(c, node, &raw_inode, f->name, 0)) < 0) {
		D(printk("jffs_file_write(): jffs_write_node() failed.\n"));
		free(node);
		DJM(no_jffs_node--);
		return -1;
	}

	/* Insert the new node into the file system.  */
	if (jffs_insert_node(c, f, &raw_inode, 0, node) < 0) {
		return -1;
	}

	D3(printk("jffs_file_write(): new f_pos %d.\n", pos));

	inode->i_dirt = 1;

	/* simonk: fixes the O_APPEND bug, but forces a buffer flush.
	   Should probably use update_vm_cache() instead.  */
	/*invalidate_inode_pages(inode);*/

	return written;
} /* jffs_file_write()  */

static int jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct jffs_file *f;
	int err;
	struct stat *pstat;


	D2(printk("***jffs_ioctl(): cmd = 0x%08x, arg = 0x%08lx\n",
		  cmd, arg));

	if (!(f = (struct jffs_file *)inode->u.generic_ip)) {
		D(printk("jffs_ioctl(): inode->u.generic_ip = 0x%p\n",
			 inode->u.generic_ip));
		return -EINVAL;
	}

	switch (cmd) {
	case JFFS_PRINT_HASH:
		/*jffs_print_hash_table(c);*/
		break;
	case JFFS_PRINT_TREE:
		/*jffs_print_tree(c->root, 0);*/
		break;
	case JFFS_GET_STATUS:
		pstat = (struct stat *)arg;
		pstat->st_mode = f->mode;
		pstat->st_size = f->size;
		break;
	case JFFS_GET_SIZE:
		*(int *)arg = f->size;
		break;
	case JFFS_FILE_TRUNC:
		jffs_file_trunc(inode, filp, arg);
		break;
	case JFFS_FS_INFO:
		if(f != NULL)
		printf("Flash使用情况: 使用=%d,脏区=%d,空闲=%d\n",
		    f->c->fmc->used_size,f->c->fmc->dirty_size,
		    f->c->fmc->flash_size - f->c->fmc->used_size - f->c->fmc->dirty_size); 

		printf("内存使用情况: no_jffs_node=%d,no_jffs_fm=%d\n",
			no_jffs_node, no_jffs_fm);
		break;
	default:
		return -ENOTTY;
	}

	return 0;
}



/* Read the contents of a directory.  Used by programs like `ls'
   for instance.  */
/*!!!   */
static int jffs_readdir(struct inode *dir, struct file *filp, void *dirent, filldir_t filldir)
{
	struct jffs_file *f;
	int j;
	int ddino;
	//int filp_f_pos = 0;		/*代替filp->f_pos*/

	D2(printk("jffs_readdir(): dir: 0x%p, filp: 0x%p\n", dir, filp));

	if (!dir || !S_ISDIR(dir->i_mode)) {
		D(printk("jffs_readdir(): 'dir' is NULL or not a dir!\n"));
		return -EBADF;
	}

	f = ((struct jffs_file *)dir->u.generic_ip)->children;

	if(filp->f_pos < 2) filp->f_pos = 2;
	switch (filp->f_pos)
	{
	case 0:
		D3(printk("jffs_readdir(): \".\" %lu\n", dir->i_ino));
		if (filldir(dirent, ".", 1, filp->f_pos, dir->i_ino) < 0) {
			return 0;
		}
		filp->f_pos = 1;
		break;
	case 1:
		/*if (dir->i_ino == JFFS_MIN_INO) {
			ddino = dir->i_sb->s_covered->i_ino;
		}
		else {
			ddino = ((struct jffs_file *)dir->u.generic_ip)->pino;
		}
		D3(printk("jffs_readdir(): \"..\" %u\n", ddino));
		if (filldir(dirent, "..", 2, filp->f_pos, ddino) < 0)
			return 0;*/

		/*if(f != NULL)
		printf("Flash使用情况: 使用=%d,脏区=%d,空闲=%d\n",
		    f->c->fmc->used_size,f->c->fmc->dirty_size,
		    f->c->fmc->flash_size - f->c->fmc->used_size - f->c->fmc->dirty_size); 

		printf("内存使用情况: no_jffs_node=%d,no_jffs_fm=%d\n",
			no_jffs_node, no_jffs_fm);
		
	   	printf("文件名\t\t大小\n");
		
		filp->f_pos++;*/
		break;
	default:
		f = ((struct jffs_file *)dir->u.generic_ip)->children;
		for (j = 2; (j < filp->f_pos) && f; j++) {
			f = f->sibling_next;
		}
		if (f) {
			if (filldir(dirent, f->name, f->nsize,
				    filp->f_pos , f->ino) < 0)
				return 0;
			filp->f_pos++;
		}
		else return 0;
#if 0
		for (; f ; f = f->sibling_next) {
			D3(printk("jffs_readdir(): \"%s\" ino: %u\n",
				  (f->name ? f->name : ""), f->ino));
			/*if (filldir(dirent, f->name, f->nsize,
				    filp_f_pos , f->ino) < 0)
				return 0;*/
			//test
			/*if(f->name)			
				printf("%s, %d\n", f->name, f->size);
			else
				printf("%d\n", f->size);*/
			
			filp->f_pos++;
		}
#endif		
	}
	return filp->f_pos;
} /* jffs_readdir()  */


/* Create an inode inside a JFFS directory (dir) and return it.  */
static int jffs_create(struct inode *dir, const char *name, int len,
            int mode, struct inode **result)
{
	struct jffs_raw_inode raw_inode;
	struct jffs_control *c;
	struct jffs_node *node;
	struct jffs_file *dir_f; /* JFFS representation of the directory.  */
	struct inode *inode;

	*result = (struct inode *)0;

	D1({
		char *s = (char *)kmalloc(len + 1, GFP_KERNEL);
		memcpy(s, name, len);
		s[len] = '\0';
		printk("jffs_create(): dir: 0x%p, name: \"%s\"\n", dir, s);
		kfree(s);
	});

	if (!dir) {
		return -ENOENT;
	}
	if (len > JFFS_MAX_NAME_LEN) {
		iput(dir);
		return -ENAMETOOLONG;
	}

	dir_f = (struct jffs_file *)dir->u.generic_ip;	/*?????*/
	/*ASSERT(if (!dir_f) {
		printk(KERN_ERR "jffs_create(): No reference to a "
		       "jffs_file struct in inode.\n");
		iput(dir);
		return -1;
	});*/
	if (!dir_f) {
		iput(dir);
		return -1;
	}

	c = dir_f->c;

	if (!JFFS_ENOUGH_SPACE(c->fmc)) {
		D1(printk("jffs_create(): Free size = %u\n",
			  jffs_free_size1(c->fmc) + jffs_free_size2(c->fmc)));
		//D(printk(KERN_NOTICE "JFFS: No space left on device\n"));
		D(printk("jffs_create: No space left on device\n"));
		iput(dir);
		return -ENOSPC;
	}

	/* If there already exists a file or directory with the same name,
	   then this operation should fail. I originally thought that VFS
	   should take care of this issue.  */
	if (jffs_find_child(dir_f, name, len)) {
		D(printk("jffs_create(): There already exists a file or "
			 "directory named \"%s\"!\n", name));
		iput(dir);
		return -EEXIST;
	}

	/* Create a node and initialize as much as needed.  */
	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
						  GFP_KERNEL))) {
		D(printk("jffs_create(): Allocation failed: node == 0\n"));
		iput(dir);
		return -ENOMEM;
	}
	DJM(no_jffs_node++);
	node->data_offset = 0;
	node->removed_size = 0;

	/* Initialize the raw inode.  */
	raw_inode.magic = JFFS_MAGIC_BITMASK;
	raw_inode.ino = c->next_ino++;
	raw_inode.pino = dir_f->ino;
	raw_inode.version = 1;
	raw_inode.mode = mode;
	/*raw_inode.uid = current->fsuid;
	raw_inode.gid = current->fsgid;*/
	raw_inode.atime = CURRENT_TIME;		/*?????*/
	raw_inode.mtime = raw_inode.atime;
	raw_inode.ctime = raw_inode.atime;
	raw_inode.offset = 0;
	raw_inode.dsize = 0;
	raw_inode.rsize = 0;
	raw_inode.nsize = len;
	raw_inode.nlink = 1;
	raw_inode.spare = 0;
	raw_inode.rename = 0;
	raw_inode.deleted = 0;

	/* Write the new node to the flash.  */
	if (jffs_write_node(c, node, &raw_inode, name, 0) < 0) {
		D(printk("jffs_create(): jffs_write_node() failed.\n"));
		kfree(node);
		DJM(no_jffs_node--);
		iput(dir);
		return -1;
	}

	/* Insert the new node into the file system.  */
	if (jffs_insert_node(c, 0, &raw_inode, name, node) < 0) {
		iput(dir);
		return -1;
	}

	/* Initialize an inode.  */
	if (!(inode = get_empty_inode())) {
		iput(dir);
		return -1;
	}
	inode->i_dev = dir->i_sb->s_dev;
	inode->i_ino = raw_inode.ino;
	inode->i_mode = mode;
	inode->i_nlink = raw_inode.nlink;
	inode->i_uid = raw_inode.uid;
	inode->i_gid = raw_inode.gid;
	inode->i_rdev = 0;
	inode->i_size = 0;
	inode->i_atime = raw_inode.atime;
	inode->i_mtime = raw_inode.mtime;
	inode->i_ctime = raw_inode.ctime;
	/*?????inode->i_blksize = PAGE_SIZE;  This is the optimal IO size (for
					 stat), not the fs block size.  */
	inode->i_blocks = 0;
	inode->i_version = 0;
	inode->i_nrpages = 0;
	/*inode->i_sem = 0;*/
	inode->i_op = &jffs_file_inode_operations;
	inode->i_sb = dir->i_sb;
	/*inode->i_wait = 0;
	inode->i_flock = 0;*/
	inode->i_count = 1;
	inode->i_flags = dir->i_sb->s_flags;
	inode->i_dirt = 1;
	inode->u.generic_ip = (void *)jffs_find_file(c, raw_inode.ino);

	iput(dir);
	*result = inode;
	return 0;
} /* jffs_create()  */

static int jffs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev)
{
	/*TODO: ???jffs_mknod与jffs_create的区别*/
	return 0;	
}

/* Remove a JFFS entry, i.e. plain files, directories, etc.  Here we
   shouldn't test for free space on the device.  */
static int
jffs_remove(struct inode *dir, const char *name, int len, int type,
	    int must_iput)
{
	struct jffs_raw_inode raw_inode;
	struct jffs_control *c;
	struct jffs_file *dir_f; /* The file-to-remove's parent.  */
	struct jffs_file *del_f; /* The file to remove.  */
	struct jffs_node *del_node;
	struct inode *inode = 0;
	int result = 0;

	D1({
		char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);
		memcpy(_name, name, len);
		_name[len] = '\0';
		printk("***jffs_remove(): file = \"%s\"\n", _name);
		kfree(_name);
	});

	if (!dir) {
		return -ENOENT;
	}
	if (len > JFFS_MAX_NAME_LEN) {
		result = -ENAMETOOLONG;
		goto jffs_remove_end;
	}

	dir_f = (struct jffs_file *) dir->u.generic_ip;
	c = dir_f->c;

	if (!(del_f = jffs_find_child(dir_f, name, len))) {
		//D(printk("jffs_remove(): jffs_find_child() failed.\n"));
		result = -ENOENT;
		goto jffs_remove_end;
	}

	if (S_ISDIR(type)) {
		if (!S_ISDIR(del_f->mode)) {
			result = -ENOTDIR;
			goto jffs_remove_end;
		}
		if (del_f->children) {
			result = -ENOTEMPTY;
			goto jffs_remove_end;
		}
        }
	else if (S_ISDIR(del_f->mode)) {
		D(printk("jffs_remove(): node is a directory "
			 "but it shouldn't be.\n"));
		result = -EPERM;
		goto jffs_remove_end;
	}

	/*if (!(inode = iget(dir->i_sb, del_f->ino))) {
		printk(KERN_ERR "JFFS: Unlink failed.\n");
		result = -ENOENT;
		goto jffs_remove_end;
	}*/

	/* Create a node for the deletion.  */
	if (!(del_node = (struct jffs_node *)
			 kmalloc(sizeof(struct jffs_node), GFP_KERNEL))) {
		D(printk("jffs_remove(): Allocation failed!\n"));
		result = -ENOMEM;
		goto jffs_remove_end;
	}
	DJM(no_jffs_node++);
	del_node->data_offset = 0;
	del_node->removed_size = 0;

⌨️ 快捷键说明

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