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

📄 inode1.c

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


/* Write, append or rewrite data to an existing file.  */
static int
jffs_file_write(struct inode *inode, struct file *filp,
                const char *buf, int count)
{
	struct jffs_raw_inode raw_inode;
	struct jffs_control *c;
	struct jffs_file *f;
	struct jffs_node *node;
	int written = 0;
	int pos;

	D2(printk("***jffs_file_write(): inode: 0x%p (ino: %lu), "
		  "filp: 0x%p, buf: 0x%p, count: %d\n",
		  inode, inode->i_ino, filp, buf, count));

	if (!inode) {
		D(printk("jffs_file_write(): inode == NULL\n"));
		return -EINVAL;
	}

	if (inode->i_sb->s_flags & MS_RDONLY) {
		D(printk("jffs_file_write(): MS_RDONLY\n"));
		return -ENOSPC;
	}
	if (!S_ISREG(inode->i_mode)) {
		D(printk("jffs_file_write(): inode->i_mode == 0x%08x\n",
			 inode->i_mode));
		return -EINVAL;
	}

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

	if (!JFFS_ENOUGH_SPACE(c->fmc)) {
		D1(printk("jffs_file_write(): 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"));
		return -ENOSPC;
	}

	if (filp->f_flags & O_APPEND) {
		pos = inode->i_size;
	}
	else {
		pos = filp->f_pos;
	}

	/* Things are going to be written so we could allocate and
	   initialize the necessary data structures now.  */
	if (!(node = (struct jffs_node *) kmalloc(sizeof(struct jffs_node),
						  GFP_KERNEL))) {
		D(printk("jffs_file_write(): node == 0\n"));
		return -ENOMEM;
	}
	DJM(no_jffs_node++);
	node->data_offset = f->size;
	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 = f->size;
	raw_inode.dsize = count;
	raw_inode.rsize = 0;
	raw_inode.nsize = 0;
	raw_inode.nlink = f->nlink;
	raw_inode.spare = 0;
	raw_inode.rename = 0;
	raw_inode.deleted = 0;

	/* Write the new node to the flash.  */
	if ((written = jffs_write_node(c, node, &raw_inode, 0,
				       (const unsigned char *)buf)) < 0) {
		D(printk("jffs_file_write(): jffs_write_node() failed.\n"));
		kfree(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;
	}
	pos += written;
	filp->f_pos = pos;

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

	/* Fix things in the real inode.  */
	if (pos > inode->i_size) {
		inode->i_size = pos;
	}
	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
	inode->i_dirt = 1;

	return written;
} /* jffs_file_write()  */


/* This is our ioctl() routine.  */
static int
jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
	   unsigned long arg)
{
	struct jffs_control *c;
	int err;

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

	if (!(c = (struct jffs_control *)inode->i_sb->u.generic_sbp)) {
		printk(KERN_ERR "JFFS: Bad inode in ioctl() call. "
		       "(cmd = 0x%08x)\n", cmd);
		return -1;
	}

	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:
		{
			struct jffs_flash_status fst;
			struct jffs_fmcontrol *fmc = c->fmc;
			printk("Flash status -- ");
			err = verify_area(VERIFY_WRITE,
					  (struct jffs_flash_status *)arg,
					  sizeof(struct jffs_flash_status));
			if (err) {
				D(printk("jffs_ioctl(): Bad arg in "
					 "JFFS_GET_STATUS ioctl!\n"));
				return err;
			}
			fst.size = fmc->flash_size;
			fst.used = fmc->used_size;
			fst.dirty = fmc->dirty_size;
			fst.begin = fmc->head->offset;
			fst.end = fmc->tail->offset + fmc->tail->size;
			printk("size: %d, used: %d, dirty: %d, "
			       "begin: %d, end: %d\n",
			       fst.size, fst.used, fst.dirty,
			       fst.begin, fst.end);
			memcpy_tofs((struct jffs_flash_status *)arg, &fst,
				    sizeof(struct jffs_flash_status));
		}
		break;
	default:
		return -ENOTTY;
	}

	return 0;
} /* jffs_ioctl()  */


static struct file_operations jffs_file_operations =
{
	NULL,                 /* lseek - default */
	generic_file_read,    /* read */
	jffs_file_write,      /* write */
	NULL,                 /* readdir */
	NULL,                 /* select - default */
	jffs_ioctl,           /* ioctl */
	generic_file_mmap,    /* mmap */
	NULL,                 /* open */
	NULL,                 /* release */
	NULL,                 /* fsync */
	NULL,                 /* fasync */
	NULL,                 /* check_media_change */
	NULL                  /* revalidate */
};

static struct inode_operations jffs_file_inode_operations =
{
	&jffs_file_operations,
	NULL,                 /* create */
	jffs_lookup,          /* lookup */
	NULL,                 /* link */
	NULL,                 /* unlink */
	NULL,                 /* symlink */
	NULL,                 /* mkdir */
	NULL,                 /* rmdir */
	NULL,                 /* mknod */
	NULL,                 /* rename */
	NULL,                 /* readlink */
	NULL,                 /* follow_link */
	jffs_readpage,        /* readpage */
	NULL,                 /* writepage */
	NULL,                 /* bmap -- not really */
	NULL,                 /* truncate */
	NULL,                 /* permission */
	NULL                  /* smap */
};


