vfs_addr.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. #include <linux/module.h>
  26. #include <linux/errno.h>
  27. #include <linux/fs.h>
  28. #include <linux/file.h>
  29. #include <linux/stat.h>
  30. #include <linux/string.h>
  31. #include <linux/inet.h>
  32. #include <linux/pagemap.h>
  33. #include <linux/idr.h>
  34. #include <linux/sched.h>
  35. #include <net/9p/9p.h>
  36. #include <net/9p/client.h>
  37. #include "v9fs.h"
  38. #include "v9fs_vfs.h"
  39. #include "cache.h"
  40. /**
  41. * v9fs_vfs_readpage - read an entire page in from 9P
  42. *
  43. * @filp: file being read
  44. * @page: structure to page
  45. *
  46. */
  47. static int v9fs_vfs_readpage(struct file *filp, struct page *page)
  48. {
  49. int retval;
  50. loff_t offset;
  51. char *buffer;
  52. struct inode *inode;
  53. inode = page->mapping->host;
  54. P9_DPRINTK(P9_DEBUG_VFS, "\n");
  55. BUG_ON(!PageLocked(page));
  56. retval = v9fs_readpage_from_fscache(inode, page);
  57. if (retval == 0)
  58. return retval;
  59. buffer = kmap(page);
  60. offset = page_offset(page);
  61. retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset);
  62. if (retval < 0) {
  63. v9fs_uncache_page(inode, page);
  64. goto done;
  65. }
  66. memset(buffer + retval, 0, PAGE_CACHE_SIZE - retval);
  67. flush_dcache_page(page);
  68. SetPageUptodate(page);
  69. v9fs_readpage_to_fscache(inode, page);
  70. retval = 0;
  71. done:
  72. kunmap(page);
  73. unlock_page(page);
  74. return retval;
  75. }
  76. /**
  77. * v9fs_vfs_readpages - read a set of pages from 9P
  78. *
  79. * @filp: file being read
  80. * @mapping: the address space
  81. * @pages: list of pages to read
  82. * @nr_pages: count of pages to read
  83. *
  84. */
  85. static int v9fs_vfs_readpages(struct file *filp, struct address_space *mapping,
  86. struct list_head *pages, unsigned nr_pages)
  87. {
  88. int ret = 0;
  89. struct inode *inode;
  90. inode = mapping->host;
  91. P9_DPRINTK(P9_DEBUG_VFS, "inode: %p file: %p\n", inode, filp);
  92. ret = v9fs_readpages_from_fscache(inode, mapping, pages, &nr_pages);
  93. if (ret == 0)
  94. return ret;
  95. ret = read_cache_pages(mapping, pages, (void *)v9fs_vfs_readpage, filp);
  96. P9_DPRINTK(P9_DEBUG_VFS, " = %d\n", ret);
  97. return ret;
  98. }
  99. /**
  100. * v9fs_release_page - release the private state associated with a page
  101. *
  102. * Returns 1 if the page can be released, false otherwise.
  103. */
  104. static int v9fs_release_page(struct page *page, gfp_t gfp)
  105. {
  106. if (PagePrivate(page))
  107. return 0;
  108. return v9fs_fscache_release_page(page, gfp);
  109. }
  110. /**
  111. * v9fs_invalidate_page - Invalidate a page completely or partially
  112. *
  113. * @page: structure to page
  114. * @offset: offset in the page
  115. */
  116. static void v9fs_invalidate_page(struct page *page, unsigned long offset)
  117. {
  118. if (offset == 0)
  119. v9fs_fscache_invalidate_page(page);
  120. }
  121. /**
  122. * v9fs_launder_page - Writeback a dirty page
  123. * Since the writes go directly to the server, we simply return a 0
  124. * here to indicate success.
  125. *
  126. * Returns 0 on success.
  127. */
  128. static int v9fs_launder_page(struct page *page)
  129. {
  130. return 0;
  131. }
  132. const struct address_space_operations v9fs_addr_operations = {
  133. .readpage = v9fs_vfs_readpage,
  134. .readpages = v9fs_vfs_readpages,
  135. .releasepage = v9fs_release_page,
  136. .invalidatepage = v9fs_invalidate_page,
  137. .launder_page = v9fs_launder_page,
  138. };