1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 #include "disk.h"
33 #include "stdio.h"
34 #include "stdlib.h"
35 #include "unistd.h"
36 #include "sys/mount.h"
37 #include "linux/spinlock.h"
38 #include "path_cache.h"
39 #ifndef LOSCFG_FS_FAT_CACHE
40 #include "los_vm_common.h"
41 #include "user_copy.h"
42 #endif
43
44 los_disk g_sysDisk[SYS_MAX_DISK];
45 los_part g_sysPart[SYS_MAX_PART];
46
47 UINT32 g_uwFatSectorsPerBlock = CONFIG_FS_FAT_SECTOR_PER_BLOCK;
48 UINT32 g_uwFatBlockNums = CONFIG_FS_FAT_BLOCK_NUMS;
49
50 spinlock_t g_diskSpinlock;
51 spinlock_t g_diskFatBlockSpinlock;
52
53 UINT32 g_usbMode = 0;
54
55 #define MEM_ADDR_ALIGN_BYTE 64
56 #define RWE_RW_RW 0755
57
58 #define DISK_LOCK(mux) do { \
59 if (pthread_mutex_lock(mux) != 0) { \
60 PRINT_ERR("%s %d, mutex lock failed\n", __FUNCTION__, __LINE__); \
61 } \
62 } while (0)
63
64 #define DISK_UNLOCK(mux) do { \
65 if (pthread_mutex_unlock(mux) != 0) { \
66 PRINT_ERR("%s %d, mutex unlock failed\n", __FUNCTION__, __LINE__); \
67 } \
68 } while (0)
69
70 typedef VOID *(*StorageHookFunction)(VOID *);
71
72 #ifdef LOSCFG_FS_FAT_CACHE
73 static UINT32 OsReHookFuncAddDiskRef(StorageHookFunction handler,
74 VOID *param) __attribute__((weakref("osReHookFuncAdd")));
75
76 static UINT32 OsReHookFuncDelDiskRef(StorageHookFunction handler) __attribute__((weakref("osReHookFuncDel")));
77
GetFatBlockNums(VOID)78 UINT32 GetFatBlockNums(VOID)
79 {
80 return g_uwFatBlockNums;
81 }
82
SetFatBlockNums(UINT32 blockNums)83 VOID SetFatBlockNums(UINT32 blockNums)
84 {
85 g_uwFatBlockNums = blockNums;
86 }
87
GetFatSectorsPerBlock(VOID)88 UINT32 GetFatSectorsPerBlock(VOID)
89 {
90 return g_uwFatSectorsPerBlock;
91 }
92
SetFatSectorsPerBlock(UINT32 sectorsPerBlock)93 VOID SetFatSectorsPerBlock(UINT32 sectorsPerBlock)
94 {
95 if (((sectorsPerBlock % UNSIGNED_INTEGER_BITS) == 0) &&
96 ((sectorsPerBlock >> UNINT_LOG2_SHIFT) <= BCACHE_BLOCK_FLAGS)) {
97 g_uwFatSectorsPerBlock = sectorsPerBlock;
98 }
99 }
100 #endif
101
los_alloc_diskid_byname(const CHAR * diskName)102 INT32 los_alloc_diskid_byname(const CHAR *diskName)
103 {
104 INT32 diskID;
105 los_disk *disk = NULL;
106 UINT32 intSave;
107 size_t nameLen;
108
109 if (diskName == NULL) {
110 PRINT_ERR("The parameter disk_name is NULL");
111 return VFS_ERROR;
112 }
113
114 nameLen = strlen(diskName);
115 if (nameLen > DISK_NAME) {
116 PRINT_ERR("diskName is too long!\n");
117 return VFS_ERROR;
118 }
119 spin_lock_irqsave(&g_diskSpinlock, intSave);
120
121 for (diskID = 0; diskID < SYS_MAX_DISK; diskID++) {
122 disk = get_disk(diskID);
123 if ((disk != NULL) && (disk->disk_status == STAT_UNUSED)) {
124 disk->disk_status = STAT_UNREADY;
125 break;
126 }
127 }
128
129 spin_unlock_irqrestore(&g_diskSpinlock, intSave);
130
131 if ((disk == NULL) || (diskID == SYS_MAX_DISK)) {
132 PRINT_ERR("los_alloc_diskid_byname failed %d!\n", diskID);
133 return VFS_ERROR;
134 }
135
136 if (disk->disk_name != NULL) {
137 LOS_MemFree(m_aucSysMem0, disk->disk_name);
138 disk->disk_name = NULL;
139 }
140
141 disk->disk_name = LOS_MemAlloc(m_aucSysMem0, (nameLen + 1));
142 if (disk->disk_name == NULL) {
143 PRINT_ERR("los_alloc_diskid_byname alloc disk name failed\n");
144 return VFS_ERROR;
145 }
146
147 if (strncpy_s(disk->disk_name, (nameLen + 1), diskName, nameLen) != EOK) {
148 PRINT_ERR("The strncpy_s failed.\n");
149 LOS_MemFree(m_aucSysMem0, disk->disk_name);
150 disk->disk_name = NULL;
151 return VFS_ERROR;
152 }
153
154 disk->disk_name[nameLen] = '\0';
155
156 return diskID;
157 }
158
los_get_diskid_byname(const CHAR * diskName)159 INT32 los_get_diskid_byname(const CHAR *diskName)
160 {
161 INT32 diskID;
162 los_disk *disk = NULL;
163 size_t diskNameLen;
164
165 if (diskName == NULL) {
166 PRINT_ERR("The parameter diskName is NULL");
167 return VFS_ERROR;
168 }
169
170 diskNameLen = strlen(diskName);
171 if (diskNameLen > DISK_NAME) {
172 PRINT_ERR("diskName is too long!\n");
173 return VFS_ERROR;
174 }
175
176 for (diskID = 0; diskID < SYS_MAX_DISK; diskID++) {
177 disk = get_disk(diskID);
178 if ((disk != NULL) && (disk->disk_name != NULL) && (disk->disk_status == STAT_INUSED)) {
179 if (strlen(disk->disk_name) != diskNameLen) {
180 continue;
181 }
182 if (strcmp(diskName, disk->disk_name) == 0) {
183 break;
184 }
185 }
186 }
187 if ((disk == NULL) || (diskID == SYS_MAX_DISK)) {
188 PRINT_ERR("los_get_diskid_byname failed!\n");
189 return VFS_ERROR;
190 }
191 return diskID;
192 }
193
los_get_mmcdisk_bytype(UINT8 type)194 los_disk *los_get_mmcdisk_bytype(UINT8 type)
195 {
196 const CHAR *mmcDevHead = "/dev/mmcblk";
197
198 for (INT32 diskId = 0; diskId < SYS_MAX_DISK; diskId++) {
199 los_disk *disk = get_disk(diskId);
200 if (disk == NULL) {
201 continue;
202 } else if ((disk->type == type) && (strncmp(disk->disk_name, mmcDevHead, strlen(mmcDevHead)) == 0)) {
203 return disk;
204 }
205 }
206 PRINT_ERR("Cannot find the mmc disk!\n");
207 return NULL;
208 }
209
OsSetUsbStatus(UINT32 diskID)210 VOID OsSetUsbStatus(UINT32 diskID)
211 {
212 if (diskID < SYS_MAX_DISK) {
213 g_usbMode |= (1u << diskID) & UINT_MAX;
214 }
215 }
216
OsClearUsbStatus(UINT32 diskID)217 VOID OsClearUsbStatus(UINT32 diskID)
218 {
219 if (diskID < SYS_MAX_DISK) {
220 g_usbMode &= ~((1u << diskID) & UINT_MAX);
221 }
222 }
223
224 #ifdef LOSCFG_FS_FAT_CACHE
GetDiskUsbStatus(UINT32 diskID)225 static BOOL GetDiskUsbStatus(UINT32 diskID)
226 {
227 return (g_usbMode & (1u << diskID)) ? TRUE : FALSE;
228 }
229 #endif
230
get_disk(INT32 id)231 los_disk *get_disk(INT32 id)
232 {
233 if ((id >= 0) && (id < SYS_MAX_DISK)) {
234 return &g_sysDisk[id];
235 }
236
237 return NULL;
238 }
239
get_part(INT32 id)240 los_part *get_part(INT32 id)
241 {
242 if ((id >= 0) && (id < SYS_MAX_PART)) {
243 return &g_sysPart[id];
244 }
245
246 return NULL;
247 }
248
GetFirstPartStart(const los_part * part)249 static UINT64 GetFirstPartStart(const los_part *part)
250 {
251 los_part *firstPart = NULL;
252 los_disk *disk = get_disk((INT32)part->disk_id);
253 firstPart = (disk == NULL) ? NULL : LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
254 return (firstPart == NULL) ? 0 : firstPart->sector_start;
255 }
256
DiskPartAddToDisk(los_disk * disk,los_part * part)257 static VOID DiskPartAddToDisk(los_disk *disk, los_part *part)
258 {
259 part->disk_id = disk->disk_id;
260 part->part_no_disk = disk->part_count;
261 LOS_ListTailInsert(&disk->head, &part->list);
262 disk->part_count++;
263 }
264
DiskPartDelFromDisk(los_disk * disk,los_part * part)265 static VOID DiskPartDelFromDisk(los_disk *disk, los_part *part)
266 {
267 LOS_ListDelete(&part->list);
268 disk->part_count--;
269 }
270
DiskPartAllocate(struct Vnode * dev,UINT64 start,UINT64 count)271 static los_part *DiskPartAllocate(struct Vnode *dev, UINT64 start, UINT64 count)
272 {
273 UINT32 i;
274 los_part *part = get_part(0); /* traversing from the beginning of the array */
275
276 if (part == NULL) {
277 return NULL;
278 }
279
280 for (i = 0; i < SYS_MAX_PART; i++) {
281 if (part->dev == NULL) {
282 part->part_id = i;
283 part->part_no_mbr = 0;
284 part->dev = dev;
285 part->sector_start = start;
286 part->sector_count = count;
287 part->part_name = NULL;
288 LOS_ListInit(&part->list);
289
290 return part;
291 }
292 part++;
293 }
294
295 return NULL;
296 }
297
DiskPartRelease(los_part * part)298 static VOID DiskPartRelease(los_part *part)
299 {
300 part->dev = NULL;
301 part->part_no_disk = 0;
302 part->part_no_mbr = 0;
303 if (part->part_name != NULL) {
304 free(part->part_name);
305 part->part_name = NULL;
306 }
307 }
308
309 /*
310 * name is a combination of disk_name, 'p' and part_count, such as "/dev/mmcblk0p0"
311 * disk_name : DISK_NAME + 1
312 * 'p' : 1
313 * part_count: 1
314 */
315 #define DEV_NAME_BUFF_SIZE (DISK_NAME + 3)
316
DiskAddPart(los_disk * disk,UINT64 sectorStart,UINT64 sectorCount,BOOL IsValidPart)317 static INT32 DiskAddPart(los_disk *disk, UINT64 sectorStart, UINT64 sectorCount, BOOL IsValidPart)
318 {
319 CHAR devName[DEV_NAME_BUFF_SIZE];
320 struct Vnode *diskDev = NULL;
321 struct Vnode *partDev = NULL;
322 los_part *part = NULL;
323 INT32 ret;
324
325 if ((disk == NULL) || (disk->disk_status == STAT_UNUSED) ||
326 (disk->dev == NULL)) {
327 return VFS_ERROR;
328 }
329
330 if ((sectorCount > disk->sector_count) || ((disk->sector_count - sectorCount) < sectorStart)) {
331 PRINT_ERR("DiskAddPart failed: sector start is %llu, sector count is %llu\n", sectorStart, sectorCount);
332 return VFS_ERROR;
333 }
334
335 diskDev = disk->dev;
336 if (IsValidPart == TRUE) {
337 ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%u",
338 ((disk->disk_name == NULL) ? "null" : disk->disk_name), 'p', disk->part_count);
339 if (ret < 0) {
340 return VFS_ERROR;
341 }
342
343 if (register_blockdriver(devName, ((struct drv_data *)diskDev->data)->ops,
344 RWE_RW_RW, ((struct drv_data *)diskDev->data)->priv)) {
345 PRINT_ERR("DiskAddPart : register %s fail!\n", devName);
346 return VFS_ERROR;
347 }
348
349 VnodeHold();
350 VnodeLookup(devName, &partDev, 0);
351
352 part = DiskPartAllocate(partDev, sectorStart, sectorCount);
353 VnodeDrop();
354 if (part == NULL) {
355 (VOID)unregister_blockdriver(devName);
356 return VFS_ERROR;
357 }
358 } else {
359 part = DiskPartAllocate(diskDev, sectorStart, sectorCount);
360 if (part == NULL) {
361 return VFS_ERROR;
362 }
363 }
364
365 DiskPartAddToDisk(disk, part);
366 if (disk->type == EMMC) {
367 part->type = EMMC;
368 }
369 return (INT32)part->part_id;
370 }
371
DiskDivide(los_disk * disk,struct disk_divide_info * info)372 static INT32 DiskDivide(los_disk *disk, struct disk_divide_info *info)
373 {
374 UINT32 i;
375 INT32 ret;
376
377 disk->type = info->part[0].type;
378 for (i = 0; i < info->part_count; i++) {
379 if (info->sector_count < info->part[i].sector_start) {
380 return VFS_ERROR;
381 }
382 if (info->part[i].sector_count > (info->sector_count - info->part[i].sector_start)) {
383 PRINT_ERR("Part[%u] sector_start:%llu, sector_count:%llu, exceed emmc sector_count:%llu.\n", i,
384 info->part[i].sector_start, info->part[i].sector_count,
385 (info->sector_count - info->part[i].sector_start));
386 info->part[i].sector_count = info->sector_count - info->part[i].sector_start;
387 PRINT_ERR("Part[%u] sector_count change to %llu.\n", i, info->part[i].sector_count);
388
389 ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE);
390 if (ret == VFS_ERROR) {
391 return VFS_ERROR;
392 }
393 break;
394 }
395 ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE);
396 if (ret == VFS_ERROR) {
397 return VFS_ERROR;
398 }
399 }
400
401 return ENOERR;
402 }
403
GPTPartitionTypeRecognition(const CHAR * parBuf)404 static CHAR GPTPartitionTypeRecognition(const CHAR *parBuf)
405 {
406 const CHAR *buf = parBuf;
407 const CHAR *fsType = "FAT";
408 const CHAR *str = "\xEB\x52\x90" "NTFS "; /* NTFS Boot entry point */
409
410 if (((LD_DWORD_DISK(&buf[BS_FILSYSTEMTYPE32]) & BS_FS_TYPE_MASK) == BS_FS_TYPE_VALUE) ||
411 (strncmp(&buf[BS_FILSYSTYPE], fsType, strlen(fsType)) == 0)) {
412 return BS_FS_TYPE_FAT;
413 } else if (strncmp(&buf[BS_JMPBOOT], str, strlen(str)) == 0) {
414 return BS_FS_TYPE_NTFS;
415 }
416
417 return ENOERR;
418 }
419
DiskPartitionMemZalloc(size_t boundary,size_t size,CHAR ** gptBuf,CHAR ** partitionBuf)420 static INT32 DiskPartitionMemZalloc(size_t boundary, size_t size, CHAR **gptBuf, CHAR **partitionBuf)
421 {
422 CHAR *buffer1 = NULL;
423 CHAR *buffer2 = NULL;
424
425 buffer1 = (CHAR *)memalign(boundary, size);
426 if (buffer1 == NULL) {
427 PRINT_ERR("%s buffer1 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__);
428 return -ENOMEM;
429 }
430 buffer2 = (CHAR *)memalign(boundary, size);
431 if (buffer2 == NULL) {
432 PRINT_ERR("%s buffer2 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__);
433 free(buffer1);
434 return -ENOMEM;
435 }
436 (VOID)memset_s(buffer1, size, 0, size);
437 (VOID)memset_s(buffer2, size, 0, size);
438
439 *gptBuf = buffer1;
440 *partitionBuf = buffer2;
441
442 return ENOERR;
443 }
444
GPTInfoGet(struct Vnode * blkDrv,CHAR * gptBuf)445 static INT32 GPTInfoGet(struct Vnode *blkDrv, CHAR *gptBuf)
446 {
447 INT32 ret;
448
449 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
450
451 ret = bops->read(blkDrv, (UINT8 *)gptBuf, 1, 1); /* Read the device first sector */
452 if (ret != 1) { /* Read failed */
453 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
454 return -EIO;
455 }
456
457 if (!VERIFY_GPT(gptBuf)) {
458 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
459 return VFS_ERROR;
460 }
461
462 return ENOERR;
463 }
464
OsGPTPartitionRecognitionSub(struct disk_divide_info * info,const CHAR * partitionBuf,UINT32 * partitionCount,UINT64 partitionStart,UINT64 partitionEnd)465 static INT32 OsGPTPartitionRecognitionSub(struct disk_divide_info *info, const CHAR *partitionBuf,
466 UINT32 *partitionCount, UINT64 partitionStart, UINT64 partitionEnd)
467 {
468 CHAR partitionType;
469
470 if (VERIFY_FS(partitionBuf)) {
471 partitionType = GPTPartitionTypeRecognition(partitionBuf);
472 if (partitionType) {
473 if (*partitionCount >= MAX_DIVIDE_PART_PER_DISK) {
474 return VFS_ERROR;
475 }
476 info->part[*partitionCount].type = partitionType;
477 info->part[*partitionCount].sector_start = partitionStart;
478 info->part[*partitionCount].sector_count = (partitionEnd - partitionStart) + 1;
479 (*partitionCount)++;
480 } else {
481 PRINT_ERR("The partition type is not allowed to use!\n");
482 }
483 } else {
484 PRINT_ERR("Do not support the partition type!\n");
485 }
486 return ENOERR;
487 }
488
OsGPTPartitionRecognition(struct Vnode * blkDrv,struct disk_divide_info * info,const CHAR * gptBuf,CHAR * partitionBuf,UINT32 * partitionCount)489 static INT32 OsGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info,
490 const CHAR *gptBuf, CHAR *partitionBuf, UINT32 *partitionCount)
491 {
492 UINT32 j;
493 INT32 ret = VFS_ERROR;
494 UINT64 partitionStart, partitionEnd;
495 struct block_operations *bops = NULL;
496
497 for (j = 0; j < PAR_ENTRY_NUM_PER_SECTOR; j++) {
498 if (!VERITY_AVAILABLE_PAR(&gptBuf[j * TABLE_SIZE])) {
499 PRINTK("The partition type is ESP or MSR!\n");
500 continue;
501 }
502
503 if (!VERITY_PAR_VALID(&gptBuf[j * TABLE_SIZE])) {
504 return VFS_ERROR;
505 }
506
507 partitionStart = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_START_OFFSET]);
508 partitionEnd = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_END_OFFSET]);
509 if ((partitionStart >= partitionEnd) || (partitionEnd > info->sector_count)) {
510 PRINT_ERR("GPT partition %u recognition failed : partitionStart = %llu, partitionEnd = %llu\n",
511 j, partitionStart, partitionEnd);
512 return VFS_ERROR;
513 }
514
515 (VOID)memset_s(partitionBuf, info->sector_size, 0, info->sector_size);
516
517 bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
518
519 ret = bops->read(blkDrv, (UINT8 *)partitionBuf, partitionStart, 1);
520 if (ret != 1) { /* read failed */
521 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
522 return -EIO;
523 }
524
525 ret = OsGPTPartitionRecognitionSub(info, partitionBuf, partitionCount, partitionStart, partitionEnd);
526 if (ret != ENOERR) {
527 return VFS_ERROR;
528 }
529 }
530
531 return ret;
532 }
533
DiskGPTPartitionRecognition(struct Vnode * blkDrv,struct disk_divide_info * info)534 static INT32 DiskGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
535 {
536 CHAR *gptBuf = NULL;
537 CHAR *partitionBuf = NULL;
538 UINT32 tableNum, i, index;
539 UINT32 partitionCount = 0;
540 INT32 ret;
541
542 ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &gptBuf, &partitionBuf);
543 if (ret != ENOERR) {
544 return ret;
545 }
546
547 ret = GPTInfoGet(blkDrv, gptBuf);
548 if (ret < 0) {
549 goto OUT_WITH_MEM;
550 }
551
552 tableNum = LD_DWORD_DISK(&gptBuf[TABLE_NUM_OFFSET]);
553 if (tableNum > TABLE_MAX_NUM) {
554 tableNum = TABLE_MAX_NUM;
555 }
556
557 index = (tableNum % PAR_ENTRY_NUM_PER_SECTOR) ? ((tableNum / PAR_ENTRY_NUM_PER_SECTOR) + 1) :
558 (tableNum / PAR_ENTRY_NUM_PER_SECTOR);
559
560 for (i = 0; i < index; i++) {
561 (VOID)memset_s(gptBuf, info->sector_size, 0, info->sector_size);
562 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
563 ret = bops->read(blkDrv, (UINT8 *)gptBuf, TABLE_START_SECTOR + i, 1);
564 if (ret != 1) { /* read failed */
565 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
566 ret = -EIO;
567 goto OUT_WITH_MEM;
568 }
569
570 ret = OsGPTPartitionRecognition(blkDrv, info, gptBuf, partitionBuf, &partitionCount);
571 if (ret < 0) {
572 if (ret == VFS_ERROR) {
573 ret = (INT32)partitionCount;
574 }
575 goto OUT_WITH_MEM;
576 }
577 }
578 ret = (INT32)partitionCount;
579
580 OUT_WITH_MEM:
581 free(gptBuf);
582 free(partitionBuf);
583 return ret;
584 }
585
OsMBRInfoGet(struct Vnode * blkDrv,CHAR * mbrBuf)586 static INT32 OsMBRInfoGet(struct Vnode *blkDrv, CHAR *mbrBuf)
587 {
588 INT32 ret;
589
590 /* read MBR, start from sector 0, length is 1 sector */
591 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
592
593 ret = bops->read(blkDrv, (UINT8 *)mbrBuf, 0, 1);
594 if (ret != 1) { /* read failed */
595 PRINT_ERR("driver read return error: %d\n", ret);
596 return -EIO;
597 }
598
599 /* Check boot record signature. */
600 if (LD_WORD_DISK(&mbrBuf[BS_SIG55AA]) != BS_SIG55AA_VALUE) {
601 return VFS_ERROR;
602 }
603
604 return ENOERR;
605 }
606
OsEBRInfoGet(struct Vnode * blkDrv,const struct disk_divide_info * info,CHAR * ebrBuf,const CHAR * mbrBuf)607 static INT32 OsEBRInfoGet(struct Vnode *blkDrv, const struct disk_divide_info *info,
608 CHAR *ebrBuf, const CHAR *mbrBuf)
609 {
610 INT32 ret;
611
612 if (VERIFY_FS(mbrBuf)) {
613 if (info->sector_count <= LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET])) {
614 return VFS_ERROR;
615 }
616
617 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
618 ret = bops->read(blkDrv, (UINT8 *)ebrBuf, LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET]), 1);
619 if ((ret != 1) || (!VERIFY_FS(ebrBuf))) { /* read failed */
620 PRINT_ERR("OsEBRInfoGet, verify_fs error, ret = %d\n", ret);
621 return -EIO;
622 }
623 }
624
625 return ENOERR;
626 }
627
OsPrimaryPartitionRecognition(const CHAR * mbrBuf,struct disk_divide_info * info,INT32 * extendedPos,INT32 * mbrCount)628 static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divide_info *info,
629 INT32 *extendedPos, INT32 *mbrCount)
630 {
631 INT32 i;
632 CHAR mbrPartitionType;
633 INT32 extendedFlag = 0;
634 INT32 count = 0;
635
636 for (i = 0; i < MAX_PRIMARY_PART_PER_DISK; i++) {
637 mbrPartitionType = mbrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + (i * PAR_TABLE_SIZE)];
638 if (mbrPartitionType) {
639 info->part[i].type = mbrPartitionType;
640 info->part[i].sector_start = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (i * PAR_TABLE_SIZE)]);
641 info->part[i].sector_count = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_COUNT_OFFSET + (i * PAR_TABLE_SIZE)]);
642 if ((mbrPartitionType == EXTENDED_PAR) || (mbrPartitionType == EXTENDED_8G)) {
643 extendedFlag = 1;
644 *extendedPos = i;
645 continue;
646 }
647 count++;
648 }
649 }
650 *mbrCount = count;
651
652 return extendedFlag;
653 }
654
OsLogicalPartitionRecognition(struct Vnode * blkDrv,struct disk_divide_info * info,UINT32 extendedAddress,CHAR * ebrBuf,INT32 mbrCount)655 static INT32 OsLogicalPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info,
656 UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount)
657 {
658 INT32 ret;
659 UINT32 extendedOffset = 0;
660 CHAR ebrPartitionType;
661 INT32 ebrCount = 0;
662
663 do {
664 (VOID)memset_s(ebrBuf, info->sector_size, 0, info->sector_size);
665 if (((UINT64)(extendedAddress) + extendedOffset) >= info->sector_count) {
666 PRINT_ERR("extended partition is out of disk range: extendedAddress = %u, extendedOffset = %u\n",
667 extendedAddress, extendedOffset);
668 break;
669 }
670 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
671 ret = bops->read(blkDrv, (UINT8 *)ebrBuf, extendedAddress + extendedOffset, 1);
672 if (ret != 1) { /* read failed */
673 PRINT_ERR("driver read return error: %d, extendedAddress = %u, extendedOffset = %u\n", ret,
674 extendedAddress, extendedOffset);
675 return -EIO;
676 }
677 ebrPartitionType = ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET];
678 if (ebrPartitionType && ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK)) {
679 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].type = ebrPartitionType;
680 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_start = extendedAddress + extendedOffset +
681 LD_DWORD_DISK(&ebrBuf[PAR_OFFSET +
682 PAR_START_OFFSET]);
683 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_count = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET +
684 PAR_COUNT_OFFSET]);
685 ebrCount++;
686 }
687 extendedOffset = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET + PAR_START_OFFSET + PAR_TABLE_SIZE]);
688 } while ((ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + PAR_TABLE_SIZE] != 0) &&
689 ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK));
690
691 return ebrCount;
692 }
693
DiskPartitionRecognition(struct Vnode * blkDrv,struct disk_divide_info * info)694 static INT32 DiskPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
695 {
696 INT32 ret;
697 INT32 extendedFlag;
698 INT32 extendedPos = 0;
699 INT32 mbrCount = 0;
700 UINT32 extendedAddress;
701 CHAR *mbrBuf = NULL;
702 CHAR *ebrBuf = NULL;
703
704 if (blkDrv == NULL) {
705 return -EINVAL;
706 }
707
708 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
709
710 if ((bops == NULL) || (bops->read == NULL)) {
711 return -EINVAL;
712 }
713
714 ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &mbrBuf, &ebrBuf);
715 if (ret != ENOERR) {
716 return ret;
717 }
718
719 ret = OsMBRInfoGet(blkDrv, mbrBuf);
720 if (ret < 0) {
721 goto OUT_WITH_MEM;
722 }
723
724 /* The partition type is GPT */
725 if (mbrBuf[PARTION_MODE_BTYE] == (CHAR)PARTION_MODE_GPT) {
726 ret = DiskGPTPartitionRecognition(blkDrv, info);
727 goto OUT_WITH_MEM;
728 }
729
730 ret = OsEBRInfoGet(blkDrv, info, ebrBuf, mbrBuf);
731 if (ret < 0) {
732 ret = 0; /* no mbr */
733 goto OUT_WITH_MEM;
734 }
735
736 extendedFlag = OsPrimaryPartitionRecognition(mbrBuf, info, &extendedPos, &mbrCount);
737 if (extendedFlag) {
738 extendedAddress = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (extendedPos * PAR_TABLE_SIZE)]);
739 ret = OsLogicalPartitionRecognition(blkDrv, info, extendedAddress, ebrBuf, mbrCount);
740 if (ret <= 0) {
741 goto OUT_WITH_MEM;
742 }
743 }
744 ret += mbrCount;
745
746 OUT_WITH_MEM:
747 free(ebrBuf);
748 free(mbrBuf);
749 return ret;
750 }
751
DiskPartitionRegister(los_disk * disk)752 INT32 DiskPartitionRegister(los_disk *disk)
753 {
754 INT32 count;
755 UINT32 i, partSize;
756 los_part *part = NULL;
757 struct disk_divide_info parInfo;
758
759 /* Fill disk_divide_info structure to set partition's information. */
760 (VOID)memset_s(parInfo.part, sizeof(parInfo.part), 0, sizeof(parInfo.part));
761 partSize = sizeof(parInfo.part) / sizeof(parInfo.part[0]);
762
763 parInfo.sector_size = disk->sector_size;
764 parInfo.sector_count = disk->sector_count;
765 count = DiskPartitionRecognition(disk->dev, &parInfo);
766 if (count == VFS_ERROR) {
767 part = get_part(DiskAddPart(disk, 0, disk->sector_count, FALSE));
768 if (part == NULL) {
769 return VFS_ERROR;
770 }
771 part->part_no_mbr = 0;
772 PRINTK("Disk %s doesn't contain a valid partition table.\n", disk->disk_name);
773 return ENOERR;
774 } else if (count < 0) {
775 return VFS_ERROR;
776 }
777
778 parInfo.part_count = count;
779 if (count == 0) {
780 part = get_part(DiskAddPart(disk, 0, disk->sector_count, TRUE));
781 if (part == NULL) {
782 return VFS_ERROR;
783 }
784 part->part_no_mbr = 0;
785
786 PRINTK("No MBR detected.\n");
787 return ENOERR;
788 }
789
790 for (i = 0; i < partSize; i++) {
791 /* Read the disk_divide_info structure to get partition's information. */
792 if ((parInfo.part[i].type != 0) && (parInfo.part[i].type != EXTENDED_PAR) &&
793 (parInfo.part[i].type != EXTENDED_8G)) {
794 part = get_part(DiskAddPart(disk, parInfo.part[i].sector_start, parInfo.part[i].sector_count, TRUE));
795 if (part == NULL) {
796 return VFS_ERROR;
797 }
798 part->part_no_mbr = i + 1;
799 part->filesystem_type = parInfo.part[i].type;
800 }
801 }
802
803 return ENOERR;
804 }
805
806 #ifndef LOSCFG_FS_FAT_CACHE
disk_read_directly(los_disk * disk,VOID * buf,UINT64 sector,UINT32 count)807 static INT32 disk_read_directly(los_disk *disk, VOID *buf, UINT64 sector, UINT32 count)
808 {
809 INT32 result = VFS_ERROR;
810 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
811 if ((bops == NULL) || (bops->read == NULL)) {
812 return VFS_ERROR;
813 }
814 if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
815 UINT32 cnt = 0;
816 UINT8 *buffer = disk->buff;
817 for (; count != 0; count -= cnt) {
818 cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
819 result = bops->read(disk->dev, buffer, sector, cnt);
820 if (result == (INT32)cnt) {
821 result = ENOERR;
822 } else {
823 break;
824 }
825 if (LOS_CopyFromKernel(buf, disk->sector_size * cnt, buffer, disk->sector_size * cnt)) {
826 result = VFS_ERROR;
827 break;
828 }
829 buf = (UINT8 *)buf + disk->sector_size * cnt;
830 sector += cnt;
831 }
832 } else {
833 result = bops->read(disk->dev, buf, sector, count);
834 if (result == count) {
835 result = ENOERR;
836 }
837 }
838
839 return result;
840 }
841
disk_write_directly(los_disk * disk,const VOID * buf,UINT64 sector,UINT32 count)842 static INT32 disk_write_directly(los_disk *disk, const VOID *buf, UINT64 sector, UINT32 count)
843 {
844 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
845 INT32 result = VFS_ERROR;
846 if ((bops == NULL) || (bops->read == NULL)) {
847 return VFS_ERROR;
848 }
849 if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
850 UINT32 cnt = 0;
851 UINT8 *buffer = disk->buff;
852 for (; count != 0; count -= cnt) {
853 cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
854 if (LOS_CopyToKernel(buffer, disk->sector_size * cnt, buf, disk->sector_size * cnt)) {
855 result = VFS_ERROR;
856 break;
857 }
858 result = bops->write(disk->dev, buffer, sector, cnt);
859 if (result == (INT32)cnt) {
860 result = ENOERR;
861 } else {
862 break;
863 }
864 buf = (UINT8 *)buf + disk->sector_size * cnt;
865 sector += cnt;
866 }
867 } else {
868 result = bops->write(disk->dev, buf, sector, count);
869 if (result == count) {
870 result = ENOERR;
871 }
872 }
873
874 return result;
875 }
876 #endif
877
los_disk_read(INT32 drvID,VOID * buf,UINT64 sector,UINT32 count,BOOL useRead)878 INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
879 {
880 #ifdef LOSCFG_FS_FAT_CACHE
881 UINT32 len;
882 #endif
883 INT32 result = VFS_ERROR;
884 los_disk *disk = get_disk(drvID);
885
886 if ((buf == NULL) || (count == 0)) { /* buff equal to NULL or count equal to 0 */
887 return result;
888 }
889
890 if (disk == NULL) {
891 return result;
892 }
893
894 DISK_LOCK(&disk->disk_mutex);
895
896 if (disk->disk_status != STAT_INUSED) {
897 goto ERROR_HANDLE;
898 }
899
900 if ((count > disk->sector_count) || ((disk->sector_count - count) < sector)) {
901 goto ERROR_HANDLE;
902 }
903
904 #ifdef LOSCFG_FS_FAT_CACHE
905 if (disk->bcache != NULL) {
906 if (((UINT64)(disk->bcache->sectorSize) * count) > UINT_MAX) {
907 goto ERROR_HANDLE;
908 }
909 len = disk->bcache->sectorSize * count;
910 /* useRead should be FALSE when reading large contiguous data */
911 result = BlockCacheRead(disk->bcache, (UINT8 *)buf, &len, sector, useRead);
912 if (result != ENOERR) {
913 PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len);
914 }
915 } else {
916 result = VFS_ERROR;
917 }
918 #else
919 if (disk->dev == NULL) {
920 goto ERROR_HANDLE;
921 }
922 result = disk_read_directly(disk, buf, sector, count);
923 #endif
924 if (result != ENOERR) {
925 goto ERROR_HANDLE;
926 }
927
928 DISK_UNLOCK(&disk->disk_mutex);
929 return ENOERR;
930
931 ERROR_HANDLE:
932 DISK_UNLOCK(&disk->disk_mutex);
933 return VFS_ERROR;
934 }
935
los_disk_write(INT32 drvID,const VOID * buf,UINT64 sector,UINT32 count)936 INT32 los_disk_write(INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count)
937 {
938 #ifdef LOSCFG_FS_FAT_CACHE
939 UINT32 len;
940 #endif
941 INT32 result = VFS_ERROR;
942 los_disk *disk = get_disk(drvID);
943 if (disk == NULL || disk->dev == NULL || disk->dev->data == NULL) {
944 return result;
945 }
946
947 if ((buf == NULL) || (count == 0)) { /* buff equal to NULL or count equal to 0 */
948 return result;
949 }
950
951 DISK_LOCK(&disk->disk_mutex);
952
953 if (disk->disk_status != STAT_INUSED) {
954 goto ERROR_HANDLE;
955 }
956
957 if ((count > disk->sector_count) || ((disk->sector_count - count) < sector)) {
958 goto ERROR_HANDLE;
959 }
960
961 #ifdef LOSCFG_FS_FAT_CACHE
962 if (disk->bcache != NULL) {
963 if (((UINT64)(disk->bcache->sectorSize) * count) > UINT_MAX) {
964 goto ERROR_HANDLE;
965 }
966 len = disk->bcache->sectorSize * count;
967 result = BlockCacheWrite(disk->bcache, (const UINT8 *)buf, &len, sector);
968 if (result != ENOERR) {
969 PRINT_ERR("los_disk_write write err = %d, sector = %llu, len = %u\n", result, sector, len);
970 }
971 } else {
972 result = VFS_ERROR;
973 }
974 #else
975 if (disk->dev == NULL) {
976 goto ERROR_HANDLE;
977 }
978 result = disk_write_directly(disk, buf, sector, count);
979 #endif
980 if (result != ENOERR) {
981 goto ERROR_HANDLE;
982 }
983
984 DISK_UNLOCK(&disk->disk_mutex);
985 return ENOERR;
986
987 ERROR_HANDLE:
988 DISK_UNLOCK(&disk->disk_mutex);
989 return VFS_ERROR;
990 }
991
los_disk_ioctl(INT32 drvID,INT32 cmd,VOID * buf)992 INT32 los_disk_ioctl(INT32 drvID, INT32 cmd, VOID *buf)
993 {
994 struct geometry info;
995 los_disk *disk = get_disk(drvID);
996 if (disk == NULL) {
997 return VFS_ERROR;
998 }
999
1000 DISK_LOCK(&disk->disk_mutex);
1001
1002 if ((disk->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1003 goto ERROR_HANDLE;
1004 }
1005
1006 if (cmd == DISK_CTRL_SYNC) {
1007 DISK_UNLOCK(&disk->disk_mutex);
1008 return ENOERR;
1009 }
1010
1011 if (buf == NULL) {
1012 goto ERROR_HANDLE;
1013 }
1014
1015 (VOID)memset_s(&info, sizeof(info), 0, sizeof(info));
1016
1017 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
1018 if ((bops == NULL) || (bops->geometry == NULL) ||
1019 (bops->geometry(disk->dev, &info) != 0)) {
1020 goto ERROR_HANDLE;
1021 }
1022
1023 if (cmd == DISK_GET_SECTOR_COUNT) {
1024 *(UINT64 *)buf = info.geo_nsectors;
1025 if (info.geo_nsectors == 0) {
1026 goto ERROR_HANDLE;
1027 }
1028 } else if (cmd == DISK_GET_SECTOR_SIZE) {
1029 *(size_t *)buf = info.geo_sectorsize;
1030 } else if (cmd == DISK_GET_BLOCK_SIZE) { /* Get erase block size in unit of sectors (UINT32) */
1031 /* Block Num SDHC == 512, SD can be set to 512 or other */
1032 *(size_t *)buf = DISK_MAX_SECTOR_SIZE / info.geo_sectorsize;
1033 } else {
1034 goto ERROR_HANDLE;
1035 }
1036
1037 DISK_UNLOCK(&disk->disk_mutex);
1038 return ENOERR;
1039
1040 ERROR_HANDLE:
1041 DISK_UNLOCK(&disk->disk_mutex);
1042 return VFS_ERROR;
1043 }
1044
los_part_read(INT32 pt,VOID * buf,UINT64 sector,UINT32 count,BOOL useRead)1045 INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
1046 {
1047 const los_part *part = get_part(pt);
1048 los_disk *disk = NULL;
1049 INT32 ret;
1050
1051 if (part == NULL) {
1052 return VFS_ERROR;
1053 }
1054
1055 disk = get_disk((INT32)part->disk_id);
1056 if (disk == NULL) {
1057 return VFS_ERROR;
1058 }
1059
1060 DISK_LOCK(&disk->disk_mutex);
1061 if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1062 goto ERROR_HANDLE;
1063 }
1064
1065 if (count > part->sector_count) {
1066 PRINT_ERR("los_part_read failed, invalid count, count = %u\n", count);
1067 goto ERROR_HANDLE;
1068 }
1069
1070 /* Read from absolute sector. */
1071 if (part->type == EMMC) {
1072 if ((disk->sector_count - part->sector_start) > sector) {
1073 sector += part->sector_start;
1074 } else {
1075 PRINT_ERR("los_part_read failed, invalid sector, sector = %llu\n", sector);
1076 goto ERROR_HANDLE;
1077 }
1078 }
1079
1080 if ((sector >= GetFirstPartStart(part)) &&
1081 (((sector + count) > (part->sector_start + part->sector_count)) || (sector < part->sector_start))) {
1082 PRINT_ERR("los_part_read error, sector = %llu, count = %u, part->sector_start = %llu, "
1083 "part->sector_count = %llu\n", sector, count, part->sector_start, part->sector_count);
1084 goto ERROR_HANDLE;
1085 }
1086
1087 /* useRead should be FALSE when reading large contiguous data */
1088 ret = los_disk_read((INT32)part->disk_id, buf, sector, count, useRead);
1089 if (ret < 0) {
1090 goto ERROR_HANDLE;
1091 }
1092
1093 DISK_UNLOCK(&disk->disk_mutex);
1094 return ENOERR;
1095
1096 ERROR_HANDLE:
1097 DISK_UNLOCK(&disk->disk_mutex);
1098 return VFS_ERROR;
1099 }
1100
los_part_write(INT32 pt,const VOID * buf,UINT64 sector,UINT32 count)1101 INT32 los_part_write(INT32 pt, const VOID *buf, UINT64 sector, UINT32 count)
1102 {
1103 const los_part *part = get_part(pt);
1104 los_disk *disk = NULL;
1105 INT32 ret;
1106
1107 if (part == NULL) {
1108 return VFS_ERROR;
1109 }
1110
1111 disk = get_disk((INT32)part->disk_id);
1112 if (disk == NULL) {
1113 return VFS_ERROR;
1114 }
1115
1116 DISK_LOCK(&disk->disk_mutex);
1117 if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1118 goto ERROR_HANDLE;
1119 }
1120
1121 if (count > part->sector_count) {
1122 PRINT_ERR("los_part_write failed, invalid count, count = %u\n", count);
1123 goto ERROR_HANDLE;
1124 }
1125
1126 /* Write to absolute sector. */
1127 if (part->type == EMMC) {
1128 if ((disk->sector_count - part->sector_start) > sector) {
1129 sector += part->sector_start;
1130 } else {
1131 PRINT_ERR("los_part_write failed, invalid sector, sector = %llu\n", sector);
1132 goto ERROR_HANDLE;
1133 }
1134 }
1135
1136 if ((sector >= GetFirstPartStart(part)) &&
1137 (((sector + count) > (part->sector_start + part->sector_count)) || (sector < part->sector_start))) {
1138 PRINT_ERR("los_part_write, sector = %llu, count = %u, part->sector_start = %llu, "
1139 "part->sector_count = %llu\n", sector, count, part->sector_start, part->sector_count);
1140 goto ERROR_HANDLE;
1141 }
1142
1143 ret = los_disk_write((INT32)part->disk_id, buf, sector, count);
1144 if (ret < 0) {
1145 goto ERROR_HANDLE;
1146 }
1147
1148 DISK_UNLOCK(&disk->disk_mutex);
1149 return ENOERR;
1150
1151 ERROR_HANDLE:
1152 DISK_UNLOCK(&disk->disk_mutex);
1153 return VFS_ERROR;
1154 }
1155
1156 #define GET_ERASE_BLOCK_SIZE 0x2
1157
los_part_ioctl(INT32 pt,INT32 cmd,VOID * buf)1158 INT32 los_part_ioctl(INT32 pt, INT32 cmd, VOID *buf)
1159 {
1160 struct geometry info;
1161 los_part *part = get_part(pt);
1162 los_disk *disk = NULL;
1163
1164 if (part == NULL) {
1165 return VFS_ERROR;
1166 }
1167
1168 disk = get_disk((INT32)part->disk_id);
1169 if (disk == NULL) {
1170 return VFS_ERROR;
1171 }
1172
1173 DISK_LOCK(&disk->disk_mutex);
1174 if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1175 goto ERROR_HANDLE;
1176 }
1177
1178 if (cmd == DISK_CTRL_SYNC) {
1179 DISK_UNLOCK(&disk->disk_mutex);
1180 return ENOERR;
1181 }
1182
1183 if (buf == NULL) {
1184 goto ERROR_HANDLE;
1185 }
1186
1187 (VOID)memset_s(&info, sizeof(info), 0, sizeof(info));
1188
1189 struct block_operations *bops = (struct block_operations *)((struct drv_data *)part->dev->data)->ops;
1190 if ((bops == NULL) || (bops->geometry == NULL) ||
1191 (bops->geometry(part->dev, &info) != 0)) {
1192 goto ERROR_HANDLE;
1193 }
1194
1195 if (cmd == DISK_GET_SECTOR_COUNT) {
1196 *(UINT64 *)buf = part->sector_count;
1197 if (*(UINT64 *)buf == 0) {
1198 goto ERROR_HANDLE;
1199 }
1200 } else if (cmd == DISK_GET_SECTOR_SIZE) {
1201 *(size_t *)buf = info.geo_sectorsize;
1202 } else if (cmd == DISK_GET_BLOCK_SIZE) { /* Get erase block size in unit of sectors (UINT32) */
1203 if ((bops->ioctl == NULL) ||
1204 (bops->ioctl(part->dev, GET_ERASE_BLOCK_SIZE, (UINTPTR)buf) != 0)) {
1205 goto ERROR_HANDLE;
1206 }
1207 } else {
1208 goto ERROR_HANDLE;
1209 }
1210
1211 DISK_UNLOCK(&disk->disk_mutex);
1212 return ENOERR;
1213
1214 ERROR_HANDLE:
1215 DISK_UNLOCK(&disk->disk_mutex);
1216 return VFS_ERROR;
1217 }
1218
los_disk_cache_clear(INT32 drvID)1219 INT32 los_disk_cache_clear(INT32 drvID)
1220 {
1221 INT32 result = ENOERR;
1222 #ifdef LOSCFG_FS_FAT_CACHE
1223 los_part *part = get_part(drvID);
1224 los_disk *disk = NULL;
1225
1226 if (part == NULL) {
1227 return VFS_ERROR;
1228 }
1229 result = OsSdSync(part->disk_id);
1230 if (result != ENOERR) {
1231 PRINTK("[ERROR]disk_cache_clear SD sync failed!\n");
1232 return result;
1233 }
1234
1235 disk = get_disk(part->disk_id);
1236 if (disk == NULL) {
1237 return VFS_ERROR;
1238 }
1239
1240 DISK_LOCK(&disk->disk_mutex);
1241 result = BcacheClearCache(disk->bcache);
1242 DISK_UNLOCK(&disk->disk_mutex);
1243 #endif
1244 return result;
1245 }
1246
1247 #ifdef LOSCFG_FS_FAT_CACHE
DiskCacheThreadInit(UINT32 diskID,OsBcache * bc)1248 static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
1249 {
1250 bc->prereadFun = NULL;
1251
1252 if (GetDiskUsbStatus(diskID) == FALSE) {
1253 if (BcacheAsyncPrereadInit(bc) == LOS_OK) {
1254 bc->prereadFun = ResumeAsyncPreread;
1255 }
1256
1257 #ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
1258 BcacheSyncThreadInit(bc, diskID);
1259 #endif
1260 }
1261
1262 if (OsReHookFuncAddDiskRef != NULL) {
1263 (VOID)OsReHookFuncAddDiskRef((StorageHookFunction)OsSdSync, (VOID *)0);
1264 (VOID)OsReHookFuncAddDiskRef((StorageHookFunction)OsSdSync, (VOID *)1);
1265 }
1266 }
1267
DiskCacheInit(UINT32 diskID,const struct geometry * diskInfo,struct Vnode * blkDriver)1268 static OsBcache *DiskCacheInit(UINT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver)
1269 {
1270 #define SECTOR_SIZE 512
1271
1272 OsBcache *bc = NULL;
1273 UINT32 sectorPerBlock = diskInfo->geo_sectorsize / SECTOR_SIZE;
1274 if (sectorPerBlock != 0) {
1275 sectorPerBlock = g_uwFatSectorsPerBlock / sectorPerBlock;
1276 if (sectorPerBlock != 0) {
1277 bc = BlockCacheInit(blkDriver, diskInfo->geo_sectorsize, sectorPerBlock,
1278 g_uwFatBlockNums, diskInfo->geo_nsectors / sectorPerBlock);
1279 }
1280 }
1281
1282 if (bc == NULL) {
1283 PRINT_ERR("disk_init : disk have not init bcache cache!\n");
1284 return NULL;
1285 }
1286
1287 DiskCacheThreadInit(diskID, bc);
1288 return bc;
1289 }
1290
DiskCacheDeinit(los_disk * disk)1291 static VOID DiskCacheDeinit(los_disk *disk)
1292 {
1293 UINT32 diskID = disk->disk_id;
1294 if (GetDiskUsbStatus(diskID) == FALSE) {
1295 if (BcacheAsyncPrereadDeinit(disk->bcache) != LOS_OK) {
1296 PRINT_ERR("Blib async preread deinit failed in %s, %d\n", __FUNCTION__, __LINE__);
1297 }
1298 #ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
1299 BcacheSyncThreadDeinit(disk->bcache);
1300 #endif
1301 }
1302
1303 BlockCacheDeinit(disk->bcache);
1304 disk->bcache = NULL;
1305
1306 if (OsReHookFuncDelDiskRef != NULL) {
1307 (VOID)OsReHookFuncDelDiskRef((StorageHookFunction)OsSdSync);
1308 }
1309 }
1310 #endif
1311
DiskStructInit(const CHAR * diskName,INT32 diskID,const struct geometry * diskInfo,struct Vnode * blkDriver,los_disk * disk)1312 static VOID DiskStructInit(const CHAR *diskName, INT32 diskID, const struct geometry *diskInfo,
1313 struct Vnode *blkDriver, los_disk *disk)
1314 {
1315 size_t nameLen;
1316 disk->disk_id = diskID;
1317 disk->dev = blkDriver;
1318 disk->sector_start = 0;
1319 disk->sector_size = diskInfo->geo_sectorsize;
1320 disk->sector_count = diskInfo->geo_nsectors;
1321
1322 nameLen = strlen(diskName); /* caller los_disk_init has chek name */
1323
1324 if (disk->disk_name != NULL) {
1325 LOS_MemFree(m_aucSysMem0, disk->disk_name);
1326 disk->disk_name = NULL;
1327 }
1328
1329 disk->disk_name = LOS_MemAlloc(m_aucSysMem0, (nameLen + 1));
1330 if (disk->disk_name == NULL) {
1331 PRINT_ERR("DiskStructInit alloc memory failed.\n");
1332 return;
1333 }
1334
1335 if (strncpy_s(disk->disk_name, (nameLen + 1), diskName, nameLen) != EOK) {
1336 PRINT_ERR("DiskStructInit strncpy_s failed.\n");
1337 LOS_MemFree(m_aucSysMem0, disk->disk_name);
1338 disk->disk_name = NULL;
1339 return;
1340 }
1341 disk->disk_name[nameLen] = '\0';
1342 LOS_ListInit(&disk->head);
1343 }
1344
DiskDivideAndPartitionRegister(struct disk_divide_info * info,los_disk * disk)1345 static INT32 DiskDivideAndPartitionRegister(struct disk_divide_info *info, los_disk *disk)
1346 {
1347 INT32 ret;
1348
1349 if (info != NULL) {
1350 ret = DiskDivide(disk, info);
1351 if (ret != ENOERR) {
1352 PRINT_ERR("DiskDivide failed, ret = %d\n", ret);
1353 return ret;
1354 }
1355 } else {
1356 ret = DiskPartitionRegister(disk);
1357 if (ret != ENOERR) {
1358 PRINT_ERR("DiskPartitionRegister failed, ret = %d\n", ret);
1359 return ret;
1360 }
1361 }
1362 return ENOERR;
1363 }
1364
DiskDeinit(los_disk * disk)1365 static INT32 DiskDeinit(los_disk *disk)
1366 {
1367 los_part *part = NULL;
1368 char *diskName = NULL;
1369 CHAR devName[DEV_NAME_BUFF_SIZE];
1370 INT32 ret;
1371
1372 if (LOS_ListEmpty(&disk->head) == FALSE) {
1373 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
1374 while (&part->list != &disk->head) {
1375 diskName = (disk->disk_name == NULL) ? "null" : disk->disk_name;
1376 ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%d",
1377 diskName, 'p', disk->part_count - 1);
1378 if (ret < 0) {
1379 return -ENAMETOOLONG;
1380 }
1381 DiskPartDelFromDisk(disk, part);
1382 (VOID)unregister_blockdriver(devName);
1383 DiskPartRelease(part);
1384
1385 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
1386 }
1387 }
1388
1389 DISK_LOCK(&disk->disk_mutex);
1390
1391 #ifdef LOSCFG_FS_FAT_CACHE
1392 DiskCacheDeinit(disk);
1393 #else
1394 if (disk->buff != NULL) {
1395 free(disk->buff);
1396 }
1397 #endif
1398
1399 disk->dev = NULL;
1400 DISK_UNLOCK(&disk->disk_mutex);
1401 (VOID)unregister_blockdriver(disk->disk_name);
1402 if (disk->disk_name != NULL) {
1403 LOS_MemFree(m_aucSysMem0, disk->disk_name);
1404 disk->disk_name = NULL;
1405 }
1406 ret = pthread_mutex_destroy(&disk->disk_mutex);
1407 if (ret != 0) {
1408 PRINT_ERR("%s %d, mutex destroy failed, ret = %d\n", __FUNCTION__, __LINE__, ret);
1409 return -EFAULT;
1410 }
1411
1412 disk->disk_status = STAT_UNUSED;
1413
1414 return ENOERR;
1415 }
1416
OsDiskInitSub(const CHAR * diskName,INT32 diskID,los_disk * disk,struct geometry * diskInfo,struct Vnode * blkDriver)1417 static UINT32 OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk,
1418 struct geometry *diskInfo, struct Vnode *blkDriver)
1419 {
1420 pthread_mutexattr_t attr;
1421 #ifdef LOSCFG_FS_FAT_CACHE
1422 OsBcache *bc = DiskCacheInit((UINT32)diskID, diskInfo, blkDriver);
1423 if (bc == NULL) {
1424 return VFS_ERROR;
1425 }
1426 disk->bcache = bc;
1427 #endif
1428
1429 (VOID)pthread_mutexattr_init(&attr);
1430 attr.type = PTHREAD_MUTEX_RECURSIVE;
1431 (VOID)pthread_mutex_init(&disk->disk_mutex, &attr);
1432
1433 DiskStructInit(diskName, diskID, diskInfo, blkDriver, disk);
1434
1435 #ifndef LOSCFG_FS_FAT_CACHE
1436 disk->buff = malloc(diskInfo->geo_sectorsize * DISK_DIRECT_BUFFER_SIZE);
1437 if (disk->buff == NULL) {
1438 PRINT_ERR("OsDiskInitSub: direct buffer of disk init failed\n");
1439 return VFS_ERROR;
1440 }
1441 #endif
1442
1443 return ENOERR;
1444 }
1445
los_disk_init(const CHAR * diskName,const struct block_operations * bops,VOID * priv,INT32 diskID,VOID * info)1446 INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
1447 VOID *priv, INT32 diskID, VOID *info)
1448 {
1449 struct geometry diskInfo;
1450 struct Vnode *blkDriver = NULL;
1451 los_disk *disk = get_disk(diskID);
1452 INT32 ret;
1453
1454 if ((diskName == NULL) || (disk == NULL) ||
1455 (disk->disk_status != STAT_UNREADY) || (strlen(diskName) > DISK_NAME)) {
1456 return VFS_ERROR;
1457 }
1458
1459 if (register_blockdriver(diskName, bops, RWE_RW_RW, priv) != 0) {
1460 PRINT_ERR("disk_init : register %s fail!\n", diskName);
1461 return VFS_ERROR;
1462 }
1463
1464 VnodeHold();
1465 ret = VnodeLookup(diskName, &blkDriver, 0);
1466 if (ret < 0) {
1467 VnodeDrop();
1468 PRINT_ERR("disk_init : %s, failed to find the vnode, ERRNO=%d\n", diskName, ret);
1469 goto DISK_FIND_ERROR;
1470 }
1471 struct block_operations *bops2 = (struct block_operations *)((struct drv_data *)blkDriver->data)->ops;
1472
1473 if ((bops2 == NULL) || (bops2->geometry == NULL) || (bops2->geometry(blkDriver, &diskInfo) != 0)) {
1474 goto DISK_BLKDRIVER_ERROR;
1475 }
1476
1477 if (diskInfo.geo_sectorsize < DISK_MAX_SECTOR_SIZE) {
1478 goto DISK_BLKDRIVER_ERROR;
1479 }
1480
1481 ret = OsDiskInitSub(diskName, diskID, disk, &diskInfo, blkDriver);
1482 if (ret != ENOERR) {
1483 (VOID)DiskDeinit(disk);
1484 VnodeDrop();
1485 return VFS_ERROR;
1486 }
1487 VnodeDrop();
1488 if (DiskDivideAndPartitionRegister(info, disk) != ENOERR) {
1489 (VOID)DiskDeinit(disk);
1490 return VFS_ERROR;
1491 }
1492
1493 disk->disk_status = STAT_INUSED;
1494 if (info != NULL) {
1495 disk->type = EMMC;
1496 } else {
1497 disk->type = OTHERS;
1498 }
1499 return ENOERR;
1500
1501 DISK_BLKDRIVER_ERROR:
1502 PRINT_ERR("disk_init : register %s ok but get disk info fail!\n", diskName);
1503 VnodeDrop();
1504 DISK_FIND_ERROR:
1505 (VOID)unregister_blockdriver(diskName);
1506 return VFS_ERROR;
1507 }
1508
los_disk_deinit(INT32 diskID)1509 INT32 los_disk_deinit(INT32 diskID)
1510 {
1511 int ret;
1512 los_disk *disk = get_disk(diskID);
1513 if (disk == NULL) {
1514 return -EINVAL;
1515 }
1516 ret = ForceUmountDev(disk->dev);
1517 PRINTK("warning: %s lost, force umount ret = %d\n", disk->disk_name, ret);
1518
1519 DISK_LOCK(&disk->disk_mutex);
1520
1521 if (disk->disk_status != STAT_INUSED) {
1522 DISK_UNLOCK(&disk->disk_mutex);
1523 return -EINVAL;
1524 }
1525
1526 disk->disk_status = STAT_UNREADY;
1527 DISK_UNLOCK(&disk->disk_mutex);
1528
1529 return DiskDeinit(disk);
1530 }
1531
los_disk_sync(INT32 drvID)1532 INT32 los_disk_sync(INT32 drvID)
1533 {
1534 INT32 ret = ENOERR;
1535 los_disk *disk = get_disk(drvID);
1536 if (disk == NULL) {
1537 return EINVAL;
1538 }
1539
1540 DISK_LOCK(&disk->disk_mutex);
1541 if (disk->disk_status != STAT_INUSED) {
1542 DISK_UNLOCK(&disk->disk_mutex);
1543 return EINVAL;
1544 }
1545
1546 #ifdef LOSCFG_FS_FAT_CACHE
1547 if (disk->bcache != NULL) {
1548 ret = BlockCacheSync(disk->bcache);
1549 }
1550 #endif
1551
1552 DISK_UNLOCK(&disk->disk_mutex);
1553 return ret;
1554 }
1555
los_disk_set_bcache(INT32 drvID,UINT32 sectorPerBlock,UINT32 blockNum)1556 INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum)
1557 {
1558 #ifdef LOSCFG_FS_FAT_CACHE
1559
1560 INT32 ret;
1561 UINT32 intSave;
1562 OsBcache *bc = NULL;
1563 los_disk *disk = get_disk(drvID);
1564 if ((disk == NULL) || (sectorPerBlock == 0)) {
1565 return EINVAL;
1566 }
1567
1568 /*
1569 * Because we use UINT32 flag[BCACHE_BLOCK_FLAGS] in bcache for sectors bitmap tag, so it must
1570 * be less than 32 * BCACHE_BLOCK_FLAGS.
1571 */
1572 if (((sectorPerBlock % UNSIGNED_INTEGER_BITS) != 0) ||
1573 ((sectorPerBlock >> UNINT_LOG2_SHIFT) > BCACHE_BLOCK_FLAGS)) {
1574 return EINVAL;
1575 }
1576
1577 DISK_LOCK(&disk->disk_mutex);
1578
1579 if (disk->disk_status != STAT_INUSED) {
1580 goto ERROR_HANDLE;
1581 }
1582
1583 if (disk->bcache != NULL) {
1584 ret = BlockCacheSync(disk->bcache);
1585 if (ret != ENOERR) {
1586 DISK_UNLOCK(&disk->disk_mutex);
1587 return ret;
1588 }
1589 }
1590
1591 spin_lock_irqsave(&g_diskFatBlockSpinlock, intSave);
1592 DiskCacheDeinit(disk);
1593
1594 g_uwFatBlockNums = blockNum;
1595 g_uwFatSectorsPerBlock = sectorPerBlock;
1596
1597 bc = BlockCacheInit(disk->dev, disk->sector_size, sectorPerBlock, blockNum, disk->sector_count / sectorPerBlock);
1598 if ((bc == NULL) && (blockNum != 0)) {
1599 spin_unlock_irqrestore(&g_diskFatBlockSpinlock, intSave);
1600 DISK_UNLOCK(&disk->disk_mutex);
1601 return ENOMEM;
1602 }
1603
1604 if (bc != NULL) {
1605 DiskCacheThreadInit((UINT32)drvID, bc);
1606 }
1607
1608 disk->bcache = bc;
1609 spin_unlock_irqrestore(&g_diskFatBlockSpinlock, intSave);
1610 DISK_UNLOCK(&disk->disk_mutex);
1611 return ENOERR;
1612
1613 ERROR_HANDLE:
1614 DISK_UNLOCK(&disk->disk_mutex);
1615 return EINVAL;
1616 #else
1617 return VFS_ERROR;
1618 #endif
1619 }
1620
OsPartFind(los_disk * disk,const struct Vnode * blkDriver)1621 static los_part *OsPartFind(los_disk *disk, const struct Vnode *blkDriver)
1622 {
1623 los_part *part = NULL;
1624
1625 DISK_LOCK(&disk->disk_mutex);
1626 if ((disk->disk_status != STAT_INUSED) || (LOS_ListEmpty(&disk->head) == TRUE)) {
1627 goto EXIT;
1628 }
1629 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
1630 if (disk->dev == blkDriver) {
1631 goto EXIT;
1632 }
1633
1634 while (&part->list != &disk->head) {
1635 if (part->dev == blkDriver) {
1636 goto EXIT;
1637 }
1638 part = LOS_DL_LIST_ENTRY(part->list.pstNext, los_part, list);
1639 }
1640 part = NULL;
1641
1642 EXIT:
1643 DISK_UNLOCK(&disk->disk_mutex);
1644 return part;
1645 }
1646
los_part_find(struct Vnode * blkDriver)1647 los_part *los_part_find(struct Vnode *blkDriver)
1648 {
1649 INT32 i;
1650 los_disk *disk = NULL;
1651 los_part *part = NULL;
1652
1653 if (blkDriver == NULL) {
1654 return NULL;
1655 }
1656
1657 for (i = 0; i < SYS_MAX_DISK; i++) {
1658 disk = get_disk(i);
1659 if (disk == NULL) {
1660 continue;
1661 }
1662 part = OsPartFind(disk, blkDriver);
1663 if (part != NULL) {
1664 return part;
1665 }
1666 }
1667
1668 return NULL;
1669 }
1670
los_part_access(const CHAR * dev,mode_t mode)1671 INT32 los_part_access(const CHAR *dev, mode_t mode)
1672 {
1673 los_part *part = NULL;
1674 struct Vnode *node = NULL;
1675
1676 VnodeHold();
1677 if (VnodeLookup(dev, &node, 0) < 0) {
1678 VnodeDrop();
1679 return VFS_ERROR;
1680 }
1681
1682 part = los_part_find(node);
1683 VnodeDrop();
1684 if (part == NULL) {
1685 return VFS_ERROR;
1686 }
1687
1688 return ENOERR;
1689 }
1690
SetDiskPartName(los_part * part,const CHAR * src)1691 INT32 SetDiskPartName(los_part *part, const CHAR *src)
1692 {
1693 size_t len;
1694 los_disk *disk = NULL;
1695
1696 if ((part == NULL) || (src == NULL)) {
1697 return VFS_ERROR;
1698 }
1699
1700 len = strlen(src);
1701 if ((len == 0) || (len >= DISK_NAME)) {
1702 return VFS_ERROR;
1703 }
1704
1705 disk = get_disk((INT32)part->disk_id);
1706 if (disk == NULL) {
1707 return VFS_ERROR;
1708 }
1709
1710 DISK_LOCK(&disk->disk_mutex);
1711 if (disk->disk_status != STAT_INUSED) {
1712 goto ERROR_HANDLE;
1713 }
1714
1715 part->part_name = (CHAR *)zalloc(len + 1);
1716 if (part->part_name == NULL) {
1717 PRINT_ERR("%s[%d] zalloc failure\n", __FUNCTION__, __LINE__);
1718 goto ERROR_HANDLE;
1719 }
1720
1721 if (strcpy_s(part->part_name, len + 1, src) != EOK) {
1722 free(part->part_name);
1723 part->part_name = NULL;
1724 goto ERROR_HANDLE;
1725 }
1726
1727 DISK_UNLOCK(&disk->disk_mutex);
1728 return ENOERR;
1729
1730 ERROR_HANDLE:
1731 DISK_UNLOCK(&disk->disk_mutex);
1732 return VFS_ERROR;
1733 }
1734
add_mmc_partition(struct disk_divide_info * info,size_t sectorStart,size_t sectorCount)1735 INT32 add_mmc_partition(struct disk_divide_info *info, size_t sectorStart, size_t sectorCount)
1736 {
1737 UINT32 index, i;
1738
1739 if (info == NULL) {
1740 return VFS_ERROR;
1741 }
1742
1743 if ((info->part_count >= MAX_DIVIDE_PART_PER_DISK) || (sectorCount == 0)) {
1744 return VFS_ERROR;
1745 }
1746
1747 if ((sectorCount > info->sector_count) || ((info->sector_count - sectorCount) < sectorStart)) {
1748 return VFS_ERROR;
1749 }
1750
1751 index = info->part_count;
1752 for (i = 0; i < index; i++) {
1753 if (sectorStart < (info->part[i].sector_start + info->part[i].sector_count)) {
1754 return VFS_ERROR;
1755 }
1756 }
1757
1758 info->part[index].sector_start = sectorStart;
1759 info->part[index].sector_count = sectorCount;
1760 info->part[index].type = EMMC;
1761 info->part_count++;
1762
1763 return ENOERR;
1764 }
1765
show_part(los_part * part)1766 VOID show_part(los_part *part)
1767 {
1768 if ((part == NULL) || (part->dev == NULL)) {
1769 PRINT_ERR("part is NULL\n");
1770 return;
1771 }
1772
1773 PRINTK("\npart info :\n");
1774 PRINTK("disk id : %u\n", part->disk_id);
1775 PRINTK("part_id in system: %u\n", part->part_id);
1776 PRINTK("part no in disk : %u\n", part->part_no_disk);
1777 PRINTK("part no in mbr : %u\n", part->part_no_mbr);
1778 PRINTK("part filesystem : %02X\n", part->filesystem_type);
1779 PRINTK("part sec start : %llu\n", part->sector_start);
1780 PRINTK("part sec count : %llu\n", part->sector_count);
1781 }
1782
1783 #ifdef LOSCFG_DRIVERS_MMC
1784 ssize_t StorageBlockMmcErase(uint32_t blockId, size_t secStart, size_t secNr);
1785 #endif
1786
EraseDiskByID(UINT32 diskID,size_t startSector,UINT32 sectors)1787 INT32 EraseDiskByID(UINT32 diskID, size_t startSector, UINT32 sectors)
1788 {
1789 INT32 ret = VFS_ERROR;
1790 #ifdef LOSCFG_DRIVERS_MMC
1791 los_disk *disk = get_disk((INT32)diskID);
1792 if (disk != NULL) {
1793 ret = StorageBlockMmcErase(diskID, startSector, sectors);
1794 }
1795 #endif
1796
1797 return ret;
1798 }
1799
1800