0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/mm.h>
0009 #include <linux/mtd/super.h>
0010 #include "internal.h"
0011
0012
0013
0014
0015
0016
0017
0018 static unsigned long romfs_get_unmapped_area(struct file *file,
0019 unsigned long addr,
0020 unsigned long len,
0021 unsigned long pgoff,
0022 unsigned long flags)
0023 {
0024 struct inode *inode = file->f_mapping->host;
0025 struct mtd_info *mtd = inode->i_sb->s_mtd;
0026 unsigned long isize, offset, maxpages, lpages;
0027 int ret;
0028
0029 if (!mtd)
0030 return (unsigned long) -ENOSYS;
0031
0032
0033 lpages = (len + PAGE_SIZE - 1) >> PAGE_SHIFT;
0034 isize = i_size_read(inode);
0035 offset = pgoff << PAGE_SHIFT;
0036
0037 maxpages = (isize + PAGE_SIZE - 1) >> PAGE_SHIFT;
0038 if ((pgoff >= maxpages) || (maxpages - pgoff < lpages))
0039 return (unsigned long) -EINVAL;
0040
0041 if (addr != 0)
0042 return (unsigned long) -EINVAL;
0043
0044 if (len > mtd->size || pgoff >= (mtd->size >> PAGE_SHIFT))
0045 return (unsigned long) -EINVAL;
0046
0047 offset += ROMFS_I(inode)->i_dataoffset;
0048 if (offset >= mtd->size)
0049 return (unsigned long) -EINVAL;
0050
0051 if ((offset + len) > mtd->size)
0052 len = mtd->size - offset;
0053
0054 ret = mtd_get_unmapped_area(mtd, len, offset, flags);
0055 if (ret == -EOPNOTSUPP)
0056 ret = -ENOSYS;
0057 return (unsigned long) ret;
0058 }
0059
0060
0061
0062
0063
0064 static int romfs_mmap(struct file *file, struct vm_area_struct *vma)
0065 {
0066 return vma->vm_flags & (VM_SHARED | VM_MAYSHARE) ? 0 : -ENOSYS;
0067 }
0068
0069 static unsigned romfs_mmap_capabilities(struct file *file)
0070 {
0071 struct mtd_info *mtd = file_inode(file)->i_sb->s_mtd;
0072
0073 if (!mtd)
0074 return NOMMU_MAP_COPY;
0075 return mtd_mmap_capabilities(mtd);
0076 }
0077
0078 const struct file_operations romfs_ro_fops = {
0079 .llseek = generic_file_llseek,
0080 .read_iter = generic_file_read_iter,
0081 .splice_read = generic_file_splice_read,
0082 .mmap = romfs_mmap,
0083 .get_unmapped_area = romfs_get_unmapped_area,
0084 .mmap_capabilities = romfs_mmap_capabilities,
0085 };