fs: sdfat: Update to version 2.3.0
[GitHub/LineageOS/android_kernel_samsung_universal7580.git] / fs / sdfat / core_fat.c
1 /*
2 * Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version 2
7 * of the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see <http://www.gnu.org/licenses/>.
16 */
17
18 /************************************************************************/
19 /* */
20 /* PROJECT : exFAT & FAT12/16/32 File System */
21 /* FILE : core_fat.c */
22 /* PURPOSE : FAT-fs core code for sdFAT */
23 /* */
24 /*----------------------------------------------------------------------*/
25 /* NOTES */
26 /* */
27 /* */
28 /************************************************************************/
29
30 #include <linux/version.h>
31 #include <linux/blkdev.h>
32 #include <linux/workqueue.h>
33 #include <linux/kernel.h>
34 #include <linux/log2.h>
35
36 #include "sdfat.h"
37 #include "core.h"
38 #include <asm/byteorder.h>
39 #include <asm/unaligned.h>
40
41 /*----------------------------------------------------------------------*/
42 /* Constant & Macro Definitions */
43 /*----------------------------------------------------------------------*/
44 #define MAX_LFN_ORDER (20)
45
46 /*
47 * MAX_EST_AU_SECT should be changed according to 32/64bits.
48 * On 32bit, 4KB page supports 512 clusters per AU.
49 * But, on 64bit, 4KB page can handle a half of total list_head of 32bit's.
50 * Bcause the size of list_head structure on 64bit increases twofold over 32bit.
51 */
52 #if (BITS_PER_LONG == 64)
53 //#define MAX_EST_AU_SECT (16384) /* upto 8MB */
54 #define MAX_EST_AU_SECT (32768) /* upto 16MB, used more page for list_head */
55 #else
56 #define MAX_EST_AU_SECT (32768) /* upto 16MB */
57 #endif
58
59 /*======================================================================*/
60 /* Local Function Declarations */
61 /*======================================================================*/
62 static s32 __extract_uni_name_from_ext_entry(EXT_DENTRY_T *, u16 *, s32);
63
64 /*----------------------------------------------------------------------*/
65 /* Global Variable Definitions */
66 /*----------------------------------------------------------------------*/
67
68 /*----------------------------------------------------------------------*/
69 /* Local Variable Definitions */
70 /*----------------------------------------------------------------------*/
71
72 /*======================================================================*/
73 /* Local Function Definitions */
74 /*======================================================================*/
75 static u32 __calc_default_au_size(struct super_block *sb)
76 {
77 struct block_device *bdev = sb->s_bdev;
78 struct gendisk *disk;
79 struct request_queue *queue;
80 struct queue_limits *limit;
81 unsigned int est_au_sect = MAX_EST_AU_SECT;
82 unsigned int est_au_size = 0;
83 unsigned int queue_au_size = 0;
84 sector_t total_sect = 0;
85
86 /* we assumed that sector size is 512 bytes */
87
88 disk = bdev->bd_disk;
89 if (!disk)
90 goto out;
91
92 queue = disk->queue;
93 if (!queue)
94 goto out;
95
96 limit = &queue->limits;
97 queue_au_size = limit->discard_granularity;
98
99 /* estimate function(x) =
100 * (total_sect / 2) * 512 / 1024
101 * => (total_sect >> 1) >> 1)
102 * => (total_sect >> 2)
103 * => estimated bytes size
104 *
105 * ex1) <= 8GB -> 4MB
106 * ex2) 16GB -> 8MB
107 * ex3) >= 32GB -> 16MB
108 */
109 total_sect = disk->part0.nr_sects;
110 est_au_size = total_sect >> 2;
111
112 /* au_size assumed that bytes per sector is 512 */
113 est_au_sect = est_au_size >> 9;
114
115 MMSG("DBG1: total_sect(%llu) est_au_size(%u) est_au_sect(%u)\n",
116 (u64)total_sect, est_au_size, est_au_sect);
117
118 if (est_au_sect <= 8192) {
119 /* 4MB */
120 est_au_sect = 8192;
121 } else if (est_au_sect <= 16384) {
122 /* 8MB */
123 est_au_sect = 16384;
124 } else {
125 /* 8MB or 16MB */
126 est_au_sect = MAX_EST_AU_SECT;
127 }
128
129 MMSG("DBG2: total_sect(%llu) est_au_size(%u) est_au_sect(%u)\n",
130 (u64)total_sect, est_au_size, est_au_sect);
131
132 if (est_au_size < queue_au_size &&
133 queue_au_size <= (MAX_EST_AU_SECT << 9)) {
134 DMSG("use queue_au_size(%u) instead of est_au_size(%u)\n",
135 queue_au_size, est_au_size);
136 est_au_sect = queue_au_size >> 9;
137 }
138
139 out:
140 if (sb->s_blocksize != 512) {
141 ASSERT(sb->s_blocksize_bits > 9);
142 sdfat_log_msg(sb, KERN_INFO,
143 "adjustment est_au_size by logical block size(%lu)",
144 sb->s_blocksize);
145 est_au_sect >>= (sb->s_blocksize_bits - 9);
146 }
147
148 sdfat_log_msg(sb, KERN_INFO, "set default AU sectors : %u "
149 "(queue_au_size : %u KB, disk_size : %llu MB)",
150 est_au_sect, queue_au_size >> 10, (u64)(total_sect >> 11));
151 return est_au_sect;
152 }
153
154
155 /*
156 * Cluster Management Functions
157 */
158 static s32 fat_free_cluster(struct super_block *sb, CHAIN_T *p_chain, s32 do_relse)
159 {
160 s32 ret = -EIO;
161 s32 num_clusters = 0;
162 u32 clu, prev;
163 FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
164 s32 i;
165 u64 sector;
166
167 /* invalid cluster number */
168 if (IS_CLUS_FREE(p_chain->dir) || IS_CLUS_EOF(p_chain->dir))
169 return 0;
170
171 /* no cluster to truncate */
172 if (!p_chain->size) {
173 DMSG("%s: cluster(%u) truncation is not required.",
174 __func__, p_chain->dir);
175 return 0;
176 }
177
178 /* check cluster validation */
179 if ((p_chain->dir < 2) && (p_chain->dir >= fsi->num_clusters)) {
180 EMSG("%s: invalid start cluster (%u)\n", __func__, p_chain->dir);
181 sdfat_debug_bug_on(1);
182 return -EIO;
183 }
184
185
186 set_sb_dirty(sb);
187 clu = p_chain->dir;
188
189 do {
190 if (do_relse) {
191 sector = CLUS_TO_SECT(fsi, clu);
192 for (i = 0; i < fsi->sect_per_clus; i++) {
193 if (dcache_release(sb, sector+i) == -EIO)
194 goto out;
195 }
196 }
197
198 prev = clu;
199 if (get_next_clus_safe(sb, &clu)) {
200 /* print more helpful log */
201 if (IS_CLUS_BAD(clu)) {
202 sdfat_log_msg(sb, KERN_ERR, "%s : "
203 "deleting bad cluster (clu[%u]->BAD)",
204 __func__, prev);
205 } else if (IS_CLUS_FREE(clu)) {
206 sdfat_log_msg(sb, KERN_ERR, "%s : "
207 "deleting free cluster (clu[%u]->FREE)",
208 __func__, prev);
209 }
210 goto out;
211 }
212
213 /* Free FAT chain */
214 if (fat_ent_set(sb, prev, CLUS_FREE))
215 goto out;
216
217 /* Update AMAP if needed */
218 if (fsi->amap) {
219 if (amap_release_cluster(sb, prev))
220 return -EIO;
221 }
222
223 num_clusters++;
224
225 } while (!IS_CLUS_EOF(clu));
226
227 /* success */
228 ret = 0;
229 out:
230 fsi->used_clusters -= num_clusters;
231 return ret;
232 } /* end of fat_free_cluster */
233
234 static s32 fat_alloc_cluster(struct super_block *sb, u32 num_alloc, CHAIN_T *p_chain, s32 dest)
235 {
236 s32 ret = -ENOSPC;
237 u32 i, num_clusters = 0, total_cnt;
238 u32 new_clu, last_clu = CLUS_EOF, read_clu;
239 FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
240
241 total_cnt = fsi->num_clusters - CLUS_BASE;
242
243 if (unlikely(total_cnt < fsi->used_clusters)) {
244 sdfat_fs_error_ratelimit(sb,
245 "%s : invalid used clusters(t:%u,u:%u)\n",
246 __func__, total_cnt, fsi->used_clusters);
247 return -EIO;
248 }
249
250 if (num_alloc > total_cnt - fsi->used_clusters)
251 return -ENOSPC;
252
253 new_clu = p_chain->dir;
254 if (IS_CLUS_EOF(new_clu))
255 new_clu = fsi->clu_srch_ptr;
256 else if (new_clu >= fsi->num_clusters)
257 new_clu = CLUS_BASE;
258
259 set_sb_dirty(sb);
260
261 p_chain->dir = CLUS_EOF;
262
263 for (i = CLUS_BASE; i < fsi->num_clusters; i++) {
264 if (fat_ent_get(sb, new_clu, &read_clu)) {
265 ret = -EIO;
266 goto error;
267 }
268
269 if (IS_CLUS_FREE(read_clu)) {
270 if (fat_ent_set(sb, new_clu, CLUS_EOF)) {
271 ret = -EIO;
272 goto error;
273 }
274 num_clusters++;
275
276 if (IS_CLUS_EOF(p_chain->dir)) {
277 p_chain->dir = new_clu;
278 } else {
279 if (fat_ent_set(sb, last_clu, new_clu)) {
280 ret = -EIO;
281 goto error;
282 }
283 }
284
285 last_clu = new_clu;
286
287 if ((--num_alloc) == 0) {
288 fsi->clu_srch_ptr = new_clu;
289 fsi->used_clusters += num_clusters;
290
291 return 0;
292 }
293 }
294 if ((++new_clu) >= fsi->num_clusters)
295 new_clu = CLUS_BASE;
296 }
297 error:
298 if (num_clusters)
299 fat_free_cluster(sb, p_chain, 0);
300 return ret;
301 } /* end of fat_alloc_cluster */
302
303 static s32 fat_count_used_clusters(struct super_block *sb, u32 *ret_count)
304 {
305 s32 i;
306 u32 clu, count = 0;
307 FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
308
309 for (i = CLUS_BASE; i < fsi->num_clusters; i++) {
310 if (fat_ent_get(sb, i, &clu))
311 return -EIO;
312
313 if (!IS_CLUS_FREE(clu))
314 count++;
315 }
316
317 *ret_count = count;
318 return 0;
319 } /* end of fat_count_used_clusters */
320
321
322 /*
323 * Directory Entry Management Functions
324 */
325 static u32 fat_get_entry_type(DENTRY_T *p_entry)
326 {
327 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
328
329 /* first byte of 32bytes dummy */
330 if (*(ep->name) == MSDOS_UNUSED)
331 return TYPE_UNUSED;
332
333 /* 0xE5 of Kanji Japanese is replaced to 0x05 */
334 else if (*(ep->name) == MSDOS_DELETED)
335 return TYPE_DELETED;
336
337 /* 11th byte of 32bytes dummy */
338 else if ((ep->attr & ATTR_EXTEND_MASK) == ATTR_EXTEND)
339 return TYPE_EXTEND;
340
341 else if (!(ep->attr & (ATTR_SUBDIR | ATTR_VOLUME)))
342 return TYPE_FILE;
343
344 else if ((ep->attr & (ATTR_SUBDIR | ATTR_VOLUME)) == ATTR_SUBDIR)
345 return TYPE_DIR;
346
347 else if ((ep->attr & (ATTR_SUBDIR | ATTR_VOLUME)) == ATTR_VOLUME)
348 return TYPE_VOLUME;
349
350 return TYPE_INVALID;
351 } /* end of fat_get_entry_type */
352
353 static void fat_set_entry_type(DENTRY_T *p_entry, u32 type)
354 {
355 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
356
357 if (type == TYPE_UNUSED)
358 *(ep->name) = MSDOS_UNUSED; /* 0x0 */
359
360 else if (type == TYPE_DELETED)
361 *(ep->name) = MSDOS_DELETED; /* 0xE5 */
362
363 else if (type == TYPE_EXTEND)
364 ep->attr = ATTR_EXTEND;
365
366 else if (type == TYPE_DIR)
367 ep->attr = ATTR_SUBDIR;
368
369 else if (type == TYPE_FILE)
370 ep->attr = ATTR_ARCHIVE;
371
372 else if (type == TYPE_SYMLINK)
373 ep->attr = ATTR_ARCHIVE | ATTR_SYMLINK;
374 } /* end of fat_set_entry_type */
375
376 static u32 fat_get_entry_attr(DENTRY_T *p_entry)
377 {
378 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
379
380 return (u32)ep->attr;
381 } /* end of fat_get_entry_attr */
382
383 static void fat_set_entry_attr(DENTRY_T *p_entry, u32 attr)
384 {
385 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
386
387 ep->attr = (u8)attr;
388 } /* end of fat_set_entry_attr */
389
390 static u8 fat_get_entry_flag(DENTRY_T *p_entry)
391 {
392 return 0x01;
393 } /* end of fat_get_entry_flag */
394
395 static void fat_set_entry_flag(DENTRY_T *p_entry, u8 flags)
396 {
397 } /* end of fat_set_entry_flag */
398
399 static u32 fat_get_entry_clu0(DENTRY_T *p_entry)
400 {
401 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
402 /* FIXME : is ok? */
403 return(((u32)(le16_to_cpu(ep->start_clu_hi)) << 16) | le16_to_cpu(ep->start_clu_lo));
404 } /* end of fat_get_entry_clu0 */
405
406 static void fat_set_entry_clu0(DENTRY_T *p_entry, u32 start_clu)
407 {
408 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
409
410 ep->start_clu_lo = cpu_to_le16(CLUSTER_16(start_clu));
411 ep->start_clu_hi = cpu_to_le16(CLUSTER_16(start_clu >> 16));
412 } /* end of fat_set_entry_clu0 */
413
414 static u64 fat_get_entry_size(DENTRY_T *p_entry)
415 {
416 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
417
418 return (u64)le32_to_cpu(ep->size);
419 } /* end of fat_get_entry_size */
420
421 static void fat_set_entry_size(DENTRY_T *p_entry, u64 size)
422 {
423 DOS_DENTRY_T *ep = (DOS_DENTRY_T *)p_entry;
424
425 ep->size = cpu_to_le32((u32)size);
426 } /* end of fat_set_entry_size */
427
428 static void fat_get_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode)
429 {
430 u16 t = 0x00, d = 0x21;
431 DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry;
432
433 switch (mode) {
434 case TM_CREATE:
435 t = le16_to_cpu(ep->create_time);
436 d = le16_to_cpu(ep->create_date);
437 break;
438 case TM_MODIFY:
439 t = le16_to_cpu(ep->modify_time);
440 d = le16_to_cpu(ep->modify_date);
441 break;
442 }
443
444 tp->tz.value = 0x00;
445 tp->sec = (t & 0x001F) << 1;
446 tp->min = (t >> 5) & 0x003F;
447 tp->hour = (t >> 11);
448 tp->day = (d & 0x001F);
449 tp->mon = (d >> 5) & 0x000F;
450 tp->year = (d >> 9);
451 } /* end of fat_get_entry_time */
452
453 static void fat_set_entry_time(DENTRY_T *p_entry, TIMESTAMP_T *tp, u8 mode)
454 {
455 u16 t, d;
456 DOS_DENTRY_T *ep = (DOS_DENTRY_T *) p_entry;
457
458 t = (tp->hour << 11) | (tp->min << 5) | (tp->sec >> 1);
459 d = (tp->year << 9) | (tp->mon << 5) | tp->day;
460
461 switch (mode) {
462 case TM_CREATE:
463 ep->create_time = cpu_to_le16(t);
464 ep->create_date = cpu_to_le16(d);
465 break;
466 case TM_MODIFY:
467 ep->modify_time = cpu_to_le16(t);
468 ep->modify_date = cpu_to_le16(d);
469 break;
470 }
471 } /* end of fat_set_entry_time */
472
473 static void __init_dos_entry(struct super_block *sb, DOS_DENTRY_T *ep, u32 type, u32 start_clu)
474 {
475 TIMESTAMP_T tm, *tp;
476
477 fat_set_entry_type((DENTRY_T *) ep, type);
478 ep->start_clu_lo = cpu_to_le16(CLUSTER_16(start_clu));
479 ep->start_clu_hi = cpu_to_le16(CLUSTER_16(start_clu >> 16));
480 ep->size = 0;
481
482 tp = tm_now(SDFAT_SB(sb), &tm);
483 fat_set_entry_time((DENTRY_T *) ep, tp, TM_CREATE);
484 fat_set_entry_time((DENTRY_T *) ep, tp, TM_MODIFY);
485 ep->access_date = 0;
486 ep->create_time_ms = 0;
487 } /* end of __init_dos_entry */
488
489 static void __init_ext_entry(EXT_DENTRY_T *ep, s32 order, u8 chksum, u16 *uniname)
490 {
491 s32 i;
492 u8 end = false;
493
494 fat_set_entry_type((DENTRY_T *) ep, TYPE_EXTEND);
495 ep->order = (u8) order;
496 ep->sysid = 0;
497 ep->checksum = chksum;
498 ep->start_clu = 0;
499
500 /* unaligned name */
501 for (i = 0; i < 5; i++) {
502 if (!end) {
503 put_unaligned_le16(*uniname, &(ep->unicode_0_4[i<<1]));
504 if (*uniname == 0x0)
505 end = true;
506 else
507 uniname++;
508 } else {
509 put_unaligned_le16(0xFFFF, &(ep->unicode_0_4[i<<1]));
510 }
511 }
512
513 /* aligned name */
514 for (i = 0; i < 6; i++) {
515 if (!end) {
516 ep->unicode_5_10[i] = cpu_to_le16(*uniname);
517 if (*uniname == 0x0)
518 end = true;
519 else
520 uniname++;
521 } else {
522 ep->unicode_5_10[i] = cpu_to_le16(0xFFFF);
523 }
524 }
525
526 /* aligned name */
527 for (i = 0; i < 2; i++) {
528 if (!end) {
529 ep->unicode_11_12[i] = cpu_to_le16(*uniname);
530 if (*uniname == 0x0)
531 end = true;
532 else
533 uniname++;
534 } else {
535 ep->unicode_11_12[i] = cpu_to_le16(0xFFFF);
536 }
537 }
538 } /* end of __init_ext_entry */
539
540 static s32 fat_init_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u32 type,
541 u32 start_clu, u64 size)
542 {
543 u64 sector;
544 DOS_DENTRY_T *dos_ep;
545
546 dos_ep = (DOS_DENTRY_T *) get_dentry_in_dir(sb, p_dir, entry, &sector);
547 if (!dos_ep)
548 return -EIO;
549
550 __init_dos_entry(sb, dos_ep, type, start_clu);
551 dcache_modify(sb, sector);
552
553 return 0;
554 } /* end of fat_init_dir_entry */
555
556 static s32 fat_init_ext_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 num_entries,
557 UNI_NAME_T *p_uniname, DOS_NAME_T *p_dosname)
558 {
559 s32 i;
560 u64 sector;
561 u8 chksum;
562 u16 *uniname = p_uniname->name;
563 DOS_DENTRY_T *dos_ep;
564 EXT_DENTRY_T *ext_ep;
565
566 dos_ep = (DOS_DENTRY_T *) get_dentry_in_dir(sb, p_dir, entry, &sector);
567 if (!dos_ep)
568 return -EIO;
569
570 dos_ep->lcase = p_dosname->name_case;
571 memcpy(dos_ep->name, p_dosname->name, DOS_NAME_LENGTH);
572 if (dcache_modify(sb, sector))
573 return -EIO;
574
575 if ((--num_entries) > 0) {
576 chksum = calc_chksum_1byte((void *) dos_ep->name, DOS_NAME_LENGTH, 0);
577
578 for (i = 1; i < num_entries; i++) {
579 ext_ep = (EXT_DENTRY_T *) get_dentry_in_dir(sb, p_dir, entry-i, &sector);
580 if (!ext_ep)
581 return -EIO;
582
583 __init_ext_entry(ext_ep, i, chksum, uniname);
584 if (dcache_modify(sb, sector))
585 return -EIO;
586 uniname += 13;
587 }
588
589 ext_ep = (EXT_DENTRY_T *) get_dentry_in_dir(sb, p_dir, entry-i, &sector);
590 if (!ext_ep)
591 return -EIO;
592
593 __init_ext_entry(ext_ep, i+MSDOS_LAST_LFN, chksum, uniname);
594 if (dcache_modify(sb, sector))
595 return -EIO;
596 }
597
598 return 0;
599 } /* end of fat_init_ext_entry */
600
601 static s32 fat_delete_dir_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, s32 order, s32 num_entries)
602 {
603 s32 i;
604 u64 sector;
605 DENTRY_T *ep;
606
607 for (i = num_entries-1; i >= order; i--) {
608 ep = get_dentry_in_dir(sb, p_dir, entry-i, &sector);
609 if (!ep)
610 return -EIO;
611
612 fat_set_entry_type(ep, TYPE_DELETED);
613 if (dcache_modify(sb, sector))
614 return -EIO;
615 }
616
617 return 0;
618 }
619
620 /* return values of fat_find_dir_entry()
621 * >= 0 : return dir entiry position with the name in dir
622 * -EEXIST : (root dir, ".") it is the root dir itself
623 * -ENOENT : entry with the name does not exist
624 * -EIO : I/O error
625 */
626 static inline s32 __get_dentries_per_clu(FS_INFO_T *fsi, s32 clu)
627 {
628 if (IS_CLUS_FREE(clu)) /* FAT16 root_dir */
629 return fsi->dentries_in_root;
630
631 return fsi->dentries_per_clu;
632 }
633
634 static s32 fat_find_dir_entry(struct super_block *sb, FILE_ID_T *fid,
635 CHAIN_T *p_dir, UNI_NAME_T *p_uniname, s32 num_entries, DOS_NAME_T *p_dosname, u32 type)
636 {
637 s32 i, rewind = 0, dentry = 0, end_eidx = 0;
638 s32 chksum = 0, lfn_ord = 0, lfn_len = 0;
639 s32 dentries_per_clu, num_empty = 0;
640 u32 entry_type;
641 u16 entry_uniname[14], *uniname = NULL;
642 CHAIN_T clu;
643 DENTRY_T *ep;
644 HINT_T *hint_stat = &fid->hint_stat;
645 HINT_FEMP_T candi_empty;
646 FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
647
648 /*
649 * REMARK:
650 * DOT and DOTDOT are handled by VFS layer
651 */
652
653 dentries_per_clu = __get_dentries_per_clu(fsi, p_dir->dir);
654 clu.dir = p_dir->dir;
655 clu.flags = p_dir->flags;
656
657 if (hint_stat->eidx) {
658 clu.dir = hint_stat->clu;
659 dentry = hint_stat->eidx;
660 end_eidx = dentry;
661 }
662
663 candi_empty.eidx = -1;
664
665 MMSG("lookup dir= %s\n", p_dosname->name);
666 rewind:
667 while (!IS_CLUS_EOF(clu.dir)) {
668 i = dentry % dentries_per_clu;
669 for (; i < dentries_per_clu; i++, dentry++) {
670 if (rewind && (dentry == end_eidx))
671 goto not_found;
672
673 ep = get_dentry_in_dir(sb, &clu, i, NULL);
674 if (!ep)
675 return -EIO;
676
677 entry_type = fat_get_entry_type(ep);
678
679 /*
680 * Most directory entries have long name,
681 * So, we check extend directory entry first.
682 */
683 if (entry_type == TYPE_EXTEND) {
684 EXT_DENTRY_T *ext_ep = (EXT_DENTRY_T *)ep;
685 u32 cur_ord = (u32)ext_ep->order;
686 u32 cur_chksum = (s32)ext_ep->checksum;
687 s32 len = 13;
688 u16 unichar;
689
690 num_empty = 0;
691 candi_empty.eidx = -1;
692
693 /* check whether new lfn or not */
694 if (cur_ord & MSDOS_LAST_LFN) {
695 cur_ord &= ~(MSDOS_LAST_LFN);
696 chksum = cur_chksum;
697 len = (13 * (cur_ord-1));
698 uniname = (p_uniname->name + len);
699 lfn_ord = cur_ord + 1;
700 lfn_len = 0;
701
702 /* check minimum name length */
703 if (cur_ord &&
704 (len > p_uniname->name_len)) {
705 /* MISMATCHED NAME LENGTH */
706 lfn_len = -1;
707 }
708 len = 0;
709 }
710
711 /* invalid lfn order */
712 if (!cur_ord || (cur_ord > MAX_LFN_ORDER) ||
713 ((cur_ord + 1) != lfn_ord))
714 goto reset_dentry_set;
715
716 /* check checksum of directory entry set */
717 if (cur_chksum != chksum)
718 goto reset_dentry_set;
719
720 /* update order for next dentry */
721 lfn_ord = cur_ord;
722
723 /* check whether mismatched lfn or not */
724 if (lfn_len == -1) {
725 /* MISMATCHED LFN DENTRY SET */
726 continue;
727 }
728
729 if (!uniname) {
730 sdfat_fs_error(sb,
731 "%s : abnormal dentry "
732 "(start_clu[%u], "
733 "idx[%u])", __func__,
734 p_dir->dir, dentry);
735 sdfat_debug_bug_on(1);
736 return -EIO;
737 }
738
739 /* update position of name buffer */
740 uniname -= len;
741
742 /* get utf16 characters saved on this entry */
743 len = __extract_uni_name_from_ext_entry(ext_ep, entry_uniname, lfn_ord);
744
745 /* replace last char to null */
746 unichar = *(uniname+len);
747 *(uniname+len) = (u16)0x0;
748
749 /* uniname ext_dentry unit compare repeatdly */
750 if (nls_cmp_uniname(sb, uniname, entry_uniname)) {
751 /* DO HANDLE WRONG NAME */
752 lfn_len = -1;
753 } else {
754 /* add matched chars length */
755 lfn_len += len;
756 }
757
758 /* restore previous character */
759 *(uniname+len) = unichar;
760
761 /* jump to check next dentry */
762 continue;
763
764 } else if ((entry_type == TYPE_FILE) || (entry_type == TYPE_DIR)) {
765 DOS_DENTRY_T *dos_ep = (DOS_DENTRY_T *)ep;
766 u32 cur_chksum = (s32)calc_chksum_1byte(
767 (void *) dos_ep->name,
768 DOS_NAME_LENGTH, 0);
769
770 num_empty = 0;
771 candi_empty.eidx = -1;
772
773 MMSG("checking dir= %c%c%c%c%c%c%c%c%c%c%c\n",
774 dos_ep->name[0], dos_ep->name[1],
775 dos_ep->name[2], dos_ep->name[3],
776 dos_ep->name[4], dos_ep->name[5],
777 dos_ep->name[6], dos_ep->name[7],
778 dos_ep->name[8], dos_ep->name[9],
779 dos_ep->name[10]);
780
781 /*
782 * if there is no valid long filename,
783 * we should check short filename.
784 */
785 if (!lfn_len || (cur_chksum != chksum)) {
786 /* check shortname */
787 if ((p_dosname->name[0] != '\0') &&
788 !nls_cmp_sfn(sb,
789 p_dosname->name,
790 dos_ep->name)) {
791 goto found;
792 }
793 /* check name length */
794 } else if ((lfn_len > 0) &&
795 ((s32)p_uniname->name_len ==
796 lfn_len)) {
797 goto found;
798 }
799
800 /* DO HANDLE MISMATCHED SFN, FALL THROUGH */
801 } else if ((entry_type == TYPE_UNUSED) || (entry_type == TYPE_DELETED)) {
802 num_empty++;
803 if (candi_empty.eidx == -1) {
804 if (num_empty == 1) {
805 candi_empty.cur.dir = clu.dir;
806 candi_empty.cur.size = clu.size;
807 candi_empty.cur.flags = clu.flags;
808 }
809
810 if (num_empty >= num_entries) {
811 candi_empty.eidx = dentry - (num_empty - 1);
812 ASSERT(0 <= candi_empty.eidx);
813 candi_empty.count = num_empty;
814
815 if ((fid->hint_femp.eidx == -1) ||
816 (candi_empty.eidx <= fid->hint_femp.eidx)) {
817 memcpy(&fid->hint_femp,
818 &candi_empty,
819 sizeof(HINT_FEMP_T));
820 }
821 }
822 }
823
824 if (entry_type == TYPE_UNUSED)
825 goto not_found;
826 /* FALL THROUGH */
827 }
828 reset_dentry_set:
829 /* TYPE_DELETED, TYPE_VOLUME OR MISMATCHED SFN */
830 lfn_ord = 0;
831 lfn_len = 0;
832 chksum = 0;
833 }
834
835 if (IS_CLUS_FREE(p_dir->dir))
836 break; /* FAT16 root_dir */
837
838 if (get_next_clus_safe(sb, &clu.dir))
839 return -EIO;
840 }
841
842 not_found:
843 /* we started at not 0 index,so we should try to find target
844 * from 0 index to the index we started at.
845 */
846 if (!rewind && end_eidx) {
847 rewind = 1;
848 dentry = 0;
849 clu.dir = p_dir->dir;
850 /* reset dentry set */
851 lfn_ord = 0;
852 lfn_len = 0;
853 chksum = 0;
854 /* reset empty hint_*/
855 num_empty = 0;
856 candi_empty.eidx = -1;
857 goto rewind;
858 }
859
860 /* initialized hint_stat */
861 hint_stat->clu = p_dir->dir;
862 hint_stat->eidx = 0;
863 return -ENOENT;
864
865 found:
866 /* next dentry we'll find is out of this cluster */
867 if (!((dentry + 1) % dentries_per_clu)) {
868 int ret = 0;
869 /* FAT16 root_dir */
870 if (IS_CLUS_FREE(p_dir->dir))
871 clu.dir = CLUS_EOF;
872 else
873 ret = get_next_clus_safe(sb, &clu.dir);
874
875 if (ret || IS_CLUS_EOF(clu.dir)) {
876 /* just initialized hint_stat */
877 hint_stat->clu = p_dir->dir;
878 hint_stat->eidx = 0;
879 return dentry;
880 }
881 }
882
883 hint_stat->clu = clu.dir;
884 hint_stat->eidx = dentry + 1;
885 return dentry;
886 } /* end of fat_find_dir_entry */
887
888 /* returns -EIO on error */
889 static s32 fat_count_ext_entries(struct super_block *sb, CHAIN_T *p_dir, s32 entry, DENTRY_T *p_entry)
890 {
891 s32 count = 0;
892 u8 chksum;
893 DOS_DENTRY_T *dos_ep = (DOS_DENTRY_T *) p_entry;
894 EXT_DENTRY_T *ext_ep;
895
896 chksum = calc_chksum_1byte((void *) dos_ep->name, DOS_NAME_LENGTH, 0);
897
898 for (entry--; entry >= 0; entry--) {
899 ext_ep = (EXT_DENTRY_T *)get_dentry_in_dir(sb, p_dir, entry, NULL);
900 if (!ext_ep)
901 return -EIO;
902
903 if ((fat_get_entry_type((DENTRY_T *)ext_ep) == TYPE_EXTEND) &&
904 (ext_ep->checksum == chksum)) {
905 count++;
906 if (ext_ep->order > MSDOS_LAST_LFN)
907 return count;
908 } else {
909 return count;
910 }
911 }
912
913 return count;
914 }
915
916
917 /*
918 * Name Conversion Functions
919 */
920 static s32 __extract_uni_name_from_ext_entry(EXT_DENTRY_T *ep, u16 *uniname, s32 order)
921 {
922 s32 i, len = 0;
923
924 for (i = 0; i < 5; i++) {
925 *uniname = get_unaligned_le16(&(ep->unicode_0_4[i<<1]));
926 if (*uniname == 0x0)
927 return len;
928 uniname++;
929 len++;
930 }
931
932 if (order < 20) {
933 for (i = 0; i < 6; i++) {
934 /* FIXME : unaligned? */
935 *uniname = le16_to_cpu(ep->unicode_5_10[i]);
936 if (*uniname == 0x0)
937 return len;
938 uniname++;
939 len++;
940 }
941 } else {
942 for (i = 0; i < 4; i++) {
943 /* FIXME : unaligned? */
944 *uniname = le16_to_cpu(ep->unicode_5_10[i]);
945 if (*uniname == 0x0)
946 return len;
947 uniname++;
948 len++;
949 }
950 *uniname = 0x0; /* uniname[MAX_NAME_LENGTH] */
951 return len;
952 }
953
954 for (i = 0; i < 2; i++) {
955 /* FIXME : unaligned? */
956 *uniname = le16_to_cpu(ep->unicode_11_12[i]);
957 if (*uniname == 0x0)
958 return len;
959 uniname++;
960 len++;
961 }
962
963 *uniname = 0x0;
964 return len;
965
966 } /* end of __extract_uni_name_from_ext_entry */
967
968 static void fat_get_uniname_from_ext_entry(struct super_block *sb, CHAIN_T *p_dir, s32 entry, u16 *uniname)
969 {
970 u32 i;
971 u16 *name = uniname;
972 u32 chksum;
973
974 DOS_DENTRY_T *dos_ep =
975 (DOS_DENTRY_T *)get_dentry_in_dir(sb, p_dir, entry, NULL);
976
977 if (unlikely(!dos_ep))
978 goto invalid_lfn;
979
980 chksum = (u32)calc_chksum_1byte(
981 (void *) dos_ep->name,
982 DOS_NAME_LENGTH, 0);
983
984 for (entry--, i = 1; entry >= 0; entry--, i++) {
985 EXT_DENTRY_T *ep;
986
987 ep = (EXT_DENTRY_T *)get_dentry_in_dir(sb, p_dir, entry, NULL);
988 if (!ep)
989 goto invalid_lfn;
990
991 if (fat_get_entry_type((DENTRY_T *) ep) != TYPE_EXTEND)
992 goto invalid_lfn;
993
994 if (chksum != (u32)ep->checksum)
995 goto invalid_lfn;
996
997 if (i != (u32)(ep->order & ~(MSDOS_LAST_LFN)))
998 goto invalid_lfn;
999
1000 __extract_uni_name_from_ext_entry(ep, name, (s32)i);
1001 if (ep->order & MSDOS_LAST_LFN)
1002 return;
1003
1004 name += 13;
1005 }
1006 invalid_lfn:
1007 *uniname = (u16)0x0;
1008 } /* end of fat_get_uniname_from_ext_entry */
1009
1010 /* Find if the shortname exists
1011 * and check if there are free entries
1012 */
1013 static s32 __fat_find_shortname_entry(struct super_block *sb, CHAIN_T *p_dir,
1014 u8 *p_dosname, s32 *offset, __attribute__((unused))int n_entry_needed)
1015 {
1016 u32 type;
1017 s32 i, dentry = 0;
1018 s32 dentries_per_clu;
1019 DENTRY_T *ep = NULL;
1020 DOS_DENTRY_T *dos_ep = NULL;
1021 CHAIN_T clu = *p_dir;
1022 FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
1023
1024 if (offset)
1025 *offset = -1;
1026
1027 if (IS_CLUS_FREE(clu.dir)) /* FAT16 root_dir */
1028 dentries_per_clu = fsi->dentries_in_root;
1029 else
1030 dentries_per_clu = fsi->dentries_per_clu;
1031
1032 while (!IS_CLUS_EOF(clu.dir)) {
1033 for (i = 0; i < dentries_per_clu; i++, dentry++) {
1034 ep = get_dentry_in_dir(sb, &clu, i, NULL);
1035 if (!ep)
1036 return -EIO;
1037
1038 type = fat_get_entry_type(ep);
1039
1040 if ((type == TYPE_FILE) || (type == TYPE_DIR)) {
1041 dos_ep = (DOS_DENTRY_T *)ep;
1042 if (!nls_cmp_sfn(sb, p_dosname, dos_ep->name)) {
1043 if (offset)
1044 *offset = dentry;
1045 return 0;
1046 }
1047 }
1048 }
1049
1050 /* fat12/16 root dir */
1051 if (IS_CLUS_FREE(clu.dir))
1052 break;
1053
1054 if (get_next_clus_safe(sb, &clu.dir))
1055 return -EIO;
1056 }
1057 return -ENOENT;
1058 }
1059
1060 #ifdef CONFIG_SDFAT_FAT32_SHORTNAME_SEQ
1061 static void __fat_attach_count_to_dos_name(u8 *dosname, s32 count)
1062 {
1063 s32 i, j, length;
1064 s8 str_count[6];
1065
1066 snprintf(str_count, sizeof(str_count), "~%d", count);
1067 length = strlen(str_count);
1068
1069 i = j = 0;
1070 while (j <= (8 - length)) {
1071 i = j;
1072 if (dosname[j] == ' ')
1073 break;
1074 if (dosname[j] & 0x80)
1075 j += 2;
1076 else
1077 j++;
1078 }
1079
1080 for (j = 0; j < length; i++, j++)
1081 dosname[i] = (u8) str_count[j];
1082
1083 if (i == 7)
1084 dosname[7] = ' ';
1085
1086 } /* end of __fat_attach_count_to_dos_name */
1087 #endif
1088
1089 s32 fat_generate_dos_name_new(struct super_block *sb, CHAIN_T *p_dir, DOS_NAME_T *p_dosname, s32 n_entry_needed)
1090 {
1091 s32 i;
1092 s32 baselen, err;
1093 u8 work[DOS_NAME_LENGTH], buf[5];
1094 u8 tail;
1095
1096 baselen = 8;
1097 memset(work, ' ', DOS_NAME_LENGTH);
1098 memcpy(work, p_dosname->name, DOS_NAME_LENGTH);
1099
1100 while (baselen && (work[--baselen] == ' ')) {
1101 /* DO NOTHING, JUST FOR CHECK_PATCH */
1102 }
1103
1104 if (baselen > 6)
1105 baselen = 6;
1106
1107 BUG_ON(baselen < 0);
1108
1109 #ifdef CONFIG_SDFAT_FAT32_SHORTNAME_SEQ
1110 /* example) namei_exfat.c -> NAMEI_~1 - NAMEI_~9 */
1111 work[baselen] = '~';
1112 for (i = 1; i < 10; i++) {
1113 // '0' + i = 1 ~ 9 ASCII
1114 work[baselen + 1] = '0' + i;
1115 err = __fat_find_shortname_entry(sb, p_dir, work, NULL, n_entry_needed);
1116 if (err == -ENOENT) {
1117 /* void return */
1118 __fat_attach_count_to_dos_name(p_dosname->name, i);
1119 return 0;
1120 }
1121
1122 /* any other error */
1123 if (err)
1124 return err;
1125 }
1126 #endif
1127
1128 i = jiffies;
1129 tail = (jiffies >> 16) & 0x7;
1130
1131 if (baselen > 2)
1132 baselen = 2;
1133
1134 BUG_ON(baselen < 0);
1135
1136 work[baselen + 4] = '~';
1137 // 1 ~ 8 ASCII
1138 work[baselen + 5] = '1' + tail;
1139 while (1) {
1140 snprintf(buf, sizeof(buf), "%04X", i & 0xffff);
1141 memcpy(&work[baselen], buf, 4);
1142 err = __fat_find_shortname_entry(sb, p_dir, work, NULL, n_entry_needed);
1143 if (err == -ENOENT) {
1144 memcpy(p_dosname->name, work, DOS_NAME_LENGTH);
1145 break;
1146 }
1147
1148 /* any other error */
1149 if (err)
1150 return err;
1151
1152 i -= 11;
1153 }
1154 return 0;
1155 } /* end of generate_dos_name_new */
1156
1157 static s32 fat_calc_num_entries(UNI_NAME_T *p_uniname)
1158 {
1159 s32 len;
1160
1161 len = p_uniname->name_len;
1162 if (len == 0)
1163 return 0;
1164
1165 /* 1 dos name entry + extended entries */
1166 return((len-1) / 13 + 2);
1167
1168 } /* end of calc_num_enties */
1169
1170 static s32 fat_check_max_dentries(FILE_ID_T *fid)
1171 {
1172 if ((fid->size >> DENTRY_SIZE_BITS) >= MAX_FAT_DENTRIES) {
1173 /* FAT spec allows a dir to grow upto 65536 dentries */
1174 return -ENOSPC;
1175 }
1176 return 0;
1177 } /* end of check_max_dentries */
1178
1179
1180 /*
1181 * File Operation Functions
1182 */
1183 static FS_FUNC_T fat_fs_func = {
1184 .alloc_cluster = fat_alloc_cluster,
1185 .free_cluster = fat_free_cluster,
1186 .count_used_clusters = fat_count_used_clusters,
1187
1188 .init_dir_entry = fat_init_dir_entry,
1189 .init_ext_entry = fat_init_ext_entry,
1190 .find_dir_entry = fat_find_dir_entry,
1191 .delete_dir_entry = fat_delete_dir_entry,
1192 .get_uniname_from_ext_entry = fat_get_uniname_from_ext_entry,
1193 .count_ext_entries = fat_count_ext_entries,
1194 .calc_num_entries = fat_calc_num_entries,
1195 .check_max_dentries = fat_check_max_dentries,
1196
1197 .get_entry_type = fat_get_entry_type,
1198 .set_entry_type = fat_set_entry_type,
1199 .get_entry_attr = fat_get_entry_attr,
1200 .set_entry_attr = fat_set_entry_attr,
1201 .get_entry_flag = fat_get_entry_flag,
1202 .set_entry_flag = fat_set_entry_flag,
1203 .get_entry_clu0 = fat_get_entry_clu0,
1204 .set_entry_clu0 = fat_set_entry_clu0,
1205 .get_entry_size = fat_get_entry_size,
1206 .set_entry_size = fat_set_entry_size,
1207 .get_entry_time = fat_get_entry_time,
1208 .set_entry_time = fat_set_entry_time,
1209 };
1210
1211 static FS_FUNC_T amap_fat_fs_func = {
1212 .alloc_cluster = amap_fat_alloc_cluster,
1213 .free_cluster = fat_free_cluster,
1214 .count_used_clusters = fat_count_used_clusters,
1215
1216 .init_dir_entry = fat_init_dir_entry,
1217 .init_ext_entry = fat_init_ext_entry,
1218 .find_dir_entry = fat_find_dir_entry,
1219 .delete_dir_entry = fat_delete_dir_entry,
1220 .get_uniname_from_ext_entry = fat_get_uniname_from_ext_entry,
1221 .count_ext_entries = fat_count_ext_entries,
1222 .calc_num_entries = fat_calc_num_entries,
1223 .check_max_dentries = fat_check_max_dentries,
1224
1225 .get_entry_type = fat_get_entry_type,
1226 .set_entry_type = fat_set_entry_type,
1227 .get_entry_attr = fat_get_entry_attr,
1228 .set_entry_attr = fat_set_entry_attr,
1229 .get_entry_flag = fat_get_entry_flag,
1230 .set_entry_flag = fat_set_entry_flag,
1231 .get_entry_clu0 = fat_get_entry_clu0,
1232 .set_entry_clu0 = fat_set_entry_clu0,
1233 .get_entry_size = fat_get_entry_size,
1234 .set_entry_size = fat_set_entry_size,
1235 .get_entry_time = fat_get_entry_time,
1236 .set_entry_time = fat_set_entry_time,
1237
1238 .get_au_stat = amap_get_au_stat,
1239 };
1240
1241 s32 mount_fat16(struct super_block *sb, pbr_t *p_pbr)
1242 {
1243 s32 num_root_sectors;
1244 bpb16_t *p_bpb = &(p_pbr->bpb.f16);
1245 FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
1246
1247 if (!p_bpb->num_fats) {
1248 sdfat_msg(sb, KERN_ERR, "bogus number of FAT structure");
1249 return -EINVAL;
1250 }
1251
1252 num_root_sectors = get_unaligned_le16(p_bpb->num_root_entries) << DENTRY_SIZE_BITS;
1253 num_root_sectors = ((num_root_sectors-1) >> sb->s_blocksize_bits) + 1;
1254
1255 fsi->sect_per_clus = p_bpb->sect_per_clus;
1256 fsi->sect_per_clus_bits = ilog2(p_bpb->sect_per_clus);
1257 fsi->cluster_size_bits = fsi->sect_per_clus_bits + sb->s_blocksize_bits;
1258 fsi->cluster_size = 1 << fsi->cluster_size_bits;
1259
1260 fsi->num_FAT_sectors = le16_to_cpu(p_bpb->num_fat_sectors);
1261
1262 fsi->FAT1_start_sector = le16_to_cpu(p_bpb->num_reserved);
1263 if (p_bpb->num_fats == 1)
1264 fsi->FAT2_start_sector = fsi->FAT1_start_sector;
1265 else
1266 fsi->FAT2_start_sector = fsi->FAT1_start_sector + fsi->num_FAT_sectors;
1267
1268 fsi->root_start_sector = fsi->FAT2_start_sector + fsi->num_FAT_sectors;
1269 fsi->data_start_sector = fsi->root_start_sector + num_root_sectors;
1270
1271 fsi->num_sectors = get_unaligned_le16(p_bpb->num_sectors);
1272 if (!fsi->num_sectors)
1273 fsi->num_sectors = le32_to_cpu(p_bpb->num_huge_sectors);
1274
1275 if (!fsi->num_sectors) {
1276 sdfat_msg(sb, KERN_ERR, "bogus number of total sector count");
1277 return -EINVAL;
1278 }
1279
1280 fsi->num_clusters = (u32)((fsi->num_sectors - fsi->data_start_sector) >> fsi->sect_per_clus_bits) + CLUS_BASE;
1281 /* because the cluster index starts with 2 */
1282
1283 fsi->vol_type = FAT16;
1284 if (fsi->num_clusters < FAT12_THRESHOLD)
1285 fsi->vol_type = FAT12;
1286
1287 fsi->vol_id = get_unaligned_le32(p_bpb->vol_serial);
1288
1289 fsi->root_dir = 0;
1290 fsi->dentries_in_root = get_unaligned_le16(p_bpb->num_root_entries);
1291 if (!fsi->dentries_in_root) {
1292 sdfat_msg(sb, KERN_ERR, "bogus number of max dentry count "
1293 "of the root directory");
1294 return -EINVAL;
1295 }
1296
1297 fsi->dentries_per_clu = 1 << (fsi->cluster_size_bits - DENTRY_SIZE_BITS);
1298
1299 fsi->vol_flag = VOL_CLEAN;
1300 fsi->clu_srch_ptr = 2;
1301 fsi->used_clusters = (u32) ~0;
1302
1303 fsi->fs_func = &fat_fs_func;
1304 fat_ent_ops_init(sb);
1305
1306 if (p_bpb->state & FAT_VOL_DIRTY) {
1307 fsi->vol_flag |= VOL_DIRTY;
1308 sdfat_log_msg(sb, KERN_WARNING, "Volume was not properly "
1309 "unmounted. Some data may be corrupt. "
1310 "Please run fsck.");
1311 }
1312
1313 return 0;
1314 } /* end of mount_fat16 */
1315
1316 static sector_t __calc_hidden_sect(struct super_block *sb)
1317 {
1318 struct block_device *bdev = sb->s_bdev;
1319 sector_t hidden = 0;
1320
1321 if (!bdev)
1322 goto out;
1323
1324 hidden = bdev->bd_part->start_sect;
1325 /* a disk device, not a partition */
1326 if (!hidden) {
1327 if (bdev != bdev->bd_contains)
1328 sdfat_log_msg(sb, KERN_WARNING,
1329 "hidden(0), but disk has a partition table");
1330 goto out;
1331 }
1332
1333 if (sb->s_blocksize_bits != 9) {
1334 ASSERT(sb->s_blocksize_bits > 9);
1335 hidden >>= (sb->s_blocksize_bits - 9);
1336 }
1337
1338 out:
1339 sdfat_log_msg(sb, KERN_INFO, "start_sect of part(%d) : %lld",
1340 bdev ? bdev->bd_part->partno : -1, (s64)hidden);
1341 return hidden;
1342
1343 }
1344
1345 s32 mount_fat32(struct super_block *sb, pbr_t *p_pbr)
1346 {
1347 pbr32_t *p_bpb = (pbr32_t *)p_pbr;
1348 FS_INFO_T *fsi = &(SDFAT_SB(sb)->fsi);
1349
1350 if (!p_bpb->bpb.num_fats) {
1351 sdfat_msg(sb, KERN_ERR, "bogus number of FAT structure");
1352 return -EINVAL;
1353 }
1354
1355 fsi->sect_per_clus = p_bpb->bpb.sect_per_clus;
1356 fsi->sect_per_clus_bits = ilog2(p_bpb->bpb.sect_per_clus);
1357 fsi->cluster_size_bits = fsi->sect_per_clus_bits + sb->s_blocksize_bits;
1358 fsi->cluster_size = 1 << fsi->cluster_size_bits;
1359
1360 fsi->num_FAT_sectors = le32_to_cpu(p_bpb->bpb.num_fat32_sectors);
1361
1362 fsi->FAT1_start_sector = le16_to_cpu(p_bpb->bpb.num_reserved);
1363 if (p_bpb->bpb.num_fats == 1)
1364 fsi->FAT2_start_sector = fsi->FAT1_start_sector;
1365 else
1366 fsi->FAT2_start_sector = fsi->FAT1_start_sector + fsi->num_FAT_sectors;
1367
1368 fsi->root_start_sector = fsi->FAT2_start_sector + fsi->num_FAT_sectors;
1369 fsi->data_start_sector = fsi->root_start_sector;
1370
1371 /* SPEC violation for compatibility */
1372 fsi->num_sectors = get_unaligned_le16(p_bpb->bpb.num_sectors);
1373 if (!fsi->num_sectors)
1374 fsi->num_sectors = le32_to_cpu(p_bpb->bpb.num_huge_sectors);
1375
1376 /* 2nd check */
1377 if (!fsi->num_sectors) {
1378 sdfat_msg(sb, KERN_ERR, "bogus number of total sector count");
1379 return -EINVAL;
1380 }
1381
1382 fsi->num_clusters = (u32)((fsi->num_sectors - fsi->data_start_sector) >> fsi->sect_per_clus_bits) + CLUS_BASE;
1383 /* because the cluster index starts with 2 */
1384
1385 fsi->vol_type = FAT32;
1386 fsi->vol_id = get_unaligned_le32(p_bpb->bsx.vol_serial);
1387
1388 fsi->root_dir = le32_to_cpu(p_bpb->bpb.root_cluster);
1389 fsi->dentries_in_root = 0;
1390 fsi->dentries_per_clu = 1 << (fsi->cluster_size_bits - DENTRY_SIZE_BITS);
1391
1392 fsi->vol_flag = VOL_CLEAN;
1393 fsi->clu_srch_ptr = 2;
1394 fsi->used_clusters = (u32) ~0;
1395
1396 fsi->fs_func = &fat_fs_func;
1397
1398 /* Delayed / smart allocation related init */
1399 fsi->reserved_clusters = 0;
1400
1401 /* Should be initialized before calling amap_create() */
1402 fat_ent_ops_init(sb);
1403
1404 /* AU Map Creation */
1405 if (SDFAT_SB(sb)->options.improved_allocation & SDFAT_ALLOC_SMART) {
1406 u32 hidden_sectors = le32_to_cpu(p_bpb->bpb.num_hid_sectors);
1407 u32 calc_hid_sect = 0;
1408 int ret;
1409
1410
1411 /* calculate hidden sector size */
1412 calc_hid_sect = __calc_hidden_sect(sb);
1413 if (calc_hid_sect != hidden_sectors) {
1414 sdfat_log_msg(sb, KERN_WARNING, "abnormal hidden "
1415 "sector : bpb(%u) != ondisk(%u)",
1416 hidden_sectors, calc_hid_sect);
1417 if (SDFAT_SB(sb)->options.adj_hidsect) {
1418 sdfat_log_msg(sb, KERN_INFO,
1419 "adjustment hidden sector : "
1420 "bpb(%u) -> ondisk(%u)",
1421 hidden_sectors, calc_hid_sect);
1422 hidden_sectors = calc_hid_sect;
1423 }
1424 }
1425
1426 SDFAT_SB(sb)->options.amap_opt.misaligned_sect = hidden_sectors;
1427
1428 /* calculate AU size if it's not set */
1429 if (!SDFAT_SB(sb)->options.amap_opt.sect_per_au) {
1430 SDFAT_SB(sb)->options.amap_opt.sect_per_au =
1431 __calc_default_au_size(sb);
1432 }
1433
1434 ret = amap_create(sb,
1435 SDFAT_SB(sb)->options.amap_opt.pack_ratio,
1436 SDFAT_SB(sb)->options.amap_opt.sect_per_au,
1437 SDFAT_SB(sb)->options.amap_opt.misaligned_sect);
1438 if (ret) {
1439 sdfat_log_msg(sb, KERN_WARNING, "failed to create AMAP."
1440 " disabling smart allocation. (err:%d)", ret);
1441 SDFAT_SB(sb)->options.improved_allocation &= ~(SDFAT_ALLOC_SMART);
1442 } else {
1443 fsi->fs_func = &amap_fat_fs_func;
1444 }
1445 }
1446
1447 /* Check dependency of mount options */
1448 if (SDFAT_SB(sb)->options.improved_allocation !=
1449 (SDFAT_ALLOC_DELAY | SDFAT_ALLOC_SMART)) {
1450 sdfat_log_msg(sb, KERN_INFO, "disabling defragmentation because"
1451 " smart, delay options are disabled");
1452 SDFAT_SB(sb)->options.defrag = 0;
1453 }
1454
1455 if (p_bpb->bsx.state & FAT_VOL_DIRTY) {
1456 fsi->vol_flag |= VOL_DIRTY;
1457 sdfat_log_msg(sb, KERN_WARNING, "Volume was not properly "
1458 "unmounted. Some data may be corrupt. "
1459 "Please run fsck.");
1460 }
1461
1462 return 0;
1463 } /* end of mount_fat32 */
1464
1465 /* end of core_fat.c */