brel_ma.c 4.1 KB

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