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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* cnode related routines for the coda kernel code
  2.    (C) 1996 Peter Braam
  3.    */
  4. #include <linux/types.h>
  5. #include <linux/string.h>
  6. #include <linux/time.h>
  7. #include <linux/coda.h>
  8. #include <linux/coda_linux.h>
  9. #include <linux/coda_fs_i.h>
  10. #include <linux/coda_psdev.h>
  11. extern int coda_debug;
  12. inline int coda_fideq(ViceFid *fid1, ViceFid *fid2)
  13. {
  14. if (fid1->Vnode != fid2->Vnode)   return 0;
  15. if (fid1->Volume != fid2->Volume) return 0;
  16. if (fid1->Unique != fid2->Unique) return 0;
  17. return 1;
  18. }
  19. inline int coda_isnullfid(ViceFid *fid)
  20. {
  21. if (fid->Vnode || fid->Volume || fid->Unique) return 0;
  22. return 1;
  23. }
  24. static int coda_inocmp(struct inode *inode, unsigned long ino, void *opaque)
  25. {
  26. return (coda_fideq((ViceFid *)opaque, &(ITOC(inode)->c_fid)));
  27. }
  28. static struct inode_operations coda_symlink_inode_operations = {
  29. readlink: page_readlink,
  30. follow_link: page_follow_link,
  31. setattr: coda_notify_change,
  32. };
  33. /* cnode.c */
  34. static void coda_fill_inode(struct inode *inode, struct coda_vattr *attr)
  35. {
  36.         CDEBUG(D_SUPER, "ino: %ldn", inode->i_ino);
  37.         if (coda_debug & D_SUPER ) 
  38. print_vattr(attr);
  39.         coda_vattr_to_iattr(inode, attr);
  40.         if (S_ISREG(inode->i_mode)) {
  41.                 inode->i_op = &coda_file_inode_operations;
  42.                 inode->i_fop = &coda_file_operations;
  43.         } else if (S_ISDIR(inode->i_mode)) {
  44.                 inode->i_op = &coda_dir_inode_operations;
  45.                 inode->i_fop = &coda_dir_operations;
  46.         } else if (S_ISLNK(inode->i_mode)) {
  47. inode->i_op = &coda_symlink_inode_operations;
  48. inode->i_data.a_ops = &coda_symlink_aops;
  49. inode->i_mapping = &inode->i_data;
  50. } else
  51.                 init_special_inode(inode, inode->i_mode, attr->va_rdev);
  52. }
  53. struct inode * coda_iget(struct super_block * sb, ViceFid * fid,
  54.  struct coda_vattr * attr)
  55. {
  56. struct inode *inode;
  57. struct coda_inode_info *cii;
  58. ino_t ino = coda_f2i(fid);
  59. struct coda_sb_info *sbi = coda_sbp(sb);
  60. down(&sbi->sbi_iget4_mutex);
  61. inode = iget4(sb, ino, coda_inocmp, fid);
  62. if ( !inode ) { 
  63. CDEBUG(D_CNODE, "coda_iget: no inoden");
  64. up(&sbi->sbi_iget4_mutex);
  65. return ERR_PTR(-ENOMEM);
  66. }
  67. /* check if the inode is already initialized */
  68. cii = ITOC(inode);
  69. if (coda_isnullfid(&cii->c_fid))
  70. /* new, empty inode found... initializing */
  71. cii->c_fid = *fid;
  72. up(&sbi->sbi_iget4_mutex);
  73. /* always replace the attributes, type might have changed */
  74. coda_fill_inode(inode, attr);
  75. return inode;
  76. }
  77. /* this is effectively coda_iget:
  78.    - get attributes (might be cached)
  79.    - get the inode for the fid using vfs iget
  80.    - link the two up if this is needed
  81.    - fill in the attributes
  82. */
  83. int coda_cnode_make(struct inode **inode, ViceFid *fid, struct super_block *sb)
  84. {
  85.         struct coda_vattr attr;
  86.         int error;
  87.         
  88. /* We get inode numbers from Venus -- see venus source */
  89. error = venus_getattr(sb, fid, &attr);
  90. if ( error ) {
  91.     CDEBUG(D_CNODE, 
  92.    "coda_cnode_make: coda_getvattr returned %d for %s.n", 
  93.    error, coda_f2s(fid));
  94.     *inode = NULL;
  95.     return error;
  96. *inode = coda_iget(sb, fid, &attr);
  97. if ( IS_ERR(*inode) ) {
  98. printk("coda_cnode_make: coda_iget failedn");
  99.                 return PTR_ERR(*inode);
  100.         }
  101. CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %sn",
  102. (*inode)->i_ino, atomic_read(&(*inode)->i_count), 
  103. coda_f2s(&ITOC(*inode)->c_fid));
  104. return 0;
  105. }
  106. void coda_replace_fid(struct inode *inode, struct ViceFid *oldfid, 
  107.       struct ViceFid *newfid)
  108. {
  109. struct coda_inode_info *cii;
  110. cii = ITOC(inode);
  111. if (!coda_fideq(&cii->c_fid, oldfid))
  112. BUG();
  113. /* replace fid and rehash inode */
  114. /* XXX we probably need to hold some lock here! */
  115. remove_inode_hash(inode);
  116. cii->c_fid = *newfid;
  117. inode->i_ino = coda_f2i(newfid);
  118. insert_inode_hash(inode);
  119. }
  120. /* convert a fid to an inode. */
  121. struct inode *coda_fid_to_inode(ViceFid *fid, struct super_block *sb) 
  122. {
  123. ino_t nr;
  124. struct inode *inode;
  125. struct coda_inode_info *cii;
  126. struct coda_sb_info *sbi;
  127. if ( !sb ) {
  128. printk("coda_fid_to_inode: no sb!n");
  129. return NULL;
  130. }
  131. CDEBUG(D_INODE, "%sn", coda_f2s(fid));
  132. sbi = coda_sbp(sb);
  133. nr = coda_f2i(fid);
  134. down(&sbi->sbi_iget4_mutex);
  135. inode = iget4(sb, nr, coda_inocmp, fid);
  136. if ( !inode ) {
  137. printk("coda_fid_to_inode: null from iget, sb %p, nr %ld.n",
  138.        sb, (long)nr);
  139. goto out_unlock;
  140. }
  141. cii = ITOC(inode);
  142. /* The inode could already be purged due to memory pressure */
  143. if (coda_isnullfid(&cii->c_fid)) {
  144. inode->i_nlink = 0;
  145. iput(inode);
  146. goto out_unlock;
  147. }
  148.         CDEBUG(D_INODE, "found %ldn", inode->i_ino);
  149. up(&sbi->sbi_iget4_mutex);
  150. return inode;
  151. out_unlock:
  152. up(&sbi->sbi_iget4_mutex);
  153. return NULL;
  154. }
  155. /* the CONTROL inode is made without asking attributes from Venus */
  156. int coda_cnode_makectl(struct inode **inode, struct super_block *sb)
  157. {
  158. int error = 0;
  159. *inode = iget(sb, CTL_INO);
  160. if ( *inode ) {
  161. (*inode)->i_op = &coda_ioctl_inode_operations;
  162. (*inode)->i_fop = &coda_ioctl_operations;
  163. (*inode)->i_mode = 0444;
  164. error = 0;
  165. } else { 
  166. error = -ENOMEM;
  167. }
  168.     
  169. return error;
  170. }