X-Git-Url: http://nv-tegra.nvidia.com/gitweb/?p=linux-2.6.git;a=blobdiff_plain;f=fs%2F9p%2Fvfs_addr.c;h=90e38449f4b3a7dd0ab5c642e63bc504eb5adaef;hp=8100fb5171b70d1e20c26290cd37862d1856545c;hb=6f054164322bc6c1233402b9ed6b40d4af39a98f;hpb=147b31cf09ee493aa71c87c0dd2eef74b6b2aeba diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 8100fb5..90e3844 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c @@ -7,9 +7,8 @@ * Copyright (C) 2002 by Ron Minnich * * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -30,80 +29,135 @@ #include #include #include -#include #include -#include #include #include +#include +#include +#include -#include "debug.h" #include "v9fs.h" -#include "9p.h" #include "v9fs_vfs.h" -#include "fid.h" +#include "cache.h" /** * v9fs_vfs_readpage - read an entire page in from 9P * - * @file: file being read + * @filp: file being read * @page: structure to page * */ static int v9fs_vfs_readpage(struct file *filp, struct page *page) { - char *buffer = NULL; - int retval = -EIO; - loff_t offset = page_offset(page); - int count = PAGE_CACHE_SIZE; - struct inode *inode = filp->f_dentry->d_inode; - struct v9fs_session_info *v9ses = v9fs_inode2v9ses(inode); - int rsize = v9ses->maxdata - V9FS_IOHDRSZ; - struct v9fs_fid *v9f = filp->private_data; - struct v9fs_fcall *fcall = NULL; - int fid = v9f->fid; - int total = 0; - int result = 0; + int retval; + loff_t offset; + char *buffer; + struct inode *inode; - buffer = kmap(page); - do { - if (count < rsize) - rsize = count; - - result = v9fs_t_read(v9ses, fid, offset, rsize, &fcall); - - if (result < 0) { - printk(KERN_ERR "v9fs_t_read returned %d\n", - result); + inode = page->mapping->host; + P9_DPRINTK(P9_DEBUG_VFS, "\n"); - kfree(fcall); - goto UnmapAndUnlock; - } else - offset += result; + BUG_ON(!PageLocked(page)); - memcpy(buffer, fcall->params.rread.data, result); + retval = v9fs_readpage_from_fscache(inode, page); + if (retval == 0) + return retval; - count -= result; - buffer += result; - total += result; - - kfree(fcall); + buffer = kmap(page); + offset = page_offset(page); - if (result < rsize) - break; - } while (count); + retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset); + if (retval < 0) { + v9fs_uncache_page(inode, page); + goto done; + } - memset(buffer, 0, count); + memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval); flush_dcache_page(page); SetPageUptodate(page); + + v9fs_readpage_to_fscache(inode, page); retval = 0; -UnmapAndUnlock: +done: kunmap(page); unlock_page(page); return retval; } -struct address_space_operations v9fs_addr_operations = { +/** + * 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; +} + +const struct address_space_operations v9fs_addr_operations = { .readpage = v9fs_vfs_readpage, + .readpages = v9fs_vfs_readpages, + .releasepage = v9fs_release_page, + .invalidatepage = v9fs_invalidate_page, + .launder_page = v9fs_launder_page, };