1 | // SPDX-License-Identifier: GPL-2.0-or-later |
2 | /* |
3 | * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd. |
4 | */ |
5 | |
6 | #include <linux/slab.h> |
7 | #include <asm/unaligned.h> |
8 | #include <linux/buffer_head.h> |
9 | #include <linux/blkdev.h> |
10 | |
11 | #include "exfat_raw.h" |
12 | #include "exfat_fs.h" |
13 | |
14 | static int exfat_mirror_bh(struct super_block *sb, sector_t sec, |
15 | struct buffer_head *bh) |
16 | { |
17 | struct buffer_head *c_bh; |
18 | struct exfat_sb_info *sbi = EXFAT_SB(sb); |
19 | sector_t sec2; |
20 | int err = 0; |
21 | |
22 | if (sbi->FAT2_start_sector != sbi->FAT1_start_sector) { |
23 | sec2 = sec - sbi->FAT1_start_sector + sbi->FAT2_start_sector; |
24 | c_bh = sb_getblk(sb, block: sec2); |
25 | if (!c_bh) |
26 | return -ENOMEM; |
27 | memcpy(c_bh->b_data, bh->b_data, sb->s_blocksize); |
28 | set_buffer_uptodate(c_bh); |
29 | mark_buffer_dirty(bh: c_bh); |
30 | if (sb->s_flags & SB_SYNCHRONOUS) |
31 | err = sync_dirty_buffer(bh: c_bh); |
32 | brelse(bh: c_bh); |
33 | } |
34 | |
35 | return err; |
36 | } |
37 | |
38 | static int __exfat_ent_get(struct super_block *sb, unsigned int loc, |
39 | unsigned int *content) |
40 | { |
41 | unsigned int off; |
42 | sector_t sec; |
43 | struct buffer_head *bh; |
44 | |
45 | sec = FAT_ENT_OFFSET_SECTOR(sb, loc); |
46 | off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); |
47 | |
48 | bh = sb_bread(sb, block: sec); |
49 | if (!bh) |
50 | return -EIO; |
51 | |
52 | *content = le32_to_cpu(*(__le32 *)(&bh->b_data[off])); |
53 | |
54 | /* remap reserved clusters to simplify code */ |
55 | if (*content > EXFAT_BAD_CLUSTER) |
56 | *content = EXFAT_EOF_CLUSTER; |
57 | |
58 | brelse(bh); |
59 | return 0; |
60 | } |
61 | |
62 | int exfat_ent_set(struct super_block *sb, unsigned int loc, |
63 | unsigned int content) |
64 | { |
65 | unsigned int off; |
66 | sector_t sec; |
67 | __le32 *fat_entry; |
68 | struct buffer_head *bh; |
69 | |
70 | sec = FAT_ENT_OFFSET_SECTOR(sb, loc); |
71 | off = FAT_ENT_OFFSET_BYTE_IN_SECTOR(sb, loc); |
72 | |
73 | bh = sb_bread(sb, block: sec); |
74 | if (!bh) |
75 | return -EIO; |
76 | |
77 | fat_entry = (__le32 *)&(bh->b_data[off]); |
78 | *fat_entry = cpu_to_le32(content); |
79 | exfat_update_bh(bh, sync: sb->s_flags & SB_SYNCHRONOUS); |
80 | exfat_mirror_bh(sb, sec, bh); |
81 | brelse(bh); |
82 | return 0; |
83 | } |
84 | |
85 | int exfat_ent_get(struct super_block *sb, unsigned int loc, |
86 | unsigned int *content) |
87 | { |
88 | struct exfat_sb_info *sbi = EXFAT_SB(sb); |
89 | int err; |
90 | |
91 | if (!is_valid_cluster(sbi, clus: loc)) { |
92 | exfat_fs_error(sb, "invalid access to FAT (entry 0x%08x)" , |
93 | loc); |
94 | return -EIO; |
95 | } |
96 | |
97 | err = __exfat_ent_get(sb, loc, content); |
98 | if (err) { |
99 | exfat_fs_error(sb, |
100 | "failed to access to FAT (entry 0x%08x, err:%d)" , |
101 | loc, err); |
102 | return err; |
103 | } |
104 | |
105 | if (*content == EXFAT_FREE_CLUSTER) { |
106 | exfat_fs_error(sb, |
107 | "invalid access to FAT free cluster (entry 0x%08x)" , |
108 | loc); |
109 | return -EIO; |
110 | } |
111 | |
112 | if (*content == EXFAT_BAD_CLUSTER) { |
113 | exfat_fs_error(sb, |
114 | "invalid access to FAT bad cluster (entry 0x%08x)" , |
115 | loc); |
116 | return -EIO; |
117 | } |
118 | |
119 | if (*content != EXFAT_EOF_CLUSTER && !is_valid_cluster(sbi, clus: *content)) { |
120 | exfat_fs_error(sb, |
121 | "invalid access to FAT (entry 0x%08x) bogus content (0x%08x)" , |
122 | loc, *content); |
123 | return -EIO; |
124 | } |
125 | |
126 | return 0; |
127 | } |
128 | |
129 | int exfat_chain_cont_cluster(struct super_block *sb, unsigned int chain, |
130 | unsigned int len) |
131 | { |
132 | if (!len) |
133 | return 0; |
134 | |
135 | while (len > 1) { |
136 | if (exfat_ent_set(sb, loc: chain, content: chain + 1)) |
137 | return -EIO; |
138 | chain++; |
139 | len--; |
140 | } |
141 | |
142 | if (exfat_ent_set(sb, loc: chain, EXFAT_EOF_CLUSTER)) |
143 | return -EIO; |
144 | return 0; |
145 | } |
146 | |
147 | /* This function must be called with bitmap_lock held */ |
148 | static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain) |
149 | { |
150 | struct super_block *sb = inode->i_sb; |
151 | struct exfat_sb_info *sbi = EXFAT_SB(sb); |
152 | int cur_cmap_i, next_cmap_i; |
153 | unsigned int num_clusters = 0; |
154 | unsigned int clu; |
155 | |
156 | /* invalid cluster number */ |
157 | if (p_chain->dir == EXFAT_FREE_CLUSTER || |
158 | p_chain->dir == EXFAT_EOF_CLUSTER || |
159 | p_chain->dir < EXFAT_FIRST_CLUSTER) |
160 | return 0; |
161 | |
162 | /* no cluster to truncate */ |
163 | if (p_chain->size == 0) |
164 | return 0; |
165 | |
166 | /* check cluster validation */ |
167 | if (!is_valid_cluster(sbi, clus: p_chain->dir)) { |
168 | exfat_err(sb, "invalid start cluster (%u)" , p_chain->dir); |
169 | return -EIO; |
170 | } |
171 | |
172 | clu = p_chain->dir; |
173 | |
174 | cur_cmap_i = next_cmap_i = |
175 | BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu)); |
176 | |
177 | if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { |
178 | unsigned int last_cluster = p_chain->dir + p_chain->size - 1; |
179 | do { |
180 | bool sync = false; |
181 | |
182 | if (clu < last_cluster) |
183 | next_cmap_i = |
184 | BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu+1)); |
185 | |
186 | /* flush bitmap only if index would be changed or for last cluster */ |
187 | if (clu == last_cluster || cur_cmap_i != next_cmap_i) { |
188 | sync = true; |
189 | cur_cmap_i = next_cmap_i; |
190 | } |
191 | |
192 | exfat_clear_bitmap(inode, clu, sync: (sync && IS_DIRSYNC(inode))); |
193 | clu++; |
194 | num_clusters++; |
195 | } while (num_clusters < p_chain->size); |
196 | } else { |
197 | do { |
198 | bool sync = false; |
199 | unsigned int n_clu = clu; |
200 | int err = exfat_get_next_cluster(sb, &n_clu); |
201 | |
202 | if (err || n_clu == EXFAT_EOF_CLUSTER) |
203 | sync = true; |
204 | else |
205 | next_cmap_i = |
206 | BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(n_clu)); |
207 | |
208 | if (cur_cmap_i != next_cmap_i) { |
209 | sync = true; |
210 | cur_cmap_i = next_cmap_i; |
211 | } |
212 | |
213 | exfat_clear_bitmap(inode, clu, sync: (sync && IS_DIRSYNC(inode))); |
214 | clu = n_clu; |
215 | num_clusters++; |
216 | |
217 | if (err) |
218 | goto dec_used_clus; |
219 | } while (clu != EXFAT_EOF_CLUSTER); |
220 | } |
221 | |
222 | dec_used_clus: |
223 | sbi->used_clusters -= num_clusters; |
224 | return 0; |
225 | } |
226 | |
227 | int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain) |
228 | { |
229 | int ret = 0; |
230 | |
231 | mutex_lock(&EXFAT_SB(inode->i_sb)->bitmap_lock); |
232 | ret = __exfat_free_cluster(inode, p_chain); |
233 | mutex_unlock(lock: &EXFAT_SB(sb: inode->i_sb)->bitmap_lock); |
234 | |
235 | return ret; |
236 | } |
237 | |
238 | int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain, |
239 | unsigned int *ret_clu) |
240 | { |
241 | unsigned int clu, next; |
242 | unsigned int count = 0; |
243 | |
244 | next = p_chain->dir; |
245 | if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { |
246 | *ret_clu = next + p_chain->size - 1; |
247 | return 0; |
248 | } |
249 | |
250 | do { |
251 | count++; |
252 | clu = next; |
253 | if (exfat_ent_get(sb, loc: clu, content: &next)) |
254 | return -EIO; |
255 | } while (next != EXFAT_EOF_CLUSTER); |
256 | |
257 | if (p_chain->size != count) { |
258 | exfat_fs_error(sb, |
259 | "bogus directory size (clus : ondisk(%d) != counted(%d))" , |
260 | p_chain->size, count); |
261 | return -EIO; |
262 | } |
263 | |
264 | *ret_clu = clu; |
265 | return 0; |
266 | } |
267 | |
268 | int exfat_zeroed_cluster(struct inode *dir, unsigned int clu) |
269 | { |
270 | struct super_block *sb = dir->i_sb; |
271 | struct exfat_sb_info *sbi = EXFAT_SB(sb); |
272 | struct buffer_head *bh; |
273 | sector_t blknr, last_blknr, i; |
274 | |
275 | blknr = exfat_cluster_to_sector(sbi, clus: clu); |
276 | last_blknr = blknr + sbi->sect_per_clus; |
277 | |
278 | if (last_blknr > sbi->num_sectors && sbi->num_sectors > 0) { |
279 | exfat_fs_error_ratelimit(sb, |
280 | "%s: out of range(sect:%llu len:%u)" , |
281 | __func__, (unsigned long long)blknr, |
282 | sbi->sect_per_clus); |
283 | return -EIO; |
284 | } |
285 | |
286 | /* Zeroing the unused blocks on this cluster */ |
287 | for (i = blknr; i < last_blknr; i++) { |
288 | bh = sb_getblk(sb, block: i); |
289 | if (!bh) |
290 | return -ENOMEM; |
291 | |
292 | memset(bh->b_data, 0, sb->s_blocksize); |
293 | set_buffer_uptodate(bh); |
294 | mark_buffer_dirty(bh); |
295 | brelse(bh); |
296 | } |
297 | |
298 | if (IS_DIRSYNC(dir)) |
299 | return sync_blockdev_range(bdev: sb->s_bdev, |
300 | EXFAT_BLK_TO_B(blknr, sb), |
301 | EXFAT_BLK_TO_B(last_blknr, sb) - 1); |
302 | |
303 | return 0; |
304 | } |
305 | |
306 | int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc, |
307 | struct exfat_chain *p_chain, bool sync_bmap) |
308 | { |
309 | int ret = -ENOSPC; |
310 | unsigned int total_cnt; |
311 | unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER; |
312 | struct super_block *sb = inode->i_sb; |
313 | struct exfat_sb_info *sbi = EXFAT_SB(sb); |
314 | |
315 | total_cnt = EXFAT_DATA_CLUSTER_COUNT(sbi); |
316 | |
317 | if (unlikely(total_cnt < sbi->used_clusters)) { |
318 | exfat_fs_error_ratelimit(sb, |
319 | "%s: invalid used clusters(t:%u,u:%u)\n" , |
320 | __func__, total_cnt, sbi->used_clusters); |
321 | return -EIO; |
322 | } |
323 | |
324 | if (num_alloc > total_cnt - sbi->used_clusters) |
325 | return -ENOSPC; |
326 | |
327 | mutex_lock(&sbi->bitmap_lock); |
328 | |
329 | hint_clu = p_chain->dir; |
330 | /* find new cluster */ |
331 | if (hint_clu == EXFAT_EOF_CLUSTER) { |
332 | if (sbi->clu_srch_ptr < EXFAT_FIRST_CLUSTER) { |
333 | exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)" , |
334 | sbi->clu_srch_ptr); |
335 | sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER; |
336 | } |
337 | |
338 | hint_clu = exfat_find_free_bitmap(sb, clu: sbi->clu_srch_ptr); |
339 | if (hint_clu == EXFAT_EOF_CLUSTER) { |
340 | ret = -ENOSPC; |
341 | goto unlock; |
342 | } |
343 | } |
344 | |
345 | /* check cluster validation */ |
346 | if (!is_valid_cluster(sbi, clus: hint_clu)) { |
347 | if (hint_clu != sbi->num_clusters) |
348 | exfat_err(sb, "hint_cluster is invalid (%u), rewind to the first cluster" , |
349 | hint_clu); |
350 | hint_clu = EXFAT_FIRST_CLUSTER; |
351 | p_chain->flags = ALLOC_FAT_CHAIN; |
352 | } |
353 | |
354 | p_chain->dir = EXFAT_EOF_CLUSTER; |
355 | |
356 | while ((new_clu = exfat_find_free_bitmap(sb, clu: hint_clu)) != |
357 | EXFAT_EOF_CLUSTER) { |
358 | if (new_clu != hint_clu && |
359 | p_chain->flags == ALLOC_NO_FAT_CHAIN) { |
360 | if (exfat_chain_cont_cluster(sb, chain: p_chain->dir, |
361 | len: p_chain->size)) { |
362 | ret = -EIO; |
363 | goto free_cluster; |
364 | } |
365 | p_chain->flags = ALLOC_FAT_CHAIN; |
366 | } |
367 | |
368 | /* update allocation bitmap */ |
369 | if (exfat_set_bitmap(inode, clu: new_clu, sync: sync_bmap)) { |
370 | ret = -EIO; |
371 | goto free_cluster; |
372 | } |
373 | |
374 | /* update FAT table */ |
375 | if (p_chain->flags == ALLOC_FAT_CHAIN) { |
376 | if (exfat_ent_set(sb, loc: new_clu, EXFAT_EOF_CLUSTER)) { |
377 | ret = -EIO; |
378 | goto free_cluster; |
379 | } |
380 | } |
381 | |
382 | if (p_chain->dir == EXFAT_EOF_CLUSTER) { |
383 | p_chain->dir = new_clu; |
384 | } else if (p_chain->flags == ALLOC_FAT_CHAIN) { |
385 | if (exfat_ent_set(sb, loc: last_clu, content: new_clu)) { |
386 | ret = -EIO; |
387 | goto free_cluster; |
388 | } |
389 | } |
390 | p_chain->size++; |
391 | |
392 | last_clu = new_clu; |
393 | |
394 | if (p_chain->size == num_alloc) { |
395 | sbi->clu_srch_ptr = hint_clu; |
396 | sbi->used_clusters += num_alloc; |
397 | |
398 | mutex_unlock(lock: &sbi->bitmap_lock); |
399 | return 0; |
400 | } |
401 | |
402 | hint_clu = new_clu + 1; |
403 | if (hint_clu >= sbi->num_clusters) { |
404 | hint_clu = EXFAT_FIRST_CLUSTER; |
405 | |
406 | if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { |
407 | if (exfat_chain_cont_cluster(sb, chain: p_chain->dir, |
408 | len: p_chain->size)) { |
409 | ret = -EIO; |
410 | goto free_cluster; |
411 | } |
412 | p_chain->flags = ALLOC_FAT_CHAIN; |
413 | } |
414 | } |
415 | } |
416 | free_cluster: |
417 | __exfat_free_cluster(inode, p_chain); |
418 | unlock: |
419 | mutex_unlock(lock: &sbi->bitmap_lock); |
420 | return ret; |
421 | } |
422 | |
423 | int exfat_count_num_clusters(struct super_block *sb, |
424 | struct exfat_chain *p_chain, unsigned int *ret_count) |
425 | { |
426 | unsigned int i, count; |
427 | unsigned int clu; |
428 | struct exfat_sb_info *sbi = EXFAT_SB(sb); |
429 | |
430 | if (!p_chain->dir || p_chain->dir == EXFAT_EOF_CLUSTER) { |
431 | *ret_count = 0; |
432 | return 0; |
433 | } |
434 | |
435 | if (p_chain->flags == ALLOC_NO_FAT_CHAIN) { |
436 | *ret_count = p_chain->size; |
437 | return 0; |
438 | } |
439 | |
440 | clu = p_chain->dir; |
441 | count = 0; |
442 | for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; i++) { |
443 | count++; |
444 | if (exfat_ent_get(sb, loc: clu, content: &clu)) |
445 | return -EIO; |
446 | if (clu == EXFAT_EOF_CLUSTER) |
447 | break; |
448 | } |
449 | |
450 | *ret_count = count; |
451 | return 0; |
452 | } |
453 | |