statistics.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. #include "sdfat.h"
  2. #define SDFAT_VF_CLUS_MAX 7 /* 512 Byte ~ 32 KByte */
  3. #define SDFAT_EF_CLUS_MAX 17 /* 512 Byte ~ 32 MByte */
  4. enum {
  5. SDFAT_MNT_FAT12,
  6. SDFAT_MNT_FAT16,
  7. SDFAT_MNT_FAT32,
  8. SDFAT_MNT_EXFAT,
  9. SDFAT_MNT_RO,
  10. SDFAT_MNT_MAX
  11. };
  12. enum {
  13. SDFAT_OP_EXFAT_MNT,
  14. SDFAT_OP_MKDIR,
  15. SDFAT_OP_CREATE,
  16. SDFAT_OP_READ,
  17. SDFAT_OP_WRITE,
  18. SDFAT_OP_TRUNC,
  19. SDFAT_OP_MAX
  20. };
  21. enum {
  22. SDFAT_VOL_4G,
  23. SDFAT_VOL_8G,
  24. SDFAT_VOL_16G,
  25. SDFAT_VOL_32G,
  26. SDFAT_VOL_64G,
  27. SDFAT_VOL_128G,
  28. SDFAT_VOL_256G,
  29. SDFAT_VOL_512G,
  30. SDFAT_VOL_XTB,
  31. SDFAT_VOL_MAX
  32. };
  33. static struct sdfat_statistics {
  34. u32 clus_vfat[SDFAT_VF_CLUS_MAX];
  35. u32 clus_exfat[SDFAT_EF_CLUS_MAX];
  36. u32 mnt_cnt[SDFAT_MNT_MAX];
  37. u32 nofat_op[SDFAT_OP_MAX];
  38. u32 vol_size[SDFAT_VOL_MAX];
  39. } statistics;
  40. static struct kset *sdfat_statistics_kset;
  41. static ssize_t vfat_cl_show(struct kobject *kobj,
  42. struct kobj_attribute *attr, char *buff)
  43. {
  44. return snprintf(buff, PAGE_SIZE, "\"VCL_512B_I\":\"%u\","
  45. "\"VCL_1K_I\":\"%u\",\"VCL_2K_I\":\"%u\","
  46. "\"VCL_4K_I\":\"%u\",\"VCL_8K_I\":\"%u\","
  47. "\"VCL_16K_I\":\"%u\",\"VCL_32K_I\":\"%u\"\n",
  48. statistics.clus_vfat[0], statistics.clus_vfat[1],
  49. statistics.clus_vfat[2], statistics.clus_vfat[3],
  50. statistics.clus_vfat[4], statistics.clus_vfat[5],
  51. statistics.clus_vfat[6]);
  52. }
  53. static ssize_t exfat_cl_show(struct kobject *kobj,
  54. struct kobj_attribute *attr, char *buff)
  55. {
  56. return snprintf(buff, PAGE_SIZE, "\"ECL_512B_I\":\"%u\","
  57. "\"ECL_1K_I\":\"%u\",\"ECL_2K_I\":\"%u\","
  58. "\"ECL_4K_I\":\"%u\",\"ECL_8K_I\":\"%u\","
  59. "\"ECL_16K_I\":\"%u\",\"ECL_32K_I\":\"%u\","
  60. "\"ECL_64K_I\":\"%u\",\"ECL_128K_I\":\"%u\","
  61. "\"ECL_256K_I\":\"%u\",\"ECL_512K_I\":\"%u\","
  62. "\"ECL_1M_I\":\"%u\",\"ECL_2M_I\":\"%u\","
  63. "\"ECL_4M_I\":\"%u\",\"ECL_8M_I\":\"%u\","
  64. "\"ECL_16M_I\":\"%u\",\"ECL_32M_I\":\"%u\"\n",
  65. statistics.clus_exfat[0], statistics.clus_exfat[1],
  66. statistics.clus_exfat[2], statistics.clus_exfat[3],
  67. statistics.clus_exfat[4], statistics.clus_exfat[5],
  68. statistics.clus_exfat[6], statistics.clus_exfat[7],
  69. statistics.clus_exfat[8], statistics.clus_exfat[9],
  70. statistics.clus_exfat[10], statistics.clus_exfat[11],
  71. statistics.clus_exfat[12], statistics.clus_exfat[13],
  72. statistics.clus_exfat[14], statistics.clus_exfat[15],
  73. statistics.clus_exfat[16]);
  74. }
  75. static ssize_t mount_show(struct kobject *kobj,
  76. struct kobj_attribute *attr, char *buff)
  77. {
  78. return snprintf(buff, PAGE_SIZE, "\"FAT12_MNT_I\":\"%u\","
  79. "\"FAT16_MNT_I\":\"%u\",\"FAT32_MNT_I\":\"%u\","
  80. "\"EXFAT_MNT_I\":\"%u\",\"RO_MNT_I\":\"%u\"\n",
  81. statistics.mnt_cnt[SDFAT_MNT_FAT12],
  82. statistics.mnt_cnt[SDFAT_MNT_FAT16],
  83. statistics.mnt_cnt[SDFAT_MNT_FAT32],
  84. statistics.mnt_cnt[SDFAT_MNT_EXFAT],
  85. statistics.mnt_cnt[SDFAT_MNT_RO]);
  86. }
  87. static ssize_t nofat_op_show(struct kobject *kobj,
  88. struct kobj_attribute *attr, char *buff)
  89. {
  90. return snprintf(buff, PAGE_SIZE, "\"NOFAT_MOUNT_I\":\"%u\","
  91. "\"NOFAT_MKDIR_I\":\"%u\",\"NOFAT_CREATE_I\":\"%u\","
  92. "\"NOFAT_READ_I\":\"%u\",\"NOFAT_WRITE_I\":\"%u\","
  93. "\"NOFAT_TRUNC_I\":\"%u\"\n",
  94. statistics.nofat_op[SDFAT_OP_EXFAT_MNT],
  95. statistics.nofat_op[SDFAT_OP_MKDIR],
  96. statistics.nofat_op[SDFAT_OP_CREATE],
  97. statistics.nofat_op[SDFAT_OP_READ],
  98. statistics.nofat_op[SDFAT_OP_WRITE],
  99. statistics.nofat_op[SDFAT_OP_TRUNC]);
  100. }
  101. static ssize_t vol_size_show(struct kobject *kobj,
  102. struct kobj_attribute *attr, char *buff)
  103. {
  104. return snprintf(buff, PAGE_SIZE, "\"VOL_4G_I\":\"%u\","
  105. "\"VOL_8G_I\":\"%u\",\"VOL_16G_I\":\"%u\","
  106. "\"VOL_32G_I\":\"%u\",\"VOL_64G_I\":\"%u\","
  107. "\"VOL_128G_I\":\"%u\",\"VOL_256G_I\":\"%u\","
  108. "\"VOL_512G_I\":\"%u\",\"VOL_XTB_I\":\"%u\"\n",
  109. statistics.vol_size[SDFAT_VOL_4G],
  110. statistics.vol_size[SDFAT_VOL_8G],
  111. statistics.vol_size[SDFAT_VOL_16G],
  112. statistics.vol_size[SDFAT_VOL_32G],
  113. statistics.vol_size[SDFAT_VOL_64G],
  114. statistics.vol_size[SDFAT_VOL_128G],
  115. statistics.vol_size[SDFAT_VOL_256G],
  116. statistics.vol_size[SDFAT_VOL_512G],
  117. statistics.vol_size[SDFAT_VOL_XTB]);
  118. }
  119. static struct kobj_attribute vfat_cl_attr = __ATTR_RO(vfat_cl);
  120. static struct kobj_attribute exfat_cl_attr = __ATTR_RO(exfat_cl);
  121. static struct kobj_attribute mount_attr = __ATTR_RO(mount);
  122. static struct kobj_attribute nofat_op_attr = __ATTR_RO(nofat_op);
  123. static struct kobj_attribute vol_size_attr = __ATTR_RO(vol_size);
  124. static struct attribute *attributes_statistics[] = {
  125. &vfat_cl_attr.attr,
  126. &exfat_cl_attr.attr,
  127. &mount_attr.attr,
  128. &nofat_op_attr.attr,
  129. &vol_size_attr.attr,
  130. NULL,
  131. };
  132. static struct attribute_group attr_group_statistics = {
  133. .attrs = attributes_statistics,
  134. };
  135. int sdfat_statistics_init(struct kset *sdfat_kset)
  136. {
  137. int err;
  138. sdfat_statistics_kset = kset_create_and_add("statistics", NULL, &sdfat_kset->kobj);
  139. if (!sdfat_statistics_kset) {
  140. pr_err("[SDFAT] failed to create sdfat statistics kobj\n");
  141. return -ENOMEM;
  142. }
  143. err = sysfs_create_group(&sdfat_statistics_kset->kobj, &attr_group_statistics);
  144. if (err) {
  145. pr_err("[SDFAT] failed to create sdfat statistics attributes\n");
  146. kset_unregister(sdfat_statistics_kset);
  147. sdfat_statistics_kset = NULL;
  148. return err;
  149. }
  150. return 0;
  151. }
  152. void sdfat_statistics_uninit(void)
  153. {
  154. if (sdfat_statistics_kset) {
  155. sysfs_remove_group(&sdfat_statistics_kset->kobj, &attr_group_statistics);
  156. kset_unregister(sdfat_statistics_kset);
  157. sdfat_statistics_kset = NULL;
  158. }
  159. memset(&statistics, 0, sizeof(struct sdfat_statistics));
  160. }
  161. void sdfat_statistics_set_mnt(FS_INFO_T *fsi)
  162. {
  163. if (fsi->vol_type == EXFAT) {
  164. statistics.mnt_cnt[SDFAT_MNT_EXFAT]++;
  165. statistics.nofat_op[SDFAT_OP_EXFAT_MNT] = 1;
  166. if (fsi->sect_per_clus_bits < SDFAT_EF_CLUS_MAX)
  167. statistics.clus_exfat[fsi->sect_per_clus_bits]++;
  168. else
  169. statistics.clus_exfat[SDFAT_EF_CLUS_MAX - 1]++;
  170. return;
  171. }
  172. if (fsi->vol_type == FAT32)
  173. statistics.mnt_cnt[SDFAT_MNT_FAT32]++;
  174. else if (fsi->vol_type == FAT16)
  175. statistics.mnt_cnt[SDFAT_MNT_FAT16]++;
  176. else if (fsi->vol_type == FAT12)
  177. statistics.mnt_cnt[SDFAT_MNT_FAT12]++;
  178. if (fsi->sect_per_clus_bits < SDFAT_VF_CLUS_MAX)
  179. statistics.clus_vfat[fsi->sect_per_clus_bits]++;
  180. else
  181. statistics.clus_vfat[SDFAT_VF_CLUS_MAX - 1]++;
  182. }
  183. void sdfat_statistics_set_mnt_ro(void)
  184. {
  185. statistics.mnt_cnt[SDFAT_MNT_RO]++;
  186. }
  187. void sdfat_statistics_set_mkdir(u8 flags)
  188. {
  189. if (flags != 0x03)
  190. return;
  191. statistics.nofat_op[SDFAT_OP_MKDIR] = 1;
  192. }
  193. void sdfat_statistics_set_create(u8 flags)
  194. {
  195. if (flags != 0x03)
  196. return;
  197. statistics.nofat_op[SDFAT_OP_CREATE] = 1;
  198. }
  199. /* flags : file or dir flgas, 0x03 means no fat-chain.
  200. * clu_offset : file or dir logical cluster offset
  201. * create : BMAP_ADD_CLUSTER or not
  202. *
  203. * File or dir have BMAP_ADD_CLUSTER is no fat-chain write
  204. * when they have 0x03 flag and two or more clusters.
  205. * And don`t have BMAP_ADD_CLUSTER is no fat-chain read
  206. * when above same condition.
  207. */
  208. void sdfat_statistics_set_rw(u8 flags, u32 clu_offset, s32 create)
  209. {
  210. if ((flags == 0x03) && (clu_offset > 1)) {
  211. if (create)
  212. statistics.nofat_op[SDFAT_OP_WRITE] = 1;
  213. else
  214. statistics.nofat_op[SDFAT_OP_READ] = 1;
  215. }
  216. }
  217. /* flags : file or dir flgas, 0x03 means no fat-chain.
  218. * clu : cluster chain
  219. *
  220. * Set no fat-chain trunc when file or dir have 0x03 flag
  221. * and two or more clusters.
  222. */
  223. void sdfat_statistics_set_trunc(u8 flags, CHAIN_T *clu)
  224. {
  225. if ((flags == 0x03) && (clu->size > 1))
  226. statistics.nofat_op[SDFAT_OP_TRUNC] = 1;
  227. }
  228. void sdfat_statistics_set_vol_size(struct super_block *sb)
  229. {
  230. u64 vol_size;
  231. FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
  232. vol_size = (u64)fsi->num_sectors << sb->s_blocksize_bits;
  233. if (vol_size <= ((u64)1 << 32))
  234. statistics.vol_size[SDFAT_VOL_4G]++;
  235. else if (vol_size <= ((u64)1 << 33))
  236. statistics.vol_size[SDFAT_VOL_8G]++;
  237. else if (vol_size <= ((u64)1 << 34))
  238. statistics.vol_size[SDFAT_VOL_16G]++;
  239. else if (vol_size <= ((u64)1 << 35))
  240. statistics.vol_size[SDFAT_VOL_32G]++;
  241. else if (vol_size <= ((u64)1 << 36))
  242. statistics.vol_size[SDFAT_VOL_64G]++;
  243. else if (vol_size <= ((u64)1 << 37))
  244. statistics.vol_size[SDFAT_VOL_128G]++;
  245. else if (vol_size <= ((u64)1 << 38))
  246. statistics.vol_size[SDFAT_VOL_256G]++;
  247. else if (vol_size <= ((u64)1 << 39))
  248. statistics.vol_size[SDFAT_VOL_512G]++;
  249. else
  250. statistics.vol_size[SDFAT_VOL_XTB]++;
  251. }