Advertisement
Guest User

Untitled

a guest
Aug 20th, 2017
66
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.70 KB | None | 0 0
  1. #include <stdio.h>
  2. #include "ext2.h"
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <assert.h>
  6. #include <stdlib.h>
  7.  
  8. /* Given an i-node and a logical block number, this function looks up the corresponding
  9. physical block number, and obtains a reference to the block via the buffer cache. */
  10.  
  11. int get_inode_block(inode *ino, uint32_t lblock, int alloc, buffer **buf)
  12. {
  13. /* calculate references per block */
  14. uint32_t rpb = ino->fs->blocksize / 4;
  15. buffer *tempbuf; /* will point to buffer object */
  16. tempbuf = (buffer *)malloc(sizeof(buffer));
  17. int r; /* error code */
  18. /* Access method: Direct */
  19. if (lblock < 12) {
  20. if (0 > (r = bufcache_get(ino->fs->bc,ino->in.block[lblock],buf))) {
  21. /* perform any necessary cleanup */
  22. return r; /* notify caller of error */
  23. }
  24. return 0;
  25. }
  26. /* Access method: Triple Indirect */
  27. if (lblock >= (rpb*rpb + rpb + 12)) {
  28. uint32_t pblock = ino->in.block[14];
  29. int tripoffset = (lblock-12-rpb-rpb*rpb)/(rpb*rpb);
  30. if (0 > (r = bufcache_get(ino->fs->bc,pblock,&tempbuf))) {
  31. /* perform any necessary cleanup */
  32. return r; /* notify caller of error */
  33. }
  34. memcpy(&pblock,&tempbuf->data[tripoffset*4],4);
  35. bufcache_release(ino->fs->bc,tempbuf,0);
  36. int douboffset = ((lblock-12-rpb-rpb*rpb)/rpb)%rpb;
  37. if (0 > (r = bufcache_get(ino->fs->bc,pblock,&tempbuf))) {
  38. /* perform any necessary cleanup */
  39. return r; /* notify caller of error */
  40. }
  41. memcpy(&pblock,&tempbuf->data[douboffset*4],4);
  42. bufcache_release(ino->fs->bc,tempbuf,0);
  43. int singoffset = (lblock-12-rpb-rpb*rpb)%rpb;
  44. if (0 > (r = bufcache_get(ino->fs->bc,pblock,&tempbuf))) {
  45. /* perform any necessary cleanup */
  46. return r; /* notify caller of error */
  47. }
  48. memcpy(&pblock,&tempbuf->data[singoffset*4],4);
  49. bufcache_release(ino->fs->bc,tempbuf,0);
  50. if (0 > (r = bufcache_get(ino->fs->bc,pblock,buf))) {
  51. /* perform any necessary cleanup */
  52. return r; /* notify caller of error */
  53. }
  54. return 0;
  55. }
  56. /* Access method: Double Indirect */
  57. if (lblock >= rpb + 12) {
  58. uint32_t pblock = ino->in.block[13];
  59. int douboffset = (lblock-12-rpb)/rpb;
  60. if (0 > (r = bufcache_get(ino->fs->bc,pblock,&tempbuf))) {
  61. /* perform any necessary cleanup */
  62. return r; /* notify caller of error */
  63. }
  64. memcpy(&pblock,&tempbuf->data[douboffset*4],4);
  65. bufcache_release(ino->fs->bc,tempbuf,0);
  66. int singoffset = (lblock-12-rpb)%rpb;
  67. if (0 > (r = bufcache_get(ino->fs->bc,pblock,&tempbuf))) {
  68. /* perform any necessary cleanup */
  69. return r; /* notify caller of error */
  70. }
  71. memcpy(&pblock,&tempbuf->data[singoffset*4],4);
  72. bufcache_release(ino->fs->bc,tempbuf,0);
  73. if (0 > (r = bufcache_get(ino->fs->bc,pblock,buf))) {
  74. /* perform any necessary cleanup */
  75. return r; /* notify caller of error */
  76. }
  77. return 0;
  78. }
  79. /* Access method: Single Indirect */
  80. uint32_t pblock = ino->in.block[12];
  81. int singoffset = lblock - 12;
  82. if (0 > (r = bufcache_get(ino->fs->bc,pblock,&tempbuf))) {
  83. /* perform any necessary cleanup */
  84. return r; /* notify caller of error */
  85. }
  86. memcpy(&pblock,&tempbuf->data[singoffset*4],4);
  87. bufcache_release(ino->fs->bc,tempbuf,0);
  88. if (0 > (r = bufcache_get(ino->fs->bc,pblock,buf))) {
  89. /* perform any necessary cleanup */
  90. return r; /* notify caller of error */
  91. }
  92. return 0;
  93. }
  94.  
  95. /* Corresponds to the read system call, as described in the manpage (man 2 read). The
  96. only two differences with this function is that it also takes an offset as a parameter, and
  97. uses an i-node object to indicate the file to read from, instead of a file descriptor. */
  98.  
  99. ssize_t ext2_read(inode *ino, void *buf, off_t start, size_t len)
  100. {
  101. int size = ino->in.size;
  102. buffer *tempbuf;
  103. if (start >= size) {
  104. return 0;
  105. }
  106. /* calculate logical block */
  107. uint32_t lblockcounter = start/ino->fs->blocksize;
  108. int lefttoread = size - start;
  109. /* check to see the length limitation */
  110. if (lefttoread > len) {
  111. lefttoread = len;
  112. }
  113. int amountreaditer, amountreadtotal = 0;
  114. /* if start is non-zero then the first read is going to start from an offset */
  115. if (start%ino->fs->blocksize && lefttoread > 0) {
  116. /* fetch physical block */
  117. get_inode_block(ino, lblockcounter, 0, &tempbuf);
  118. /* set amount to be read this iteration */
  119. amountreaditer = ino->fs->blocksize - (start%ino->fs->blocksize);
  120. /* increase amount read and decrement amount left to read */
  121. amountreadtotal += amountreaditer;
  122. lefttoread -= amountreaditer;
  123. /* copy chunk of data into the buffer and increase the buffer position */
  124. memcpy(buf, tempbuf->data + start%ino->fs->blocksize, amountreaditer);
  125. buf = ((uint8_t *)buf) + amountreaditer;
  126. /* release resources and fetch next logical block */
  127. bufcache_release(ino->fs->bc,tempbuf,0);
  128. lblockcounter++;
  129. }
  130. /* continue reading blocks normally */
  131. while (lefttoread > 0) {
  132. /* fetch physical block */
  133. get_inode_block(ino, lblockcounter, 0, &tempbuf);
  134. /* check to see if the the current block is the last we need to read */
  135. if (lefttoread >= ino->fs->blocksize) {
  136. amountreaditer = ino->fs->blocksize;
  137. } else {
  138. /* set amount read this iteration */
  139. amountreaditer = lefttoread;
  140. }
  141. /* increase amount read and decrement amount left to read */
  142. amountreadtotal += amountreaditer;
  143. lefttoread -= amountreaditer;
  144. /* copy chunk of data into the buffer and increase the buffer position */
  145. memcpy(buf, tempbuf->data, amountreaditer);
  146. buf = ((uint8_t *)buf) + amountreaditer;
  147. /* release resources and fetch next logical block */
  148. bufcache_release(ino->fs->bc,tempbuf,0);
  149. lblockcounter++;
  150. }
  151. return amountreadtotal;
  152. }
  153.  
  154. ssize_t ext2_write(inode *ino, const void *buf, off_t start, size_t len)
  155. {
  156. return -ENOSYS;
  157. }
  158.  
  159. int ext2_truncate(inode *ino, off_t length)
  160. {
  161. return -ENOSYS;
  162. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement