📄 j_inode.cpp
字号:
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 + -