VirtualBox

Ignore:
Timestamp:
Jul 7, 2011 2:47:37 PM (13 years ago)
Author:
vboxsync
Message:

Additions/solaris/SharedFolders: readonly mmap bits.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/solaris/SharedFolders/vboxfs_vnode.c

    r37806 r37823  
    8484#include <sys/vfs.h>
    8585#include <sys/vmsystm.h>
     86#include <vm/seg_kpm.h>
     87#include <vm/pvn.h>
    8688#if !defined(VBOX_VFS_SOLARIS_10U6)
    8789#include <sys/vfs_opreg.h>
     
    14561458
    14571459#if 0
     1460static caddr_t
     1461sffs_page_map(
     1462        page_t *ppage,
     1463        enum seg_rw segaccess)
     1464{
     1465        /* Use seg_kpm driver if possible (64-bit) */
     1466        if (kpm_enable)
     1467                return (hat_kpm_mapin(ppage, NULL));
     1468        ASSERT(segaccess == S_READ || segaccess == S_WRITE);
     1469        return (ppmapin(ppage, PROT_READ | ((segaccess == S_WRITE) ? PROT_WRITE : 0), (caddr_t)-1));
     1470}
     1471
     1472
     1473static void
     1474sffs_page_unmap(
     1475        page_t *ppage,
     1476        caddr_t addr)
     1477{
     1478        if (kpm_enable)
     1479                hat_kpm_mapout(ppage, NULL, addr);
     1480        else
     1481                ppmapout(addr);
     1482}
     1483
     1484
     1485/*
     1486 * Called when there's no page in the cache. This will create new page(s) and read
     1487 * the file data into it.
     1488 */
     1489static int
     1490sffs_readpages(
     1491        vnode_t         *dvp,
     1492        offset_t        off,
     1493        page_t          *pagelist[],
     1494        size_t          pagelistsize,
     1495        struct seg  *segp,
     1496        caddr_t         addr,
     1497        enum seg_rw     segaccess)
     1498{
     1499        ASSERT(MUTEX_HELD(&sffs_lock));
     1500
     1501        int error = 0;
     1502        u_offset_t io_off, total;
     1503        size_t io_len;
     1504        page_t *ppages;
     1505        page_t *pcur;
     1506
     1507        sfnode_t *node = VN2SFN(dvp);
     1508        ASSERT(node);
     1509        ASSERT(node->sf_file);
     1510
     1511        if (pagelistsize == PAGESIZE)
     1512        {
     1513                io_off = off;
     1514                io_len = PAGESIZE;
     1515
     1516                ppages = page_create_va(dvp, io_off, io_len, PG_WAIT | PG_EXCL, segp, addr);
     1517        }
     1518        else
     1519                ppages = pvn_read_kluster(dvp, off, segp, addr, &io_off, &io_len, off, pagelistsize, 0);
     1520
     1521        /* If page already exists return success */
     1522        if (!ppages)
     1523        {
     1524                *pagelist = NULL;
     1525                return (0);
     1526        }
     1527
     1528        /*
     1529         * Map & read page-by-page.
     1530         */
     1531        total = io_off + io_len;
     1532        pcur = ppages;
     1533        while (io_off < total)
     1534        {
     1535                ASSERT3U(io_off, ==, pcur->p_offset);
     1536
     1537                caddr_t virtaddr = sffs_page_map(pcur, segaccess);
     1538                uint32_t bytes = PAGESIZE;
     1539                error = sfprov_read(node->sf_file, virtaddr, io_off, &bytes);
     1540                sffs_page_unmap(pcur, virtaddr);
     1541                if (error != 0 || bytes < PAGESIZE)
     1542                {
     1543                        /* Get rid of all kluster pages read & bail.  */
     1544                        pvn_read_done(ppages,  B_ERROR);
     1545                        return (error);
     1546                }
     1547                pcur = pcur->p_next;
     1548                io_off += PAGESIZE;
     1549        }
     1550
     1551        /*
     1552         * Fill in the pagelist from kluster at the requested offset.
     1553         */
     1554        pvn_plist_init(ppages, pagelist, pagelistsize, off, io_len, segaccess);
     1555        ASSERT(pagelist == NULL || (*pagelist)->p_offset == off);
     1556        return (0);
     1557}
     1558
     1559
    14581560/*ARGSUSED*/
    14591561static int
     
    14741576        )
    14751577{
     1578        int error = 0;
     1579        page_t **pageliststart = pagelist;
     1580
     1581        if (segaccess == S_WRITE)
     1582                return (ENOSYS);        /* Will this ever happen? */
     1583
     1584        if (protp)
     1585                *protp = PROT_ALL;
     1586
     1587        /* We don't really support async ops, pretend success. */
     1588        if (pagelist == NULL)
     1589                return (0);
     1590
     1591        if (len > pagelistsize)
     1592                len = pagelistsize;
     1593        else
     1594                len = P2ROUNDUP(len, PAGESIZE);
     1595        ASSERT(pagelistsize >= len);
     1596
     1597        mutex_enter(&sffs_lock);
     1598
     1599        while (len > 0)
     1600        {
     1601                /*
     1602                 * Look for pages in the requested offset range, or create them if we can't find any.
     1603                 */
     1604                if ((*pagelist = page_lookup(dvp, off, SE_SHARED)) != NULL)
     1605                        *(pagelist + 1) = NULL;
     1606                else if ((error = sffs_readpages(dvp, off, pagelist, pagelistsize, segp, addr, segaccess)) != 0)
     1607                {
     1608                        while (pagelist > pageliststart)
     1609                                page_unlock(*--pagelist);
     1610
     1611                        *pagelist = NULL;
     1612                        mutex_exit(&sffs_lock);
     1613                        return (error);
     1614                }
     1615
     1616                while (*pagelist)
     1617                {
     1618                        ASSERT3U((*pagelist)->p_offset, ==, off);
     1619                        off += PAGESIZE;
     1620                        addr += PAGESIZE;
     1621                        if (len > 0)
     1622                        {
     1623                                ASSERT3U(len, >=, PAGESIZE);
     1624                                len -= PAGESIZE;
     1625                        }
     1626
     1627                        ASSERT3U(pagelistsize,  >=, PAGESIZE);
     1628                        pagelistsize -= PAGESIZE;
     1629                        pagelist++;
     1630                }
     1631
     1632                /*
     1633                 * Fill the page list array with any pages left in the cache.
     1634                 */
     1635                while (pagelistsize > 0)
     1636                {
     1637                        if ((*pagelist++ = page_lookup_nowait(dvp, off, SE_SHARED)) != NULL)
     1638                        {
     1639                                off += PAGESIZE;
     1640                                pagelistsize -= PAGESIZE;
     1641                        }
     1642                        else
     1643                                break;
     1644                }
     1645        }
     1646
     1647        *pagelist = NULL;
     1648        mutex_exit(&sffs_lock);
     1649        return (error);
    14761650}
    14771651
     
    14901664        )
    14911665{
     1666        /*
     1667         * We don't support PROT_WRITE mmaps. For normal writes we do not map and IO via
     1668         * vop_putpage() either, therefore, afaik this shouldn't ever be called.
     1669         */
     1670        return (ENOSYS);
    14921671}
    14931672
     
    15111690{
    15121691        /*
    1513          * Invocation: mmap()-smmap_common()->VOP_MAP()->sffs_map(). Once the segment driver
    1514          * creates the new segment in segvn_create(), it'll invoke down the line VOP_ADDMAP()->sffs_addmap()
     1692         * Invocation: mmap()->smmap_common()->VOP_MAP()->sffs_map(). Once the
     1693         * segment driver creates the new segment via segvn_create(), it'll
     1694         * invoke down the line VOP_ADDMAP()->sffs_addmap()
    15151695         */
    15161696        int error;
     1697        sfnode_t *node = VN2SFN(dvp);
     1698        ASSERT(node);
    15171699        if ((prot & PROT_WRITE))
    15181700                return (ENOTSUP);
     
    15261708        if (dvp->v_flag & VNOMAP)
    15271709                return (ENOSYS);
     1710
     1711        if (vn_has_mandatory_locks(dvp, node->sf_stat.sf_mode))
     1712                return (EAGAIN);
    15281713
    15291714        mutex_enter(&sffs_lock);
     
    15761761        uint64_t npages = btopr(len);
    15771762
     1763        if (dvp->v_flag & VNOMAP)
     1764                return (ENOSYS);
     1765
    15781766        ASSERT(node);
    15791767        ASMAtomicAddU64(&node->sf_mapcnt, npages);
     
    16011789        sfnode_t *node = VN2SFN(dvp);
    16021790        uint64_t npages = btopr(len);
     1791
     1792        if (dvp->v_flag & VNOMAP)
     1793                return (ENOSYS);
    16031794
    16041795        ASSERT(node->sf_mapcnt >= npages);
     
    19472138        VOPNAME_WRITE,          { .vop_write = sffs_write },
    19482139
    1949 #if 0
     2140# if 0
    19502141        VOPNAME_MAP,            { .vop_map = sffs_map },
    19512142        VOPNAME_ADDMAP,         { .vop_addmap = sffs_addmap },
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette