📄 inode-v22.c
字号:
result = -EPERM; goto jffs_remove_end; } inode = dentry->d_inode; result = -EIO; if (del_f->ino != inode->i_ino) { D(printk("jffs_remove(): wrong inodes\n")); goto jffs_remove_end; } if (!inode->i_nlink) { printk("Deleting nonexistent file inode: %lu, nlink: %d\n", inode->i_ino, inode->i_nlink); inode->i_nlink=1; } /* Create a node for the deletion. */ result = -ENOMEM; if (!(del_node = jffs_alloc_node())) { D(printk("jffs_remove(): Allocation failed!\n")); goto jffs_remove_end; } del_node->data_offset = 0; del_node->removed_size = 0; /* Initialize the raw inode. */ raw_inode.magic = JFFS_MAGIC_BITMASK; raw_inode.ino = del_f->ino; raw_inode.pino = del_f->pino; /* raw_inode.version = del_f->highest_version + 1; */ raw_inode.mode = del_f->mode; raw_inode.uid = current->fsuid; raw_inode.gid = current->fsgid; raw_inode.atime = CURRENT_TIME; raw_inode.mtime = del_f->mtime; raw_inode.ctime = raw_inode.atime; raw_inode.offset = 0; raw_inode.dsize = 0; raw_inode.rsize = 0; raw_inode.nsize = 0; raw_inode.nlink = del_f->nlink; raw_inode.spare = 0; raw_inode.rename = 0; raw_inode.deleted = 1; /* Write the new node to the flash memory. */ if (jffs_write_node(c, del_node, &raw_inode, 0, 0, 1, del_f) < 0) { jffs_free_node(del_node); result = -EIO; 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_version = ++global_event; dir->i_ctime = dir->i_mtime = CURRENT_TIME; mark_inode_dirty(dir); inode->i_nlink--; inode->i_ctime = dir->i_ctime; mark_inode_dirty(inode); d_delete(dentry); /* This also frees the inode */ result = 0; jffs_remove_end: return result;} /* jffs_remove() */static intjffs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rdev){ struct jffs_raw_inode raw_inode; struct jffs_file *dir_f; struct jffs_node *node = 0; struct jffs_control *c; struct inode *inode; int result = 0; kdev_t dev = to_kdev_t(rdev); int err; D1(printk("***jffs_mknod()\n")); if (!dir->i_nlink) { D(printk("jffs_mknod(): dir->i_nlink is zero\n")); return -ENOENT; } dir_f = (struct jffs_file *)dir->u.generic_ip; c = dir_f->c; D3(printk (KERN_NOTICE "mknod(): down biglock\n")); down(&c->fmc->biglock); /* Create and initialize a new node. */ if (!(node = jffs_alloc_node())) { D(printk("jffs_mknod(): Allocation failed!\n")); result = -ENOMEM; goto jffs_mknod_err; } 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 = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; /* 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 = dentry->d_name.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 ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name, (unsigned char *)&dev, 0, NULL)) < 0) { D(printk("jffs_mknod(): jffs_write_node() failed.\n")); result = err; goto jffs_mknod_err; } /* Insert the new node into the file system. */ if ((err = jffs_insert_node(c, 0, &raw_inode, dentry->d_name.name, node)) < 0) { result = err; goto jffs_mknod_end; } inode = jffs_new_inode(dir, &raw_inode, &err); if (inode == NULL) { result = err; goto jffs_mknod_end; } inode->i_mode = mode; if (S_ISREG(mode)) inode->i_op = &jffs_file_inode_operations; if (S_ISCHR(mode)) { inode->i_op = &chrdev_inode_operations; inode->i_rdev = to_kdev_t(rdev); } else if (S_ISBLK(mode)) { inode->i_op = &blkdev_inode_operations; inode->i_rdev = to_kdev_t(rdev); } else if (S_ISFIFO(mode)) init_fifo(inode); else if (S_ISSOCK(mode)) ; else printk(KERN_DEBUG "jffs_mknod: bogus imode (%o)\n", mode); d_instantiate(dentry, inode); goto jffs_mknod_end; jffs_mknod_err: if (node) { jffs_free_node(node); } jffs_mknod_end: D3(printk (KERN_NOTICE "mknod(): up biglock\n")); up(&c->fmc->biglock); return result;} /* jffs_mknod() */static intjffs_symlink(struct inode *dir, struct dentry *dentry, const char *symname){ struct jffs_raw_inode raw_inode; struct jffs_control *c; struct jffs_file *dir_f; struct jffs_node *node; struct inode *inode; int symname_len = strlen(symname); int err; D1({ int len = dentry->d_name.len; char *_name = (char *)kmalloc(len + 1, GFP_KERNEL); char *_symname = (char *)kmalloc(symname_len + 1, GFP_KERNEL); memcpy(_name, dentry->d_name.name, len); _name[len] = '\0'; memcpy(_symname, symname, symname_len); _symname[symname_len] = '\0'; printk("***jffs_symlink(): dir = 0x%p, " "dentry->dname.name = \"%s\", " "symname = \"%s\"\n", dir, _name, _symname); kfree(_name); kfree(_symname); }); if (!dir->i_nlink) { D(printk("jffs_symlink(): dir->i_nlink is zero\n")); return -ENOENT; } 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"); return -EIO; }); c = dir_f->c; /* Create a node and initialize it as much as needed. */ if (!(node = jffs_alloc_node())) { D(printk("jffs_symlink(): Allocation failed: node = NULL\n")); return -ENOMEM; } D3(printk (KERN_NOTICE "symlink(): down biglock\n")); down(&c->fmc->biglock); 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 = (dir->i_mode & S_ISGID) ? dir->i_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 = dentry->d_name.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 ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name, (const unsigned char *)symname, 0, NULL)) < 0) { D(printk("jffs_symlink(): jffs_write_node() failed.\n")); jffs_free_node(node); goto jffs_symlink_end; } /* Insert the new node into the file system. */ if ((err = jffs_insert_node(c, 0, &raw_inode, dentry->d_name.name, node)) < 0) { goto jffs_symlink_end; } inode = jffs_new_inode(dir, &raw_inode, &err); if (inode == NULL) { goto jffs_symlink_end; } err = 0; inode->i_mode = S_IFLNK | S_IRWXUGO; inode->i_op = &jffs_symlink_inode_operations; d_instantiate(dentry, inode); jffs_symlink_end: D3(printk (KERN_NOTICE "symlink(): up biglock\n")); up(&c->fmc->biglock); return err;} /* jffs_symlink() *//* Shamelessly stolen from kernel 2.3.99-pre8 */static intvfs_readlink(struct dentry *dentry, char *buffer, int buflen, const char *link){ int len; len = PTR_ERR(link); if (IS_ERR(link)) goto out; len = strlen(link); if (len > (unsigned) buflen) len = buflen; if (copy_to_user(buffer, link, len)) len = -EFAULT; out: return len;}/* Read the path that a symbolic link is referring to. */static intjffs_readlink(struct dentry *dentry, char *buffer, int buflen){ struct jffs_file *f; struct inode *inode = dentry->d_inode; char *link; int result; struct jffs_control *c = (struct jffs_control *)inode->i_sb->u.generic_sbp; D(printk("***jffs_readlink()\n")); /* Continue only if the file is a symbolic link. */ if (!S_ISLNK(inode->i_mode)) { // iput(inode); return -EINVAL; } 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"); return -EIO; }); if (!(link = (char *)kmalloc(f->size + 1, GFP_KERNEL))) { return -ENOMEM; } D3(printk (KERN_NOTICE "readlink(): down biglock\n")); down(&c->fmc->biglock); result = jffs_read_data(f, link, 0, f->size); D3(printk (KERN_NOTICE "readlink(): up biglock\n")); up(&c->fmc->biglock); if (result < 0) { kfree(link); return result; } link[result] = '\0'; /* for (i = 0; (i < buflen) && (i < result); i++) { put_user(link[i], buffer++); } UPDATE_ATIME(inode);*/ result = vfs_readlink(dentry, buffer, buflen, link); kfree(link); D(printk("jffs_readlink: Leaving...\n")); return result;} /* jffs_readlink() */static struct dentry *jffs_follow_link(struct dentry *dentry, struct dentry *base, unsigned int flags){ struct jffs_file *f; struct inode *inode = dentry->d_inode; struct jffs_control *c = (struct jffs_control *)inode->i_sb->u.generic_sbp; struct dentry *res; char *link; int r; D(printk("jffs_follow_link(): " "dentry = 0x%p, inode = 0x%p, flag = 0x%08x\n", dentry, inode, flags)); f = (struct jffs_file *)inode->u.generic_ip; if (!(link = (char *)kmalloc(f->size + 1, GFP_KERNEL))) { return ERR_PTR(-ENOMEM); } D3(printk (KERN_NOTICE "follow_link(): down biglock\n")); down(&c->fmc->biglock); r = jffs_read_data(f, link, 0, f->size); D3(printk (KERN_NOTICE "follow_link(): up biglock\n")); up(&c->fmc->biglock); if (r < f->size) { D(printk("jffs_follow_link(): Failed to read symname.\n")); kfree(link); return ERR_PTR(-EIO); } link[r] = '\0'; UPDATE_ATIME(dentry->d_inode); if (IS_ERR(link)) { dput(base); res = (struct dentry *)link; } else { res = lookup_dentry(link, base, flags); } kfree(link); D(printk("jffs_follow_link: Leaving...\n")); return res;} /* jffs_follow_link() *//* Create an inode inside a JFFS directory (dir) and return it. * * By the time this is called, we already have created * the directory cache entry for the new file, but it * is so far negative - it has no inode. * * If the create succeeds, we fill in the inode information * with d_instantiate(). */static intjffs_create(struct inode *dir, struct dentry *dentry, int mode){ 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; int err; D1({ int len = dentry->d_name.len; char *s = (char *)kmalloc(len + 1, GFP_KERNEL); memcpy(s, dentry->d_name.name, len); s[len] = '\0'; printk("jffs_create(): dir: 0x%p, name: \"%s\"\n", dir, s); kfree(s); }); if (!dir->i_nlink) { D(printk("jffs_create(): dir->i_nlink is zero\n")); return -ENOENT; } 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"); return -EIO; }); c = dir_f->c; /* Create a node and initialize as much as needed. */ if (!(node = jffs_alloc_node())) { D(printk("jffs_create(): Allocation failed: node == 0\n")); return -ENOMEM; } D3(printk (KERN_NOTICE "create(): down biglock\n")); down(&c->fmc->biglock); 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 = (dir->i_mode & S_ISGID) ? dir->i_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 = dentry->d_name.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 ((err = jffs_write_node(c, node, &raw_inode, dentry->d_name.name, 0, 0, NULL)) < 0) { D(printk("jffs_create(): jffs_write_node() failed.\n")); jffs_free_node(node); goto jffs_create_end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -