《操作系统》的实验代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

167 lines
5.2 KiB

12 years ago
  1. #include <defs.h>
  2. #include <string.h>
  3. #include <dev.h>
  4. #include <sfs.h>
  5. #include <iobuf.h>
  6. #include <bitmap.h>
  7. #include <assert.h>
  8. //Basic block-level I/O routines
  9. /* sfs_rwblock_nolock - Basic block-level I/O routine for Rd/Wr one disk block,
  10. * without lock protect for mutex process on Rd/Wr disk block
  11. * @sfs: sfs_fs which will be process
  12. * @buf: the buffer uesed for Rd/Wr
  13. * @blkno: the NO. of disk block
  14. * @write: BOOL: Read or Write
  15. * @check: BOOL: if check (blono < sfs super.blocks)
  16. */
  17. static int
  18. sfs_rwblock_nolock(struct sfs_fs *sfs, void *buf, uint32_t blkno, bool write, bool check) {
  19. assert((blkno != 0 || !check) && blkno < sfs->super.blocks);
  20. struct iobuf __iob, *iob = iobuf_init(&__iob, buf, SFS_BLKSIZE, blkno * SFS_BLKSIZE);
  21. return dop_io(sfs->dev, iob, write);
  22. }
  23. /* sfs_rwblock - Basic block-level I/O routine for Rd/Wr N disk blocks ,
  24. * with lock protect for mutex process on Rd/Wr disk block
  25. * @sfs: sfs_fs which will be process
  26. * @buf: the buffer uesed for Rd/Wr
  27. * @blkno: the NO. of disk block
  28. * @nblks: Rd/Wr number of disk block
  29. * @write: BOOL: Read - 0 or Write - 1
  30. */
  31. static int
  32. sfs_rwblock(struct sfs_fs *sfs, void *buf, uint32_t blkno, uint32_t nblks, bool write) {
  33. int ret = 0;
  34. lock_sfs_io(sfs);
  35. {
  36. while (nblks != 0) {
  37. if ((ret = sfs_rwblock_nolock(sfs, buf, blkno, write, 1)) != 0) {
  38. break;
  39. }
  40. blkno ++, nblks --;
  41. buf += SFS_BLKSIZE;
  42. }
  43. }
  44. unlock_sfs_io(sfs);
  45. return ret;
  46. }
  47. /* sfs_rblock - The Wrap of sfs_rwblock function for Rd N disk blocks ,
  48. *
  49. * @sfs: sfs_fs which will be process
  50. * @buf: the buffer uesed for Rd/Wr
  51. * @blkno: the NO. of disk block
  52. * @nblks: Rd/Wr number of disk block
  53. */
  54. int
  55. sfs_rblock(struct sfs_fs *sfs, void *buf, uint32_t blkno, uint32_t nblks) {
  56. return sfs_rwblock(sfs, buf, blkno, nblks, 0);
  57. }
  58. /* sfs_wblock - The Wrap of sfs_rwblock function for Wr N disk blocks ,
  59. *
  60. * @sfs: sfs_fs which will be process
  61. * @buf: the buffer uesed for Rd/Wr
  62. * @blkno: the NO. of disk block
  63. * @nblks: Rd/Wr number of disk block
  64. */
  65. int
  66. sfs_wblock(struct sfs_fs *sfs, void *buf, uint32_t blkno, uint32_t nblks) {
  67. return sfs_rwblock(sfs, buf, blkno, nblks, 1);
  68. }
  69. /* sfs_rbuf - The Basic block-level I/O routine for Rd( non-block & non-aligned io) one disk block(using sfs->sfs_buffer)
  70. * with lock protect for mutex process on Rd/Wr disk block
  71. * @sfs: sfs_fs which will be process
  72. * @buf: the buffer uesed for Rd
  73. * @len: the length need to Rd
  74. * @blkno: the NO. of disk block
  75. * @offset: the offset in the content of disk block
  76. */
  77. int
  78. sfs_rbuf(struct sfs_fs *sfs, void *buf, size_t len, uint32_t blkno, off_t offset) {
  79. assert(offset >= 0 && offset < SFS_BLKSIZE && offset + len <= SFS_BLKSIZE);
  80. int ret;
  81. lock_sfs_io(sfs);
  82. {
  83. if ((ret = sfs_rwblock_nolock(sfs, sfs->sfs_buffer, blkno, 0, 1)) == 0) {
  84. memcpy(buf, sfs->sfs_buffer + offset, len);
  85. }
  86. }
  87. unlock_sfs_io(sfs);
  88. return ret;
  89. }
  90. /* sfs_wbuf - The Basic block-level I/O routine for Wr( non-block & non-aligned io) one disk block(using sfs->sfs_buffer)
  91. * with lock protect for mutex process on Rd/Wr disk block
  92. * @sfs: sfs_fs which will be process
  93. * @buf: the buffer uesed for Wr
  94. * @len: the length need to Wr
  95. * @blkno: the NO. of disk block
  96. * @offset: the offset in the content of disk block
  97. */
  98. int
  99. sfs_wbuf(struct sfs_fs *sfs, void *buf, size_t len, uint32_t blkno, off_t offset) {
  100. assert(offset >= 0 && offset < SFS_BLKSIZE && offset + len <= SFS_BLKSIZE);
  101. int ret;
  102. lock_sfs_io(sfs);
  103. {
  104. if ((ret = sfs_rwblock_nolock(sfs, sfs->sfs_buffer, blkno, 0, 1)) == 0) {
  105. memcpy(sfs->sfs_buffer + offset, buf, len);
  106. ret = sfs_rwblock_nolock(sfs, sfs->sfs_buffer, blkno, 1, 1);
  107. }
  108. }
  109. unlock_sfs_io(sfs);
  110. return ret;
  111. }
  112. /*
  113. * sfs_sync_super - write sfs->super (in memory) into disk (SFS_BLKN_SUPER, 1) with lock protect.
  114. */
  115. int
  116. sfs_sync_super(struct sfs_fs *sfs) {
  117. int ret;
  118. lock_sfs_io(sfs);
  119. {
  120. memset(sfs->sfs_buffer, 0, SFS_BLKSIZE);
  121. memcpy(sfs->sfs_buffer, &(sfs->super), sizeof(sfs->super));
  122. ret = sfs_rwblock_nolock(sfs, sfs->sfs_buffer, SFS_BLKN_SUPER, 1, 0);
  123. }
  124. unlock_sfs_io(sfs);
  125. return ret;
  126. }
  127. /*
  128. * sfs_sync_freemap - write sfs bitmap into disk (SFS_BLKN_FREEMAP, nblks) without lock protect.
  129. */
  130. int
  131. sfs_sync_freemap(struct sfs_fs *sfs) {
  132. uint32_t nblks = sfs_freemap_blocks(&(sfs->super));
  133. return sfs_wblock(sfs, bitmap_getdata(sfs->freemap, NULL), SFS_BLKN_FREEMAP, nblks);
  134. }
  135. /*
  136. * sfs_clear_block - write zero info into disk (blkno, nblks) with lock protect.
  137. * @sfs: sfs_fs which will be process
  138. * @blkno: the NO. of disk block
  139. * @nblks: Rd/Wr number of disk block
  140. */
  141. int
  142. sfs_clear_block(struct sfs_fs *sfs, uint32_t blkno, uint32_t nblks) {
  143. int ret;
  144. lock_sfs_io(sfs);
  145. {
  146. memset(sfs->sfs_buffer, 0, SFS_BLKSIZE);
  147. while (nblks != 0) {
  148. if ((ret = sfs_rwblock_nolock(sfs, sfs->sfs_buffer, blkno, 1, 1)) != 0) {
  149. break;
  150. }
  151. blkno ++, nblks --;
  152. }
  153. }
  154. unlock_sfs_io(sfs);
  155. return ret;
  156. }