This source file includes following definitions.
- invalidate_inode_pages
- truncate_inode_pages
- shrink_mmap
- page_unuse
- update_vm_cache
- try_to_read_ahead
- __wait_on_page
- generic_file_read
- fill_page
- filemap_nopage
- filemap_write_page
- filemap_swapout
- filemap_swapin
- filemap_sync_pte
- filemap_sync_pte_range
- filemap_sync_pmd_range
- filemap_sync
- filemap_unmap
- generic_file_mmap
- msync_interval
- sys_msync
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/stat.h>
13 #include <linux/sched.h>
14 #include <linux/kernel.h>
15 #include <linux/mm.h>
16 #include <linux/shm.h>
17 #include <linux/errno.h>
18 #include <linux/mman.h>
19 #include <linux/string.h>
20 #include <linux/malloc.h>
21 #include <linux/fs.h>
22 #include <linux/locks.h>
23 #include <linux/pagemap.h>
24 #include <linux/swap.h>
25
26 #include <asm/segment.h>
27 #include <asm/system.h>
28 #include <asm/pgtable.h>
29
30
31
32
33
34
35
36
37 unsigned long page_cache_size = 0;
38 struct page * page_hash_table[PAGE_HASH_SIZE];
39
40
41
42
43
44
45
46
47
48
49 void invalidate_inode_pages(struct inode * inode)
50 {
51 struct page ** p;
52 struct page * page;
53
54 p = &inode->i_pages;
55 while ((page = *p) != NULL) {
56 if (page->locked) {
57 p = &page->next;
58 continue;
59 }
60 inode->i_nrpages--;
61 if ((*p = page->next) != NULL)
62 (*p)->prev = page->prev;
63 page->dirty = 0;
64 page->next = NULL;
65 page->prev = NULL;
66 remove_page_from_hash_queue(page);
67 page->inode = NULL;
68 free_page(page_address(page));
69 continue;
70 }
71 }
72
73
74
75
76
77 void truncate_inode_pages(struct inode * inode, unsigned long start)
78 {
79 struct page ** p;
80 struct page * page;
81
82 repeat:
83 p = &inode->i_pages;
84 while ((page = *p) != NULL) {
85 unsigned long offset = page->offset;
86
87
88 if (offset >= start) {
89 if (page->locked) {
90 wait_on_page(page);
91 goto repeat;
92 }
93 inode->i_nrpages--;
94 if ((*p = page->next) != NULL)
95 (*p)->prev = page->prev;
96 page->dirty = 0;
97 page->next = NULL;
98 page->prev = NULL;
99 remove_page_from_hash_queue(page);
100 page->inode = NULL;
101 free_page(page_address(page));
102 continue;
103 }
104 p = &page->next;
105 offset = start - offset;
106
107 if (offset < PAGE_SIZE)
108 memset((void *) (offset + page_address(page)), 0, PAGE_SIZE - offset);
109 }
110 }
111
112 int shrink_mmap(int priority, unsigned long limit)
113 {
114 static int clock = 0;
115 struct page * page;
116 struct buffer_head *tmp, *bh;
117
118 if (limit > high_memory)
119 limit = high_memory;
120 limit = MAP_NR(limit);
121 if (clock >= limit)
122 clock = 0;
123 priority = (limit<<2) >> priority;
124 page = mem_map + clock;
125 while (priority-- > 0) {
126 if (page->locked)
127 goto next;
128
129
130 bh = buffer_pages[MAP_NR(page_address(page))];
131 if (bh) {
132 tmp = bh;
133 do {
134 if (buffer_touched(tmp)) {
135 clear_bit(BH_Touched, &tmp->b_state);
136 page->referenced = 1;
137 }
138 tmp = tmp->b_this_page;
139 } while (tmp != bh);
140 }
141
142
143
144
145
146
147 if (page->count > 1)
148 page->referenced = 1;
149 else if (page->referenced)
150 page->referenced = 0;
151 else if (page->count) {
152
153
154 if (page->inode) {
155 remove_page_from_hash_queue(page);
156 remove_page_from_inode_queue(page);
157 free_page(page_address(page));
158 return 1;
159 }
160 if (bh && try_to_free_buffer(bh, &bh, 6))
161 return 1;
162 }
163 next:
164 page++;
165 clock++;
166 if (clock >= limit) {
167 clock = 0;
168 page = mem_map;
169 }
170 }
171 return 0;
172 }
173
174
175
176
177
178
179
180 unsigned long page_unuse(unsigned long page)
181 {
182 struct page * p = mem_map + MAP_NR(page);
183 int count = p->count;
184
185 if (count != 2)
186 return count;
187 if (!p->inode)
188 return count;
189 remove_page_from_hash_queue(p);
190 remove_page_from_inode_queue(p);
191 free_page(page);
192 return 1;
193 }
194
195
196
197
198
199 void update_vm_cache(struct inode * inode, unsigned long pos, const char * buf, int count)
200 {
201 unsigned long offset, len;
202
203 offset = (pos & ~PAGE_MASK);
204 pos = pos & PAGE_MASK;
205 len = PAGE_SIZE - offset;
206 do {
207 struct page * page;
208
209 if (len > count)
210 len = count;
211 page = find_page(inode, pos);
212 if (page) {
213 unsigned long addr;
214
215 wait_on_page(page);
216 addr = page_address(page);
217 memcpy((void *) (offset + addr), buf, len);
218 free_page(addr);
219 }
220 count -= len;
221 buf += len;
222 len = PAGE_SIZE;
223 offset = 0;
224 pos += PAGE_SIZE;
225 } while (count);
226 }
227
228
229
230
231
232
233 static unsigned long try_to_read_ahead(struct inode * inode, unsigned long offset, unsigned long page_cache)
234 {
235 struct page * page;
236
237 offset &= PAGE_MASK;
238 if (!page_cache) {
239 page_cache = __get_free_page(GFP_KERNEL);
240 if (!page_cache)
241 return 0;
242 }
243 if (offset >= inode->i_size)
244 return page_cache;
245 #if 1
246 page = find_page(inode, offset);
247 if (page) {
248 page->count--;
249 return page_cache;
250 }
251
252
253
254 page = mem_map + MAP_NR(page_cache);
255 page->count++;
256 page->uptodate = 0;
257 page->error = 0;
258 page->offset = offset;
259 add_page_to_inode_queue(inode, page);
260 add_page_to_hash_queue(inode, page);
261
262 inode->i_op->readpage(inode, page);
263
264 free_page(page_cache);
265 return 0;
266 #else
267 return page_cache;
268 #endif
269 }
270
271
272
273
274 void __wait_on_page(struct page *page)
275 {
276 struct wait_queue wait = { current, NULL };
277
278 page->count++;
279 add_wait_queue(&page->wait, &wait);
280 repeat:
281 current->state = TASK_UNINTERRUPTIBLE;
282 if (page->locked) {
283 schedule();
284 goto repeat;
285 }
286 remove_wait_queue(&page->wait, &wait);
287 page->count--;
288 current->state = TASK_RUNNING;
289 }
290
291
292
293
294
295
296
297
298
299
300 #define MAX_READAHEAD (PAGE_SIZE*4)
301 int generic_file_read(struct inode * inode, struct file * filp, char * buf, int count)
302 {
303 int error, read;
304 unsigned long pos, page_cache;
305
306 if (count <= 0)
307 return 0;
308 error = 0;
309 read = 0;
310 page_cache = 0;
311
312 pos = filp->f_pos;
313 for (;;) {
314 struct page *page;
315 unsigned long offset, addr, nr;
316
317 if (pos >= inode->i_size)
318 break;
319 offset = pos & ~PAGE_MASK;
320 nr = PAGE_SIZE - offset;
321
322
323
324 page = find_page(inode, pos & PAGE_MASK);
325 if (page)
326 goto found_page;
327
328
329
330
331
332 if (page_cache)
333 goto new_page;
334
335 error = -ENOMEM;
336 page_cache = __get_free_page(GFP_KERNEL);
337 if (!page_cache)
338 break;
339 error = 0;
340
341
342
343
344 if (pos >= inode->i_size)
345 break;
346 page = find_page(inode, pos & PAGE_MASK);
347 if (!page)
348 goto new_page;
349
350 found_page:
351 addr = page_address(page);
352 if (nr > count)
353 nr = count;
354
355
356
357
358
359
360
361
362 if (page->locked) {
363 unsigned long max_ahead, ahead;
364
365 max_ahead = count - nr;
366 if (filp->f_reada || max_ahead > MAX_READAHEAD)
367 max_ahead = MAX_READAHEAD;
368 ahead = 0;
369 while (ahead < max_ahead) {
370 ahead += PAGE_SIZE;
371 page_cache = try_to_read_ahead(inode, pos + ahead, page_cache);
372 }
373 __wait_on_page(page);
374 }
375 if (!page->uptodate)
376 goto read_page;
377 if (nr > inode->i_size - pos)
378 nr = inode->i_size - pos;
379 memcpy_tofs(buf, (void *) (addr + offset), nr);
380 free_page(addr);
381 buf += nr;
382 pos += nr;
383 read += nr;
384 count -= nr;
385 if (count)
386 continue;
387 break;
388
389
390 new_page:
391
392
393
394 addr = page_cache;
395 page = mem_map + MAP_NR(page_cache);
396 page_cache = 0;
397 page->count++;
398 page->uptodate = 0;
399 page->error = 0;
400 page->offset = pos & PAGE_MASK;
401 add_page_to_inode_queue(inode, page);
402 add_page_to_hash_queue(inode, page);
403
404
405
406
407
408
409
410
411
412 read_page:
413 error = inode->i_op->readpage(inode, page);
414 if (!error)
415 goto found_page;
416 free_page(addr);
417 break;
418 }
419
420 filp->f_pos = pos;
421 filp->f_reada = 1;
422 if (page_cache)
423 free_page(page_cache);
424 if (!IS_RDONLY(inode)) {
425 inode->i_atime = CURRENT_TIME;
426 inode->i_dirt = 1;
427 }
428 if (!read)
429 read = error;
430 return read;
431 }
432
433
434
435
436
437 static inline unsigned long fill_page(struct inode * inode, unsigned long offset)
438 {
439 struct page * page;
440 unsigned long new_page;
441
442 page = find_page(inode, offset);
443 if (page)
444 goto found_page;
445 new_page = __get_free_page(GFP_KERNEL);
446 page = find_page(inode, offset);
447 if (page) {
448 if (new_page)
449 free_page(new_page);
450 goto found_page;
451 }
452 if (!new_page)
453 return 0;
454 page = mem_map + MAP_NR(new_page);
455 new_page = 0;
456 page->count++;
457 page->uptodate = 0;
458 page->error = 0;
459 page->offset = offset;
460 add_page_to_inode_queue(inode, page);
461 add_page_to_hash_queue(inode, page);
462 inode->i_op->readpage(inode, page);
463 found_page:
464 wait_on_page(page);
465 return page_address(page);
466 }
467
468
469
470
471
472
473 static unsigned long filemap_nopage(struct vm_area_struct * area, unsigned long address, int no_share)
474 {
475 unsigned long offset;
476 struct inode * inode = area->vm_inode;
477 unsigned long page;
478
479 offset = (address & PAGE_MASK) - area->vm_start + area->vm_offset;
480 if (offset >= inode->i_size && (area->vm_flags & VM_SHARED) && area->vm_mm == current->mm)
481 return 0;
482
483 page = fill_page(inode, offset);
484 if (page && no_share) {
485 unsigned long new_page = __get_free_page(GFP_KERNEL);
486 if (new_page)
487 memcpy((void *) new_page, (void *) page, PAGE_SIZE);
488 free_page(page);
489 return new_page;
490 }
491 return page;
492 }
493
494
495
496
497
498 static int filemap_write_page(struct vm_area_struct * vma,
499 unsigned long offset,
500 unsigned long page)
501 {
502 int old_fs;
503 unsigned long size, result;
504 struct file file;
505 struct inode * inode;
506 struct buffer_head * bh;
507
508 bh = buffer_pages[MAP_NR(page)];
509 if (bh) {
510
511 struct buffer_head * tmp = bh;
512 do {
513 mark_buffer_dirty(tmp, 0);
514 tmp = tmp->b_this_page;
515 } while (tmp != bh);
516 return 0;
517 }
518
519 inode = vma->vm_inode;
520 file.f_op = inode->i_op->default_file_ops;
521 if (!file.f_op->write)
522 return -EIO;
523 size = offset + PAGE_SIZE;
524
525 if (S_ISREG(inode->i_mode)) {
526 if (size > inode->i_size)
527 size = inode->i_size;
528
529 if (size < offset)
530 return -EIO;
531 }
532 size -= offset;
533 file.f_mode = 3;
534 file.f_flags = 0;
535 file.f_count = 1;
536 file.f_inode = inode;
537 file.f_pos = offset;
538 file.f_reada = 0;
539 old_fs = get_fs();
540 set_fs(KERNEL_DS);
541 result = file.f_op->write(inode, &file, (const char *) page, size);
542 set_fs(old_fs);
543 if (result != size)
544 return -EIO;
545 return 0;
546 }
547
548
549
550
551
552
553
554
555
556
557
558
559 int filemap_swapout(struct vm_area_struct * vma,
560 unsigned long offset,
561 pte_t *page_table)
562 {
563 int error;
564 unsigned long page = pte_page(*page_table);
565 unsigned long entry = SWP_ENTRY(SHM_SWP_TYPE, MAP_NR(page));
566
567 set_pte(page_table, __pte(entry));
568
569 invalidate_page(vma, (offset + vma->vm_start - vma->vm_offset));
570 error = filemap_write_page(vma, offset, page);
571 if (pte_val(*page_table) == entry)
572 pte_clear(page_table);
573 return error;
574 }
575
576
577
578
579
580
581
582 static pte_t filemap_swapin(struct vm_area_struct * vma,
583 unsigned long offset,
584 unsigned long entry)
585 {
586 unsigned long page = SWP_OFFSET(entry);
587
588 mem_map[page].count++;
589 page = (page << PAGE_SHIFT) + PAGE_OFFSET;
590 return mk_pte(page,vma->vm_page_prot);
591 }
592
593
594 static inline int filemap_sync_pte(pte_t * ptep, struct vm_area_struct *vma,
595 unsigned long address, unsigned int flags)
596 {
597 pte_t pte = *ptep;
598 unsigned long page;
599 int error;
600
601 if (!(flags & MS_INVALIDATE)) {
602 if (!pte_present(pte))
603 return 0;
604 if (!pte_dirty(pte))
605 return 0;
606 set_pte(ptep, pte_mkclean(pte));
607 invalidate_page(vma, address);
608 page = pte_page(pte);
609 mem_map[MAP_NR(page)].count++;
610 } else {
611 if (pte_none(pte))
612 return 0;
613 pte_clear(ptep);
614 invalidate_page(vma, address);
615 if (!pte_present(pte)) {
616 swap_free(pte_val(pte));
617 return 0;
618 }
619 page = pte_page(pte);
620 if (!pte_dirty(pte) || flags == MS_INVALIDATE) {
621 free_page(page);
622 return 0;
623 }
624 }
625 error = filemap_write_page(vma, address - vma->vm_start + vma->vm_offset, page);
626 free_page(page);
627 return error;
628 }
629
630 static inline int filemap_sync_pte_range(pmd_t * pmd,
631 unsigned long address, unsigned long size,
632 struct vm_area_struct *vma, unsigned long offset, unsigned int flags)
633 {
634 pte_t * pte;
635 unsigned long end;
636 int error;
637
638 if (pmd_none(*pmd))
639 return 0;
640 if (pmd_bad(*pmd)) {
641 printk("filemap_sync_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd));
642 pmd_clear(pmd);
643 return 0;
644 }
645 pte = pte_offset(pmd, address);
646 offset += address & PMD_MASK;
647 address &= ~PMD_MASK;
648 end = address + size;
649 if (end > PMD_SIZE)
650 end = PMD_SIZE;
651 error = 0;
652 do {
653 error |= filemap_sync_pte(pte, vma, address + offset, flags);
654 address += PAGE_SIZE;
655 pte++;
656 } while (address < end);
657 return error;
658 }
659
660 static inline int filemap_sync_pmd_range(pgd_t * pgd,
661 unsigned long address, unsigned long size,
662 struct vm_area_struct *vma, unsigned int flags)
663 {
664 pmd_t * pmd;
665 unsigned long offset, end;
666 int error;
667
668 if (pgd_none(*pgd))
669 return 0;
670 if (pgd_bad(*pgd)) {
671 printk("filemap_sync_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd));
672 pgd_clear(pgd);
673 return 0;
674 }
675 pmd = pmd_offset(pgd, address);
676 offset = address & PMD_MASK;
677 address &= ~PMD_MASK;
678 end = address + size;
679 if (end > PGDIR_SIZE)
680 end = PGDIR_SIZE;
681 error = 0;
682 do {
683 error |= filemap_sync_pte_range(pmd, address, end - address, vma, offset, flags);
684 address = (address + PMD_SIZE) & PMD_MASK;
685 pmd++;
686 } while (address < end);
687 return error;
688 }
689
690 static int filemap_sync(struct vm_area_struct * vma, unsigned long address,
691 size_t size, unsigned int flags)
692 {
693 pgd_t * dir;
694 unsigned long end = address + size;
695 int error = 0;
696
697 dir = pgd_offset(current->mm, address);
698 while (address < end) {
699 error |= filemap_sync_pmd_range(dir, address, end - address, vma, flags);
700 address = (address + PGDIR_SIZE) & PGDIR_MASK;
701 dir++;
702 }
703 invalidate_range(vma->vm_mm, end - size, end);
704 return error;
705 }
706
707
708
709
710 static void filemap_unmap(struct vm_area_struct *vma, unsigned long start, size_t len)
711 {
712 filemap_sync(vma, start, len, MS_ASYNC);
713 }
714
715
716
717
718
719
720 static struct vm_operations_struct file_shared_mmap = {
721 NULL,
722 NULL,
723 filemap_unmap,
724 NULL,
725 filemap_sync,
726 NULL,
727 filemap_nopage,
728 NULL,
729 filemap_swapout,
730 filemap_swapin,
731 };
732
733
734
735
736
737
738
739 static struct vm_operations_struct file_private_mmap = {
740 NULL,
741 NULL,
742 NULL,
743 NULL,
744 NULL,
745 NULL,
746 filemap_nopage,
747 NULL,
748 NULL,
749 NULL,
750 };
751
752
753 int generic_file_mmap(struct inode * inode, struct file * file, struct vm_area_struct * vma)
754 {
755 struct vm_operations_struct * ops;
756
757 if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) {
758 ops = &file_shared_mmap;
759
760
761 if (vma->vm_offset & (PAGE_SIZE - 1))
762 return -EINVAL;
763 } else {
764 ops = &file_private_mmap;
765 if (vma->vm_offset & (inode->i_sb->s_blocksize - 1))
766 return -EINVAL;
767 }
768 if (!inode->i_sb || !S_ISREG(inode->i_mode))
769 return -EACCES;
770 if (!inode->i_op || !inode->i_op->readpage)
771 return -ENOEXEC;
772 if (!IS_RDONLY(inode)) {
773 inode->i_atime = CURRENT_TIME;
774 inode->i_dirt = 1;
775 }
776 vma->vm_inode = inode;
777 inode->i_count++;
778 vma->vm_ops = ops;
779 return 0;
780 }
781
782
783
784
785
786
787 static int msync_interval(struct vm_area_struct * vma,
788 unsigned long start, unsigned long end, int flags)
789 {
790 if (!vma->vm_inode)
791 return 0;
792 if (vma->vm_ops->sync) {
793 int error;
794 error = vma->vm_ops->sync(vma, start, end-start, flags);
795 if (error)
796 return error;
797 if (flags & MS_SYNC)
798 return file_fsync(vma->vm_inode, NULL);
799 return 0;
800 }
801 return 0;
802 }
803
804 asmlinkage int sys_msync(unsigned long start, size_t len, int flags)
805 {
806 unsigned long end;
807 struct vm_area_struct * vma;
808 int unmapped_error, error;
809
810 if (start & ~PAGE_MASK)
811 return -EINVAL;
812 len = (len + ~PAGE_MASK) & PAGE_MASK;
813 end = start + len;
814 if (end < start)
815 return -EINVAL;
816 if (flags & ~(MS_ASYNC | MS_INVALIDATE | MS_SYNC))
817 return -EINVAL;
818 if (end == start)
819 return 0;
820
821
822
823
824 vma = find_vma(current, start);
825 unmapped_error = 0;
826 for (;;) {
827
828 if (!vma)
829 return -EFAULT;
830
831 if (start < vma->vm_start) {
832 unmapped_error = -EFAULT;
833 start = vma->vm_start;
834 }
835
836 if (end <= vma->vm_end) {
837 if (start < end) {
838 error = msync_interval(vma, start, end, flags);
839 if (error)
840 return error;
841 }
842 return unmapped_error;
843 }
844
845 error = msync_interval(vma, start, vma->vm_end, flags);
846 if (error)
847 return error;
848 start = vma->vm_end;
849 vma = vma->vm_next;
850 }
851 }