diff options
Diffstat (limited to 'fs/squashfs/squashfs.c')
-rw-r--r-- | fs/squashfs/squashfs.c | 186 |
1 files changed, 26 insertions, 160 deletions
diff --git a/fs/squashfs/squashfs.c b/fs/squashfs/squashfs.c index cf7431ee04..d9049b7523 100644 --- a/fs/squashfs/squashfs.c +++ b/fs/squashfs/squashfs.c @@ -39,81 +39,7 @@ char *squashfs_devread(struct squashfs_sb_info *fs, int byte_offset, return buf; } -static struct inode *duplicate_inode(struct inode *inode) -{ - struct squashfs_inode_info *ei; - ei = malloc(sizeof(struct squashfs_inode_info)); - if (ei == NULL) { - ERROR("Error allocating memory for inode\n"); - return NULL; - } - memcpy(ei, squashfs_i(inode), - sizeof(struct squashfs_inode_info)); - - return &ei->vfs_inode; -} - -static struct inode *squashfs_findfile(struct super_block *sb, - const char *filename, char *buf) -{ - char *next; - char fpath[128]; - char *name = fpath; - struct inode *inode; - struct inode *t_inode = NULL; - - strcpy(fpath, filename); - - /* Remove all leading slashes */ - while (*name == '/') - name++; - - inode = duplicate_inode(sb->s_root->d_inode); - - /* - * Handle root-directory ('/') - */ - if (!name || *name == '\0') - return inode; - - for (;;) { - /* Extract the actual part from the pathname. */ - next = strchr(name, '/'); - if (next) { - /* Remove all leading slashes. */ - while (*next == '/') - *(next++) = '\0'; - } - - t_inode = squashfs_lookup(inode, name, 0); - if (t_inode == NULL) - break; - - /* - * Check if directory with this name exists - */ - - /* Found the node! */ - if (!next || *next == '\0') { - if (buf != NULL) - sprintf(buf, "%s", name); - - free(squashfs_i(inode)); - return t_inode; - } - - name = next; - - free(squashfs_i(inode)); - inode = t_inode; - } - - free(squashfs_i(inode)); - return NULL; -} - -static void squashfs_set_rootarg(struct squashfs_priv *priv, - struct fs_device_d *fsdev) +static void squashfs_set_rootarg(struct fs_device_d *fsdev) { struct ubi_volume_desc *ubi_vol; struct ubi_volume_info vi = {}; @@ -141,16 +67,27 @@ static void squashfs_set_rootarg(struct squashfs_priv *priv, free(str); } +static struct inode *squashfs_alloc_inode(struct super_block *sb) +{ + struct squashfs_inode_info *node; + + node = xzalloc(sizeof(*node)); + + return &node->vfs_inode; +} + +static const struct super_operations squashfs_super_ops = { + .alloc_inode = squashfs_alloc_inode, +}; + static int squashfs_probe(struct device_d *dev) { struct fs_device_d *fsdev; - struct squashfs_priv *priv; int ret; + struct super_block *sb; fsdev = dev_to_fs_device(dev); - - priv = xzalloc(sizeof(struct squashfs_priv)); - dev->priv = priv; + sb = &fsdev->sb; ret = fsdev_open_cdev(fsdev); if (ret) @@ -163,35 +100,34 @@ static int squashfs_probe(struct device_d *dev) goto err_out; } - squashfs_set_rootarg(priv, fsdev); + squashfs_set_rootarg(fsdev); + + sb->s_op = &squashfs_super_ops; return 0; err_out: - free(priv); return ret; } static void squashfs_remove(struct device_d *dev) { - struct squashfs_priv *priv = dev->priv; + struct fs_device_d *fsdev; + struct super_block *sb; + + fsdev = dev_to_fs_device(dev); + sb = &fsdev->sb; - squashfs_put_super(&priv->sb); - free(priv); + squashfs_put_super(sb); } static int squashfs_open(struct device_d *dev, FILE *file, const char *filename) { - struct squashfs_priv *priv = dev->priv; - struct inode *inode; + struct inode *inode = file->f_inode; struct squashfs_page *page; int i; - inode = squashfs_findfile(&priv->sb, filename, NULL); - if (!inode) - return -ENOENT; - page = malloc(sizeof(struct squashfs_page)); page->buf = calloc(32, sizeof(*page->buf)); for (i = 0; i < 32; i++) { @@ -229,7 +165,6 @@ static int squashfs_close(struct device_d *dev, FILE *f) free(page->buf[i]); free(page->buf); - free(squashfs_i(page->real_page.inode)); free(page); return 0; @@ -314,80 +249,11 @@ struct squashfs_dir { char root_d_name[256]; }; -static DIR *squashfs_opendir(struct device_d *dev, const char *pathname) -{ - struct squashfs_priv *priv = dev->priv; - struct inode *inode; - struct squashfs_dir *dir; - char buf[256]; - - inode = squashfs_findfile(&priv->sb, pathname, buf); - if (!inode) - return NULL; - - dir = xzalloc(sizeof(struct squashfs_dir)); - dir->dir.priv = dir; - - dir->root_dentry.d_inode = inode; - - sprintf(dir->d_name, "%s", buf); - sprintf(dir->root_d_name, "%s", buf); - - return &dir->dir; -} - -static struct dirent *squashfs_readdir(struct device_d *dev, DIR *_dir) -{ - struct squashfs_dir *dir = _dir->priv; - struct dentry *root_dentry = &dir->root_dentry; - - if (squashfs_lookup_next(root_dentry->d_inode, - dir->root_d_name, - dir->d_name)) - return NULL; - - strcpy(_dir->d.d_name, dir->d_name); - - return &_dir->d; -} - -static int squashfs_closedir(struct device_d *dev, DIR *_dir) -{ - struct squashfs_dir *dir = _dir->priv; - - free(squashfs_i(dir->root_dentry.d_inode)); - free(dir); - - return 0; -} - -static int squashfs_stat(struct device_d *dev, const char *filename, - struct stat *s) -{ - struct squashfs_priv *priv = dev->priv; - struct inode *inode; - - inode = squashfs_findfile(&priv->sb, filename, NULL); - if (!inode) - return -ENOENT; - - s->st_size = inode->i_size; - s->st_mode = inode->i_mode; - - free(squashfs_i(inode)); - - return 0; -} - static struct fs_driver_d squashfs_driver = { .open = squashfs_open, .close = squashfs_close, .read = squashfs_read, .lseek = squashfs_lseek, - .opendir = squashfs_opendir, - .readdir = squashfs_readdir, - .closedir = squashfs_closedir, - .stat = squashfs_stat, .type = filetype_squashfs, .drv = { .probe = squashfs_probe, |