symlink.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:2k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/affs/symlink.c
  3.  *
  4.  *  1995  Hans-Joachim Widmaier - Modified for affs.
  5.  *
  6.  *  Copyright (C) 1991, 1992  Linus Torvalds
  7.  *
  8.  *  affs symlink handling code
  9.  */
  10. #include <linux/errno.h>
  11. #include <linux/fs.h>
  12. #include <linux/stat.h>
  13. #include <linux/affs_fs.h>
  14. #include <linux/amigaffs.h>
  15. #include <linux/pagemap.h>
  16. #include <linux/smp_lock.h>
  17. static int affs_symlink_readpage(struct file *file, struct page *page)
  18. {
  19. struct buffer_head *bh;
  20. struct inode *inode = page->mapping->host;
  21. char *link = kmap(page);
  22. struct slink_front *lf;
  23. int err;
  24. int  i, j;
  25. char  c;
  26. char  lc;
  27. char *pf;
  28. pr_debug("AFFS: follow_link(ino=%lu)n",inode->i_ino);
  29. err = -EIO;
  30. lock_kernel();
  31. bh = affs_bread(inode->i_sb, inode->i_ino);
  32. unlock_kernel();
  33. if (!bh)
  34. goto fail;
  35. i  = 0;
  36. j  = 0;
  37. lf = (struct slink_front *)bh->b_data;
  38. lc = 0;
  39. pf = inode->i_sb->u.affs_sb.s_prefix ? inode->i_sb->u.affs_sb.s_prefix : "/";
  40. if (strchr(lf->symname,':')) { /* Handle assign or volume name */
  41. while (i < 1023 && (c = pf[i]))
  42. link[i++] = c;
  43. while (i < 1023 && lf->symname[j] != ':')
  44. link[i++] = lf->symname[j++];
  45. if (i < 1023)
  46. link[i++] = '/';
  47. j++;
  48. lc = '/';
  49. }
  50. while (i < 1023 && (c = lf->symname[j])) {
  51. if (c == '/' && lc == '/' && i < 1020) { /* parent dir */
  52. link[i++] = '.';
  53. link[i++] = '.';
  54. }
  55. link[i++] = c;
  56. lc = c;
  57. j++;
  58. }
  59. link[i] = '';
  60. lock_kernel();
  61. affs_brelse(bh);
  62. unlock_kernel();
  63. SetPageUptodate(page);
  64. kunmap(page);
  65. UnlockPage(page);
  66. return 0;
  67. fail:
  68. SetPageError(page);
  69. kunmap(page);
  70. UnlockPage(page);
  71. return err;
  72. }
  73. struct address_space_operations affs_symlink_aops = {
  74. readpage: affs_symlink_readpage,
  75. };
  76. struct inode_operations affs_symlink_inode_operations = {
  77. readlink: page_readlink,
  78. follow_link: page_follow_link,
  79. setattr: affs_notify_change,
  80. };