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