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

📄 inode1.c

📁 elinux jffs初始版本 具体了解JFFS的文件系统!
💻 C
📖 第 1 页 / 共 4 页
字号:
		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 int
jffs_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 int
jffs_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 int
jffs_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 int
jffs_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));

	*res_inode = 0;
	if (!dir) {
		dir = current->fs->root;
		dir->i_count++;
	}
	if (!inode) {
		iput(dir);
		return -ENOENT;
	}
	if (!S_ISLNK(inode->i_mode)) {
		*res_inode = inode;
		iput(dir);
		return 0;
	}
	if (current->link_count > 5) {
		iput(inode);
		iput(dir);
		return -ELOOP;
	}

	f = (struct jffs_file *)inode->u.generic_ip;
	if (!(link = (char *)kmalloc(f->size + 1, GFP_KERNEL))) {
		D(printk("jffs_follow_link(): kmalloc() failed.\n"));
		iput(inode);
		iput(dir);
		return -ENOMEM;
	}
	r = jffs_read_data(f, link, 0, f->size);
	if (r < f->size) {
		D(printk("jffs_follow_link(): Failed to read symname.\n"));
		kfree(link);
		iput(inode);
		iput(dir);
		return -EIO;
	}
	link[r] = '\0';
	UPDATE_ATIME(inode);
	current->link_count++;
	r = open_namei(link, flag, mode, res_inode, dir);
	current->link_count--;
	kfree(link);
	iput(inode);
	return r;
} /* jffs_follow_link()  */


/* 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;
	});

	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"));
		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) {

⌨️ 快捷键说明

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