• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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