ARM64: dts: rk3328-evb: add support for internal codec sound
[firefly-linux-kernel-4.4.55.git] / fs / cramfs / inode.c
index c0148585670d29968cace0dd342f05a7feb6660e..355c522f3585a5e3a7667225681383ff85b93a48 100644 (file)
  * The actual compression is based on zlib, see the other files.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/pagemap.h>
 #include <linux/init.h>
 #include <linux/string.h>
 #include <linux/blkdev.h>
-#include <linux/cramfs_fs.h>
 #include <linux/slab.h>
-#include <linux/cramfs_fs_sb.h>
 #include <linux/vfs.h>
 #include <linux/mutex.h>
+#include <uapi/linux/cramfs_fs.h>
+#include <linux/uaccess.h>
+
+#include "internal.h"
 
-#include <asm/uaccess.h>
+/*
+ * cramfs super-block data in memory
+ */
+struct cramfs_sb_info {
+       unsigned long magic;
+       unsigned long size;
+       unsigned long blocks;
+       unsigned long files;
+       unsigned long flags;
+};
+
+static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb)
+{
+       return sb->s_fs_info;
+}
 
 static const struct super_operations cramfs_ops;
 static const struct inode_operations cramfs_dir_inode_operations;
@@ -137,7 +155,7 @@ static struct inode *get_cramfs_inode(struct super_block *sb,
 
 static unsigned char read_buffers[READ_BUFFERS][BUFFER_SIZE];
 static unsigned buffer_blocknr[READ_BUFFERS];
-static struct super_block * buffer_dev[READ_BUFFERS];
+static struct super_block *buffer_dev[READ_BUFFERS];
 static int next_buffer;
 
 /*
@@ -179,8 +197,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
                struct page *page = NULL;
 
                if (blocknr + i < devsize) {
-                       page = read_mapping_page_async(mapping, blocknr + i,
-                                                                       NULL);
+                       page = read_mapping_page(mapping, blocknr + i, NULL);
                        /* synchronous error? */
                        if (IS_ERR(page))
                                page = NULL;
@@ -190,6 +207,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
 
        for (i = 0; i < BLKS_PER_BUF; i++) {
                struct page *page = pages[i];
+
                if (page) {
                        wait_on_page_locked(page);
                        if (!PageUptodate(page)) {
@@ -208,6 +226,7 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
        data = read_buffers[buffer];
        for (i = 0; i < BLKS_PER_BUF; i++) {
                struct page *page = pages[i];
+
                if (page) {
                        memcpy(data, kmap(page), PAGE_CACHE_SIZE);
                        kunmap(page);
@@ -219,10 +238,12 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
        return read_buffers[buffer] + offset;
 }
 
-static void cramfs_put_super(struct super_block *sb)
+static void cramfs_kill_sb(struct super_block *sb)
 {
-       kfree(sb->s_fs_info);
-       sb->s_fs_info = NULL;
+       struct cramfs_sb_info *sbi = CRAMFS_SB(sb);
+
+       kill_block_super(sb);
+       kfree(sbi);
 }
 
 static int cramfs_remount(struct super_block *sb, int *flags, char *data)
@@ -261,8 +282,8 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
                /* check for wrong endianness */
                if (super.magic == CRAMFS_MAGIC_WEND) {
                        if (!silent)
-                               printk(KERN_ERR "cramfs: wrong endianness\n");
-                       goto out;
+                               pr_err("wrong endianness\n");
+                       return -EINVAL;
                }
 
                /* check at 512 byte offset */
@@ -271,62 +292,58 @@ static int cramfs_fill_super(struct super_block *sb, void *data, int silent)
                mutex_unlock(&read_mutex);
                if (super.magic != CRAMFS_MAGIC) {
                        if (super.magic == CRAMFS_MAGIC_WEND && !silent)
-                               printk(KERN_ERR "cramfs: wrong endianness\n");
+                               pr_err("wrong endianness\n");
                        else if (!silent)
-                               printk(KERN_ERR "cramfs: wrong magic\n");
-                       goto out;
+                               pr_err("wrong magic\n");
+                       return -EINVAL;
                }
        }
 
        /* get feature flags first */
        if (super.flags & ~CRAMFS_SUPPORTED_FLAGS) {
-               printk(KERN_ERR "cramfs: unsupported filesystem features\n");
-               goto out;
+               pr_err("unsupported filesystem features\n");
+               return -EINVAL;
        }
 
        /* Check that the root inode is in a sane state */
        if (!S_ISDIR(super.root.mode)) {
-               printk(KERN_ERR "cramfs: root is not a directory\n");
-               goto out;
+               pr_err("root is not a directory\n");
+               return -EINVAL;
        }
        /* correct strange, hard-coded permissions of mkcramfs */
        super.root.mode |= (S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
 
        root_offset = super.root.offset << 2;
        if (super.flags & CRAMFS_FLAG_FSID_VERSION_2) {
-               sbi->size=super.size;
-               sbi->blocks=super.fsid.blocks;
-               sbi->files=super.fsid.files;
+               sbi->size = super.size;
+               sbi->blocks = super.fsid.blocks;
+               sbi->files = super.fsid.files;
        } else {
-               sbi->size=1<<28;
-               sbi->blocks=0;
-               sbi->files=0;
+               sbi->size = 1<<28;
+               sbi->blocks = 0;
+               sbi->files = 0;
        }
-       sbi->magic=super.magic;
-       sbi->flags=super.flags;
+       sbi->magic = super.magic;
+       sbi->flags = super.flags;
        if (root_offset == 0)
-               printk(KERN_INFO "cramfs: empty filesystem");
+               pr_info("empty filesystem");
        else if (!(super.flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
                 ((root_offset != sizeof(struct cramfs_super)) &&
                  (root_offset != 512 + sizeof(struct cramfs_super))))
        {
-               printk(KERN_ERR "cramfs: bad root offset %lu\n", root_offset);
-               goto out;
+               pr_err("bad root offset %lu\n", root_offset);
+               return -EINVAL;
        }
 
        /* Set it all up.. */
        sb->s_op = &cramfs_ops;
        root = get_cramfs_inode(sb, &super.root, 0);
        if (IS_ERR(root))
-               goto out;
+               return PTR_ERR(root);
        sb->s_root = d_make_root(root);
        if (!sb->s_root)
-               goto out;
+               return -ENOMEM;
        return 0;
-out:
-       kfree(sbi);
-       sb->s_fs_info = NULL;
-       return -EINVAL;
 }
 
 static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -350,18 +367,17 @@ static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 /*
  * Read a cramfs directory entry.
  */
-static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
+static int cramfs_readdir(struct file *file, struct dir_context *ctx)
 {
-       struct inode *inode = file_inode(filp);
+       struct inode *inode = file_inode(file);
        struct super_block *sb = inode->i_sb;
        char *buf;
        unsigned int offset;
-       int copied;
 
        /* Offset within the thing. */
-       offset = filp->f_pos;
-       if (offset >= inode->i_size)
+       if (ctx->pos >= inode->i_size)
                return 0;
+       offset = ctx->pos;
        /* Directory entries are always 4-byte aligned */
        if (offset & 3)
                return -EINVAL;
@@ -370,14 +386,13 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
        if (!buf)
                return -ENOMEM;
 
-       copied = 0;
        while (offset < inode->i_size) {
                struct cramfs_inode *de;
                unsigned long nextoffset;
                char *name;
                ino_t ino;
                umode_t mode;
-               int namelen, error;
+               int namelen;
 
                mutex_lock(&read_mutex);
                de = cramfs_read(sb, OFFSET(inode) + offset, sizeof(*de)+CRAMFS_MAXPATHLEN);
@@ -403,13 +418,10 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
                                break;
                        namelen--;
                }
-               error = filldir(dirent, buf, namelen, offset, ino, mode >> 12);
-               if (error)
+               if (!dir_emit(ctx, buf, namelen, ino, mode >> 12))
                        break;
 
-               offset = nextoffset;
-               filp->f_pos = offset;
-               copied++;
+               ctx->pos = offset = nextoffset;
        }
        kfree(buf);
        return 0;
@@ -418,7 +430,7 @@ static int cramfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 /*
  * Lookup and fill in the inode data..
  */
-static struct dentry * cramfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
+static struct dentry *cramfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
 {
        unsigned int offset = 0;
        struct inode *inode = NULL;
@@ -476,7 +488,7 @@ out:
        return NULL;
 }
 
-static int cramfs_readpage(struct file *file, struct page * page)
+static int cramfs_readpage(struct file *file, struct page *page)
 {
        struct inode *inode = page->mapping->host;
        u32 maxblock;
@@ -504,7 +516,7 @@ static int cramfs_readpage(struct file *file, struct page * page)
                if (compr_len == 0)
                        ; /* hole */
                else if (unlikely(compr_len > (PAGE_CACHE_SIZE << 1))) {
-                       pr_err("cramfs: bad compressed blocksize %u\n",
+                       pr_err("bad compressed blocksize %u\n",
                                compr_len);
                        goto err;
                } else {
@@ -548,7 +560,7 @@ static const struct address_space_operations cramfs_aops = {
 static const struct file_operations cramfs_directory_operations = {
        .llseek         = generic_file_llseek,
        .read           = generic_read_dir,
-       .readdir        = cramfs_readdir,
+       .iterate        = cramfs_readdir,
 };
 
 static const struct inode_operations cramfs_dir_inode_operations = {
@@ -556,7 +568,6 @@ static const struct inode_operations cramfs_dir_inode_operations = {
 };
 
 static const struct super_operations cramfs_ops = {
-       .put_super      = cramfs_put_super,
        .remount_fs     = cramfs_remount,
        .statfs         = cramfs_statfs,
 };
@@ -571,7 +582,7 @@ static struct file_system_type cramfs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "cramfs",
        .mount          = cramfs_mount,
-       .kill_sb        = kill_block_super,
+       .kill_sb        = cramfs_kill_sb,
        .fs_flags       = FS_REQUIRES_DEV,
 };
 MODULE_ALIAS_FS("cramfs");