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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/nfs/symlink.c
  3.  *
  4.  *  Copyright (C) 1992  Rick Sladkey
  5.  *
  6.  *  Optimization changes Copyright (C) 1994 Florian La Roche
  7.  *
  8.  *  Jun 7 1999, cache symlink lookups in the page cache.  -DaveM
  9.  *
  10.  *  nfs symlink handling code
  11.  */
  12. #define NFS_NEED_XDR_TYPES
  13. #include <linux/sched.h>
  14. #include <linux/errno.h>
  15. #include <linux/sunrpc/clnt.h>
  16. #include <linux/nfs.h>
  17. #include <linux/nfs2.h>
  18. #include <linux/nfs_fs.h>
  19. #include <linux/pagemap.h>
  20. #include <linux/stat.h>
  21. #include <linux/mm.h>
  22. #include <linux/slab.h>
  23. #include <linux/string.h>
  24. #include <linux/smp_lock.h>
  25. /* Symlink caching in the page cache is even more simplistic
  26.  * and straight-forward than readdir caching.
  27.  */
  28. static int nfs_symlink_filler(struct inode *inode, struct page *page)
  29. {
  30. int error;
  31. /* We place the length at the beginning of the page,
  32.  * in host byte order, followed by the string.  The
  33.  * XDR response verification will NULL terminate it.
  34.  */
  35. lock_kernel();
  36. error = NFS_PROTO(inode)->readlink(inode, page);
  37. unlock_kernel();
  38. if (error < 0)
  39. goto error;
  40. SetPageUptodate(page);
  41. UnlockPage(page);
  42. return 0;
  43. error:
  44. SetPageError(page);
  45. kunmap(page);
  46. UnlockPage(page);
  47. return -EIO;
  48. }
  49. static char *nfs_getlink(struct inode *inode, struct page **ppage)
  50. {
  51. struct page *page;
  52. u32 *p;
  53. /* Caller revalidated the directory inode already. */
  54. page = read_cache_page(&inode->i_data, 0,
  55. (filler_t *)nfs_symlink_filler, inode);
  56. if (IS_ERR(page))
  57. goto read_failed;
  58. if (!Page_Uptodate(page))
  59. goto getlink_read_error;
  60. *ppage = page;
  61. p = kmap(page);
  62. return (char*)(p+1);
  63. getlink_read_error:
  64. page_cache_release(page);
  65. return ERR_PTR(-EIO);
  66. read_failed:
  67. return (char*)page;
  68. }
  69. static int nfs_readlink(struct dentry *dentry, char *buffer, int buflen)
  70. {
  71. struct inode *inode = dentry->d_inode;
  72. struct page *page = NULL;
  73. int res = vfs_readlink(dentry,buffer,buflen,nfs_getlink(inode,&page));
  74. if (page) {
  75. kunmap(page);
  76. page_cache_release(page);
  77. }
  78. return res;
  79. }
  80. static int nfs_follow_link(struct dentry *dentry, struct nameidata *nd)
  81. {
  82. struct inode *inode = dentry->d_inode;
  83. struct page *page = NULL;
  84. int res = vfs_follow_link(nd, nfs_getlink(inode,&page));
  85. if (page) {
  86. kunmap(page);
  87. page_cache_release(page);
  88. }
  89. return res;
  90. }
  91. /*
  92.  * symlinks can't do much...
  93.  */
  94. struct inode_operations nfs_symlink_inode_operations = {
  95. readlink: nfs_readlink,
  96. follow_link: nfs_follow_link,
  97. revalidate: nfs_revalidate,
  98. setattr: nfs_notify_change,
  99. };