Files
linux-apfs/fs/9p/vfs_addr.c
T

164 lines
3.8 KiB
C
Raw Normal View History

2006-01-18 17:43:02 -08:00
/*
* linux/fs/9p/vfs_addr.c
*
* This file contians vfs address (mmap) ops for 9P2000.
*
* Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
*
* This program is free software; you can redistribute it and/or modify
2006-03-25 03:07:28 -08:00
* it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation.
2006-01-18 17:43:02 -08:00
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to:
* Free Software Foundation
* 51 Franklin Street, Fifth Floor
* Boston, MA 02111-1301 USA
*
*/
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/inet.h>
#include <linux/pagemap.h>
#include <linux/idr.h>
2007-05-21 01:22:52 +04:00
#include <linux/sched.h>
2007-07-10 17:57:28 -05:00
#include <net/9p/9p.h>
#include <net/9p/client.h>
2006-01-18 17:43:02 -08:00
#include "v9fs.h"
#include "v9fs_vfs.h"
2009-09-23 13:00:27 -05:00
#include "cache.h"
2006-01-18 17:43:02 -08:00
/**
* v9fs_vfs_readpage - read an entire page in from 9P
*
2008-03-05 07:08:09 -06:00
* @filp: file being read
2006-01-18 17:43:02 -08:00
* @page: structure to page
*
*/
static int v9fs_vfs_readpage(struct file *filp, struct page *page)
{
2007-07-10 17:57:28 -05:00
int retval;
loff_t offset;
char *buffer;
2009-09-23 13:00:27 -05:00
struct inode *inode;
2007-02-11 13:21:39 -06:00
2009-09-23 13:00:27 -05:00
inode = page->mapping->host;
2007-07-10 17:57:28 -05:00
P9_DPRINTK(P9_DEBUG_VFS, "\n");
2009-09-23 13:00:27 -05:00
BUG_ON(!PageLocked(page));
retval = v9fs_readpage_from_fscache(inode, page);
if (retval == 0)
return retval;
2006-01-18 17:43:02 -08:00
buffer = kmap(page);
2007-07-10 17:57:28 -05:00
offset = page_offset(page);
2006-01-18 17:43:02 -08:00
retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset);
2009-09-23 13:00:27 -05:00
if (retval < 0) {
v9fs_uncache_page(inode, page);
2007-07-10 17:57:28 -05:00
goto done;
2009-09-23 13:00:27 -05:00
}
2006-01-18 17:43:02 -08:00
2007-07-10 17:57:28 -05:00
memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
2006-01-18 17:43:02 -08:00
flush_dcache_page(page);
SetPageUptodate(page);
2009-09-23 13:00:27 -05:00
v9fs_readpage_to_fscache(inode, page);
2006-01-18 17:43:02 -08:00
retval = 0;
2007-07-10 17:57:28 -05:00
done:
2006-01-18 17:43:02 -08:00
kunmap(page);
unlock_page(page);
return retval;
}
2009-09-23 13:00:27 -05:00
/**
* v9fs_vfs_readpages - read a set of pages from 9P
*
* @filp: file being read
* @mapping: the address space
* @pages: list of pages to read
* @nr_pages: count of pages to read
*
*/
static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
struct list_head *pages, unsigned nr_pages)
{
int ret = 0;
struct inode *inode;
inode = mapping->host;
P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp);
ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages);
if (ret == 0)
return ret;
ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp);
P9_DPRINTK(P9_DEBUG_VFS, " = %d\n", ret);
return ret;
}
/**
* v9fs_release_page - release the private state associated with a page
*
* Returns 1 if the page can be released, false otherwise.
*/
static int v9fs_release_page(struct page *page, gfp_t gfp)
{
if (PagePrivate(page))
return 0;
return v9fs_fscache_release_page(page, gfp);
}
/**
* v9fs_invalidate_page - Invalidate a page completely or partially
*
* @page: structure to page
* @offset: offset in the page
*/
static void v9fs_invalidate_page(struct page *page, unsigned long offset)
{
if (offset == 0)
v9fs_fscache_invalidate_page(page);
}
/**
* v9fs_launder_page - Writeback a dirty page
* Since the writes go directly to the server, we simply return a 0
* here to indicate success.
*
* Returns 0 on success.
*/
static int v9fs_launder_page(struct page *page)
{
return 0;
}
2006-06-28 04:26:44 -07:00
const struct address_space_operations v9fs_addr_operations = {
2006-01-18 17:43:02 -08:00
.readpage = v9fs_vfs_readpage,
2009-09-23 13:00:27 -05:00
.readpages = v9fs_vfs_readpages,
.releasepage = v9fs_release_page,
.invalidatepage = v9fs_invalidate_page,
.launder_page = v9fs_launder_page,
2006-01-18 17:43:02 -08:00
};