📄 inode1.c
字号:
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 + -