4 * Written by Jacques Gelinas (jacques@solucorp.qc.ca)
5 * Inspired by fs/nfs/mmap.c (Jon Tombs 15 Aug 1993)
7 * mmap handling for fat-based filesystems
10 #define ASC_LINUX_VERSION(V, P, S) (((V) * 65536) + ((P) * 256) + (S))
11 #include <linux/version.h>
13 #include <linux/stat.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
17 #include <linux/shm.h>
18 #include <linux/errno.h>
19 #include <linux/mman.h>
20 #include <linux/string.h>
21 #include <linux/malloc.h>
22 #include <linux/msdos_fs.h>
24 #include <asm/uaccess.h>
25 #include <asm/system.h>
28 * Fill in the supplied page for mmap
30 static unsigned long fat_file_mmap_nopage(
31 struct vm_area_struct
* area
,
32 unsigned long address
,
35 struct inode
* inode
= area
->vm_file
->f_dentry
->d_inode
;
39 long gap
; /* distance from eof to pos */
41 page
= __get_free_page(GFP_KERNEL
);
45 pos
= address
- area
->vm_start
+ area
->vm_offset
;
48 gap
= inode
->i_size
- pos
;
50 /* mmaping beyond end of file */
57 clear
= PAGE_SIZE
- gap
;
61 filp
.f_dentry
=area
->vm_file
->f_dentry
;
62 need_read
= PAGE_SIZE
- clear
;
64 mm_segment_t cur_fs
= get_fs();
66 cur_read
= fat_file_read (&filp
, (char*)page
,
67 need_read
, &filp
.f_pos
);
70 if (cur_read
!= need_read
){
71 printk ("MSDOS: Error while reading an mmap file %d <> %d\n"
76 memset ((char*)page
+PAGE_SIZE
-clear
,0,clear
);
81 struct vm_operations_struct fat_file_mmap
= {
88 fat_file_mmap_nopage
, /* nopage */
95 * This is used for a general mmap of an msdos file
96 * Returns 0 if ok, or a negative error code if not.
98 int fat_mmap(struct file
* file
, struct vm_area_struct
* vma
)
100 struct inode
*inode
= file
->f_dentry
->d_inode
;
101 if (MSDOS_SB(inode
->i_sb
)->cvf_format
&&
102 MSDOS_SB(inode
->i_sb
)->cvf_format
->cvf_mmap
)
103 return MSDOS_SB(inode
->i_sb
)->cvf_format
->cvf_mmap(file
,vma
);
105 if (vma
->vm_flags
& VM_SHARED
) /* only PAGE_COW or read-only supported now */
107 if (vma
->vm_offset
& (inode
->i_sb
->s_blocksize
- 1))
109 if (!inode
->i_sb
|| !S_ISREG(inode
->i_mode
))
111 if (!IS_RDONLY(inode
)) {
112 inode
->i_atime
= CURRENT_TIME
;
113 mark_inode_dirty(inode
);
116 vma
->vm_ops
= &fat_file_mmap
;
121 int fat_readpage(struct file
*file
, struct page
* page
)
123 struct dentry
* dentry
= file
->f_dentry
;
124 struct inode
* inode
= dentry
->d_inode
;
125 if (MSDOS_SB(inode
->i_sb
)->cvf_format
&&
126 MSDOS_SB(inode
->i_sb
)->cvf_format
->cvf_readpage
)
127 return MSDOS_SB(inode
->i_sb
)->cvf_format
->cvf_readpage(inode
,page
);
129 printk("fat_readpage called with no handler (shouldn't happen)\n");