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

📄 inode.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 3 页
字号:
			r = -ENOENT;		}	}	else {		D3(printk("jffs_lookup(): Couldn't find the file. "			  "f = 0x%p, name = \"%s\", d = 0x%p, d->ino = %u\n",			  f, name, d, d->ino));		r = -ENOENT;	}jffs_lookup_end:	iput(dir);	return r;} /* jffs_lookup()  *//* Try to read a page of data from a file.  */static intjffs_readpage(struct inode *inode, struct page *page){	unsigned long buf;	unsigned long read_len;	int result = -EIO;	struct jffs_file *f = (struct jffs_file *)inode->u.generic_ip;	int r;	D2(printk("***jffs_readpage(): file = \"%s\", page->offset = %lu\n",		  (f->name ? f->name : ""), page->offset));	page->count++;	set_bit(PG_locked, &page->flags);	buf = page_address(page);	clear_bit(PG_uptodate, &page->flags);	clear_bit(PG_error, &page->flags);	if (page->offset < inode->i_size) {		read_len = jffs_min(inode->i_size - page->offset, PAGE_SIZE);		r = jffs_read_data(f, (char *)buf, page->offset, read_len);		if (r == read_len) {			if (read_len < PAGE_SIZE) {				memset((void *)(buf + read_len), 0,				       PAGE_SIZE - read_len);			}			set_bit(PG_uptodate, &page->flags);			result = 0;		}		D(else {			printk("***jffs_readpage(): Read error! "			       "Wanted to read %lu bytes but only "			       "read %d bytes.\n", read_len, r);		});	}	if (result) {		set_bit(PG_error, &page->flags);		memset((void *)buf, 0, PAGE_SIZE);	}	clear_bit(PG_locked, &page->flags);	wake_up(&page->wait);	free_page(buf);	D3(printk("jffs_readpage(): Leaving...\n"));	return result;} /* jffs_readpage()  *//* Create a new directory.  */static intjffs_mkdir(struct inode *dir, const char *name, int len, int mode){	struct jffs_raw_inode raw_inode;	struct jffs_control *c;	struct jffs_node *node;	struct jffs_file *dir_f;	int dir_mode;	int result = 0;	D1({		char *_name = (char *) kmalloc(len + 1, GFP_KERNEL);		memcpy(_name, name, len);		_name[len] = '\0';		printk("***jffs_mkdir(): dir = 0x%p, name = \"%s\", "		       "len = %d, mode = 0x%08x\n", dir, _name, len, mode);		kfree(_name);	});	if (!dir) {		return -ENOENT;	}	if (len > JFFS_MAX_NAME_LEN) {		result = -ENAMETOOLONG;		goto jffs_mkdir_end;	}	dir_f = (struct jffs_file *)dir->u.generic_ip;	ASSERT(if (!dir_f) {		printk(KERN_ERR "jffs_mkdir(): No reference to a "		       "jffs_file struct in inode.\n");		result = -1;		goto jffs_mkdir_end;	});	c = dir_f->c;	if (!JFFS_ENOUGH_SPACE(c->fmc)) {		D1(printk("jffs_mkdir(): 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"));		result = -ENOSPC;		goto jffs_mkdir_end;	}	/* 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_mkdir(): There already exists a file or "			 "directory with the same name!\n"));		result = -EEXIST;		goto jffs_mkdir_end;	}	dir_mode = S_IFDIR | (mode & (S_IRWXUGO|S_ISVTX)			      & ~current->fs->umask);	if (dir->i_mode & S_ISGID) {                dir_mode |= S_ISGID;	}	/* Create a node and initialize it as much as needed.  */	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),						  GFP_KERNEL))) {		D(printk("jffs_mkdir(): Allocation failed: node == 0\n"));		result = -ENOMEM;		goto jffs_mkdir_end;	}	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 = dir_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_mkdir(): jffs_write_node() failed.\n"));		kfree(node);		DJM(no_jffs_node--);		result = -1;		goto jffs_mkdir_end;	}	/* Insert the new node into the file system.  */	result = jffs_insert_node(c, 0, &raw_inode, name, node);jffs_mkdir_end:	iput(dir);	return result;} /* jffs_mkdir()  *//* Remove a directory.  */static intjffs_rmdir(struct inode *dir, const char *name, int len){	D3(printk("***jffs_rmdir()\n"));	return jffs_remove(dir, name, len, S_IFDIR, 1);}/* Remove any kind of file except for directories.  */static intjffs_unlink(struct inode *dir, const char *name, int len){	D3(printk("***jffs_unlink()\n"));	return jffs_remove(dir, name, len, 0, 1);}/* Remove a JFFS entry, i.e. plain files, directories, etc.  Here we   shouldn't test for free space on the device.  */static intjffs_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;	/* Initialize the raw inode.  */	raw_inode.magic = JFFS_MAGIC_BITMASK;	raw_inode.ino = del_f->ino;	raw_inode.pino = del_f->pino;	raw_inode.version = del_f->highest_version + 1;	raw_inode.mode = del_f->mode;	raw_inode.uid = current->fsuid;	raw_inode.gid = current->fsgid;	raw_inode.atime = CURRENT_TIME;	raw_inode.mtime = del_f->mtime;	raw_inode.ctime = raw_inode.atime;	raw_inode.offset = 0;	raw_inode.dsize = 0;	raw_inode.rsize = 0;	raw_inode.nsize = 0;	raw_inode.nlink = del_f->nlink;	raw_inode.spare = 0;	raw_inode.rename = 0;	raw_inode.deleted = 1;	/* Write the new node to the flash memory.  */	if (jffs_write_node(c, del_node, &raw_inode, 0, 0) < 0) {		kfree(del_node);		DJM(no_jffs_node--);		result = -1;		goto jffs_remove_end;	}	/* Update the file.  This operation will make the file disappear	   from the in-memory file system structures.  */	jffs_insert_node(c, del_f, &raw_inode, 0, del_node);	dir->i_ctime = dir->i_mtime = CURRENT_TIME;        dir->i_dirt = 1;	inode->i_nlink = inode->i_nlink ? inode->i_nlink - 1 : 0;	if (inode->i_nlink == 0) {		inode->u.generic_ip = 0;	}	inode->i_dirt = 1;	inode->i_ctime = dir->i_ctime;jffs_remove_end:	if (must_iput) {		iput(dir);	}	if (inode) {		iput(inode);	}	return result;} /* jffs_remove()  */static intjffs_mknod(struct inode *dir, const char *name, int len, int mode, int rdev){	struct jffs_raw_inode raw_inode;	struct jffs_file *dir_f;	struct jffs_node *node = 0;	struct jffs_control *c;	int result = 0;	kdev_t dev = to_kdev_t(rdev);	D1(printk("***jffs_mknod()\n"));	if (!dir) {		return -ENOENT;	}	if (len > JFFS_MAX_NAME_LEN) {		result = -ENAMETOOLONG;		goto jffs_mknod_end;	}	dir_f = (struct jffs_file *)dir->u.generic_ip;	c = dir_f->c;	if (!JFFS_ENOUGH_SPACE(c->fmc)) {		D1(printk("jffs_mknod(): 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"));		result = -ENOSPC;		goto jffs_mknod_end;	}	/* Check and see if the file exists already.  */	if (jffs_find_child(dir_f, name, len)) {		D(printk("jffs_mknod(): There already exists a file or "			 "directory with the same name!\n"));		result = -EEXIST;		goto jffs_mknod_end;	}	/* Create and initialize a new node.  */	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),						  GFP_KERNEL))) {		D(printk("jffs_mknod(): Allocation failed!\n"));		result = -ENOMEM;		goto jffs_mknod_err;	}	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 = sizeof(kdev_t);	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,			    (unsigned char *)&dev) < 0) {		D(printk("jffs_mknod(): jffs_write_node() failed.\n"));		result = -1;		goto jffs_mknod_err;	}	/* Insert the new node into the file system.  */	if (jffs_insert_node(c, 0, &raw_inode, name, node) < 0) {		result = -1;		goto jffs_mknod_end;	}	goto jffs_mknod_end;jffs_mknod_err:	if (node) {		kfree(node);		DJM(no_jffs_node--);	}jffs_mknod_end:	iput(dir);	return result;} /* jffs_mknod()  */static intjffs_symlink(struct inode *dir, const char *name, int len, const char *symname){	struct jffs_raw_inode raw_inode;	struct jffs_control *c;	struct jffs_file *dir_f;	struct jffs_node *node;	int symname_len = strlen(symname);	D1({		char *_name = (char *)kmalloc(len + 1, GFP_KERNEL);		char *_symname = (char *)kmalloc(symname_len + 1, GFP_KERNEL);		memcpy(_name, name, len);		_name[len] = '\0';		memcpy(_symname, symname, symname_len);		_symname[symname_len] = '\0';		printk("***jffs_symlink(): dir = 0x%p, name = \"%s\", "		       "symname = \"%s\"\n", dir, _name, _symname);		kfree(_name);		kfree(_symname);	});	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_symlink(): No reference to a "		       "jffs_file struct in inode.\n");		iput(dir);		return -1;	});	c = dir_f->c;	if (!JFFS_ENOUGH_SPACE(c->fmc)) {		D1(printk("jffs_symlink(): 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"));		iput(dir);		return -ENOSPC;	}	/* Check so there isn't an already existing file with the	   specified name.  */	if (jffs_find_child(dir_f, name, len)) {		iput(dir);		return -EEXIST;	}	/* Create a node and initialize it as much as needed.  */	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),						  GFP_KERNEL))) {		D(printk("jffs_symlink(): Allocation failed: node == NULL\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 = S_IFLNK | S_IRWXUGO;	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 = symname_len;	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,			    (const unsigned char *)symname) < 0) {		D(printk("jffs_symlink(): 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;	}	iput(dir);	return 0;} /* jffs_symlink()  *//* Read the path that a symbolic link is referring to.  */static intjffs_readlink(struct inode *inode, char *buffer, int buflen){	struct jffs_file *f;	int i;	char *link;	int result;	D2(printk("***jffs_readlink()\n"));	/* Continue only if the file is a symbolic link.  */	if (!S_ISLNK(inode->i_mode)) {		result = -EINVAL;		goto jffs_readlink_end1;	}	f = (struct jffs_file *)inode->u.generic_ip;	ASSERT(if (!f) {		printk(KERN_ERR "jffs_readlink(): No reference to a "		       "jffs_file struct in inode.\n");		result = -1;		goto jffs_readlink_end1;	});	if (!(link = (char *)kmalloc(f->size + 1, GFP_KERNEL))) {		result = -ENOMEM;		goto jffs_readlink_end1;	}	if ((result = jffs_read_data(f, link, 0, f->size)) < 0) {		goto jffs_readlink_end2;	}	link[result] = '\0';	for (i = 0; (i < buflen) && (i < result); i++) {		put_user(link[i], buffer++);	}	UPDATE_ATIME(inode);jffs_readlink_end2:	kfree(link);jffs_readlink_end1:	iput(inode);	return result;} /* jffs_readlink()  */static intjffs_follow_link(struct inode *dir, struct inode *inode, int flag,                 int mode, struct inode **res_inode){	struct jffs_file *f;	char *link;	int r;	D3(printk("jffs_follow_link(): dir = 0x%p, "		  "inode = 0x%p, flag = 0x%08x, mode = 0x%08x\n",		  dir, inode, flag, mode));

⌨️ 快捷键说明

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