Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/fs/exfat/fatent.c
26281 views
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 <linux/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, 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
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, 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, 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
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, 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
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, 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
static inline void exfat_discard_cluster(struct super_block *sb,
148
unsigned int clu, unsigned int num_clusters)
149
{
150
int ret;
151
struct exfat_sb_info *sbi = EXFAT_SB(sb);
152
153
ret = sb_issue_discard(sb, exfat_cluster_to_sector(sbi, clu),
154
sbi->sect_per_clus * num_clusters, GFP_NOFS, 0);
155
if (ret == -EOPNOTSUPP) {
156
exfat_err(sb, "discard not supported by device, disabling");
157
sbi->options.discard = 0;
158
}
159
}
160
161
/* This function must be called with bitmap_lock held */
162
static int __exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
163
{
164
struct super_block *sb = inode->i_sb;
165
struct exfat_sb_info *sbi = EXFAT_SB(sb);
166
int cur_cmap_i, next_cmap_i;
167
unsigned int num_clusters = 0;
168
unsigned int clu;
169
170
/* invalid cluster number */
171
if (p_chain->dir == EXFAT_FREE_CLUSTER ||
172
p_chain->dir == EXFAT_EOF_CLUSTER ||
173
p_chain->dir < EXFAT_FIRST_CLUSTER)
174
return 0;
175
176
/* no cluster to truncate */
177
if (p_chain->size == 0)
178
return 0;
179
180
/* check cluster validation */
181
if (!is_valid_cluster(sbi, p_chain->dir)) {
182
exfat_err(sb, "invalid start cluster (%u)", p_chain->dir);
183
return -EIO;
184
}
185
186
clu = p_chain->dir;
187
188
cur_cmap_i = next_cmap_i =
189
BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu));
190
191
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
192
int err;
193
unsigned int last_cluster = p_chain->dir + p_chain->size - 1;
194
do {
195
bool sync = false;
196
197
if (clu < last_cluster)
198
next_cmap_i =
199
BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(clu+1));
200
201
/* flush bitmap only if index would be changed or for last cluster */
202
if (clu == last_cluster || cur_cmap_i != next_cmap_i) {
203
sync = true;
204
cur_cmap_i = next_cmap_i;
205
}
206
207
err = exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode)));
208
if (err)
209
break;
210
clu++;
211
num_clusters++;
212
} while (num_clusters < p_chain->size);
213
214
if (sbi->options.discard)
215
exfat_discard_cluster(sb, p_chain->dir, p_chain->size);
216
} else {
217
unsigned int nr_clu = 1;
218
219
do {
220
bool sync = false;
221
unsigned int n_clu = clu;
222
int err = exfat_get_next_cluster(sb, &n_clu);
223
224
if (err || n_clu == EXFAT_EOF_CLUSTER)
225
sync = true;
226
else
227
next_cmap_i =
228
BITMAP_OFFSET_SECTOR_INDEX(sb, CLUSTER_TO_BITMAP_ENT(n_clu));
229
230
if (cur_cmap_i != next_cmap_i) {
231
sync = true;
232
cur_cmap_i = next_cmap_i;
233
}
234
235
if (exfat_clear_bitmap(inode, clu, (sync && IS_DIRSYNC(inode))))
236
break;
237
238
if (sbi->options.discard) {
239
if (n_clu == clu + 1)
240
nr_clu++;
241
else {
242
exfat_discard_cluster(sb, clu - nr_clu + 1, nr_clu);
243
nr_clu = 1;
244
}
245
}
246
247
clu = n_clu;
248
num_clusters++;
249
250
if (err)
251
break;
252
253
if (num_clusters >= sbi->num_clusters - EXFAT_FIRST_CLUSTER) {
254
/*
255
* The cluster chain includes a loop, scan the
256
* bitmap to get the number of used clusters.
257
*/
258
exfat_count_used_clusters(sb, &sbi->used_clusters);
259
260
return 0;
261
}
262
} while (clu != EXFAT_EOF_CLUSTER);
263
}
264
265
sbi->used_clusters -= num_clusters;
266
return 0;
267
}
268
269
int exfat_free_cluster(struct inode *inode, struct exfat_chain *p_chain)
270
{
271
int ret = 0;
272
273
mutex_lock(&EXFAT_SB(inode->i_sb)->bitmap_lock);
274
ret = __exfat_free_cluster(inode, p_chain);
275
mutex_unlock(&EXFAT_SB(inode->i_sb)->bitmap_lock);
276
277
return ret;
278
}
279
280
int exfat_find_last_cluster(struct super_block *sb, struct exfat_chain *p_chain,
281
unsigned int *ret_clu)
282
{
283
unsigned int clu, next;
284
unsigned int count = 0;
285
286
next = p_chain->dir;
287
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
288
*ret_clu = next + p_chain->size - 1;
289
return 0;
290
}
291
292
do {
293
count++;
294
clu = next;
295
if (exfat_ent_get(sb, clu, &next))
296
return -EIO;
297
} while (next != EXFAT_EOF_CLUSTER && count <= p_chain->size);
298
299
if (p_chain->size != count) {
300
exfat_fs_error(sb,
301
"bogus directory size (clus : ondisk(%d) != counted(%d))",
302
p_chain->size, count);
303
return -EIO;
304
}
305
306
*ret_clu = clu;
307
return 0;
308
}
309
310
int exfat_zeroed_cluster(struct inode *dir, unsigned int clu)
311
{
312
struct super_block *sb = dir->i_sb;
313
struct exfat_sb_info *sbi = EXFAT_SB(sb);
314
struct buffer_head *bh;
315
sector_t blknr, last_blknr, i;
316
317
blknr = exfat_cluster_to_sector(sbi, clu);
318
last_blknr = blknr + sbi->sect_per_clus;
319
320
if (last_blknr > sbi->num_sectors && sbi->num_sectors > 0) {
321
exfat_fs_error_ratelimit(sb,
322
"%s: out of range(sect:%llu len:%u)",
323
__func__, (unsigned long long)blknr,
324
sbi->sect_per_clus);
325
return -EIO;
326
}
327
328
/* Zeroing the unused blocks on this cluster */
329
for (i = blknr; i < last_blknr; i++) {
330
bh = sb_getblk(sb, i);
331
if (!bh)
332
return -ENOMEM;
333
334
memset(bh->b_data, 0, sb->s_blocksize);
335
set_buffer_uptodate(bh);
336
mark_buffer_dirty(bh);
337
brelse(bh);
338
}
339
340
if (IS_DIRSYNC(dir))
341
return sync_blockdev_range(sb->s_bdev,
342
EXFAT_BLK_TO_B(blknr, sb),
343
EXFAT_BLK_TO_B(last_blknr, sb) - 1);
344
345
return 0;
346
}
347
348
int exfat_alloc_cluster(struct inode *inode, unsigned int num_alloc,
349
struct exfat_chain *p_chain, bool sync_bmap)
350
{
351
int ret = -ENOSPC;
352
unsigned int total_cnt;
353
unsigned int hint_clu, new_clu, last_clu = EXFAT_EOF_CLUSTER;
354
struct super_block *sb = inode->i_sb;
355
struct exfat_sb_info *sbi = EXFAT_SB(sb);
356
357
total_cnt = EXFAT_DATA_CLUSTER_COUNT(sbi);
358
359
if (unlikely(total_cnt < sbi->used_clusters)) {
360
exfat_fs_error_ratelimit(sb,
361
"%s: invalid used clusters(t:%u,u:%u)\n",
362
__func__, total_cnt, sbi->used_clusters);
363
return -EIO;
364
}
365
366
if (num_alloc > total_cnt - sbi->used_clusters)
367
return -ENOSPC;
368
369
mutex_lock(&sbi->bitmap_lock);
370
371
hint_clu = p_chain->dir;
372
/* find new cluster */
373
if (hint_clu == EXFAT_EOF_CLUSTER) {
374
if (sbi->clu_srch_ptr < EXFAT_FIRST_CLUSTER) {
375
exfat_err(sb, "sbi->clu_srch_ptr is invalid (%u)",
376
sbi->clu_srch_ptr);
377
sbi->clu_srch_ptr = EXFAT_FIRST_CLUSTER;
378
}
379
380
hint_clu = exfat_find_free_bitmap(sb, sbi->clu_srch_ptr);
381
if (hint_clu == EXFAT_EOF_CLUSTER) {
382
ret = -ENOSPC;
383
goto unlock;
384
}
385
}
386
387
/* check cluster validation */
388
if (!is_valid_cluster(sbi, hint_clu)) {
389
if (hint_clu != sbi->num_clusters)
390
exfat_err(sb, "hint_cluster is invalid (%u), rewind to the first cluster",
391
hint_clu);
392
hint_clu = EXFAT_FIRST_CLUSTER;
393
p_chain->flags = ALLOC_FAT_CHAIN;
394
}
395
396
p_chain->dir = EXFAT_EOF_CLUSTER;
397
398
while ((new_clu = exfat_find_free_bitmap(sb, hint_clu)) !=
399
EXFAT_EOF_CLUSTER) {
400
if (new_clu != hint_clu &&
401
p_chain->flags == ALLOC_NO_FAT_CHAIN) {
402
if (exfat_chain_cont_cluster(sb, p_chain->dir,
403
p_chain->size)) {
404
ret = -EIO;
405
goto free_cluster;
406
}
407
p_chain->flags = ALLOC_FAT_CHAIN;
408
}
409
410
/* update allocation bitmap */
411
if (exfat_set_bitmap(inode, new_clu, sync_bmap)) {
412
ret = -EIO;
413
goto free_cluster;
414
}
415
416
/* update FAT table */
417
if (p_chain->flags == ALLOC_FAT_CHAIN) {
418
if (exfat_ent_set(sb, new_clu, EXFAT_EOF_CLUSTER)) {
419
ret = -EIO;
420
goto free_cluster;
421
}
422
}
423
424
if (p_chain->dir == EXFAT_EOF_CLUSTER) {
425
p_chain->dir = new_clu;
426
} else if (p_chain->flags == ALLOC_FAT_CHAIN) {
427
if (exfat_ent_set(sb, last_clu, new_clu)) {
428
ret = -EIO;
429
goto free_cluster;
430
}
431
}
432
p_chain->size++;
433
434
last_clu = new_clu;
435
436
if (p_chain->size == num_alloc) {
437
sbi->clu_srch_ptr = hint_clu;
438
sbi->used_clusters += num_alloc;
439
440
mutex_unlock(&sbi->bitmap_lock);
441
return 0;
442
}
443
444
hint_clu = new_clu + 1;
445
if (hint_clu >= sbi->num_clusters) {
446
hint_clu = EXFAT_FIRST_CLUSTER;
447
448
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
449
if (exfat_chain_cont_cluster(sb, p_chain->dir,
450
p_chain->size)) {
451
ret = -EIO;
452
goto free_cluster;
453
}
454
p_chain->flags = ALLOC_FAT_CHAIN;
455
}
456
}
457
}
458
free_cluster:
459
__exfat_free_cluster(inode, p_chain);
460
unlock:
461
mutex_unlock(&sbi->bitmap_lock);
462
return ret;
463
}
464
465
int exfat_count_num_clusters(struct super_block *sb,
466
struct exfat_chain *p_chain, unsigned int *ret_count)
467
{
468
unsigned int i, count;
469
unsigned int clu;
470
struct exfat_sb_info *sbi = EXFAT_SB(sb);
471
472
if (!p_chain->dir || p_chain->dir == EXFAT_EOF_CLUSTER) {
473
*ret_count = 0;
474
return 0;
475
}
476
477
if (p_chain->flags == ALLOC_NO_FAT_CHAIN) {
478
*ret_count = p_chain->size;
479
return 0;
480
}
481
482
clu = p_chain->dir;
483
count = 0;
484
for (i = EXFAT_FIRST_CLUSTER; i < sbi->num_clusters; i++) {
485
count++;
486
if (exfat_ent_get(sb, clu, &clu))
487
return -EIO;
488
if (clu == EXFAT_EOF_CLUSTER)
489
break;
490
}
491
492
*ret_count = count;
493
494
/*
495
* since exfat_count_used_clusters() is not called, sbi->used_clusters
496
* cannot be used here.
497
*/
498
if (unlikely(i == sbi->num_clusters && clu != EXFAT_EOF_CLUSTER)) {
499
exfat_fs_error(sb, "The cluster chain has a loop");
500
return -EIO;
501
}
502
503
return 0;
504
}
505
506