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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * Super block/filesystem wide operations
  3.  *
  4.  * Copyright (C) 1996 Peter J. Braam <braam@maths.ox.ac.uk> and 
  5.  * Michael Callahan <callahan@maths.ox.ac.uk> 
  6.  * 
  7.  * Rewritten for Linux 2.1.  Peter Braam <braam@cs.cmu.edu>
  8.  * Copyright (C) Carnegie Mellon University
  9.  */
  10. #define __NO_VERSION__
  11. #include <linux/module.h>
  12. #include <linux/kernel.h>
  13. #include <linux/mm.h>
  14. #include <linux/string.h>
  15. #include <linux/stat.h>
  16. #include <linux/errno.h>
  17. #include <linux/locks.h>
  18. #include <linux/unistd.h>
  19. #include <linux/smp_lock.h>
  20. #include <linux/file.h>
  21. #include <asm/system.h>
  22. #include <asm/uaccess.h>
  23. #include <linux/fs.h>
  24. #include <linux/vmalloc.h>
  25. #include <linux/coda.h>
  26. #include <linux/coda_linux.h>
  27. #include <linux/coda_psdev.h>
  28. #include <linux/coda_fs_i.h>
  29. #include <linux/coda_cache.h>
  30. /* VFS super_block ops */
  31. static struct super_block *coda_read_super(struct super_block *, void *, int);
  32. static void coda_read_inode(struct inode *);
  33. static void coda_clear_inode(struct inode *);
  34. static void coda_put_super(struct super_block *);
  35. static int coda_statfs(struct super_block *sb, struct statfs *buf);
  36. /* exported operations */
  37. struct super_operations coda_super_operations =
  38. {
  39. read_inode: coda_read_inode,
  40. clear_inode: coda_clear_inode,
  41. put_super: coda_put_super,
  42. statfs: coda_statfs,
  43. };
  44. static int get_device_index(struct coda_mount_data *data)
  45. {
  46. struct file *file;
  47. struct inode *inode;
  48. int idx;
  49. if(data == NULL) {
  50. printk("coda_read_super: Bad mount datan");
  51. return -1;
  52. }
  53. if(data->version != CODA_MOUNT_VERSION) {
  54. printk("coda_read_super: Bad mount versionn");
  55. return -1;
  56. }
  57. file = fget(data->fd);
  58. inode = NULL;
  59. if(file)
  60. inode = file->f_dentry->d_inode;
  61. if(!inode || !S_ISCHR(inode->i_mode) ||
  62.    MAJOR(inode->i_rdev) != CODA_PSDEV_MAJOR) {
  63. if(file)
  64. fput(file);
  65. printk("coda_read_super: Bad filen");
  66. return -1;
  67. }
  68. idx = MINOR(inode->i_rdev);
  69. fput(file);
  70. if(idx < 0 || idx >= MAX_CODADEVS) {
  71. printk("coda_read_super: Bad minor numbern");
  72. return -1;
  73. }
  74. return idx;
  75. }
  76. static struct super_block * coda_read_super(struct super_block *sb, 
  77.     void *data, int silent)
  78. {
  79.         struct inode *root = 0; 
  80. struct coda_sb_info *sbi = NULL;
  81. struct venus_comm *vc = NULL;
  82.         ViceFid fid;
  83.         int error;
  84. int idx;
  85. idx = get_device_index((struct coda_mount_data *) data);
  86. /* Ignore errors in data, for backward compatibility */
  87. if(idx == -1)
  88. idx = 0;
  89. printk(KERN_INFO "coda_read_super: device index: %in", idx);
  90. vc = &coda_comms[idx];
  91. if (!vc->vc_inuse) {
  92. printk("coda_read_super: No pseudo devicen");
  93. return NULL;
  94. }
  95.         if ( vc->vc_sb ) {
  96. printk("coda_read_super: Device already mountedn");
  97. return NULL;
  98. }
  99. sbi = kmalloc(sizeof(struct coda_sb_info), GFP_KERNEL);
  100. if(!sbi) {
  101. return NULL;
  102. }
  103. vc->vc_sb = sb;
  104. sbi->sbi_sb = sb;
  105. sbi->sbi_vcomm = vc;
  106. INIT_LIST_HEAD(&sbi->sbi_cihead);
  107. init_MUTEX(&sbi->sbi_iget4_mutex);
  108.         sb->u.generic_sbp = sbi;
  109.         sb->s_blocksize = 1024; /* XXXXX  what do we put here?? */
  110.         sb->s_blocksize_bits = 10;
  111.         sb->s_magic = CODA_SUPER_MAGIC;
  112.         sb->s_op = &coda_super_operations;
  113. /* get root fid from Venus: this needs the root inode */
  114. error = venus_rootfid(sb, &fid);
  115. if ( error ) {
  116.         printk("coda_read_super: coda_get_rootfid failed with %dn",
  117.        error);
  118. goto error;
  119. }   
  120. printk("coda_read_super: rootfid is %sn", coda_f2s(&fid));
  121. /* make root inode */
  122.         error = coda_cnode_make(&root, &fid, sb);
  123.         if ( error || !root ) {
  124.     printk("Failure of coda_cnode_make for root: error %dn", error);
  125.     goto error;
  126. printk("coda_read_super: rootinode is %ld dev %dn", 
  127.        root->i_ino, root->i_dev);
  128. sb->s_root = d_alloc_root(root);
  129.         return sb;
  130.  error:
  131. if (sbi) {
  132. kfree(sbi);
  133. if(vc)
  134. vc->vc_sb = NULL;
  135. }
  136. if (root)
  137.                 iput(root);
  138.         return NULL;
  139. }
  140. static void coda_put_super(struct super_block *sb)
  141. {
  142.         struct coda_sb_info *sbi;
  143. sbi = coda_sbp(sb);
  144. sbi->sbi_vcomm->vc_sb = NULL;
  145.         list_del_init(&sbi->sbi_cihead);
  146. printk("Coda: Bye bye.n");
  147. kfree(sbi);
  148. }
  149. /* all filling in of inodes postponed until lookup */
  150. static void coda_read_inode(struct inode *inode)
  151. {
  152. struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
  153. struct coda_inode_info *cii;
  154.         if (!sbi) BUG();
  155. cii = ITOC(inode);
  156. if (!coda_isnullfid(&cii->c_fid)) {
  157.             printk("coda_read_inode: initialized inode");
  158.             return;
  159.         }
  160. cii->c_mapcount = 0;
  161. list_add(&cii->c_cilist, &sbi->sbi_cihead);
  162. }
  163. static void coda_clear_inode(struct inode *inode)
  164. {
  165. struct coda_inode_info *cii = ITOC(inode);
  166.         CDEBUG(D_SUPER, " inode->ino: %ld, count: %dn", 
  167.        inode->i_ino, atomic_read(&inode->i_count));        
  168. CDEBUG(D_DOWNCALL, "clearing inode: %ld, %xn", inode->i_ino, cii->c_flags);
  169.         list_del_init(&cii->c_cilist);
  170. coda_cache_clear_inode(inode);
  171. }
  172. int coda_notify_change(struct dentry *de, struct iattr *iattr)
  173. {
  174. struct inode *inode = de->d_inode;
  175. struct coda_vattr vattr;
  176. int error;
  177. memset(&vattr, 0, sizeof(vattr)); 
  178. inode->i_ctime = CURRENT_TIME;
  179. coda_iattr_to_vattr(iattr, &vattr);
  180. vattr.va_type = C_VNON; /* cannot set type */
  181. CDEBUG(D_SUPER, "vattr.va_mode %on", vattr.va_mode);
  182. /* Venus is responsible for truncating the container-file!!! */
  183. error = venus_setattr(inode->i_sb, coda_i2f(inode), &vattr);
  184. if ( !error ) {
  185.         coda_vattr_to_iattr(inode, &vattr); 
  186. coda_cache_clear_inode(inode);
  187. }
  188. CDEBUG(D_SUPER, "inode.i_mode %o, error %dn", inode->i_mode, error);
  189. return error;
  190. }
  191. struct inode_operations coda_file_inode_operations = {
  192. permission: coda_permission,
  193. revalidate: coda_revalidate_inode,
  194. setattr: coda_notify_change,
  195. };
  196. static int coda_statfs(struct super_block *sb, struct statfs *buf)
  197. {
  198. int error;
  199. error = venus_statfs(sb, buf);
  200. if (error) {
  201. /* fake something like AFS does */
  202. buf->f_blocks = 9000000;
  203. buf->f_bfree  = 9000000;
  204. buf->f_bavail = 9000000;
  205. buf->f_files  = 9000000;
  206. buf->f_ffree  = 9000000;
  207. }
  208. /* and fill in the rest */
  209. buf->f_type = CODA_SUPER_MAGIC;
  210. buf->f_bsize = 1024;
  211. buf->f_namelen = CODA_MAXNAMLEN;
  212. return 0; 
  213. }
  214. /* init_coda: used by filesystems.c to register coda */
  215. DECLARE_FSTYPE( coda_fs_type, "coda", coda_read_super, 0);