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