static struct file_operations jffs_dir_operations =
{
	NULL,                 /* lseek - default */
	NULL,                 /* read */
	NULL,                 /* write */
	jffs_readdir,         /* readdir */
	NULL,                 /* select - default */
	NULL,                 /* ioctl */
	NULL,                 /* mmap */
	NULL,                 /* open */
	NULL,                 /* release */
	NULL,                 /* fsync */
	NULL,                 /* fasync */
	NULL,                 /* check_media_change */
	NULL                  /* revalidate */
};

static struct inode_operations jffs_dir_inode_operations =
{
	&jffs_dir_operations,
	jffs_create,           /* create */
	jffs_lookup,           /* lookup */
	NULL,                  /* link */
	jffs_unlink,           /* unlink */
	jffs_symlink,          /* symlink */
	jffs_mkdir,            /* mkdir */
	jffs_rmdir,            /* rmdir */
	jffs_mknod,            /* mknod */
	jffs_rename,           /* rename */
	NULL,                  /* readlink */
	NULL,                  /* follow_link */
	NULL,                  /* readpage */
	NULL,                  /* writepage */
	NULL,                  /* bmap */
	NULL,                  /* truncate */
	NULL,                  /* permission */
	NULL                   /* smap */
};


static struct inode_operations jffs_symlink_inode_operations =
{
	NULL,                  /* No file operations.  */
	NULL,                  /* create */
	NULL,                  /* lookup */
	NULL,                  /* link */
	NULL,                  /* unlink */
	NULL,                  /* symlink */
	NULL,                  /* mkdir */
	NULL,                  /* rmdir */
	NULL,                  /* mknod */
	NULL,                  /* rename */
	jffs_readlink,         /* readlink */
	jffs_follow_link,      /* follow_link */
	NULL,                  /* readpage */
	NULL,                  /* writepage */
	NULL,                  /* bmap */
	NULL,                  /* truncate */
	NULL,                  /* permission */
	NULL                   /* smap */
};


/* Initialize an inode for the VFS.  */
static void
jffs_read_inode(struct inode *inode)
{
	struct jffs_file *f;
	struct jffs_control *c;

	D3(printk("jffs_read_inode(): inode->i_ino == %lu\n", inode->i_ino));

	if (!inode->i_sb) {
		D(printk("jffs_read_inode(): !inode->i_sb ==> "
			 "No super block!\n"));
		return;
	}
	c = (struct jffs_control *)inode->i_sb->u.generic_sbp;
	if (!(f = jffs_find_file(c, inode->i_ino))) {
		D(printk("jffs_read_inode(): No such inode (%lu).\n",
			 inode->i_ino));
		return;
	}
	inode->u.generic_ip = (void *)f;
	inode->i_mode = f->mode;
	inode->i_nlink = f->nlink;
	inode->i_uid = f->uid;
	inode->i_gid = f->gid;
	inode->i_size = f->size;
	inode->i_atime = f->atime;
	inode->i_mtime = f->mtime;
	inode->i_ctime = f->ctime;
	inode->i_blksize = PAGE_SIZE;
	inode->i_blocks = 0;
	if (S_ISREG(inode->i_mode)) {
		inode->i_op = &jffs_file_inode_operations;
	}
	else if (S_ISDIR(inode->i_mode)) {
		inode->i_op = &jffs_dir_inode_operations;
	}
	else if (S_ISLNK(inode->i_mode)) {
                inode->i_op = &jffs_symlink_inode_operations;
	}
	else if (S_ISCHR(inode->i_mode)) {
		inode->i_op = &chrdev_inode_operations;
	}
	else if (S_ISBLK(inode->i_mode)) {
		inode->i_op = &blkdev_inode_operations;
	}

	/* If the node is a device of some sort, then the number of the
	   device should be read from the flash memory and then added
	   to the inode's i_rdev member.  */
	if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) {
		kdev_t rdev;
		jffs_read_data(f, (char *)&rdev, 0, sizeof(kdev_t));
		inode->i_rdev = kdev_t_to_nr(rdev);
	}
}


void
jffs_write_super(struct super_block *sb)
{
#ifdef USE_GC
	jffs_garbage_collect((struct jffs_control *)sb->u.generic_sbp);
#endif
}


static struct super_operations jffs_ops =
{
	jffs_read_inode,    /* read inode */
	jffs_notify_change, /* notify change */
	NULL,               /* write inode */
	NULL,               /* put inode */
	jffs_put_super,     /* put super */
	jffs_write_super,   /* write super */
	jffs_statfs,        /* statfs */
	NULL                /* remount */
};


static struct file_system_type jffs_fs_type =
{
	jffs_read_super,
	"jffs",
	1,
	NULL
};


int
init_jffs_fs(void)
{
	printk("JFFS "
#if defined(JFFS_FLASH_SHORTCUT) && JFFS_FLASH_SHORTCUT
	       "(Flash Shortcut) "
#endif
	       "version " JFFS_VERSION_STRING
	       ", (C) 1999, 2000  Axis Communications AB\n");
	return register_filesystem(&jffs_fs_type);
}


#ifdef MODULE
int
init_module(void)
{
	int status;

	if ((status = init_jffs_fs()) == 0) {
		register_symtab(0);
	}
	return status;
}

void
cleanup_module(void)
{
	unregister_filesystem(&jffs_fs_type);
}
#endif

⌨️ 快捷键说明

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