summaryrefslogtreecommitdiffstats
path: root/fs/squashfs/squashfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/squashfs/squashfs.c')
-rw-r--r--fs/squashfs/squashfs.c186
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,