brel_ma.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /*
  2. * brel_ma.c
  3. *
  4. * Copyright (C) 1996, 1997 Theodore Ts'o.
  5. *
  6. * TODO: rewrite to not use a direct array!!! (Fortunately this
  7. * module isn't really used yet.)
  8. *
  9. * %Begin-Header%
  10. * This file may be redistributed under the terms of the GNU Public
  11. * License.
  12. * %End-Header%
  13. */
  14. #include <fcntl.h>
  15. #include <stdio.h>
  16. #include <string.h>
  17. #if HAVE_UNISTD_H
  18. #include <unistd.h>
  19. #endif
  20. #if HAVE_ERRNO_H
  21. #include <errno.h>
  22. #endif
  23. #include "ext2_fs.h"
  24. #include "ext2fs.h"
  25. #include "brel.h"
  26. static errcode_t bma_put(ext2_brel brel, blk_t old,
  27. struct ext2_block_relocate_entry *ent);
  28. static errcode_t bma_get(ext2_brel brel, blk_t old,
  29. struct ext2_block_relocate_entry *ent);
  30. static errcode_t bma_start_iter(ext2_brel brel);
  31. static errcode_t bma_next(ext2_brel brel, blk_t *old,
  32. struct ext2_block_relocate_entry *ent);
  33. static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new);
  34. static errcode_t bma_delete(ext2_brel brel, blk_t old);
  35. static errcode_t bma_free(ext2_brel brel);
  36. struct brel_ma {
  37. __u32 magic;
  38. blk_t max_block;
  39. struct ext2_block_relocate_entry *entries;
  40. };
  41. errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
  42. ext2_brel *new_brel)
  43. {
  44. ext2_brel brel = 0;
  45. errcode_t retval;
  46. struct brel_ma *ma = 0;
  47. size_t size;
  48. *new_brel = 0;
  49. /*
  50. * Allocate memory structures
  51. */
  52. retval = ext2fs_get_mem(sizeof(struct ext2_block_relocation_table),
  53. &brel);
  54. if (retval)
  55. goto errout;
  56. memset(brel, 0, sizeof(struct ext2_block_relocation_table));
  57. retval = ext2fs_get_mem(strlen(name)+1, &brel->name);
  58. if (retval)
  59. goto errout;
  60. strcpy(brel->name, name);
  61. retval = ext2fs_get_mem(sizeof(struct brel_ma), &ma);
  62. if (retval)
  63. goto errout;
  64. memset(ma, 0, sizeof(struct brel_ma));
  65. brel->priv_data = ma;
  66. size = (size_t) (sizeof(struct ext2_block_relocate_entry) *
  67. (max_block+1));
  68. retval = ext2fs_get_mem(size, &ma->entries);
  69. if (retval)
  70. goto errout;
  71. memset(ma->entries, 0, size);
  72. ma->max_block = max_block;
  73. /*
  74. * Fill in the brel data structure
  75. */
  76. brel->put = bma_put;
  77. brel->get = bma_get;
  78. brel->start_iter = bma_start_iter;
  79. brel->next = bma_next;
  80. brel->move = bma_move;
  81. brel->delete = bma_delete;
  82. brel->free = bma_free;
  83. *new_brel = brel;
  84. return 0;
  85. errout:
  86. bma_free(brel);
  87. return retval;
  88. }
  89. static errcode_t bma_put(ext2_brel brel, blk_t old,
  90. struct ext2_block_relocate_entry *ent)
  91. {
  92. struct brel_ma *ma;
  93. ma = brel->priv_data;
  94. if (old > ma->max_block)
  95. return EXT2_ET_INVALID_ARGUMENT;
  96. ma->entries[(unsigned)old] = *ent;
  97. return 0;
  98. }
  99. static errcode_t bma_get(ext2_brel brel, blk_t old,
  100. struct ext2_block_relocate_entry *ent)
  101. {
  102. struct brel_ma *ma;
  103. ma = brel->priv_data;
  104. if (old > ma->max_block)
  105. return EXT2_ET_INVALID_ARGUMENT;
  106. if (ma->entries[(unsigned)old].new == 0)
  107. return ENOENT;
  108. *ent = ma->entries[old];
  109. return 0;
  110. }
  111. static errcode_t bma_start_iter(ext2_brel brel)
  112. {
  113. brel->current = 0;
  114. return 0;
  115. }
  116. static errcode_t bma_next(ext2_brel brel, blk_t *old,
  117. struct ext2_block_relocate_entry *ent)
  118. {
  119. struct brel_ma *ma;
  120. ma = brel->priv_data;
  121. while (++brel->current < ma->max_block) {
  122. if (ma->entries[(unsigned)brel->current].new == 0)
  123. continue;
  124. *old = brel->current;
  125. *ent = ma->entries[(unsigned)brel->current];
  126. return 0;
  127. }
  128. *old = 0;
  129. return 0;
  130. }
  131. static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new)
  132. {
  133. struct brel_ma *ma;
  134. ma = brel->priv_data;
  135. if ((old > ma->max_block) || (new > ma->max_block))
  136. return EXT2_ET_INVALID_ARGUMENT;
  137. if (ma->entries[(unsigned)old].new == 0)
  138. return ENOENT;
  139. ma->entries[(unsigned)new] = ma->entries[old];
  140. ma->entries[(unsigned)old].new = 0;
  141. return 0;
  142. }
  143. static errcode_t bma_delete(ext2_brel brel, blk_t old)
  144. {
  145. struct brel_ma *ma;
  146. ma = brel->priv_data;
  147. if (old > ma->max_block)
  148. return EXT2_ET_INVALID_ARGUMENT;
  149. if (ma->entries[(unsigned)old].new == 0)
  150. return ENOENT;
  151. ma->entries[(unsigned)old].new = 0;
  152. return 0;
  153. }
  154. static errcode_t bma_free(ext2_brel brel)
  155. {
  156. struct brel_ma *ma;
  157. if (!brel)
  158. return 0;
  159. ma = brel->priv_data;
  160. if (ma) {
  161. if (ma->entries)
  162. ext2fs_free_mem(&ma->entries);
  163. ext2fs_free_mem(&ma);
  164. }
  165. if (brel->name)
  166. ext2fs_free_mem(&brel->name);
  167. ext2fs_free_mem(&brel);
  168. return 0;
  169. }