| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: genfs_io.c,v 1.36.2.39 2010/11/19 04:46:24 uebayasi Exp $ */ | | 1 | /* $NetBSD: genfs_io.c,v 1.36.2.40 2010/11/19 05:22:29 uebayasi Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 1982, 1986, 1989, 1993 | | 4 | * Copyright (c) 1982, 1986, 1989, 1993 |
5 | * The Regents of the University of California. All rights reserved. | | 5 | * The Regents of the University of California. All rights reserved. |
6 | * | | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | | 7 | * Redistribution and use in source and binary forms, with or without |
8 | * modification, are permitted provided that the following conditions | | 8 | * modification, are permitted provided that the following conditions |
9 | * are met: | | 9 | * are met: |
10 | * 1. Redistributions of source code must retain the above copyright | | 10 | * 1. Redistributions of source code must retain the above copyright |
11 | * notice, this list of conditions and the following disclaimer. | | 11 | * notice, this list of conditions and the following disclaimer. |
12 | * 2. Redistributions in binary form must reproduce the above copyright | | 12 | * 2. Redistributions in binary form must reproduce the above copyright |
13 | * notice, this list of conditions and the following disclaimer in the | | 13 | * notice, this list of conditions and the following disclaimer in the |
14 | * documentation and/or other materials provided with the distribution. | | 14 | * documentation and/or other materials provided with the distribution. |
| @@ -21,27 +21,27 @@ | | | @@ -21,27 +21,27 @@ |
21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | | 21 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 22 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 23 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 24 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 25 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 26 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 27 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 28 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
29 | * SUCH DAMAGE. | | 29 | * SUCH DAMAGE. |
30 | * | | 30 | * |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.36.2.39 2010/11/19 04:46:24 uebayasi Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v 1.36.2.40 2010/11/19 05:22:29 uebayasi Exp $"); |
35 | | | 35 | |
36 | #include "opt_xip.h" | | 36 | #include "opt_xip.h" |
37 | | | 37 | |
38 | #include <sys/param.h> | | 38 | #include <sys/param.h> |
39 | #include <sys/systm.h> | | 39 | #include <sys/systm.h> |
40 | #include <sys/proc.h> | | 40 | #include <sys/proc.h> |
41 | #include <sys/kernel.h> | | 41 | #include <sys/kernel.h> |
42 | #include <sys/mount.h> | | 42 | #include <sys/mount.h> |
43 | #include <sys/namei.h> | | 43 | #include <sys/namei.h> |
44 | #include <sys/vnode.h> | | 44 | #include <sys/vnode.h> |
45 | #include <sys/fcntl.h> | | 45 | #include <sys/fcntl.h> |
46 | #include <sys/kmem.h> | | 46 | #include <sys/kmem.h> |
47 | #include <sys/poll.h> | | 47 | #include <sys/poll.h> |
| @@ -51,28 +51,26 @@ __KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v | | | @@ -51,28 +51,26 @@ __KERNEL_RCSID(0, "$NetBSD: genfs_io.c,v |
51 | #include <sys/fstrans.h> | | 51 | #include <sys/fstrans.h> |
52 | #include <sys/buf.h> | | 52 | #include <sys/buf.h> |
53 | #include <sys/once.h> | | 53 | #include <sys/once.h> |
54 | | | 54 | |
55 | #include <miscfs/genfs/genfs.h> | | 55 | #include <miscfs/genfs/genfs.h> |
56 | #include <miscfs/genfs/genfs_node.h> | | 56 | #include <miscfs/genfs/genfs_node.h> |
57 | #include <miscfs/specfs/specdev.h> | | 57 | #include <miscfs/specfs/specdev.h> |
58 | | | 58 | |
59 | #include <uvm/uvm.h> | | 59 | #include <uvm/uvm.h> |
60 | #include <uvm/uvm_pager.h> | | 60 | #include <uvm/uvm_pager.h> |
61 | | | 61 | |
62 | #ifdef XIP | | 62 | #ifdef XIP |
63 | static int genfs_do_getpages_xip(void *); | | 63 | static int genfs_do_getpages_xip(void *); |
64 | static int genfs_do_getpages_xip1(struct vnode *, voff_t, struct vm_page **, | | | |
65 | int *, int, vm_prot_t, int, int); | | | |
66 | static int genfs_do_getpages_xip_io(struct vnode *, voff_t, struct vm_page **, | | 64 | static int genfs_do_getpages_xip_io(struct vnode *, voff_t, struct vm_page **, |
67 | int *, int, vm_prot_t, int, int); | | 65 | int *, int, vm_prot_t, int, int); |
68 | static int genfs_do_putpages_xip(struct vnode *, off_t, off_t, int, | | 66 | static int genfs_do_putpages_xip(struct vnode *, off_t, off_t, int, |
69 | struct vm_page **); | | 67 | struct vm_page **); |
70 | #endif | | 68 | #endif |
71 | static int genfs_do_directio(struct vmspace *, vaddr_t, size_t, struct vnode *, | | 69 | static int genfs_do_directio(struct vmspace *, vaddr_t, size_t, struct vnode *, |
72 | off_t, enum uio_rw); | | 70 | off_t, enum uio_rw); |
73 | static void genfs_dio_iodone(struct buf *); | | 71 | static void genfs_dio_iodone(struct buf *); |
74 | | | 72 | |
75 | static int genfs_do_io(struct vnode *, off_t, vaddr_t, size_t, int, enum uio_rw, | | 73 | static int genfs_do_io(struct vnode *, off_t, vaddr_t, size_t, int, enum uio_rw, |
76 | void (*)(struct buf *)); | | 74 | void (*)(struct buf *)); |
77 | static void genfs_rel_pages(struct vm_page **, int); | | 75 | static void genfs_rel_pages(struct vm_page **, int); |
78 | static void genfs_markdirty(struct vnode *); | | 76 | static void genfs_markdirty(struct vnode *); |
| @@ -814,64 +812,39 @@ genfs_do_getpages_xip(void *v) | | | @@ -814,64 +812,39 @@ genfs_do_getpages_xip(void *v) |
814 | struct vop_getpages_args /* { | | 812 | struct vop_getpages_args /* { |
815 | struct vnode *a_vp; | | 813 | struct vnode *a_vp; |
816 | voff_t a_offset; | | 814 | voff_t a_offset; |
817 | struct vm_page **a_m; | | 815 | struct vm_page **a_m; |
818 | int *a_count; | | 816 | int *a_count; |
819 | int a_centeridx; | | 817 | int a_centeridx; |
820 | vm_prot_t a_access_type; | | 818 | vm_prot_t a_access_type; |
821 | int a_advice; | | 819 | int a_advice; |
822 | int a_flags; | | 820 | int a_flags; |
823 | } */ * const ap = v; | | 821 | } */ * const ap = v; |
824 | | | 822 | |
825 | UVMHIST_FUNC("genfs_do_getpages_xip"); UVMHIST_CALLED(ubchist); | | 823 | UVMHIST_FUNC("genfs_do_getpages_xip"); UVMHIST_CALLED(ubchist); |
826 | | | 824 | |
827 | return genfs_do_getpages_xip1( | | 825 | if ((ap->a_flags & PGO_LOCKED) != 0) { |
828 | ap->a_vp, | | 826 | *ap->a_count = 0; |
829 | ap->a_offset, | | | |
830 | ap->a_m, | | | |
831 | ap->a_count, | | | |
832 | ap->a_centeridx, | | | |
833 | ap->a_access_type, | | | |
834 | ap->a_advice, | | | |
835 | ap->a_flags); | | | |
836 | } | | | |
837 | | | | |
838 | static int | | | |
839 | genfs_do_getpages_xip1( | | | |
840 | struct vnode *vp, | | | |
841 | voff_t offset, | | | |
842 | struct vm_page **pps, | | | |
843 | int *npagesp, | | | |
844 | int centeridx, | | | |
845 | vm_prot_t access_type, | | | |
846 | int advice, | | | |
847 | int flags) | | | |
848 | { | | | |
849 | | | | |
850 | KASSERT((vp->v_vflag & VV_XIP) != 0); | | | |
851 | | | | |
852 | if ((flags & PGO_LOCKED) != 0) { | | | |
853 | *npagesp = 0; | | | |
854 | return 0; | | 827 | return 0; |
855 | } else | | 828 | } else |
856 | return genfs_do_getpages_xip_io( | | 829 | return genfs_do_getpages_xip_io( |
857 | vp, | | 830 | ap->a_vp, |
858 | offset, | | 831 | ap->a_offset, |
859 | pps, | | 832 | ap->a_m, |
860 | npagesp, | | 833 | ap->a_count, |
861 | centeridx, | | 834 | ap->a_centeridx, |
862 | access_type, | | 835 | ap->a_access_type, |
863 | advice, | | 836 | ap->a_advice, |
864 | flags); | | 837 | ap->a_flags); |
865 | } | | 838 | } |
866 | | | 839 | |
867 | static int | | 840 | static int |
868 | genfs_do_getpages_xip_io( | | 841 | genfs_do_getpages_xip_io( |
869 | struct vnode *vp, | | 842 | struct vnode *vp, |
870 | voff_t offset, | | 843 | voff_t offset, |
871 | struct vm_page **pps, | | 844 | struct vm_page **pps, |
872 | int *npagesp, | | 845 | int *npagesp, |
873 | int centeridx, | | 846 | int centeridx, |
874 | vm_prot_t access_type, | | 847 | vm_prot_t access_type, |
875 | int advice, | | 848 | int advice, |
876 | int flags) | | 849 | int flags) |
877 | { | | 850 | { |
| @@ -1520,49 +1493,49 @@ genfs_do_putpages_xip(struct vnode *vp, | | | @@ -1520,49 +1493,49 @@ genfs_do_putpages_xip(struct vnode *vp, |
1520 | goto done; | | 1493 | goto done; |
1521 | | | 1494 | |
1522 | /* | | 1495 | /* |
1523 | * For PGO_FREE (or (PGO_CLEANIT | PGO_FREE)), we invalidate MMU | | 1496 | * For PGO_FREE (or (PGO_CLEANIT | PGO_FREE)), we invalidate MMU |
1524 | * mappings of both XIP pages and XIP zero pages. | | 1497 | * mappings of both XIP pages and XIP zero pages. |
1525 | * | | 1498 | * |
1526 | * Zero page is freed when one of its mapped offset is freed, even if | | 1499 | * Zero page is freed when one of its mapped offset is freed, even if |
1527 | * one file (vnode) has many holes and mapping its zero page to all | | 1500 | * one file (vnode) has many holes and mapping its zero page to all |
1528 | * of those hole pages. | | 1501 | * of those hole pages. |
1529 | * | | 1502 | * |
1530 | * We don't know which pages are currently mapped in the given vnode, | | 1503 | * We don't know which pages are currently mapped in the given vnode, |
1531 | * because XIP pages are not added to vnode. What we can do is to | | 1504 | * because XIP pages are not added to vnode. What we can do is to |
1532 | * locate pages by querying the filesystem as done in getpages. Call | | 1505 | * locate pages by querying the filesystem as done in getpages. Call |
1533 | * genfs_do_getpages_xip1(). | | 1506 | * genfs_do_getpages_xip_io(). |
1534 | */ | | 1507 | */ |
1535 | | | 1508 | |
1536 | off_t off, eof; | | 1509 | off_t off, eof; |
1537 | | | 1510 | |
1538 | off = trunc_page(startoff); | | 1511 | off = trunc_page(startoff); |
1539 | if (endoff == 0 || (flags & PGO_ALLPAGES)) | | 1512 | if (endoff == 0 || (flags & PGO_ALLPAGES)) |
1540 | GOP_SIZE(vp, vp->v_size, &eof, GOP_SIZE_MEM); | | 1513 | GOP_SIZE(vp, vp->v_size, &eof, GOP_SIZE_MEM); |
1541 | else | | 1514 | else |
1542 | eof = endoff; | | 1515 | eof = endoff; |
1543 | | | 1516 | |
1544 | while (off < eof) { | | 1517 | while (off < eof) { |
1545 | int npages, orignpages, error, i; | | 1518 | int npages, orignpages, error, i; |
1546 | struct vm_page *pgs[maxpages], *pg; | | 1519 | struct vm_page *pgs[maxpages], *pg; |
1547 | | | 1520 | |
1548 | npages = round_page(eof - off) >> PAGE_SHIFT; | | 1521 | npages = round_page(eof - off) >> PAGE_SHIFT; |
1549 | if (npages > maxpages) | | 1522 | if (npages > maxpages) |
1550 | npages = maxpages; | | 1523 | npages = maxpages; |
1551 | | | 1524 | |
1552 | orignpages = npages; | | 1525 | orignpages = npages; |
1553 | KASSERT(mutex_owned(&uobj->vmobjlock)); | | 1526 | KASSERT(mutex_owned(&uobj->vmobjlock)); |
1554 | mutex_exit(&uobj->vmobjlock); | | 1527 | mutex_exit(&uobj->vmobjlock); |
1555 | error = genfs_do_getpages_xip1(vp, off, pgs, &npages, 0, | | 1528 | error = genfs_do_getpages_xip_io(vp, off, pgs, &npages, 0, |
1556 | VM_PROT_ALL, 0, 0); | | 1529 | VM_PROT_ALL, 0, 0); |
1557 | KASSERT(error == 0); | | 1530 | KASSERT(error == 0); |
1558 | KASSERT(npages == orignpages); | | 1531 | KASSERT(npages == orignpages); |
1559 | mutex_enter(&uobj->vmobjlock); | | 1532 | mutex_enter(&uobj->vmobjlock); |
1560 | for (i = 0; i < npages; i++) { | | 1533 | for (i = 0; i < npages; i++) { |
1561 | pg = pgs[i]; | | 1534 | pg = pgs[i]; |
1562 | if (pg == NULL || pg == PGO_DONTCARE) | | 1535 | if (pg == NULL || pg == PGO_DONTCARE) |
1563 | continue; | | 1536 | continue; |
1564 | /* | | 1537 | /* |
1565 | * Freeing normal XIP pages; nothing to do. | | 1538 | * Freeing normal XIP pages; nothing to do. |
1566 | */ | | 1539 | */ |
1567 | pmap_page_protect(pg, VM_PROT_NONE); | | 1540 | pmap_page_protect(pg, VM_PROT_NONE); |
1568 | KASSERT((pg->flags & PG_BUSY) != 0); | | 1541 | KASSERT((pg->flags & PG_BUSY) != 0); |