#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"
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);
#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)
{ … }
#define READ_BUFFERS …
#define NEXT_BUFFER(_ix) …
#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;
static void *cramfs_blkdev_read(struct super_block *sb, unsigned int offset,
unsigned int len)
{ … }
static void *cramfs_direct_read(struct super_block *sb, unsigned int offset,
unsigned int len)
{ … }
static void *cramfs_read(struct super_block *sb, unsigned int offset,
unsigned int len)
{ … }
static u32 cramfs_get_block_range(struct inode *inode, u32 pgoff, u32 *pages)
{ … }
#ifdef CONFIG_MMU
static bool cramfs_last_page_is_shared(struct inode *inode)
{ … }
static int cramfs_physmem_mmap(struct file *file, struct vm_area_struct *vma)
{ … }
#else
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
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)
{ … }
static int cramfs_readdir(struct file *file, struct dir_context *ctx)
{ … }
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 = …;
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 = …;
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(…) …;