lsmtd_scan.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * Copyright (C) 2017 David Oberhollenzer - sigma star gmbh
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License version 2 as published by
  6. * the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful, but WITHOUT
  9. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. * more details.
  12. *
  13. * You should have received a copy of the GNU General Public License along with
  14. * this program; see the file COPYING. If not, write to the Free Software
  15. * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA.
  16. *
  17. * Author: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
  18. */
  19. #include "lsmtd.h"
  20. struct ubi_node *ubi_dev;
  21. int num_ubi_devices;
  22. struct mtd_node *mtd_dev;
  23. int num_mtd_devices;
  24. static int compare_mtd(const void *l, const void *r)
  25. {
  26. const struct mtd_node *a = l, *b = r;
  27. switch (sort_by->type) {
  28. case COL_DEVNAME:
  29. return a->info.mtd_num - b->info.mtd_num;
  30. case COL_DEVNUM:
  31. if (a->info.major == b->info.major)
  32. return a->info.minor - b->info.minor;
  33. return a->info.major - b->info.major;
  34. case COL_TYPE:
  35. return strcmp(a->info.type_str, b->info.type_str);
  36. case COL_NAME:
  37. return strcmp(a->info.name, b->info.name);
  38. case COL_SIZE:
  39. if (a->info.size < b->info.size)
  40. return -1;
  41. if (a->info.size > b->info.size)
  42. return 1;
  43. return 0;
  44. case COL_EBSIZE:
  45. return a->info.eb_size - b->info.eb_size;
  46. case COL_EBCOUNT:
  47. return a->info.eb_cnt - b->info.eb_cnt;
  48. case COL_MINIO:
  49. return a->info.min_io_size - b->info.min_io_size;
  50. case COL_SUBSIZE:
  51. return a->info.subpage_size - b->info.subpage_size;
  52. case COL_OOBSIZE:
  53. return a->info.oob_size - b->info.oob_size;
  54. case COL_RO:
  55. return !a->info.writable - !b->info.writable;
  56. case COL_BB:
  57. return a->info.bb_allowed - b->info.bb_allowed;
  58. case COL_REGION:
  59. return a->info.region_cnt - b->info.region_cnt;
  60. }
  61. return 0;
  62. }
  63. static int compare_ubi_vol(const void *l, const void *r)
  64. {
  65. const struct ubi_vol_info *a = l, *b = r;
  66. long long all, bll;
  67. switch (sort_by->type) {
  68. case COL_DEVNAME:
  69. if (a->dev_num == b->dev_num)
  70. return a->vol_id - b->vol_id;
  71. return a->dev_num - b->dev_num;
  72. case COL_DEVNUM:
  73. if (a->major == b->major)
  74. return a->minor - b->minor;
  75. return a->major - b->major;
  76. case COL_TYPE:
  77. if (a->type == b->type)
  78. return 0;
  79. return a->type == UBI_DYNAMIC_VOLUME ? 1 : -1;
  80. case COL_NAME:
  81. return strcmp(a->name, b->name);
  82. case COL_SIZE:
  83. all = a->rsvd_bytes;
  84. bll = b->rsvd_bytes;
  85. goto out_ll;
  86. case COL_EBSIZE:
  87. return a->leb_size - b->leb_size;
  88. case COL_EBCOUNT:
  89. return a->rsvd_lebs - b->rsvd_lebs;
  90. case COL_FREE:
  91. case COL_FREE_LEB:
  92. all = (a->rsvd_bytes - a->data_bytes);
  93. bll = (b->rsvd_bytes - b->data_bytes);
  94. goto out_ll;
  95. case COL_CORRUPTED:
  96. return a->corrupted - b->corrupted;
  97. }
  98. return 0;
  99. out_ll:
  100. return (all < bll) ? -1 : ((all > bll) ? 1 : 0);
  101. }
  102. static int scan_ubi_device(libubi_t lib_ubi, struct ubi_node *dev)
  103. {
  104. int lo = dev->info.lowest_vol_id, hi = dev->info.highest_vol_id;
  105. int i, idx = 0, dev_num = dev->info.dev_num;
  106. struct ubi_vol_info vol_info;
  107. if (!dev->info.vol_count)
  108. return 0;
  109. dev->vol_info = xcalloc(dev->info.vol_count, sizeof(dev->vol_info[0]));
  110. for (i = lo; i <= hi; ++i) {
  111. if (ubi_get_vol_info1(lib_ubi, dev_num, i, &vol_info)) {
  112. if (errno == ENOENT)
  113. continue;
  114. perror("ubi_get_vol_info1");
  115. return -1;
  116. }
  117. dev->vol_info[idx++] = vol_info;
  118. }
  119. if (sort_by)
  120. qsort(dev->vol_info, idx, sizeof(vol_info), compare_ubi_vol);
  121. return 0;
  122. }
  123. int scan_ubi(libubi_t lib_ubi)
  124. {
  125. struct ubi_dev_info dev_info;
  126. struct ubi_info info;
  127. int i, j;
  128. if (ubi_get_info(lib_ubi, &info))
  129. return -1;
  130. if (!info.dev_count)
  131. return 0;
  132. ubi_dev = xcalloc(info.dev_count, sizeof(ubi_dev[0]));
  133. for (i = info.lowest_dev_num; i <= info.highest_dev_num; ++i) {
  134. if (!ubi_dev_present(lib_ubi, i))
  135. continue;
  136. if (ubi_get_dev_info1(lib_ubi, i, &dev_info)) {
  137. perror("ubi_get_dev_info1");
  138. return -1;
  139. }
  140. for (j = 0; j < num_mtd_devices; ++j) {
  141. if (mtd_dev[j].info.mtd_num == dev_info.mtd_num)
  142. break;
  143. }
  144. if (j == num_mtd_devices) {
  145. fprintf(stderr, "Cannot find mtd device %d refered to "
  146. "by ubi device %d\n", dev_info.mtd_num,
  147. dev_info.dev_num);
  148. return -1;
  149. }
  150. ubi_dev[num_ubi_devices].info = dev_info;
  151. mtd_dev[j].ubi = ubi_dev + num_ubi_devices;
  152. if (scan_ubi_device(lib_ubi, ubi_dev + num_ubi_devices))
  153. return -1;
  154. ++num_ubi_devices;
  155. }
  156. return 0;
  157. }
  158. int scan_mtd(libmtd_t lib_mtd)
  159. {
  160. struct mtd_dev_info dev_info;
  161. struct mtd_info info;
  162. int i, idx = 0;
  163. if (mtd_get_info(lib_mtd, &info))
  164. return -1;
  165. if (!info.mtd_dev_cnt)
  166. return 0;
  167. mtd_dev = xcalloc(info.mtd_dev_cnt, sizeof(mtd_dev[0]));
  168. for (i = info.lowest_mtd_num; i <= info.highest_mtd_num; ++i) {
  169. if (!mtd_dev_present(lib_mtd, i))
  170. continue;
  171. if (mtd_get_dev_info1(lib_mtd, i, &dev_info)) {
  172. perror("mtd_get_dev_info1");
  173. return -1;
  174. }
  175. memcpy(&(mtd_dev[idx++].info), &dev_info, sizeof(dev_info));
  176. }
  177. num_mtd_devices = idx;
  178. if (sort_by)
  179. qsort(mtd_dev, num_mtd_devices, sizeof(*mtd_dev), compare_mtd);
  180. return 0;
  181. }
  182. void scan_free(void)
  183. {
  184. int i;
  185. for (i = 0; i < num_ubi_devices; ++i)
  186. free(ubi_dev[i].vol_info);
  187. free(ubi_dev);
  188. free(mtd_dev);
  189. }