linux/fs/9p/vfs_addr.c
<<
>>
Prefs
   1/*
   2 *  linux/fs/9p/vfs_addr.c
   3 *
   4 * This file contians vfs address (mmap) ops for 9P2000.
   5 *
   6 *  Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
   7 *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
   8 *
   9 *  This program is free software; you can redistribute it and/or modify
  10 *  it under the terms of the GNU General Public License version 2
  11 *  as published by the Free Software Foundation.
  12 *
  13 *  This program is distributed in the hope that it will be useful,
  14 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 *  GNU General Public License for more details.
  17 *
  18 *  You should have received a copy of the GNU General Public License
  19 *  along with this program; if not, write to:
  20 *  Free Software Foundation
  21 *  51 Franklin Street, Fifth Floor
  22 *  Boston, MA  02111-1301  USA
  23 *
  24 */
  25
  26#include <linux/module.h>
  27#include <linux/errno.h>
  28#include <linux/fs.h>
  29#include <linux/file.h>
  30#include <linux/stat.h>
  31#include <linux/string.h>
  32#include <linux/inet.h>
  33#include <linux/pagemap.h>
  34#include <linux/idr.h>
  35#include <linux/sched.h>
  36#include <net/9p/9p.h>
  37#include <net/9p/client.h>
  38
  39#include "v9fs.h"
  40#include "v9fs_vfs.h"
  41#include "cache.h"
  42
  43/**
  44 * v9fs_vfs_readpage - read an entire page in from 9P
  45 *
  46 * @filp: file being read
  47 * @page: structure to page
  48 *
  49 */
  50
  51static int v9fs_vfs_readpage(struct file *filp, struct page *page)
  52{
  53        int retval;
  54        loff_t offset;
  55        char *buffer;
  56        struct inode *inode;
  57
  58        inode = page->mapping->host;
  59        P9_DPRINTK(P9_DEBUG_VFS, "\n");
  60
  61        BUG_ON(!PageLocked(page));
  62
  63        retval = v9fs_readpage_from_fscache(inode, page);
  64        if (retval == 0)
  65                return retval;
  66
  67        buffer = kmap(page);
  68        offset = page_offset(page);
  69
  70        retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset);
  71        if (retval < 0) {
  72                v9fs_uncache_page(inode, page);
  73                goto done;
  74        }
  75
  76        memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
  77        flush_dcache_page(page);
  78        SetPageUptodate(page);
  79
  80        v9fs_readpage_to_fscache(inode, page);
  81        retval = 0;
  82
  83done:
  84        kunmap(page);
  85        unlock_page(page);
  86        return retval;
  87}
  88
  89/**
  90 * v9fs_vfs_readpages - read a set of pages from 9P
  91 *
  92 * @filp: file being read
  93 * @mapping: the address space
  94 * @pages: list of pages to read
  95 * @nr_pages: count of pages to read
  96 *
  97 */
  98
  99static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
 100                             struct list_head *pages, unsigned nr_pages)
 101{
 102        int ret = 0;
 103        struct inode *inode;
 104
 105        inode = mapping->host;
 106        P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp);
 107
 108        ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages);
 109        if (ret == 0)
 110                return ret;
 111
 112        ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp);
 113        P9_DPRINTK(P9_DEBUG_VFS, "  = %d\n", ret);
 114        return ret;
 115}
 116
 117/**
 118 * v9fs_release_page - release the private state associated with a page
 119 *
 120 * Returns 1 if the page can be released, false otherwise.
 121 */
 122
 123static int v9fs_release_page(struct page *page, gfp_t gfp)
 124{
 125        if (PagePrivate(page))
 126                return 0;
 127
 128        return v9fs_fscache_release_page(page, gfp);
 129}
 130
 131/**
 132 * v9fs_invalidate_page - Invalidate a page completely or partially
 133 *
 134 * @page: structure to page
 135 * @offset: offset in the page
 136 */
 137
 138static void v9fs_invalidate_page(struct page *page, unsigned long offset)
 139{
 140        if (offset == 0)
 141                v9fs_fscache_invalidate_page(page);
 142}
 143
 144/**
 145 * v9fs_launder_page - Writeback a dirty page
 146 * Since the writes go directly to the server, we simply return a 0
 147 * here to indicate success.
 148 *
 149 * Returns 0 on success.
 150 */
 151
 152static int v9fs_launder_page(struct page *page)
 153{
 154        return 0;
 155}
 156
 157const struct address_space_operations v9fs_addr_operations = {
 158      .readpage = v9fs_vfs_readpage,
 159      .readpages = v9fs_vfs_readpages,
 160      .releasepage = v9fs_release_page,
 161      .invalidatepage = v9fs_invalidate_page,
 162      .launder_page = v9fs_launder_page,
 163};
 164