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
14static 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, 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(c_bh);
30		if (sb->s_flags & SB_SYNCHRONOUS)
31			err = sync_dirty_buffer(c_bh);
32		brelse(c_bh);
33	}
34
35	return err;
36}
37
38static 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, 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
62int 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, 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, sb->s_flags & SB_SYNCHRONOUS);
80	exfat_mirror_bh(sb, sec, bh);
81	brelse(bh);
82	return 0;
83}
84
85int 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, 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, *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
129int 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, chain, chain + 1))
137			return -EIO;
138		chain++;
139		len--;
140	}
141
142	if (exfat_ent_set(sb, chain, EXFAT_EOF_CLUSTER))
143		return -EIO;
144	return 0;
145}
146
147/* This function must be called with bitmap_lock held */
148static 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, 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 && 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 && 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
222dec_used_clus:
223	sbi->used_clusters -= num_clusters;
224	return 0;
225}
226
227int 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(&EXFAT_SB(inode->i_sb)->bitmap_lock);
234
235	return ret;
236}
237
238int 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, clu, &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
268int 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, 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, 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(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
306int 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, 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, 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, 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, p_chain->dir,
361					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, new_clu, 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, 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, last_clu, 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(&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, p_chain->dir,
408						p_chain->size)) {
409					ret = -EIO;
410					goto free_cluster;
411				}
412				p_chain->flags = ALLOC_FAT_CHAIN;
413			}
414		}
415	}
416free_cluster:
417	__exfat_free_cluster(inode, p_chain);
418unlock:
419	mutex_unlock(&sbi->bitmap_lock);
420	return ret;
421}
422
423int 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, clu, &clu))
445			return -EIO;
446		if (clu == EXFAT_EOF_CLUSTER)
447			break;
448	}
449
450	*ret_count = count;
451	return 0;
452}
453