linux/fs/cramfs/inode.c

/*
 * Compressed rom filesystem for Linux.
 *
 * Copyright (C) 1999 Linus Torvalds.
 *
 * This file is released under the GPL.
 */

/*
 * These are the VFS interfaces to the compressed rom filesystem.
 * The actual compression is based on zlib, see the other files.
 */

#define pr_fmt(fmt)

#include <linux/module.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/pagemap.h>
#include <linux/pfn_t.h>
#include <linux/ramfs.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/blkdev.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/super.h>
#include <linux/fs_context.h>
#include <linux/slab.h>
#include <linux/vfs.h>
#include <linux/mutex.h>
#include <uapi/linux/cramfs_fs.h>
#include <linux/uaccess.h>

#include "internal.h"

/*
 * cramfs super-block data in memory
 */
struct cramfs_sb_info {};

static inline struct cramfs_sb_info *CRAMFS_SB(struct super_block *sb)
{}

static const struct super_operations cramfs_ops;
static const struct inode_operations cramfs_dir_inode_operations;
static const struct file_operations cramfs_directory_operations;
static const struct file_operations cramfs_physmem_fops;
static const struct address_space_operations cramfs_aops;

static DEFINE_MUTEX(read_mutex);


/* These macros may change in future, to provide better st_ino semantics. */
#define OFFSET(x)

static unsigned long cramino(const struct cramfs_inode *cino, unsigned int offset)
{}

static struct inode *get_cramfs_inode(struct super_block *sb,
	const struct cramfs_inode *cramfs_inode, unsigned int offset)
{}

/*
 * We have our own block cache: don't fill up the buffer cache
 * with the rom-image, because the way the filesystem is set
 * up the accesses should be fairly regular and cached in the
 * page cache and dentry tree anyway..
 *
 * This also acts as a way to guarantee contiguous areas of up to
 * BLKS_PER_BUF*PAGE_SIZE, so that the caller doesn't need to
 * worry about end-of-buffer issues even when decompressing a full
 * page cache.
 *
 * Note: This is all optimized away at compile time when
 *       CONFIG_CRAMFS_BLOCKDEV=n.
 */
#define READ_BUFFERS
/* NEXT_BUFFER(): Loop over [0..(READ_BUFFERS-1)]. */
#define NEXT_BUFFER(_ix)

/*
 * BLKS_PER_BUF_SHIFT should be at least 2 to allow for "compressed"
 * data that takes up more space than the original and with unlucky
 * alignment.
 */
#define BLKS_PER_BUF_SHIFT
#define BLKS_PER_BUF
#define BUFFER_SIZE

static unsigned char read_buffers[READ_BUFFERS][BUFFER_SIZE];
static unsigned buffer_blocknr[READ_BUFFERS];
static struct super_block *buffer_dev[READ_BUFFERS];
static int next_buffer;

/*
 * Populate our block cache and return a pointer to it.
 */
static void *cramfs_blkdev_read(struct super_block *sb, unsigned int offset,
				unsigned int len)
{}

/*
 * Return a pointer to the linearly addressed cramfs image in memory.
 */
static void *cramfs_direct_read(struct super_block *sb, unsigned int offset,
				unsigned int len)
{}

/*
 * Returns a pointer to a buffer containing at least LEN bytes of
 * filesystem starting at byte offset OFFSET into the filesystem.
 */
static void *cramfs_read(struct super_block *sb, unsigned int offset,
			 unsigned int len)
{}

/*
 * For a mapping to be possible, we need a range of uncompressed and
 * contiguous blocks. Return the offset for the first block and number of
 * valid blocks for which that is true, or zero otherwise.
 */
static u32 cramfs_get_block_range(struct inode *inode, u32 pgoff, u32 *pages)
{}

#ifdef CONFIG_MMU

/*
 * Return true if the last page of a file in the filesystem image contains
 * some other data that doesn't belong to that file. It is assumed that the
 * last block is CRAMFS_BLK_FLAG_DIRECT_PTR | CRAMFS_BLK_FLAG_UNCOMPRESSED
 * (verified by cramfs_get_block_range() and directly accessible in memory.
 */
static bool cramfs_last_page_is_shared(struct inode *inode)
{}

static int cramfs_physmem_mmap(struct file *file, struct vm_area_struct *vma)
{}

#else /* CONFIG_MMU */

static int cramfs_physmem_mmap(struct file *file, struct vm_area_struct *vma)
{
	return is_nommu_shared_mapping(vma->vm_flags) ? 0 : -ENOSYS;
}

static unsigned long cramfs_physmem_get_unmapped_area(struct file *file,
			unsigned long addr, unsigned long len,
			unsigned long pgoff, unsigned long flags)
{
	struct inode *inode = file_inode(file);
	struct super_block *sb = inode->i_sb;
	struct cramfs_sb_info *sbi = CRAMFS_SB(sb);
	unsigned int pages, block_pages, max_pages, offset;

	pages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
	max_pages = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
	if (pgoff >= max_pages || pages > max_pages - pgoff)
		return -EINVAL;
	block_pages = pages;
	offset = cramfs_get_block_range(inode, pgoff, &block_pages);
	if (!offset || block_pages != pages)
		return -ENOSYS;
	addr = sbi->linear_phys_addr + offset;
	pr_debug("get_unmapped for %pD ofs %#lx siz %lu at 0x%08lx\n",
		 file, pgoff*PAGE_SIZE, len, addr);
	return addr;
}

static unsigned int cramfs_physmem_mmap_capabilities(struct file *file)
{
	return NOMMU_MAP_COPY | NOMMU_MAP_DIRECT |
	       NOMMU_MAP_READ | NOMMU_MAP_EXEC;
}

#endif /* CONFIG_MMU */

static const struct file_operations cramfs_physmem_fops =;

static void cramfs_kill_sb(struct super_block *sb)
{}

static int cramfs_reconfigure(struct fs_context *fc)
{}

static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
			     struct cramfs_super *super)
{}

static int cramfs_finalize_super(struct super_block *sb,
				 struct cramfs_inode *cramfs_root)
{}

static int cramfs_blkdev_fill_super(struct super_block *sb, struct fs_context *fc)
{}

static int cramfs_mtd_fill_super(struct super_block *sb, struct fs_context *fc)
{}

static int cramfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{}

/*
 * Read a cramfs directory entry.
 */
static int cramfs_readdir(struct file *file, struct dir_context *ctx)
{}

/*
 * Lookup and fill in the inode data..
 */
static struct dentry *cramfs_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{}

static int cramfs_read_folio(struct file *file, struct folio *folio)
{}

static const struct address_space_operations cramfs_aops =;

/*
 * Our operations:
 */

/*
 * A directory can only readdir
 */
static const struct file_operations cramfs_directory_operations =;

static const struct inode_operations cramfs_dir_inode_operations =;

static const struct super_operations cramfs_ops =;

static int cramfs_get_tree(struct fs_context *fc)
{}

static const struct fs_context_operations cramfs_context_ops =;

/*
 * Set up the filesystem mount context.
 */
static int cramfs_init_fs_context(struct fs_context *fc)
{}

static struct file_system_type cramfs_fs_type =;
MODULE_ALIAS_FS();

static int __init init_cramfs_fs(void)
{}

static void __exit exit_cramfs_fs(void)
{}

module_init()
module_exit()
MODULE_DESCRIPTION();
MODULE_LICENSE();