read.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:13k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * linux/fs/nfs/read.c
  3.  *
  4.  * Block I/O for NFS
  5.  *
  6.  * Partial copy of Linus' read cache modifications to fs/nfs/file.c
  7.  * modified for async RPC by okir@monad.swb.de
  8.  *
  9.  * We do an ugly hack here in order to return proper error codes to the
  10.  * user program when a read request failed: since generic_file_read
  11.  * only checks the return value of inode->i_op->readpage() which is always 0
  12.  * for async RPC, we set the error bit of the page to 1 when an error occurs,
  13.  * and make nfs_readpage transmit requests synchronously when encountering this.
  14.  * This is only a small problem, though, since we now retry all operations
  15.  * within the RPC code when root squashing is suspected.
  16.  */
  17. #include <linux/config.h>
  18. #include <linux/sched.h>
  19. #include <linux/kernel.h>
  20. #include <linux/errno.h>
  21. #include <linux/fcntl.h>
  22. #include <linux/stat.h>
  23. #include <linux/mm.h>
  24. #include <linux/slab.h>
  25. #include <linux/pagemap.h>
  26. #include <linux/sunrpc/clnt.h>
  27. #include <linux/nfs_fs.h>
  28. #include <linux/nfs_page.h>
  29. #include <linux/nfs_flushd.h>
  30. #include <linux/smp_lock.h>
  31. #include <asm/system.h>
  32. #define NFSDBG_FACILITY NFSDBG_PAGECACHE
  33. struct nfs_read_data {
  34. struct rpc_task task;
  35. struct inode *inode;
  36. struct rpc_cred *cred;
  37. struct nfs_readargs args; /* XDR argument struct */
  38. struct nfs_readres res; /* ... and result struct */
  39. struct nfs_fattr fattr; /* fattr storage */
  40. struct list_head pages; /* Coalesced read requests */
  41. struct page *pagevec[NFS_READ_MAXIOV];
  42. };
  43. /*
  44.  * Local function declarations
  45.  */
  46. static void nfs_readpage_result(struct rpc_task *task);
  47. /* Hack for future NFS swap support */
  48. #ifndef IS_SWAPFILE
  49. # define IS_SWAPFILE(inode) (0)
  50. #endif
  51. static kmem_cache_t *nfs_rdata_cachep;
  52. static __inline__ struct nfs_read_data *nfs_readdata_alloc(void)
  53. {
  54. struct nfs_read_data   *p;
  55. p = kmem_cache_alloc(nfs_rdata_cachep, SLAB_NOFS);
  56. if (p) {
  57. memset(p, 0, sizeof(*p));
  58. INIT_LIST_HEAD(&p->pages);
  59. p->args.pages = p->pagevec;
  60. }
  61. return p;
  62. }
  63. static __inline__ void nfs_readdata_free(struct nfs_read_data *p)
  64. {
  65. kmem_cache_free(nfs_rdata_cachep, p);
  66. }
  67. static void nfs_readdata_release(struct rpc_task *task)
  68. {
  69.         struct nfs_read_data   *data = (struct nfs_read_data *)task->tk_calldata;
  70.         nfs_readdata_free(data);
  71. }
  72. /*
  73.  * Read a page synchronously.
  74.  */
  75. static int
  76. nfs_readpage_sync(struct file *file, struct inode *inode, struct page *page)
  77. {
  78. struct rpc_cred *cred = NULL;
  79. struct nfs_fattr fattr;
  80. unsigned int offset = 0;
  81. int rsize = NFS_SERVER(inode)->rsize;
  82. int result;
  83. int count = PAGE_CACHE_SIZE;
  84. int flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0;
  85. int eof;
  86. dprintk("NFS: nfs_readpage_sync(%p)n", page);
  87. if (file)
  88. cred = nfs_file_cred(file);
  89. /*
  90.  * This works now because the socket layer never tries to DMA
  91.  * into this buffer directly.
  92.  */
  93. do {
  94. if (count < rsize)
  95. rsize = count;
  96. dprintk("NFS: nfs_proc_read(%s, (%x/%Ld), %u, %u, %p)n",
  97. NFS_SERVER(inode)->hostname,
  98. inode->i_dev, (long long)NFS_FILEID(inode),
  99. offset, rsize, page);
  100. lock_kernel();
  101. result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags,
  102. offset, rsize, page, &eof);
  103. nfs_refresh_inode(inode, &fattr);
  104. unlock_kernel();
  105. /*
  106.  * Even if we had a partial success we can't mark the page
  107.  * cache valid.
  108.  */
  109. if (result < 0) {
  110. if (result == -EISDIR)
  111. result = -EINVAL;
  112. goto io_error;
  113. }
  114. count  -= result;
  115. offset += result;
  116. if (result < rsize) /* NFSv2ism */
  117. break;
  118. } while (count);
  119. if (count) {
  120. char *kaddr = kmap(page);
  121. memset(kaddr + offset, 0, count);
  122. kunmap(page);
  123. }
  124. flush_dcache_page(page);
  125. SetPageUptodate(page);
  126. if (PageError(page))
  127. ClearPageError(page);
  128. result = 0;
  129. io_error:
  130. UnlockPage(page);
  131. return result;
  132. }
  133. /*
  134.  * Add a request to the inode's asynchronous read list.
  135.  */
  136. static inline void
  137. nfs_mark_request_read(struct nfs_page *req)
  138. {
  139. struct inode *inode = req->wb_inode;
  140. spin_lock(&nfs_wreq_lock);
  141. nfs_list_add_request(req, &inode->u.nfs_i.read);
  142. inode->u.nfs_i.nread++;
  143. __nfs_add_lru(&NFS_SERVER(inode)->lru_read, req);
  144. spin_unlock(&nfs_wreq_lock);
  145. }
  146. static int
  147. nfs_readpage_async(struct file *file, struct inode *inode, struct page *page)
  148. {
  149. struct nfs_page *new;
  150. new = nfs_create_request(nfs_file_cred(file), inode, page, 0, PAGE_CACHE_SIZE);
  151. if (IS_ERR(new))
  152. return PTR_ERR(new);
  153. nfs_mark_request_read(new);
  154. if (inode->u.nfs_i.nread >= NFS_SERVER(inode)->rpages ||
  155.     page_index(page) == (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT)
  156. nfs_pagein_inode(inode, 0, 0);
  157. return 0;
  158. }
  159. /*
  160.  * Set up the NFS read request struct
  161.  */
  162. static void
  163. nfs_read_rpcsetup(struct list_head *head, struct nfs_read_data *data)
  164. {
  165. struct nfs_page *req;
  166. struct page **pages;
  167. unsigned int count;
  168. pages = data->args.pages;
  169. count = 0;
  170. while (!list_empty(head)) {
  171. struct nfs_page *req = nfs_list_entry(head->next);
  172. nfs_list_remove_request(req);
  173. nfs_list_add_request(req, &data->pages);
  174. *pages++ = req->wb_page;
  175. count += req->wb_bytes;
  176. }
  177. req = nfs_list_entry(data->pages.next);
  178. data->inode   = req->wb_inode;
  179. data->cred   = req->wb_cred;
  180. data->args.fh     = NFS_FH(req->wb_inode);
  181. data->args.offset = page_offset(req->wb_page) + req->wb_offset;
  182. data->args.pgbase = req->wb_offset;
  183. data->args.count  = count;
  184. data->res.fattr   = &data->fattr;
  185. data->res.count   = count;
  186. data->res.eof     = 0;
  187. }
  188. static void
  189. nfs_async_read_error(struct list_head *head)
  190. {
  191. struct nfs_page *req;
  192. struct page *page;
  193. while (!list_empty(head)) {
  194. req = nfs_list_entry(head->next);
  195. page = req->wb_page;
  196. nfs_list_remove_request(req);
  197. SetPageError(page);
  198. UnlockPage(page);
  199. nfs_clear_request(req);
  200. nfs_release_request(req);
  201. nfs_unlock_request(req);
  202. }
  203. }
  204. static int
  205. nfs_pagein_one(struct list_head *head, struct inode *inode)
  206. {
  207. struct rpc_task *task;
  208. struct rpc_clnt *clnt = NFS_CLIENT(inode);
  209. struct nfs_read_data *data;
  210. struct rpc_message msg;
  211. int flags;
  212. sigset_t oldset;
  213. data = nfs_readdata_alloc();
  214. if (!data)
  215. goto out_bad;
  216. task = &data->task;
  217. /* N.B. Do we need to test? Never called for swapfile inode */
  218. flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0);
  219. nfs_read_rpcsetup(head, data);
  220. /* Finalize the task. */
  221. rpc_init_task(task, clnt, nfs_readpage_result, flags);
  222. task->tk_calldata = data;
  223. /* Release requests */
  224. task->tk_release = nfs_readdata_release;
  225. #ifdef CONFIG_NFS_V3
  226. msg.rpc_proc = (NFS_PROTO(inode)->version == 3) ? NFS3PROC_READ : NFSPROC_READ;
  227. #else
  228. msg.rpc_proc = NFSPROC_READ;
  229. #endif
  230. msg.rpc_argp = &data->args;
  231. msg.rpc_resp = &data->res;
  232. msg.rpc_cred = data->cred;
  233. /* Start the async call */
  234. dprintk("NFS: %4d initiated read call (req %x/%Ld count %u.n",
  235. task->tk_pid,
  236. inode->i_dev, (long long)NFS_FILEID(inode),
  237. data->args.count);
  238. rpc_clnt_sigmask(clnt, &oldset);
  239. rpc_call_setup(task, &msg, 0);
  240. lock_kernel();
  241. rpc_execute(task);
  242. unlock_kernel();
  243. rpc_clnt_sigunmask(clnt, &oldset);
  244. return 0;
  245. out_bad:
  246. nfs_async_read_error(head);
  247. return -ENOMEM;
  248. }
  249. int
  250. nfs_pagein_list(struct list_head *head, int rpages)
  251. {
  252. LIST_HEAD(one_request);
  253. struct nfs_page *req;
  254. int error = 0;
  255. unsigned int pages = 0;
  256. while (!list_empty(head)) {
  257. pages += nfs_coalesce_requests(head, &one_request, rpages);
  258. req = nfs_list_entry(one_request.next);
  259. error = nfs_pagein_one(&one_request, req->wb_inode);
  260. if (error < 0)
  261. break;
  262. }
  263. if (error >= 0)
  264. return pages;
  265. nfs_async_read_error(head);
  266. return error;
  267. }
  268. /**
  269.  * nfs_scan_lru_read_timeout - Scan LRU list for timed out read requests
  270.  * @server: NFS superblock data
  271.  * @dst: destination list
  272.  *
  273.  * Moves a maximum of 'rpages' timed out requests from the NFS read LRU list.
  274.  * The elements are checked to ensure that they form a contiguous set
  275.  * of pages, and that they originated from the same file.
  276.  */
  277. int
  278. nfs_scan_lru_read_timeout(struct nfs_server *server, struct list_head *dst)
  279. {
  280. struct inode *inode;
  281. int npages;
  282. npages = nfs_scan_lru_timeout(&server->lru_read, dst, server->rpages);
  283. if (npages) {
  284. inode = nfs_list_entry(dst->next)->wb_inode;
  285. inode->u.nfs_i.nread -= npages;
  286. }
  287. return npages;
  288. }
  289. /**
  290.  * nfs_scan_lru_read - Scan LRU list for read requests
  291.  * @server: NFS superblock data
  292.  * @dst: destination list
  293.  *
  294.  * Moves a maximum of 'rpages' requests from the NFS read LRU list.
  295.  * The elements are checked to ensure that they form a contiguous set
  296.  * of pages, and that they originated from the same file.
  297.  */
  298. int
  299. nfs_scan_lru_read(struct nfs_server *server, struct list_head *dst)
  300. {
  301. struct inode *inode;
  302. int npages;
  303. npages = nfs_scan_lru(&server->lru_read, dst, server->rpages);
  304. if (npages) {
  305. inode = nfs_list_entry(dst->next)->wb_inode;
  306. inode->u.nfs_i.nread -= npages;
  307. }
  308. return npages;
  309. }
  310. /*
  311.  * nfs_scan_read - Scan an inode for read requests
  312.  * @inode: NFS inode to scan
  313.  * @dst: destination list
  314.  * @idx_start: lower bound of page->index to scan
  315.  * @npages: idx_start + npages sets the upper bound to scan
  316.  *
  317.  * Moves requests from the inode's read list.
  318.  * The requests are *not* checked to ensure that they form a contiguous set.
  319.  */
  320. static int
  321. nfs_scan_read(struct inode *inode, struct list_head *dst, unsigned long idx_start, unsigned int npages)
  322. {
  323. int res;
  324. res = nfs_scan_list(&inode->u.nfs_i.read, dst, NULL, idx_start, npages);
  325. inode->u.nfs_i.nread -= res;
  326. if ((inode->u.nfs_i.nread == 0) != list_empty(&inode->u.nfs_i.read))
  327. printk(KERN_ERR "NFS: desynchronized value of nfs_i.nread.n");
  328. return res;
  329. }
  330. int nfs_pagein_inode(struct inode *inode, unsigned long idx_start,
  331.      unsigned int npages)
  332. {
  333. LIST_HEAD(head);
  334. int res,
  335. error = 0;
  336. spin_lock(&nfs_wreq_lock);
  337. res = nfs_scan_read(inode, &head, idx_start, npages);
  338. spin_unlock(&nfs_wreq_lock);
  339. if (res)
  340. error = nfs_pagein_list(&head, NFS_SERVER(inode)->rpages);
  341. if (error < 0)
  342. return error;
  343. return res;
  344. }
  345. /*
  346.  * This is the callback from RPC telling us whether a reply was
  347.  * received or some error occurred (timeout or socket shutdown).
  348.  */
  349. static void
  350. nfs_readpage_result(struct rpc_task *task)
  351. {
  352. struct nfs_read_data *data = (struct nfs_read_data *) task->tk_calldata;
  353. struct inode *inode = data->inode;
  354. unsigned int count = data->res.count;
  355. dprintk("NFS: %4d nfs_readpage_result, (status %d)n",
  356. task->tk_pid, task->tk_status);
  357. if (nfs_async_handle_jukebox(task))
  358. return;
  359. nfs_refresh_inode(inode, &data->fattr);
  360. while (!list_empty(&data->pages)) {
  361. struct nfs_page *req = nfs_list_entry(data->pages.next);
  362. struct page *page = req->wb_page;
  363. nfs_list_remove_request(req);
  364. if (task->tk_status >= 0) {
  365. if (count < PAGE_CACHE_SIZE) {
  366. char *p = kmap(page);
  367. memset(p + count, 0, PAGE_CACHE_SIZE - count);
  368. kunmap(page);
  369. count = 0;
  370. if (data->res.eof)
  371. SetPageUptodate(page);
  372. else
  373. SetPageError(page);
  374. } else {
  375. count -= PAGE_CACHE_SIZE;
  376. SetPageUptodate(page);
  377. }
  378. } else
  379. SetPageError(page);
  380. flush_dcache_page(page);
  381. UnlockPage(page);
  382. dprintk("NFS: read (%x/%Ld %d@%Ld)n",
  383.                         req->wb_inode->i_dev,
  384.                         (long long)NFS_FILEID(req->wb_inode),
  385.                         req->wb_bytes,
  386.                         (long long)(page_offset(page) + req->wb_offset));
  387. nfs_clear_request(req);
  388. nfs_release_request(req);
  389. nfs_unlock_request(req);
  390. }
  391. }
  392. /*
  393.  * Read a page over NFS.
  394.  * We read the page synchronously in the following cases:
  395.  *  - The NFS rsize is smaller than PAGE_CACHE_SIZE. We could kludge our way
  396.  * around this by creating several consecutive read requests, but
  397.  * that's hardly worth it.
  398.  *  - The error flag is set for this page. This happens only when a
  399.  * previous async read operation failed.
  400.  */
  401. int
  402. nfs_readpage(struct file *file, struct page *page)
  403. {
  404. struct inode *inode = page->mapping->host;
  405. int error;
  406. dprintk("NFS: nfs_readpage (%p %ld@%lu)n",
  407. page, PAGE_CACHE_SIZE, page->index);
  408. /*
  409.  * Try to flush any pending writes to the file..
  410.  *
  411.  * NOTE! Because we own the page lock, there cannot
  412.  * be any new pending writes generated at this point
  413.  * for this page (other pages can be written to).
  414.  */
  415. error = nfs_wb_page(inode, page);
  416. if (error)
  417. goto out_error;
  418. if (!PageError(page) && NFS_SERVER(inode)->rsize >= PAGE_CACHE_SIZE) {
  419. error = nfs_readpage_async(file, inode, page);
  420. goto out;
  421. }
  422. error = nfs_readpage_sync(file, inode, page);
  423. if (error < 0 && IS_SWAPFILE(inode))
  424. printk("Aiee.. nfs swap-in of page failed!n");
  425. out:
  426. return error;
  427. out_error:
  428. UnlockPage(page);
  429. goto out;
  430. }
  431. int nfs_init_readpagecache(void)
  432. {
  433. nfs_rdata_cachep = kmem_cache_create("nfs_read_data",
  434.      sizeof(struct nfs_read_data),
  435.      0, SLAB_HWCACHE_ALIGN,
  436.      NULL, NULL);
  437. if (nfs_rdata_cachep == NULL)
  438. return -ENOMEM;
  439. return 0;
  440. }
  441. void nfs_destroy_readpagecache(void)
  442. {
  443. if (kmem_cache_destroy(nfs_rdata_cachep))
  444. printk(KERN_INFO "nfs_read_data: not all structures were freedn");
  445. }