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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/fs/ufs/cylinder.c
  3.  *
  4.  * Copyright (C) 1998
  5.  * Daniel Pirkl <daniel.pirkl@email.cz>
  6.  * Charles University, Faculty of Mathematics and Physics
  7.  *
  8.  *  ext2 - inode (block) bitmap caching inspired
  9.  */
  10. #include <linux/fs.h>
  11. #include <linux/ufs_fs.h>
  12. #include <linux/sched.h>
  13. #include <linux/stat.h>
  14. #include <linux/string.h>
  15. #include <linux/locks.h>
  16. #include <asm/bitops.h>
  17. #include <asm/byteorder.h>
  18. #include "swab.h"
  19. #include "util.h"
  20. #undef UFS_CYLINDER_DEBUG
  21. #ifdef UFS_CYLINDER_DEBUG
  22. #define UFSD(x) printk("(%s, %d), %s:", __FILE__, __LINE__, __FUNCTION__); printk x;
  23. #else
  24. #define UFSD(x)
  25. #endif
  26. /*
  27.  * Read cylinder group into cache. The memory space for ufs_cg_private_info
  28.  * structure is already allocated during ufs_read_super.
  29.  */
  30. static void ufs_read_cylinder (struct super_block * sb,
  31. unsigned cgno, unsigned bitmap_nr)
  32. {
  33. struct ufs_sb_private_info * uspi;
  34. struct ufs_cg_private_info * ucpi;
  35. struct ufs_cylinder_group * ucg;
  36. unsigned i, j;
  37. UFSD(("ENTER, cgno %u, bitmap_nr %un", cgno, bitmap_nr))
  38. uspi = sb->u.ufs_sb.s_uspi;
  39. ucpi = sb->u.ufs_sb.s_ucpi[bitmap_nr];
  40. ucg = (struct ufs_cylinder_group *)sb->u.ufs_sb.s_ucg[cgno]->b_data;
  41. UCPI_UBH->fragment = ufs_cgcmin(cgno);
  42. UCPI_UBH->count = uspi->s_cgsize >> sb->s_blocksize_bits;
  43. /*
  44.  * We have already the first fragment of cylinder group block in buffer
  45.  */
  46. UCPI_UBH->bh[0] = sb->u.ufs_sb.s_ucg[cgno];
  47. for (i = 1; i < UCPI_UBH->count; i++)
  48. if (!(UCPI_UBH->bh[i] = sb_bread(sb, UCPI_UBH->fragment + i)))
  49. goto failed;
  50. sb->u.ufs_sb.s_cgno[bitmap_nr] = cgno;
  51. ucpi->c_cgx = fs32_to_cpu(sb, ucg->cg_cgx);
  52. ucpi->c_ncyl = fs16_to_cpu(sb, ucg->cg_ncyl);
  53. ucpi->c_niblk = fs16_to_cpu(sb, ucg->cg_niblk);
  54. ucpi->c_ndblk = fs32_to_cpu(sb, ucg->cg_ndblk);
  55. ucpi->c_rotor = fs32_to_cpu(sb, ucg->cg_rotor);
  56. ucpi->c_frotor = fs32_to_cpu(sb, ucg->cg_frotor);
  57. ucpi->c_irotor = fs32_to_cpu(sb, ucg->cg_irotor);
  58. ucpi->c_btotoff = fs32_to_cpu(sb, ucg->cg_btotoff);
  59. ucpi->c_boff = fs32_to_cpu(sb, ucg->cg_boff);
  60. ucpi->c_iusedoff = fs32_to_cpu(sb, ucg->cg_iusedoff);
  61. ucpi->c_freeoff = fs32_to_cpu(sb, ucg->cg_freeoff);
  62. ucpi->c_nextfreeoff = fs32_to_cpu(sb, ucg->cg_nextfreeoff);
  63. ucpi->c_clustersumoff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clustersumoff);
  64. ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff);
  65. ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks);
  66. UFSD(("EXITn"))
  67. return;
  68. failed:
  69. for (j = 1; j < i; j++)
  70. brelse (sb->u.ufs_sb.s_ucg[j]);
  71. sb->u.ufs_sb.s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
  72. ufs_error (sb, "ufs_read_cylinder", "can't read cylinder group block %u", cgno);
  73. }
  74. /*
  75.  * Remove cylinder group from cache, doesn't release memory
  76.  * allocated for cylinder group (this is done at ufs_put_super only).
  77.  */
  78. void ufs_put_cylinder (struct super_block * sb, unsigned bitmap_nr)
  79. {
  80. struct ufs_sb_private_info * uspi; 
  81. struct ufs_cg_private_info * ucpi;
  82. struct ufs_cylinder_group * ucg;
  83. unsigned i;
  84. UFSD(("ENTER, bitmap_nr %un", bitmap_nr))
  85. uspi = sb->u.ufs_sb.s_uspi;
  86. if (sb->u.ufs_sb.s_cgno[bitmap_nr] == UFS_CGNO_EMPTY) {
  87. UFSD(("EXITn"))
  88. return;
  89. }
  90. ucpi = sb->u.ufs_sb.s_ucpi[bitmap_nr];
  91. ucg = ubh_get_ucg(UCPI_UBH);
  92. if (uspi->s_ncg > UFS_MAX_GROUP_LOADED && bitmap_nr >= sb->u.ufs_sb.s_cg_loaded) {
  93. ufs_panic (sb, "ufs_put_cylinder", "internal error");
  94. return;
  95. }
  96. /*
  97.  * rotor is not so important data, so we put it to disk 
  98.  * at the end of working with cylinder
  99.  */
  100. ucg->cg_rotor = cpu_to_fs32(sb, ucpi->c_rotor);
  101. ucg->cg_frotor = cpu_to_fs32(sb, ucpi->c_frotor);
  102. ucg->cg_irotor = cpu_to_fs32(sb, ucpi->c_irotor);
  103. ubh_mark_buffer_dirty (UCPI_UBH);
  104. for (i = 1; i < UCPI_UBH->count; i++) {
  105. brelse (UCPI_UBH->bh[i]);
  106. }
  107. sb->u.ufs_sb.s_cgno[bitmap_nr] = UFS_CGNO_EMPTY;
  108. UFSD(("EXITn"))
  109. }
  110. /*
  111.  * Find cylinder group in cache and return it as pointer.
  112.  * If cylinder group is not in cache, we will load it from disk.
  113.  *
  114.  * The cache is managed by LRU algorithm. 
  115.  */
  116. struct ufs_cg_private_info * ufs_load_cylinder (
  117. struct super_block * sb, unsigned cgno)
  118. {
  119. struct ufs_sb_private_info * uspi;
  120. struct ufs_cg_private_info * ucpi;
  121. unsigned cg, i, j;
  122. UFSD(("ENTER, cgno %un", cgno))
  123. uspi = sb->u.ufs_sb.s_uspi;
  124. if (cgno >= uspi->s_ncg) {
  125. ufs_panic (sb, "ufs_load_cylinder", "internal error, high number of cg");
  126. return NULL;
  127. }
  128. /*
  129.  * Cylinder group number cg it in cache and it was last used
  130.  */
  131. if (sb->u.ufs_sb.s_cgno[0] == cgno) {
  132. UFSD(("EXITn"))
  133. return sb->u.ufs_sb.s_ucpi[0];
  134. }
  135. /*
  136.  * Number of cylinder groups is not higher than UFS_MAX_GROUP_LOADED
  137.  */
  138. if (uspi->s_ncg <= UFS_MAX_GROUP_LOADED) {
  139. if (sb->u.ufs_sb.s_cgno[cgno] != UFS_CGNO_EMPTY) {
  140. if (sb->u.ufs_sb.s_cgno[cgno] != cgno) {
  141. ufs_panic (sb, "ufs_load_cylinder", "internal error, wrong number of cg in cache");
  142. UFSD(("EXIT (FAILED)n"))
  143. return NULL;
  144. }
  145. else {
  146. UFSD(("EXITn"))
  147. return sb->u.ufs_sb.s_ucpi[cgno];
  148. }
  149. } else {
  150. ufs_read_cylinder (sb, cgno, cgno);
  151. UFSD(("EXITn"))
  152. return sb->u.ufs_sb.s_ucpi[cgno];
  153. }
  154. }
  155. /*
  156.  * Cylinder group number cg is in cache but it was not last used, 
  157.  * we will move to the first position
  158.  */
  159. for (i = 0; i < sb->u.ufs_sb.s_cg_loaded && sb->u.ufs_sb.s_cgno[i] != cgno; i++);
  160. if (i < sb->u.ufs_sb.s_cg_loaded && sb->u.ufs_sb.s_cgno[i] == cgno) {
  161. cg = sb->u.ufs_sb.s_cgno[i];
  162. ucpi = sb->u.ufs_sb.s_ucpi[i];
  163. for (j = i; j > 0; j--) {
  164. sb->u.ufs_sb.s_cgno[j] = sb->u.ufs_sb.s_cgno[j-1];
  165. sb->u.ufs_sb.s_ucpi[j] = sb->u.ufs_sb.s_ucpi[j-1];
  166. }
  167. sb->u.ufs_sb.s_cgno[0] = cg;
  168. sb->u.ufs_sb.s_ucpi[0] = ucpi;
  169. /*
  170.  * Cylinder group number cg is not in cache, we will read it from disk
  171.  * and put it to the first position
  172.  */
  173. } else {
  174. if (sb->u.ufs_sb.s_cg_loaded < UFS_MAX_GROUP_LOADED)
  175. sb->u.ufs_sb.s_cg_loaded++;
  176. else
  177. ufs_put_cylinder (sb, UFS_MAX_GROUP_LOADED-1);
  178. ucpi = sb->u.ufs_sb.s_ucpi[sb->u.ufs_sb.s_cg_loaded - 1];
  179. for (j = sb->u.ufs_sb.s_cg_loaded - 1; j > 0; j--) {
  180. sb->u.ufs_sb.s_cgno[j] = sb->u.ufs_sb.s_cgno[j-1];
  181. sb->u.ufs_sb.s_ucpi[j] = sb->u.ufs_sb.s_ucpi[j-1];
  182. }
  183. sb->u.ufs_sb.s_ucpi[0] = ucpi;
  184. ufs_read_cylinder (sb, cgno, 0);
  185. }
  186. UFSD(("EXITn"))
  187. return sb->u.ufs_sb.s_ucpi[0];
  188. }