lkml.org 
[lkml]   [2002]   [Oct]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[PATCH] tmpfs 9/9 Ingo's shmem_populate
    Instate Ingo's shmem_populate on top of the previous patches, now using
    shmem_getpage(,,,SGP_QUICK) for the nonblocking case (its find_lock_page
    may block, but rarely for long). Note install_page will need redefining
    if PAGE_CACHE_SIZE departs from PAGE_SIZE; note pgoff to populate must
    be in terms of PAGE_SIZE; note page_cache_release if install_page fails.

    filemap_populate similarly needs page_cache_release when install_page
    fails, but filemap.c not included in this patch since we started out
    from 2.5.43 rather than 2.5.43-mm2: whereas patches 1-8 could go
    directly to 2.5.43, this 9/9 belongs with Ingo's population work.

    --- tmpfs8/mm/shmem.c Thu Oct 17 22:01:59 2002
    +++ tmpfs9/mm/shmem.c Thu Oct 17 22:02:09 2002
    @@ -53,6 +53,7 @@

    /* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */
    enum sgp_type {
    + SGP_QUICK, /* don't try more than file page cache lookup */
    SGP_READ, /* don't exceed i_size, don't allocate page */
    SGP_CACHE, /* don't exceed i_size, may allocate page */
    SGP_WRITE, /* may exceed i_size, may allocate page */
    @@ -757,6 +758,8 @@
    if (filepage && PageUptodate(filepage))
    goto done;
    error = 0;
    + if (sgp == SGP_QUICK)
    + goto failed;

    spin_lock(&info->lock);
    shmem_recalc_inode(inode);
    @@ -949,6 +952,42 @@
    return page;
    }

    +static int shmem_populate(struct vm_area_struct *vma,
    + unsigned long addr, unsigned long len,
    + unsigned long prot, unsigned long pgoff, int nonblock)
    +{
    + struct inode *inode = vma->vm_file->f_dentry->d_inode;
    + struct mm_struct *mm = vma->vm_mm;
    + enum sgp_type sgp = nonblock? SGP_QUICK: SGP_CACHE;
    + unsigned long size;
    +
    + size = (inode->i_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
    + if (pgoff >= size || pgoff + (len >> PAGE_SHIFT) > size)
    + return -EINVAL;
    +
    + while ((long) len > 0) {
    + struct page *page = NULL;
    + int err;
    + /*
    + * Will need changing if PAGE_CACHE_SIZE != PAGE_SIZE
    + */
    + err = shmem_getpage(inode, pgoff, &page, sgp);
    + if (err)
    + return err;
    + if (page) {
    + err = install_page(mm, vma, addr, page, prot);
    + if (err) {
    + page_cache_release(page);
    + return err;
    + }
    + }
    + len -= PAGE_SIZE;
    + addr += PAGE_SIZE;
    + pgoff++;
    + }
    + return 0;
    +}
    +
    void shmem_lock(struct file *file, int lock)
    {
    struct inode *inode = file->f_dentry->d_inode;
    @@ -1829,6 +1868,7 @@

    static struct vm_operations_struct shmem_vm_ops = {
    .nopage = shmem_nopage,
    + .populate = shmem_populate,
    };

    static struct super_block *shmem_get_sb(struct file_system_type *fs_type,
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-03-22 13:30    [W:0.024 / U:0.208 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site