更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
disk.c
浏览该文件的文档.
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/**
45 * @file disk.c
46 * @verbatim
47GPT和MBR是做什么的?
48 在使用磁盘驱动器之前,必须对其进行分区。。MBR(主引导记录)和GPT(GUID分区表)是在驱动器上存储分区信息的两种不同方法。
49 这些信息包括分区在物理磁盘上的开始和结束位置,因此您的操作系统知道哪些扇区属于每个分区,哪些分区是可引导的。
50 这就是为什么在驱动器上创建分区之前必须选择MBR或GPT的原因。
51
52 MBR于1983年首次在IBMPCDOS2.0中引入。它被称为主引导记录,因为MBR是一个特殊的引导扇区,位于驱动器的开头。
53 此扇区包含已安装操作系统的引导加载程序和有关驱动器逻辑分区的信息。引导加载程序是一小部分代码,
54 通常从驱动器上的另一个分区加载较大的引导加载程序。
55
56 GPT代表GUID划分表。这是一个正在逐步取代MBR的新标准。它与UEFI相关,UEFI用更现代的东西取代笨重的旧BIOS。
57 反过来,GPT用更现代的东西取代了笨重的旧MBR分区系统。它被称为GUIDPartitionTable【全局唯一标识磁盘分区表】,
58 因为驱动器上的每个分区都有一个“全局唯一标识符”,或者GUID--一个长时间的随机字符串,
59 以至于地球上的每个GPT分区都有自己的唯一标识符。
60
61 在MBR磁盘上,分区和引导数据存储在一个地方。如果该数据被覆盖或损坏,您就有麻烦了。
62 相反,GPT跨磁盘存储此数据的多个副本,因此它更健壮,如果数据损坏,可以恢复。
63
64 GPT还存储循环冗余校验(CRC)值,以检查其数据是否完整。如果数据损坏,GPT会注意到问题,
65 并尝试从磁盘上的另一个位置恢复损坏的数据。MBR无法知道其数据是否已损坏--只有在引导进程失败
66 或驱动器分区消失时才会看到问题。
67 GUID分区表自带备份。在磁盘的首尾部分分别保存了一份相同的分区表,因此当一份损坏可以通过另一份恢复。
68 而MBR磁盘分区表一旦被破坏就无法恢复,需要重新分区
69 https://www.howtogeek.com/193669/whats-the-difference-between-gpt-and-mbr-when-partitioning-a-drive/
70 https://www.html.cn/qa/other/20741.html
71 * @endverbatim
72 * @brief
73 */
74
75//磁盘的最小单位就是扇区
76los_disk g_sysDisk[SYS_MAX_DISK]; ///< 支持挂载的磁盘总数量 5个
77los_part g_sysPart[SYS_MAX_PART]; ///< 支持磁盘的分区总数量 5*16,每个磁盘最大分16个区
78
79UINT32 g_uwFatSectorsPerBlock = CONFIG_FS_FAT_SECTOR_PER_BLOCK; ///< 每块支持扇区数 默认64个扇区
80UINT32 g_uwFatBlockNums = CONFIG_FS_FAT_BLOCK_NUMS; ///< 块数量 默认28
81
82spinlock_t g_diskSpinlock; ///< 磁盘自锁锁
83spinlock_t g_diskFatBlockSpinlock; ///< 磁盘Fat块自旋锁
84
86
87#define MEM_ADDR_ALIGN_BYTE 64
88#define RWE_RW_RW 0755
89
90#define DISK_LOCK(mux) do { \
91 if (pthread_mutex_lock(mux) != 0) { \
92 PRINT_ERR("%s %d, mutex lock failed\n", __FUNCTION__, __LINE__); \
93 } \
94} while (0)
95
96#define DISK_UNLOCK(mux) do { \
97 if (pthread_mutex_unlock(mux) != 0) { \
98 PRINT_ERR("%s %d, mutex unlock failed\n", __FUNCTION__, __LINE__); \
99 } \
100} while (0)
101
102typedef VOID *(*StorageHookFunction)(VOID *);
103
104#ifdef LOSCFG_FS_FAT_CACHE
106 VOID *param) __attribute__((weakref("osReHookFuncAdd")));
107
108static UINT32 OsReHookFuncDelDiskRef(StorageHookFunction handler) __attribute__((weakref("osReHookFuncDel")));
109
111{
112 return g_uwFatBlockNums;
113}
114
115VOID SetFatBlockNums(UINT32 blockNums)
116{
117 g_uwFatBlockNums = blockNums;
118}
119
121{
123}
124///设置FAR每块扇区数
125VOID SetFatSectorsPerBlock(UINT32 sectorsPerBlock)
126{
127 if (((sectorsPerBlock % UNSIGNED_INTEGER_BITS) == 0) && //1.必须是整数倍
128 ((sectorsPerBlock >> UNINT_LOG2_SHIFT) <= BCACHE_BLOCK_FLAGS)) {
129 g_uwFatSectorsPerBlock = sectorsPerBlock;
130 }
131}
132#endif
133///通过名称分配磁盘ID
135{
136 INT32 diskID;
137 los_disk *disk = NULL;
138 UINT32 intSave;
139 size_t nameLen;
140
141 if (diskName == NULL) {
142 PRINT_ERR("The parameter disk_name is NULL");
143 return VFS_ERROR;
144 }
145
146 nameLen = strlen(diskName);
147 if (nameLen > DISK_NAME) {
148 PRINT_ERR("diskName is too long!\n");
149 return VFS_ERROR;
150 }
151 spin_lock_irqsave(&g_diskSpinlock, intSave);//加锁
152
153 for (diskID = 0; diskID < SYS_MAX_DISK; diskID++) {//磁盘池中分配一个磁盘描述符
154 disk = get_disk(diskID);
155 if ((disk != NULL) && (disk->disk_status == STAT_UNUSED)) {
156 disk->disk_status = STAT_UNREADY;//初始状态,可理解为未格式化
157 break;
158 }
159 }
160
161 spin_unlock_irqrestore(&g_diskSpinlock, intSave);
162
163 if ((disk == NULL) || (diskID == SYS_MAX_DISK)) {
164 PRINT_ERR("los_alloc_diskid_byname failed %d!\n", diskID);
165 return VFS_ERROR;
166 }
167
168 if (disk->disk_name != NULL) {//分配的磁盘如果有名称,可能之前用过,先释放内核内存
170 disk->disk_name = NULL;
171 }
172
173 disk->disk_name = LOS_MemAlloc(m_aucSysMem0, (nameLen + 1));
174 if (disk->disk_name == NULL) {
175 PRINT_ERR("los_alloc_diskid_byname alloc disk name failed\n");
176 return VFS_ERROR;
177 }
178 //disk->disk_name 等于 参数 名称
179 if (strncpy_s(disk->disk_name, (nameLen + 1), diskName, nameLen) != EOK) {
180 PRINT_ERR("The strncpy_s failed.\n");
182 disk->disk_name = NULL;
183 return VFS_ERROR;
184 }
185
186 disk->disk_name[nameLen] = '\0';
187
188 return diskID;
189}
190///通过名称查询使用中(STAT_INUSED)磁盘ID
192{
193 INT32 diskID;
194 los_disk *disk = NULL;
195 size_t diskNameLen;
196
197 if (diskName == NULL) {
198 PRINT_ERR("The parameter diskName is NULL");
199 return VFS_ERROR;
200 }
201
202 diskNameLen = strlen(diskName);
203 if (diskNameLen > DISK_NAME) {
204 PRINT_ERR("diskName is too long!\n");
205 return VFS_ERROR;
206 }
207
208 for (diskID = 0; diskID < SYS_MAX_DISK; diskID++) {
209 disk = get_disk(diskID);
210 if ((disk != NULL) && (disk->disk_name != NULL) && (disk->disk_status == STAT_INUSED)) {
211 if (strlen(disk->disk_name) != diskNameLen) {
212 continue;
213 }
214 if (strcmp(diskName, disk->disk_name) == 0) {
215 break;
216 }
217 }
218 }
219 if ((disk == NULL) || (diskID == SYS_MAX_DISK)) {
220 PRINT_ERR("los_get_diskid_byname failed!\n");
221 return VFS_ERROR;
222 }
223 return diskID;
224}
225
227{
228 const CHAR *mmcDevHead = "/dev/mmcblk";
229
230 for (INT32 diskId = 0; diskId < SYS_MAX_DISK; diskId++) {
231 los_disk *disk = get_disk(diskId);
232 if (disk == NULL) {
233 continue;
234 } else if ((disk->type == type) && (strncmp(disk->disk_name, mmcDevHead, strlen(mmcDevHead)) == 0)) {
235 return disk;
236 }
237 }
238 PRINT_ERR("Cannot find the mmc disk!\n");
239 return NULL;
240}
241
243{
244 if (diskID < SYS_MAX_DISK) {
245 g_usbMode |= (1u << diskID) & UINT_MAX;
246 }
247}
248
250{
251 if (diskID < SYS_MAX_DISK) {
252 g_usbMode &= ~((1u << diskID) & UINT_MAX);
253 }
254}
255
256#ifdef LOSCFG_FS_FAT_CACHE
258{
259 return (g_usbMode & (1u << diskID)) ? TRUE : FALSE;
260}
261#endif
262//获取某个磁盘的描述符
264{
265 if ((id >= 0) && (id < SYS_MAX_DISK)) {
266 return &g_sysDisk[id];
267 }
268
269 return NULL;
270}
271///获取某个分区的描述符
273{
274 if ((id >= 0) && (id < SYS_MAX_PART)) {
275 return &g_sysPart[id];
276 }
277
278 return NULL;
279}
280
282{
283 los_part *firstPart = NULL;
284 los_disk *disk = get_disk((INT32)part->disk_id);
285 firstPart = (disk == NULL) ? NULL : LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
286 return (firstPart == NULL) ? 0 : firstPart->sector_start;
287}
288///磁盘增加一个分区
289static VOID DiskPartAddToDisk(los_disk *disk, los_part *part)
290{
291 part->disk_id = disk->disk_id;
292 part->part_no_disk = disk->part_count;
293 LOS_ListTailInsert(&disk->head, &part->list);
294 disk->part_count++;
295}
296///从磁盘上删除分区
297static VOID DiskPartDelFromDisk(los_disk *disk, los_part *part)
298{
299 LOS_ListDelete(&part->list);//从分区链表上摘掉
300 disk->part_count--;//分区数量减少
301}
302///分配一个磁盘分区,必须要有索引节点才给分配.
303static los_part *DiskPartAllocate(struct Vnode *dev, UINT64 start, UINT64 count)
304{
305 UINT32 i;//从数组的开头遍历,先获取第一个分区
306 los_part *part = get_part(0); /* traversing from the beginning of the array */
307
308 if (part == NULL) {
309 return NULL;
310 }
311
312 for (i = 0; i < SYS_MAX_PART; i++) {//从数组开头开始遍历
313 if (part->dev == NULL) {//分区是否被使用,通过dev来判断.
314 part->part_id = i; //分区ID
315 part->part_no_mbr = 0; //主分区一般为0
316 part->dev = dev; //设置索引节点,所以节点这个概念很重要,贯彻了整个文件/磁盘系统,一定要理解透彻!!!
317 part->sector_start = start;//开始扇区
318 part->sector_count = count;//扇区总大小
319 part->part_name = NULL; //分区名称,暂无
320 LOS_ListInit(&part->list); //初始化链表节点,将通过它挂入磁盘分区链表上(los_disk->head).
321
322 return part; //就这个分区了.
323 }
324 part++;//找下一个空闲分区位
325 }
326
327 return NULL;
328}
329///清空分区信息
330static VOID DiskPartRelease(los_part *part)
331{
332 part->dev = NULL;//全局释放这步最关键,因为 DiskPartAllocate 中是通过它来判断是否全局分区项已被占用
333 part->part_no_disk = 0; //复位归0
334 part->part_no_mbr = 0; //复位归0
335 if (part->part_name != NULL) {
336 free(part->part_name);//分区名称是内核内存分配的,所以要单独释放.
337 part->part_name = NULL;
338 }
339}
340
341/*
342 * name is a combination of disk_name, 'p' and part_count, such as "/dev/mmcblk0p0"
343 * disk_name : DISK_NAME + 1
344 * 'p' : 1
345 * part_count: 1
346 */
347#define DEV_NAME_BUFF_SIZE (DISK_NAME + 3)//为何加3, 就是上面的"disk_name"+"p"+"part_count"
348//磁盘增加一个分区
349static INT32 DiskAddPart(los_disk *disk, UINT64 sectorStart, UINT64 sectorCount, BOOL IsValidPart)
350{
351 CHAR devName[DEV_NAME_BUFF_SIZE];
352 struct Vnode *diskDev = NULL;
353 struct Vnode *partDev = NULL;
354 los_part *part = NULL;
355 INT32 ret;
356
357 if ((disk == NULL) || (disk->disk_status == STAT_UNUSED) ||
358 (disk->dev == NULL)) {
359 return VFS_ERROR;
360 }
361 //扇区判断,磁盘在创建伊始就扇区数量就固定了
362 if ((sectorCount > disk->sector_count) || ((disk->sector_count - sectorCount) < sectorStart)) {
363 PRINT_ERR("DiskAddPart failed: sector start is %llu, sector count is %llu\n", sectorStart, sectorCount);
364 return VFS_ERROR;
365 }
366 //devName = /dev/mmcblk0p2 代表的是 0号磁盘的2号分区
367
368 diskDev = disk->dev;
369 if (IsValidPart == TRUE) {//有效分区处理
370 ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%u",
371 ((disk->disk_name == NULL) ? "null" : disk->disk_name), 'p', disk->part_count);
372 if (ret < 0) {
373 return VFS_ERROR;
374 }
375 //为节点注册块设备驱动,目的是从此可以通过块操作访问私有数据
376 if (register_blockdriver(devName, ((struct drv_data *)diskDev->data)->ops,
377 RWE_RW_RW, ((struct drv_data *)diskDev->data)->priv)) {
378 PRINT_ERR("DiskAddPart : register %s fail!\n", devName);
379 return VFS_ERROR;
380 }
381
382 VnodeHold();
383 VnodeLookup(devName, &partDev, 0);//通过路径找到索引节点
384
385 part = DiskPartAllocate(partDev, sectorStart, sectorCount);//从全局分区池中分配分区项
386 VnodeDrop();
387 if (part == NULL) {
388 (VOID)unregister_blockdriver(devName);
389 return VFS_ERROR;
390 }
391 } else { //无效的分区也分配一个? @note_why
392 part = DiskPartAllocate(diskDev, sectorStart, sectorCount);
393 if (part == NULL) {
394 return VFS_ERROR;
395 }
396 }
397
398 DiskPartAddToDisk(disk, part);
399 if (disk->type == EMMC) {
400 part->type = EMMC;
401 }
402 return (INT32)part->part_id;
403}
404///磁盘分区
405static INT32 DiskDivide(los_disk *disk, struct disk_divide_info *info)
406{
407 UINT32 i;
408 INT32 ret;
409
410 disk->type = info->part[0].type;// 类型一般为 EMMC
411 for (i = 0; i < info->part_count; i++) {//遍历分区列表
412 if (info->sector_count < info->part[i].sector_start) {//总扇区都已经被分完
413 return VFS_ERROR;
414 }
415 if (info->part[i].sector_count > (info->sector_count - info->part[i].sector_start)) {//边界检测
416 PRINT_ERR("Part[%u] sector_start:%llu, sector_count:%llu, exceed emmc sector_count:%llu.\n", i,
417 info->part[i].sector_start, info->part[i].sector_count,
418 (info->sector_count - info->part[i].sector_start));
419 info->part[i].sector_count = info->sector_count - info->part[i].sector_start;//改变区的扇区数量
420 PRINT_ERR("Part[%u] sector_count change to %llu.\n", i, info->part[i].sector_count);
421 //增加一个分区
422 ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE);
423 if (ret == VFS_ERROR) {
424 return VFS_ERROR;
425 }
426 break;
427 }
428 ret = DiskAddPart(disk, info->part[i].sector_start, info->part[i].sector_count, TRUE);
429 if (ret == VFS_ERROR) {
430 return VFS_ERROR;
431 }
432 }
433
434 return ENOERR;
435}
436///GPT分区类型识别
438{
439 const CHAR *buf = parBuf;
440 const CHAR *fsType = "FAT";
441 const CHAR *str = "\xEB\x52\x90" "NTFS "; /* NTFS Boot entry point | NTFS 引导入口点*/
442
443 if (((LD_DWORD_DISK(&buf[BS_FILSYSTEMTYPE32]) & BS_FS_TYPE_MASK) == BS_FS_TYPE_VALUE) ||
444 (strncmp(&buf[BS_FILSYSTYPE], fsType, strlen(fsType)) == 0)) {//识别FAT的方法
445 return BS_FS_TYPE_FAT;
446 } else if (strncmp(&buf[BS_JMPBOOT], str, strlen(str)) == 0) {//识别NTFS的方法
447 return BS_FS_TYPE_NTFS;
448 }
449
450 return ENOERR;
451}
452///磁盘分区内存申请
453static INT32 DiskPartitionMemZalloc(size_t boundary, size_t size, CHAR **gptBuf, CHAR **partitionBuf)
454{
455 CHAR *buffer1 = NULL;
456 CHAR *buffer2 = NULL;
457 //分配一个 size 字节的块,其地址是边界的倍数。边界必须是 2 的幂!
458 buffer1 = (CHAR *)memalign(boundary, size);//对齐 memalign -> LOS_KernelMallocAlign
459 if (buffer1 == NULL) {
460 PRINT_ERR("%s buffer1 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__);
461 return -ENOMEM;
462 }
463 buffer2 = (CHAR *)memalign(boundary, size);
464 if (buffer2 == NULL) {
465 PRINT_ERR("%s buffer2 malloc %lu failed! %d\n", __FUNCTION__, size, __LINE__);
466 free(buffer1);
467 return -ENOMEM;
468 }
469 (VOID)memset_s(buffer1, size, 0, size);
470 (VOID)memset_s(buffer2, size, 0, size);
471
472 *gptBuf = buffer1;
473 *partitionBuf = buffer2;
474
475 return ENOERR;
476}
477///获取GPT信息,是GPT还是MBR取决于磁盘上放的内容
478static INT32 GPTInfoGet(struct Vnode *blkDrv, CHAR *gptBuf)
479{
480 INT32 ret;
481 //获取驱动程序
482 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
483 //从第一个扇区,从这可以看出 GPT是兼容 MBR的,因为 MBR的内容是放在 0 扇区.
484 ret = bops->read(blkDrv, (UINT8 *)gptBuf, 1, 1); /* Read the device first sector */
485 if (ret != 1) { /* Read failed */
486 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
487 return -EIO;
488 }
489
490 if (!VERIFY_GPT(gptBuf)) {
491 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
492 return VFS_ERROR;
493 }
494
495 return ENOERR;
496}
497///解析GPT分区内容
498static INT32 OsGPTPartitionRecognitionSub(struct disk_divide_info *info, const CHAR *partitionBuf,
499 UINT32 *partitionCount, UINT64 partitionStart, UINT64 partitionEnd)
500{
501 CHAR partitionType;
502
503 if (VERIFY_FS(partitionBuf)) {
504 partitionType = GPTPartitionTypeRecognition(partitionBuf);//文件系统类型,支持FAT和NTFS
505 if (partitionType) {
506 if (*partitionCount >= MAX_DIVIDE_PART_PER_DISK) {
507 return VFS_ERROR;
508 }
509 info->part[*partitionCount].type = partitionType;//文件系统
510 info->part[*partitionCount].sector_start = partitionStart;//开始扇区
511 info->part[*partitionCount].sector_count = (partitionEnd - partitionStart) + 1;//扇区总数
512 (*partitionCount)++;//磁盘扇区数量增加
513 } else {
514 PRINT_ERR("The partition type is not allowed to use!\n");
515 }
516 } else {
517 PRINT_ERR("Do not support the partition type!\n");
518 }
519 return ENOERR;
520}
521///识别GPT分区内容
522static INT32 OsGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info,
523 const CHAR *gptBuf, CHAR *partitionBuf, UINT32 *partitionCount)
524{
525 UINT32 j;
526 INT32 ret = VFS_ERROR;
527 UINT64 partitionStart, partitionEnd;
528 struct block_operations *bops = NULL;
529
530 for (j = 0; j < PAR_ENTRY_NUM_PER_SECTOR; j++) {
531 if (!VERITY_AVAILABLE_PAR(&gptBuf[j * TABLE_SIZE])) {//ESP 和 MSR 分区
532 PRINTK("The partition type is ESP or MSR!\n");
533 continue;
534 }
535
536 if (!VERITY_PAR_VALID(&gptBuf[j * TABLE_SIZE])) {
537 return VFS_ERROR;
538 }
539
540 partitionStart = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_START_OFFSET]);//读取开始扇区
541 partitionEnd = LD_QWORD_DISK(&gptBuf[(j * TABLE_SIZE) + GPT_PAR_END_OFFSET]);//读取结束扇区
542 if ((partitionStart >= partitionEnd) || (partitionEnd > info->sector_count)) {
543 PRINT_ERR("GPT partition %u recognition failed : partitionStart = %llu, partitionEnd = %llu\n",
544 j, partitionStart, partitionEnd);
545 return VFS_ERROR;
546 }
547
548 (VOID)memset_s(partitionBuf, info->sector_size, 0, info->sector_size);
549
550 bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
551
552 ret = bops->read(blkDrv, (UINT8 *)partitionBuf, partitionStart, 1);//读取扇区内容
553 if (ret != 1) { /* read failed */
554 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
555 return -EIO;
556 }
557
558 ret = OsGPTPartitionRecognitionSub(info, partitionBuf, partitionCount, partitionStart, partitionEnd);
559 if (ret != ENOERR) {
560 return VFS_ERROR;
561 }
562 }
563
564 return ret;
565}
566
567static INT32 DiskGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
568{
569 CHAR *gptBuf = NULL;
570 CHAR *partitionBuf = NULL;
571 UINT32 tableNum, i, index;
572 UINT32 partitionCount = 0;
573 INT32 ret;
574
575 ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &gptBuf, &partitionBuf);
576 if (ret != ENOERR) {
577 return ret;
578 }
579
580 ret = GPTInfoGet(blkDrv, gptBuf);//获取GDT类型的引导扇区信息
581 if (ret < 0) {
582 goto OUT_WITH_MEM;
583 }
584
585 tableNum = LD_DWORD_DISK(&gptBuf[TABLE_NUM_OFFSET]);
586 if (tableNum > TABLE_MAX_NUM) {
587 tableNum = TABLE_MAX_NUM;
588 }
589
590 index = (tableNum % PAR_ENTRY_NUM_PER_SECTOR) ? ((tableNum / PAR_ENTRY_NUM_PER_SECTOR) + 1) :
591 (tableNum / PAR_ENTRY_NUM_PER_SECTOR);
592
593 for (i = 0; i < index; i++) {
594 (VOID)memset_s(gptBuf, info->sector_size, 0, info->sector_size);
595 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
596 ret = bops->read(blkDrv, (UINT8 *)gptBuf, TABLE_START_SECTOR + i, 1);
597 if (ret != 1) { /* read failed */
598 PRINT_ERR("%s %d\n", __FUNCTION__, __LINE__);
599 ret = -EIO;
600 goto OUT_WITH_MEM;
601 }
602
603 ret = OsGPTPartitionRecognition(blkDrv, info, gptBuf, partitionBuf, &partitionCount);
604 if (ret < 0) {
605 if (ret == VFS_ERROR) {
606 ret = (INT32)partitionCount;
607 }
608 goto OUT_WITH_MEM;
609 }
610 }
611 ret = (INT32)partitionCount;
612
613OUT_WITH_MEM:
614 free(gptBuf);
615 free(partitionBuf);
616 return ret;
617}
618///获取MBR信息,即特殊扇区信息,在MBR硬盘中,分区信息直接存储于主引导记录(MBR)中(主引导记录中还存储着系统的引导程序)。
619static INT32 OsMBRInfoGet(struct Vnode *blkDrv, CHAR *mbrBuf)
620{
621 INT32 ret;
622 //读取MBR,从0扇区开始,长度为1扇区
623 /* read MBR, start from sector 0, length is 1 sector */
624 //以块为操作的接口封装
625 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
626
627 ret = bops->read(blkDrv, (UINT8 *)mbrBuf, 0, 1);//读一个扇区 [0-1]
628 if (ret != 1) { /* read failed */
629 PRINT_ERR("driver read return error: %d\n", ret);
630 return -EIO;
631 }
632
633 /* Check boot record signature. *///检查引导记录签名
634 if (LD_WORD_DISK(&mbrBuf[BS_SIG55AA]) != BS_SIG55AA_VALUE) {//高低换位
635 return VFS_ERROR;
636 }
637
638 return ENOERR;
639}
640
641static INT32 OsEBRInfoGet(struct Vnode *blkDrv, const struct disk_divide_info *info,
642 CHAR *ebrBuf, const CHAR *mbrBuf)
643{
644 INT32 ret;
645
646 if (VERIFY_FS(mbrBuf)) {//确认是个文件系统的引导扇区,因为紧接着要去读这个扇区内容,所以先判断有没有这个扇区.
647 if (info->sector_count <= LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET])) {
648 return VFS_ERROR;
649 }
650 //获取块设备驱动程序
651 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
652 ret = bops->read(blkDrv, (UINT8 *)ebrBuf, LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET]), 1);//读取某个扇区信息
653 if ((ret != 1) || (!VERIFY_FS(ebrBuf))) { /* read failed */ //这里同样要确认下读出来的扇区是文件系统的引导扇区
654 PRINT_ERR("OsEBRInfoGet, verify_fs error, ret = %d\n", ret);
655 return -EIO;
656 }
657 }
658
659 return ENOERR;
660}
661///识别主分区
662static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divide_info *info,
663 INT32 *extendedPos, INT32 *mbrCount)
664{
665 INT32 i;
666 CHAR mbrPartitionType;
667 INT32 extendedFlag = 0;
668 INT32 count = 0;
669 //mbrBuf的内容是磁盘的第0柱面第0磁盘的首个扇区内容,也称为特殊扇区
670 for (i = 0; i < MAX_PRIMARY_PART_PER_DISK; i++) {//最多4个主分区,这是由MBR的第二部分DPT(Disk Partition Table,硬盘分区表)规定死的
671 mbrPartitionType = mbrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + (i * PAR_TABLE_SIZE)];//读取分区类型
672 if (mbrPartitionType) {
673 info->part[i].type = mbrPartitionType;//记录分区
674 info->part[i].sector_start = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (i * PAR_TABLE_SIZE)]);//读取开始扇区编号
675 info->part[i].sector_count = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_COUNT_OFFSET + (i * PAR_TABLE_SIZE)]);//读取共有多少扇区
676 if ((mbrPartitionType == EXTENDED_PAR) || (mbrPartitionType == EXTENDED_8G)) {//分区类型如果是扩展分区
677 extendedFlag = 1;//贴上硬盘分区表有扩展分区
678 *extendedPos = i;//记录第几个位置是扩展分区
679 continue;//继续,说明 count 记录的是主分区的数量
680 }
681 count++;
682 }
683 }
684 *mbrCount = count;//带出主分区数量
685
686 return extendedFlag;//返回是否为扩展分区标签
687}
688///识别扩展分区
689static INT32 OsLogicalPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info,
690 UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount)
691{
692 INT32 ret;
693 UINT32 extendedOffset = 0;
694 CHAR ebrPartitionType;
695 INT32 ebrCount = 0;
696
697 do {//循环读取一个个扩展分区信息
698 (VOID)memset_s(ebrBuf, info->sector_size, 0, info->sector_size);
699 if (((UINT64)(extendedAddress) + extendedOffset) >= info->sector_count) {
700 PRINT_ERR("extended partition is out of disk range: extendedAddress = %u, extendedOffset = %u\n",
701 extendedAddress, extendedOffset);
702 break;
703 }
704 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
705 ret = bops->read(blkDrv, (UINT8 *)ebrBuf, extendedAddress + extendedOffset, 1);//读取扇区
706 if (ret != 1) { /* read failed */
707 PRINT_ERR("driver read return error: %d, extendedAddress = %u, extendedOffset = %u\n", ret,
708 extendedAddress, extendedOffset);
709 return -EIO;
710 }
711 ebrPartitionType = ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET];//读取分区类型
712 if (ebrPartitionType && ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK)) {//填充分区信息
713 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].type = ebrPartitionType;
714 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_start = extendedAddress + extendedOffset +
715 LD_DWORD_DISK(&ebrBuf[PAR_OFFSET +
716 PAR_START_OFFSET]);
717 info->part[MAX_PRIMARY_PART_PER_DISK + ebrCount].sector_count = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET +
718 PAR_COUNT_OFFSET]);
719 ebrCount++;//扩展分区的数量
720 }
721 extendedOffset = LD_DWORD_DISK(&ebrBuf[PAR_OFFSET + PAR_START_OFFSET + PAR_TABLE_SIZE]);//继续下一个分区
722 } while ((ebrBuf[PAR_OFFSET + PAR_TYPE_OFFSET + PAR_TABLE_SIZE] != 0) &&
723 ((mbrCount + ebrCount) < MAX_DIVIDE_PART_PER_DISK));//结束条件1.读完分区表 2.总分区数超了
724
725 return ebrCount;
726}
727///识别磁盘分区信息 https://blog.csdn.net/Hilavergil/article/details/79270379
728static INT32 DiskPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
729{
730 INT32 ret;
731 INT32 extendedFlag;
732 INT32 extendedPos = 0;
733 INT32 mbrCount = 0;
734 UINT32 extendedAddress;
735 CHAR *mbrBuf = NULL;
736 CHAR *ebrBuf = NULL;
737
738 if (blkDrv == NULL) {
739 return -EINVAL;
740 }
741 //获取块设备驱动程序
742 struct block_operations *bops = (struct block_operations *)((struct drv_data *)blkDrv->data)->ops;
743
744 if ((bops == NULL) || (bops->read == NULL)) {
745 return -EINVAL;
746 }
747
748 ret = DiskPartitionMemZalloc(MEM_ADDR_ALIGN_BYTE, info->sector_size, &mbrBuf, &ebrBuf);
749 if (ret != ENOERR) {
750 return ret;
751 }
752
753 ret = OsMBRInfoGet(blkDrv, mbrBuf);//获取(MBR)首个扇区内容,
754 if (ret < 0) {
755 goto OUT_WITH_MEM;
756 }
757
758 /* The partition type is GPT */
759 if (mbrBuf[PARTION_MODE_BTYE] == (CHAR)PARTION_MODE_GPT) {//如果采用了GPT的分区方式 0xEE
760 ret = DiskGPTPartitionRecognition(blkDrv, info);//用GPT方式解析分区信息
761 goto OUT_WITH_MEM;
762 }
763
764 ret = OsEBRInfoGet(blkDrv, info, ebrBuf, mbrBuf);//获取扩展分区信息
765 if (ret < 0) {//4个分区表中不一定会有扩展分区
766 ret = 0; /* no mbr */
767 goto OUT_WITH_MEM;
768 }
769
770 extendedFlag = OsPrimaryPartitionRecognition(mbrBuf, info, &extendedPos, &mbrCount);//解析主分区信息
771 if (extendedFlag) {//如果有扩展分区
772 extendedAddress = LD_DWORD_DISK(&mbrBuf[PAR_OFFSET + PAR_START_OFFSET + (extendedPos * PAR_TABLE_SIZE)]);//逻辑分区开始解析位置
773 ret = OsLogicalPartitionRecognition(blkDrv, info, extendedAddress, ebrBuf, mbrCount);//解析逻辑分区
774 if (ret <= 0) {
775 goto OUT_WITH_MEM;
776 }
777 }
778 ret += mbrCount;
779
780OUT_WITH_MEM:
781 free(ebrBuf);
782 free(mbrBuf);
783 return ret;
784}
785///磁盘分区注册
787{
788 INT32 count;
789 UINT32 i, partSize;
790 los_part *part = NULL;
791 struct disk_divide_info parInfo;
792 //填充disk_divide_info结构体设置分区信息
793 /* Fill disk_divide_info structure to set partition's infomation. */
794 (VOID)memset_s(parInfo.part, sizeof(parInfo.part), 0, sizeof(parInfo.part));
795 partSize = sizeof(parInfo.part) / sizeof(parInfo.part[0]);//获取能分区的最大数量
796 parInfo.sector_size = disk->sector_size;//磁盘扇区大小,这是固定的,不管什么分区,扇区大小是不变的(512字节)
797 parInfo.sector_count = disk->sector_count;//扇区数量,注意:这里只是默认的值,最终的值来源于读取的MBR或EBR内容
798 //即每个分区的扇区大小和总数量是可以不一样的.
799 count = DiskPartitionRecognition(disk->dev, &parInfo);//有了分区信息就阔以开始解析了
800 if (count == VFS_ERROR) {//分区表错误, @note_thinking 直接返回就行了,做 get_part 没意义了吧
801 part = get_part(DiskAddPart(disk, 0, disk->sector_count, FALSE));//
802 if (part == NULL) {
803 return VFS_ERROR;
804 }
805 part->part_no_mbr = 0;//打印磁盘没有一个可用的分区表
806 PRINTK("Disk %s doesn't contain a valid partition table.\n", disk->disk_name);
807 return ENOERR;
808 } else if (count < 0) {
809 return VFS_ERROR;
810 }
811
812 parInfo.part_count = count;//保存分区数量
813 if (count == 0) { //整个函数写的很怪,建议重写 @note_thinking
814 part = get_part(DiskAddPart(disk, 0, disk->sector_count, TRUE));
815 if (part == NULL) {
816 return VFS_ERROR;
817 }
818 part->part_no_mbr = 0;
819
820 PRINTK("No MBR detected.\n");
821 return ENOERR;
822 }
823
824 for (i = 0; i < partSize; i++) {//磁盘的分区是解析出来了,接着要纳入全局统一管理了.
825 /* Read the disk_divide_info structure to get partition's infomation. */
826 if ((parInfo.part[i].type != 0) && (parInfo.part[i].type != EXTENDED_PAR) &&
827 (parInfo.part[i].type != EXTENDED_8G)) {
828 part = get_part(DiskAddPart(disk, parInfo.part[i].sector_start, parInfo.part[i].sector_count, TRUE));
829 if (part == NULL) {
830 return VFS_ERROR;
831 }
832 part->part_no_mbr = i + 1;//全局记录 第几个主引导分区
833 part->filesystem_type = parInfo.part[i].type;//全局记录 文件系统类型
834 }
835 }
836
837 return ENOERR;
838}
839#ifndef LOSCFG_FS_FAT_CACHE
840static INT32 disk_read_directly(los_disk *disk, VOID *buf, UINT64 sector, UINT32 count)
841{
842 INT32 result = VFS_ERROR;
843 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
844 if ((bops == NULL) || (bops->read == NULL)) {
845 return VFS_ERROR;
846 }
847 if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
848 UINT32 cnt = 0;
849 UINT8 *buffer = disk->buff;
850 for (; count != 0; count -= cnt) {
851 cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
852 result = bops->read(disk->dev, buffer, sector, cnt);
853 if (result == (INT32)cnt) {
854 result = ENOERR;
855 } else {
856 break;
857 }
858 if (LOS_CopyFromKernel(buf, disk->sector_size * cnt, buffer, disk->sector_size * cnt)) {
859 result = VFS_ERROR;
860 break;
861 }
862 buf = (UINT8 *)buf + disk->sector_size * cnt;
863 sector += cnt;
864 }
865 } else {
866 result = bops->read(disk->dev, buf, sector, count);
867 if (result == count) {
868 result = ENOERR;
869 }
870 }
871
872 return result;
873}
874
875static INT32 disk_write_directly(los_disk *disk, const VOID *buf, UINT64 sector, UINT32 count)
876{
877 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
878 INT32 result = VFS_ERROR;
879 if ((bops == NULL) || (bops->read == NULL)) {
880 return VFS_ERROR;
881 }
882 if (LOS_IsUserAddressRange((VADDR_T)buf, count * disk->sector_size)) {
883 UINT32 cnt = 0;
884 UINT8 *buffer = disk->buff;
885 for (; count != 0; count -= cnt) {
886 cnt = (count > DISK_DIRECT_BUFFER_SIZE) ? DISK_DIRECT_BUFFER_SIZE : count;
887 if (LOS_CopyToKernel(buffer, disk->sector_size * cnt, buf, disk->sector_size * cnt)) {
888 result = VFS_ERROR;
889 break;
890 }
891 result = bops->write(disk->dev, buffer, sector, cnt);
892 if (result == (INT32)cnt) {
893 result = ENOERR;
894 } else {
895 break;
896 }
897 buf = (UINT8 *)buf + disk->sector_size * cnt;
898 sector += cnt;
899 }
900 } else {
901 result = bops->write(disk->dev, buf, sector, count);
902 if (result == count) {
903 result = ENOERR;
904 }
905 }
906
907 return result;
908}
909#endif
910///读磁盘数据
911INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
912{
913#ifdef LOSCFG_FS_FAT_CACHE
914 UINT32 len;
915#endif
916 INT32 result = VFS_ERROR;
917 los_disk *disk = get_disk(drvID);
918
919 if ((buf == NULL) || (count == 0)) { /* buff equal to NULL or count equal to 0 */
920 return result;
921 }
922
923 if (disk == NULL) {
924 return result;
925 }
926
927 DISK_LOCK(&disk->disk_mutex);
928
929 if (disk->disk_status != STAT_INUSED) {
930 goto ERROR_HANDLE;
931 }
932
933 if ((count > disk->sector_count) || ((disk->sector_count - count) < sector)) {
934 goto ERROR_HANDLE;
935 }
936
937#ifdef LOSCFG_FS_FAT_CACHE
938 if (disk->bcache != NULL) {
939 if (((UINT64)(disk->bcache->sectorSize) * count) > UINT_MAX) {
940 goto ERROR_HANDLE;
941 }
942 len = disk->bcache->sectorSize * count;
943 /* useRead should be FALSE when reading large contiguous data *///读取大量连续数据时,useRead 应为 FALSE
944 result = BlockCacheRead(disk->bcache, (UINT8 *)buf, &len, sector, useRead);//从缓存区里读
945 if (result != ENOERR) {
946 PRINT_ERR("los_disk_read read err = %d, sector = %llu, len = %u\n", result, sector, len);
947 }
948 } else {
949 result = VFS_ERROR;
950 }
951#else
952 if (disk->dev == NULL) {
953 goto ERROR_HANDLE;
954 }
955 result = disk_read_directly(disk, buf, sector, count);
956#endif
957
958 if (result != ENOERR) {
959 goto ERROR_HANDLE;
960 }
961
962 DISK_UNLOCK(&disk->disk_mutex);
963 return ENOERR;
964
965ERROR_HANDLE:
966 DISK_UNLOCK(&disk->disk_mutex);
967 return VFS_ERROR;
968}
969///将buf内容写到指定扇区,
970INT32 los_disk_write(INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count)
971{
972#ifdef LOSCFG_FS_FAT_CACHE
973 UINT32 len;
974#endif
975 INT32 result = VFS_ERROR;
976 los_disk *disk = get_disk(drvID);
977 if (disk == NULL || disk->dev == NULL || disk->dev->data == NULL) {
978 return result;
979 }
980
981 if ((buf == NULL) || (count == 0)) { /* buff equal to NULL or count equal to 0 */
982 return result;
983 }
984
985 DISK_LOCK(&disk->disk_mutex);
986
987 if (disk->disk_status != STAT_INUSED) {
988 goto ERROR_HANDLE;
989 }
990
991 if ((count > disk->sector_count) || ((disk->sector_count - count) < sector)) {
992 goto ERROR_HANDLE;
993 }
994
995#ifdef LOSCFG_FS_FAT_CACHE
996 if (disk->bcache != NULL) {
997 if (((UINT64)(disk->bcache->sectorSize) * count) > UINT_MAX) {
998 goto ERROR_HANDLE;
999 }
1000 len = disk->bcache->sectorSize * count;
1001 result = BlockCacheWrite(disk->bcache, (const UINT8 *)buf, &len, sector);//写入缓存,后续由缓存同步至磁盘
1002 if (result != ENOERR) {
1003 PRINT_ERR("los_disk_write write err = %d, sector = %llu, len = %u\n", result, sector, len);
1004 }
1005 } else {
1006 result = VFS_ERROR;
1007 }
1008#else
1009 if (disk->dev == NULL) {
1010 goto ERROR_HANDLE;
1011 }
1012 result = disk_write_directly(disk, buf, sector, count);
1013#endif
1014
1015 if (result != ENOERR) {
1016 goto ERROR_HANDLE;
1017 }
1018
1019 DISK_UNLOCK(&disk->disk_mutex);
1020 return ENOERR;
1021
1022ERROR_HANDLE:
1023 DISK_UNLOCK(&disk->disk_mutex);
1024 return VFS_ERROR;
1025}
1026
1027INT32 los_disk_ioctl(INT32 drvID, INT32 cmd, VOID *buf)
1028{
1029 struct geometry info;
1030 los_disk *disk = get_disk(drvID);
1031 if (disk == NULL) {
1032 return VFS_ERROR;
1033 }
1034
1035 DISK_LOCK(&disk->disk_mutex);
1036
1037 if ((disk->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1038 goto ERROR_HANDLE;
1039 }
1040
1041 if (cmd == DISK_CTRL_SYNC) {
1042 DISK_UNLOCK(&disk->disk_mutex);
1043 return ENOERR;
1044 }
1045
1046 if (buf == NULL) {
1047 goto ERROR_HANDLE;
1048 }
1049
1050 (VOID)memset_s(&info, sizeof(info), 0, sizeof(info));
1051
1052 struct block_operations *bops = (struct block_operations *)((struct drv_data *)disk->dev->data)->ops;
1053 if ((bops == NULL) || (bops->geometry == NULL) ||
1054 (bops->geometry(disk->dev, &info) != 0)) {
1055 goto ERROR_HANDLE;
1056 }
1057
1058 if (cmd == DISK_GET_SECTOR_COUNT) {
1059 *(UINT64 *)buf = info.geo_nsectors;
1060 if (info.geo_nsectors == 0) {
1061 goto ERROR_HANDLE;
1062 }
1063 } else if (cmd == DISK_GET_SECTOR_SIZE) {
1064 *(size_t *)buf = info.geo_sectorsize;
1065 } else if (cmd == DISK_GET_BLOCK_SIZE) { /* Get erase block size in unit of sectors (UINT32) */
1066 /* Block Num SDHC == 512, SD can be set to 512 or other */
1067 *(size_t *)buf = DISK_MAX_SECTOR_SIZE / info.geo_sectorsize;
1068 } else {
1069 goto ERROR_HANDLE;
1070 }
1071
1072 DISK_UNLOCK(&disk->disk_mutex);
1073 return ENOERR;
1074
1075ERROR_HANDLE:
1076 DISK_UNLOCK(&disk->disk_mutex);
1077 return VFS_ERROR;
1078}
1079///读分区上扇区内容
1080INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
1081{
1082 const los_part *part = get_part(pt);//先拿到分区信息
1083 los_disk *disk = NULL;
1084 INT32 ret;
1085
1086 if (part == NULL) {
1087 return VFS_ERROR;
1088 }
1089
1090 disk = get_disk((INT32)part->disk_id);//再拿到磁盘信息
1091 if (disk == NULL) {
1092 return VFS_ERROR;
1093 }
1094
1095 DISK_LOCK(&disk->disk_mutex);//锁磁盘
1096 if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1097 goto ERROR_HANDLE;
1098 }
1099
1100 if (count > part->sector_count) {//不能超过分区总扇区数量
1101 PRINT_ERR("los_part_read failed, invalid count, count = %u\n", count);
1102 goto ERROR_HANDLE;
1103 }
1104
1105 /* Read from absolute sector. */
1106 if (part->type == EMMC) {//如果分区类型是磁盘介质
1107 if ((disk->sector_count - part->sector_start) > sector) {//从绝对扇区读取
1108 sector += part->sector_start;
1109 } else {
1110 PRINT_ERR("los_part_read failed, invalid sector, sector = %llu\n", sector);
1111 goto ERROR_HANDLE;
1112 }
1113 }
1114
1115 if ((sector >= GetFirstPartStart(part)) && //扇区范围判断
1116 (((sector + count) > (part->sector_start + part->sector_count)) || (sector < part->sector_start))) {
1117 PRINT_ERR("los_part_read error, sector = %llu, count = %u, part->sector_start = %llu, "
1118 "part->sector_count = %llu\n", sector, count, part->sector_start, part->sector_count);
1119 goto ERROR_HANDLE;
1120 }
1121 //读取大量连续数据时,useRead 应为 FALSE
1122 /* useRead should be FALSE when reading large contiguous data */
1123 ret = los_disk_read((INT32)part->disk_id, buf, sector, count, useRead);
1124 if (ret < 0) {
1125 goto ERROR_HANDLE;
1126 }
1127
1128 DISK_UNLOCK(&disk->disk_mutex);
1129 return ENOERR;
1130
1131ERROR_HANDLE:
1132 DISK_UNLOCK(&disk->disk_mutex);
1133 return VFS_ERROR;
1134}
1135///将数据写入指定分区的指定扇区
1136INT32 los_part_write(INT32 pt, const VOID *buf, UINT64 sector, UINT32 count)
1137{
1138 const los_part *part = get_part(pt);
1139 los_disk *disk = NULL;
1140 INT32 ret;
1141
1142 if (part == NULL) {
1143 return VFS_ERROR;
1144 }
1145
1146 disk = get_disk((INT32)part->disk_id);
1147 if (disk == NULL) {
1148 return VFS_ERROR;
1149 }
1150
1151 DISK_LOCK(&disk->disk_mutex);
1152 if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1153 goto ERROR_HANDLE;
1154 }
1155
1156 if (count > part->sector_count) {
1157 PRINT_ERR("los_part_write failed, invalid count, count = %u\n", count);
1158 goto ERROR_HANDLE;
1159 }
1160
1161 /* Write to absolute sector. */
1162 if (part->type == EMMC) {
1163 if ((disk->sector_count - part->sector_start) > sector) {
1164 sector += part->sector_start;
1165 } else {
1166 PRINT_ERR("los_part_write failed, invalid sector, sector = %llu\n", sector);
1167 goto ERROR_HANDLE;
1168 }
1169 }
1170
1171 if ((sector >= GetFirstPartStart(part)) &&
1172 (((sector + count) > (part->sector_start + part->sector_count)) || (sector < part->sector_start))) {
1173 PRINT_ERR("los_part_write, sector = %llu, count = %u, part->sector_start = %llu, "
1174 "part->sector_count = %llu\n", sector, count, part->sector_start, part->sector_count);
1175 goto ERROR_HANDLE;
1176 }
1177 //sector已变成磁盘绝对扇区
1178 ret = los_disk_write((INT32)part->disk_id, buf, sector, count);//直接写入磁盘,
1179 if (ret < 0) {
1180 goto ERROR_HANDLE;
1181 }
1182
1183 DISK_UNLOCK(&disk->disk_mutex);
1184 return ENOERR;
1185
1186ERROR_HANDLE:
1187 DISK_UNLOCK(&disk->disk_mutex);
1188 return VFS_ERROR;
1189}
1190
1191#define GET_ERASE_BLOCK_SIZE 0x2
1192
1193INT32 los_part_ioctl(INT32 pt, INT32 cmd, VOID *buf)
1194{
1195 struct geometry info;
1196 los_part *part = get_part(pt);
1197 los_disk *disk = NULL;
1198
1199 if (part == NULL) {
1200 return VFS_ERROR;
1201 }
1202
1203 disk = get_disk((INT32)part->disk_id);
1204 if (disk == NULL) {
1205 return VFS_ERROR;
1206 }
1207
1208 DISK_LOCK(&disk->disk_mutex);
1209 if ((part->dev == NULL) || (disk->disk_status != STAT_INUSED)) {
1210 goto ERROR_HANDLE;
1211 }
1212
1213 if (cmd == DISK_CTRL_SYNC) {
1214 DISK_UNLOCK(&disk->disk_mutex);
1215 return ENOERR;
1216 }
1217
1218 if (buf == NULL) {
1219 goto ERROR_HANDLE;
1220 }
1221
1222 (VOID)memset_s(&info, sizeof(info), 0, sizeof(info));
1223
1224 struct block_operations *bops = (struct block_operations *)((struct drv_data *)part->dev->data)->ops;
1225 if ((bops == NULL) || (bops->geometry == NULL) ||
1226 (bops->geometry(part->dev, &info) != 0)) {
1227 goto ERROR_HANDLE;
1228 }
1229
1230 if (cmd == DISK_GET_SECTOR_COUNT) {
1231 *(UINT64 *)buf = part->sector_count;
1232 if (*(UINT64 *)buf == 0) {
1233 goto ERROR_HANDLE;
1234 }
1235 } else if (cmd == DISK_GET_SECTOR_SIZE) {
1236 *(size_t *)buf = info.geo_sectorsize;
1237 } else if (cmd == DISK_GET_BLOCK_SIZE) { /* Get erase block size in unit of sectors (UINT32) */
1238 if ((bops->ioctl == NULL) ||
1239 (bops->ioctl(part->dev, GET_ERASE_BLOCK_SIZE, (UINTPTR)buf) != 0)) {
1240 goto ERROR_HANDLE;
1241 }
1242 } else {
1243 goto ERROR_HANDLE;
1244 }
1245
1246 DISK_UNLOCK(&disk->disk_mutex);
1247 return ENOERR;
1248
1249ERROR_HANDLE:
1250 DISK_UNLOCK(&disk->disk_mutex);
1251 return VFS_ERROR;
1252}
1253
1255{
1256 INT32 result = ENOERR;
1257#ifdef LOSCFG_FS_FAT_CACHE
1258 los_part *part = get_part(drvID);
1259 los_disk *disk = NULL;
1260
1261 if (part == NULL) {
1262 return VFS_ERROR;
1263 }
1264 result = OsSdSync(part->disk_id);
1265 if (result != ENOERR) {
1266 PRINTK("[ERROR]disk_cache_clear SD sync failed!\n");
1267 return result;
1268 }
1269
1270 disk = get_disk(part->disk_id);
1271 if (disk == NULL) {
1272 return VFS_ERROR;
1273 }
1274
1275 DISK_LOCK(&disk->disk_mutex);
1276 result = BcacheClearCache(disk->bcache);
1277 DISK_UNLOCK(&disk->disk_mutex);
1278#endif
1279 return result;
1280}
1281
1282#ifdef LOSCFG_FS_FAT_CACHE
1283static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
1284{
1285 bc->prereadFun = NULL;
1286
1287 if (GetDiskUsbStatus(diskID) == FALSE) {
1288 if (BcacheAsyncPrereadInit(bc) == LOS_OK) {
1290 }
1291
1292#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
1293 BcacheSyncThreadInit(bc, diskID);
1294#endif
1295 }
1296
1297 if (OsReHookFuncAddDiskRef != NULL) {
1300 }
1301}
1302
1303static OsBcache *DiskCacheInit(UINT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver)
1304{
1305#define SECTOR_SIZE 512
1306
1307 OsBcache *bc = NULL;
1308 UINT32 sectorPerBlock = diskInfo->geo_sectorsize / SECTOR_SIZE;
1309 if (sectorPerBlock != 0) {
1310 sectorPerBlock = g_uwFatSectorsPerBlock / sectorPerBlock;
1311 if (sectorPerBlock != 0) {
1312 bc = BlockCacheInit(blkDriver, diskInfo->geo_sectorsize, sectorPerBlock,
1313 g_uwFatBlockNums, diskInfo->geo_nsectors / sectorPerBlock);
1314 }
1315 }
1316
1317 if (bc == NULL) {
1318 PRINT_ERR("disk_init : disk have not init bcache cache!\n");
1319 return NULL;
1320 }
1321
1322 DiskCacheThreadInit(diskID, bc);
1323 return bc;
1324}
1325
1326static VOID DiskCacheDeinit(los_disk *disk)
1327{
1328 UINT32 diskID = disk->disk_id;
1329 if (GetDiskUsbStatus(diskID) == FALSE) {
1330 if (BcacheAsyncPrereadDeinit(disk->bcache) != LOS_OK) {
1331 PRINT_ERR("Blib async preread deinit failed in %s, %d\n", __FUNCTION__, __LINE__);
1332 }
1333#ifdef LOSCFG_FS_FAT_CACHE_SYNC_THREAD
1335#endif
1336 }
1337
1338 BlockCacheDeinit(disk->bcache);
1339 disk->bcache = NULL;
1340
1341 if (OsReHookFuncDelDiskRef != NULL) {
1343 }
1344}
1345#endif
1346///磁盘结构体初始化,初始化 los_disk 结构体
1347static VOID DiskStructInit(const CHAR *diskName, INT32 diskID, const struct geometry *diskInfo,
1348 struct Vnode *blkDriver, los_disk *disk)
1349{
1350 size_t nameLen;
1351 disk->disk_id = diskID;
1352 disk->dev = blkDriver;
1353 disk->sector_start = 0;
1354 disk->sector_size = diskInfo->geo_sectorsize;
1355 disk->sector_count = diskInfo->geo_nsectors;
1356
1357 nameLen = strlen(diskName); /* caller los_disk_init has chek name */
1358
1359 if (disk->disk_name != NULL) {
1361 disk->disk_name = NULL;
1362 }
1363
1364 disk->disk_name = LOS_MemAlloc(m_aucSysMem0, (nameLen + 1));
1365 if (disk->disk_name == NULL) {
1366 PRINT_ERR("DiskStructInit alloc memory failed.\n");
1367 return;
1368 }
1369
1370 if (strncpy_s(disk->disk_name, (nameLen + 1), diskName, nameLen) != EOK) {
1371 PRINT_ERR("DiskStructInit strncpy_s failed.\n");
1373 disk->disk_name = NULL;
1374 return;
1375 }
1376 disk->disk_name[nameLen] = '\0';
1377 LOS_ListInit(&disk->head);
1378}
1379///磁盘分区和注册分区
1381{
1382 INT32 ret;
1383
1384 if (info != NULL) {//有分区信息则直接分区
1385 ret = DiskDivide(disk, info);
1386 if (ret != ENOERR) {
1387 PRINT_ERR("DiskDivide failed, ret = %d\n", ret);
1388 return ret;
1389 }
1390 } else {//木有分区信息,则先注册分区
1391 ret = DiskPartitionRegister(disk);
1392 if (ret != ENOERR) {
1393 PRINT_ERR("DiskPartitionRegister failed, ret = %d\n", ret);
1394 return ret;
1395 }
1396 }
1397 return ENOERR;
1398}
1399///磁盘反初始化
1401{
1402 los_part *part = NULL;
1403 char *diskName = NULL;
1404 CHAR devName[DEV_NAME_BUFF_SIZE];
1405 INT32 ret;
1406
1407 if (LOS_ListEmpty(&disk->head) == FALSE) {
1408 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);
1409 while (&part->list != &disk->head) {
1410 diskName = (disk->disk_name == NULL) ? "null" : disk->disk_name;
1411 ret = snprintf_s(devName, sizeof(devName), sizeof(devName) - 1, "%s%c%d",
1412 diskName, 'p', disk->part_count - 1);
1413 if (ret < 0) {
1414 return -ENAMETOOLONG;
1415 }
1416 DiskPartDelFromDisk(disk, part);//从磁盘删除分区
1417 (VOID)unregister_blockdriver(devName);//注销块驱动程序
1418 DiskPartRelease(part);//释放分区信息
1419
1420 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);//下一个分区内容
1421 }
1422 }
1423
1424 DISK_LOCK(&disk->disk_mutex);
1425
1426#ifdef LOSCFG_FS_FAT_CACHE
1427 DiskCacheDeinit(disk);
1428#else
1429 if (disk->buff != NULL) {
1430 free(disk->buff);
1431 }
1432#endif
1433
1434 disk->dev = NULL;
1435 DISK_UNLOCK(&disk->disk_mutex);
1436 (VOID)unregister_blockdriver(disk->disk_name);
1437 if (disk->disk_name != NULL) {
1439 disk->disk_name = NULL;
1440 }
1441 ret = pthread_mutex_destroy(&disk->disk_mutex);
1442 if (ret != 0) {
1443 PRINT_ERR("%s %d, mutex destroy failed, ret = %d\n", __FUNCTION__, __LINE__, ret);
1444 return -EFAULT;
1445 }
1446
1447 disk->disk_status = STAT_UNUSED;
1448
1449 return ENOERR;
1450}
1451///磁盘初始化
1452static UINT32 OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk,
1453 struct geometry *diskInfo, struct Vnode *blkDriver)
1454{
1455 pthread_mutexattr_t attr;
1456#ifdef LOSCFG_FS_FAT_CACHE
1457 OsBcache *bc = DiskCacheInit((UINT32)diskID, diskInfo, blkDriver);
1458 if (bc == NULL) {
1459 return VFS_ERROR;
1460 }
1461 disk->bcache = bc;
1462#endif
1463
1464 (VOID)pthread_mutexattr_init(&attr);
1465 attr.type = PTHREAD_MUTEX_RECURSIVE;
1466 (VOID)pthread_mutex_init(&disk->disk_mutex, &attr);
1467
1468 DiskStructInit(diskName, diskID, diskInfo, blkDriver, disk);
1469
1470#ifndef LOSCFG_FS_FAT_CACHE
1471 disk->buff = malloc(diskInfo->geo_sectorsize * DISK_DIRECT_BUFFER_SIZE);
1472 if (disk->buff == NULL) {
1473 PRINT_ERR("OsDiskInitSub: direct buffer of disk init failed\n");
1474 return VFS_ERROR;
1475 }
1476#endif
1477
1478 return ENOERR;
1479}
1480///磁盘初始化
1481INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops,
1482 VOID *priv, INT32 diskID, VOID *info)
1483{
1484 struct geometry diskInfo;
1485 struct Vnode *blkDriver = NULL;
1486 los_disk *disk = get_disk(diskID);
1487 INT32 ret;
1488 //参数检查
1489 if ((diskName == NULL) || (disk == NULL) ||
1490 (disk->disk_status != STAT_UNREADY) || (strlen(diskName) > DISK_NAME)) {
1491 return VFS_ERROR;
1492 }
1493 //注册块设备驱动,设备驱动程序由设备提供
1494 if (register_blockdriver(diskName, bops, RWE_RW_RW, priv) != 0) {
1495 PRINT_ERR("disk_init : register %s fail!\n", diskName);
1496 return VFS_ERROR;
1497 }
1498
1499 VnodeHold();
1500 ret = VnodeLookup(diskName, &blkDriver, 0);
1501 if (ret < 0) {
1502 VnodeDrop();
1503 ret = ENOENT;
1504 goto DISK_FIND_ERROR;
1505 }
1506 struct block_operations *bops2 = (struct block_operations *)((struct drv_data *)blkDriver->data)->ops;
1507 //块操作,块是文件系统层面的概念,块(Block)是文件系统存取数据的最小单位,一般大小是4KB
1508 if ((bops2 == NULL) || (bops2->geometry == NULL) || (bops2->geometry(blkDriver, &diskInfo) != 0)) {
1509 goto DISK_BLKDRIVER_ERROR;
1510 }
1511
1512 if (diskInfo.geo_sectorsize < DISK_MAX_SECTOR_SIZE) {
1513 goto DISK_BLKDRIVER_ERROR;
1514 }
1515
1516 ret = OsDiskInitSub(diskName, diskID, disk, &diskInfo, blkDriver);
1517 if (ret != ENOERR) {
1518 (VOID)DiskDeinit(disk);
1519 VnodeDrop();
1520 return VFS_ERROR;
1521 }
1522 VnodeDrop();
1523 if (DiskDivideAndPartitionRegister(info, disk) != ENOERR) {
1524 (VOID)DiskDeinit(disk);
1525 return VFS_ERROR;
1526 }
1527
1528 disk->disk_status = STAT_INUSED;//磁盘状态变成使用中
1529 if (info != NULL) {//https://www.huaweicloud.com/articles/bcdefd0d9da5de83d513123ef3aabcf0.html
1530 disk->type = EMMC;//eMMC 是 embedded MultiMediaCard 的简称
1531 } else {
1532 disk->type = OTHERS;
1533 }
1534 return ENOERR;
1535
1536DISK_BLKDRIVER_ERROR:
1537 PRINT_ERR("disk_init : register %s ok but get disk info fail!\n", diskName);
1538 VnodeDrop();
1539DISK_FIND_ERROR:
1540 (VOID)unregister_blockdriver(diskName);//注销块设备驱动
1541 return VFS_ERROR;
1542}
1543///磁盘反初始化
1545{
1546 int ret;
1547 los_disk *disk = get_disk(diskID);
1548 if (disk == NULL) {
1549 return -EINVAL;
1550 }
1551 ret = ForceUmountDev(disk->dev);
1552 PRINTK("warning: %s lost, force umount ret = %d\n", disk->disk_name, ret);
1553
1554 DISK_LOCK(&disk->disk_mutex);
1555
1556 if (disk->disk_status != STAT_INUSED) {
1557 DISK_UNLOCK(&disk->disk_mutex);
1558 return -EINVAL;
1559 }
1560
1561 disk->disk_status = STAT_UNREADY;//未格式化状态
1562 DISK_UNLOCK(&disk->disk_mutex);
1563
1564 return DiskDeinit(disk);
1565}
1566///磁盘同步,同步指的是缓存同步
1568{
1569 INT32 ret = ENOERR;
1570 los_disk *disk = get_disk(drvID);
1571 if (disk == NULL) {
1572 return EINVAL;
1573 }
1574
1575 DISK_LOCK(&disk->disk_mutex);
1576 if (disk->disk_status != STAT_INUSED) {
1577 DISK_UNLOCK(&disk->disk_mutex);
1578 return EINVAL;
1579 }
1580
1581#ifdef LOSCFG_FS_FAT_CACHE
1582 if (disk->bcache != NULL) {
1583 ret = BlockCacheSync(disk->bcache);
1584 }
1585#endif
1586
1587 DISK_UNLOCK(&disk->disk_mutex);
1588 return ret;
1589}
1590///设置磁盘块缓存
1591INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum)
1592{
1593#ifdef LOSCFG_FS_FAT_CACHE
1594
1595 INT32 ret;
1596 UINT32 intSave;
1597 OsBcache *bc = NULL;
1598 los_disk *disk = get_disk(drvID);
1599 if ((disk == NULL) || (sectorPerBlock == 0)) {
1600 return EINVAL;
1601 }
1602
1603 /*
1604 * Because we use UINT32 flag[BCACHE_BLOCK_FLAGS] in bcache for sectors bitmap tag, so it must
1605 * be less than 32 * BCACHE_BLOCK_FLAGS.
1606 */
1607 if (((sectorPerBlock % UNSIGNED_INTEGER_BITS) != 0) ||
1608 ((sectorPerBlock >> UNINT_LOG2_SHIFT) > BCACHE_BLOCK_FLAGS)) {
1609 return EINVAL;
1610 }
1611
1612 DISK_LOCK(&disk->disk_mutex);
1613
1614 if (disk->disk_status != STAT_INUSED) {
1615 goto ERROR_HANDLE;
1616 }
1617
1618 if (disk->bcache != NULL) {
1619 ret = BlockCacheSync(disk->bcache);
1620 if (ret != ENOERR) {
1621 DISK_UNLOCK(&disk->disk_mutex);
1622 return ret;
1623 }
1624 }
1625
1626 spin_lock_irqsave(&g_diskFatBlockSpinlock, intSave);
1627 DiskCacheDeinit(disk);
1628
1629 g_uwFatBlockNums = blockNum;
1630 g_uwFatSectorsPerBlock = sectorPerBlock;
1631
1632 bc = BlockCacheInit(disk->dev, disk->sector_size, sectorPerBlock, blockNum, disk->sector_count / sectorPerBlock);
1633 if ((bc == NULL) && (blockNum != 0)) {
1634 spin_unlock_irqrestore(&g_diskFatBlockSpinlock, intSave);
1635 DISK_UNLOCK(&disk->disk_mutex);
1636 return ENOMEM;
1637 }
1638
1639 if (bc != NULL) {
1640 DiskCacheThreadInit((UINT32)drvID, bc);
1641 }
1642
1643 disk->bcache = bc;
1644 spin_unlock_irqrestore(&g_diskFatBlockSpinlock, intSave);
1645 DISK_UNLOCK(&disk->disk_mutex);
1646 return ENOERR;
1647
1648ERROR_HANDLE:
1649 DISK_UNLOCK(&disk->disk_mutex);
1650 return EINVAL;
1651#else
1652 return VFS_ERROR;
1653#endif
1654}
1655///通过索引节点从磁盘中找分区信息
1656static los_part *OsPartFind(los_disk *disk, const struct Vnode *blkDriver)
1657{
1658 los_part *part = NULL;
1659
1660 DISK_LOCK(&disk->disk_mutex);//先上锁,disk->head上挂的是本磁盘所有的分区
1661 if ((disk->disk_status != STAT_INUSED) || (LOS_ListEmpty(&disk->head) == TRUE)) {
1662 goto EXIT;
1663 }
1664 part = LOS_DL_LIST_ENTRY(disk->head.pstNext, los_part, list);//拿出首个分区信息
1665 if (disk->dev == blkDriver) {//如果节点信息等于 disk->dev,注意此处是 disk 而不是 part->dev
1666 goto EXIT;//找到 goto
1667 }
1668
1669 while (&part->list != &disk->head) {//遍历链表
1670 if (part->dev == blkDriver) {//找到节点所在分区
1671 goto EXIT;
1672 }
1673 part = LOS_DL_LIST_ENTRY(part->list.pstNext, los_part, list);//下一个分区信息
1674 }
1675 part = NULL;
1676
1677EXIT:
1678 DISK_UNLOCK(&disk->disk_mutex);
1679 return part;
1680}
1681///通过索引节点找到分区信息
1682los_part *los_part_find(struct Vnode *blkDriver)
1683{
1684 INT32 i;
1685 los_disk *disk = NULL;
1686 los_part *part = NULL;
1687
1688 if (blkDriver == NULL) {
1689 return NULL;
1690 }
1691
1692 for (i = 0; i < SYS_MAX_DISK; i++) {//遍历所有磁盘
1693 disk = get_disk(i);
1694 if (disk == NULL) {
1695 continue;
1696 }
1697 part = OsPartFind(disk, blkDriver);//从磁盘中通过节点找分区信息
1698 if (part != NULL) {
1699 return part;
1700 }
1701 }
1702
1703 return NULL;
1704}
1705///访问分区
1707{
1708 los_part *part = NULL;
1709 struct Vnode *node = NULL;
1710
1711 VnodeHold();
1712 if (VnodeLookup(dev, &node, 0) < 0) {
1713 VnodeDrop();
1714 return VFS_ERROR;
1715 }
1716
1717 part = los_part_find(node);//通过节点找到分区
1718 VnodeDrop();
1719 if (part == NULL) {
1720 return VFS_ERROR;
1721 }
1722
1723 return ENOERR;
1724}
1725///设置分区名称
1727{
1728 size_t len;
1729 los_disk *disk = NULL;
1730
1731 if ((part == NULL) || (src == NULL)) {
1732 return VFS_ERROR;
1733 }
1734
1735 len = strlen(src);
1736 if ((len == 0) || (len >= DISK_NAME)) {
1737 return VFS_ERROR;
1738 }
1739
1740 disk = get_disk((INT32)part->disk_id);
1741 if (disk == NULL) {
1742 return VFS_ERROR;
1743 }
1744
1745 DISK_LOCK(&disk->disk_mutex);
1746 if (disk->disk_status != STAT_INUSED) {
1747 goto ERROR_HANDLE;
1748 }
1749
1750 part->part_name = (CHAR *)zalloc(len + 1);//分区名称内存需来自内核空间
1751 if (part->part_name == NULL) {
1752 PRINT_ERR("%s[%d] zalloc failure\n", __FUNCTION__, __LINE__);
1753 goto ERROR_HANDLE;
1754 }
1755
1756 if (strcpy_s(part->part_name, len + 1, src) != EOK) {
1757 free(part->part_name);
1758 part->part_name = NULL;
1759 goto ERROR_HANDLE;
1760 }
1761
1762 DISK_UNLOCK(&disk->disk_mutex);
1763 return ENOERR;
1764
1765ERROR_HANDLE:
1766 DISK_UNLOCK(&disk->disk_mutex);
1767 return VFS_ERROR;
1768}
1769
1770/**
1771 * @brief 添加 MMC分区
1772 \n MMC, 是一种闪存卡(Flash Memory Card)标准,它定义了 MMC 的架构以及访问 Flash Memory 的接口和协议。
1773 \n 而eMMC 则是对 MMC 的一个拓展,以满足更高标准的性能、成本、体积、稳定、易用等的需求。
1774 * @param info
1775 * @param sectorStart
1776 * @param sectorCount
1777 * @return INT32
1778 */
1779INT32 add_mmc_partition(struct disk_divide_info *info, size_t sectorStart, size_t sectorCount)
1780{
1781 UINT32 index, i;
1782
1783 if (info == NULL) {
1784 return VFS_ERROR;
1785 }
1786 //磁盘判断
1787 if ((info->part_count >= MAX_DIVIDE_PART_PER_DISK) || (sectorCount == 0)) {
1788 return VFS_ERROR;
1789 }
1790 //扇区判断
1791 if ((sectorCount > info->sector_count) || ((info->sector_count - sectorCount) < sectorStart)) {
1792 return VFS_ERROR;
1793 }
1794
1795 index = info->part_count;
1796 for (i = 0; i < index; i++) {//验证目的是确保分区的顺序,扇区顺序从小到大排列
1797 if (sectorStart < (info->part[i].sector_start + info->part[i].sector_count)) {
1798 return VFS_ERROR;
1799 }
1800 }
1801
1802 info->part[index].sector_start = sectorStart;//开始扇区
1803 info->part[index].sector_count = sectorCount;//扇区总数
1804 info->part[index].type = EMMC;//分区类型
1805 info->part_count++;//分区数量增加,鸿蒙分区数量上限默认是80个.
1806
1807 return ENOERR;
1808}
1809///OHOS #partinfo /dev/mmcblk0p0 命令输出信息
1811{
1812 if ((part == NULL) || (part->dev == NULL)) {
1813 PRINT_ERR("part is NULL\n");
1814 return;
1815 }
1816
1817 PRINTK("\npart info :\n");
1818 PRINTK("disk id : %u\n", part->disk_id); //磁盘ID
1819 PRINTK("part_id in system: %u\n", part->part_id); //在整个系统的分区ID
1820 PRINTK("part no in disk : %u\n", part->part_no_disk);//在磁盘分区的ID
1821 PRINTK("part no in mbr : %u\n", part->part_no_mbr);//主分区ID
1822 PRINTK("part filesystem : %02X\n", part->filesystem_type);//文件系统(FAT | NTFS)
1823 PRINTK("part sec start : %llu\n", part->sector_start);//开始扇区
1824 PRINTK("part sec count : %llu\n", part->sector_count);//扇区大小
1825}
1826///通过磁盘ID 擦除磁盘信息
1827#ifdef LOSCFG_DRIVERS_MMC
1828ssize_t StorageBlockMmcErase(uint32_t blockId, size_t secStart, size_t secNr);
1829#endif
1830
1831INT32 EraseDiskByID(UINT32 diskID, size_t startSector, UINT32 sectors)
1832{
1833 INT32 ret = VFS_ERROR;
1834#ifdef LOSCFG_DRIVERS_MMC //使能MMC
1835 los_disk *disk = get_disk((INT32)diskID);//找到磁盘信息
1836 if (disk != NULL) {
1837 ret = StorageBlockMmcErase(diskID, startSector, sectors);
1838 }//..\code-2.0-canary\device\hisilicon\third_party\uboot\u-boot-2020.01\cmd\mmc.c
1839#endif
1840
1841 return ret;
1842}
1843
VOID ResumeAsyncPreread(OsBcache *arg1, const OsBcacheBlock *arg2)
Definition: bcache.c:1169
OsBcache * BlockCacheInit(struct Vnode *devNode, UINT32 sectorSize, UINT32 sectorPerBlock, UINT32 blockNum, UINT64 blockCount)
Definition: bcache.c:1065
INT32 BlockCacheWrite(OsBcache *bc, const UINT8 *buf, UINT32 *len, UINT64 sector)
写块设备缓存
Definition: bcache.c:892
INT32 BcacheClearCache(OsBcache *bc)
Definition: bcache.c:706
VOID BlockCacheDeinit(OsBcache *bcache)
Definition: bcache.c:1122
INT32 OsSdSync(INT32 id)
Definition: bcache.c:956
INT32 BlockCacheSync(OsBcache *bc)
块缓存同步
Definition: bcache.c:951
VOID BcacheSyncThreadInit(OsBcache *bc, INT32 id)
块缓存同步任务初始化,开了个内核任务.
Definition: bcache.c:1037
INT32 BlockCacheRead(OsBcache *bc, UINT8 *buf, UINT32 *len, UINT64 sector, BOOL useRead)
读块设备缓存
Definition: bcache.c:824
UINT32 BcacheAsyncPrereadInit(OsBcache *bc)
Definition: bcache.c:1184
VOID BcacheSyncThreadDeinit(const OsBcache *bc)
Definition: bcache.c:1055
UINT32 BcacheAsyncPrereadDeinit(OsBcache *bc)
Definition: bcache.c:1210
los_disk * los_get_mmcdisk_bytype(UINT8 type)
Definition: disk.c:226
static INT32 DiskPartitionMemZalloc(size_t boundary, size_t size, CHAR **gptBuf, CHAR **partitionBuf)
磁盘分区内存申请
Definition: disk.c:453
static INT32 DiskAddPart(los_disk *disk, UINT64 sectorStart, UINT64 sectorCount, BOOL IsValidPart)
Definition: disk.c:349
static UINT32 OsDiskInitSub(const CHAR *diskName, INT32 diskID, los_disk *disk, struct geometry *diskInfo, struct Vnode *blkDriver)
磁盘初始化
Definition: disk.c:1452
static INT32 OsMBRInfoGet(struct Vnode *blkDrv, CHAR *mbrBuf)
获取MBR信息,即特殊扇区信息,在MBR硬盘中,分区信息直接存储于主引导记录(MBR)中(主引导记录中还存储着系统的引导程序)。
Definition: disk.c:619
static CHAR GPTPartitionTypeRecognition(const CHAR *parBuf)
GPT分区类型识别
Definition: disk.c:437
static OsBcache * DiskCacheInit(UINT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver)
Definition: disk.c:1303
ssize_t StorageBlockMmcErase(uint32_t blockId, size_t secStart, size_t secNr)
通过磁盘ID 擦除磁盘信息
INT32 EraseDiskByID(UINT32 diskID, size_t startSector, UINT32 sectors)
Definition: disk.c:1831
static INT32 OsPrimaryPartitionRecognition(const CHAR *mbrBuf, struct disk_divide_info *info, INT32 *extendedPos, INT32 *mbrCount)
识别主分区
Definition: disk.c:662
los_disk g_sysDisk[SYS_MAX_DISK]
支持挂载的磁盘总数量 5个
Definition: disk.c:76
static UINT32 OsReHookFuncAddDiskRef(StorageHookFunction handler, VOID *param) __attribute__((weakref("osReHookFuncAdd")))
static INT32 DiskPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
识别磁盘分区信息 https://blog.csdn.net/Hilavergil/article/details/79270379
Definition: disk.c:728
static VOID DiskCacheDeinit(los_disk *disk)
Definition: disk.c:1326
static INT32 GPTInfoGet(struct Vnode *blkDrv, CHAR *gptBuf)
获取GPT信息,是GPT还是MBR取决于磁盘上放的内容
Definition: disk.c:478
static los_part * DiskPartAllocate(struct Vnode *dev, UINT64 start, UINT64 count)
分配一个磁盘分区,必须要有索引节点才给分配.
Definition: disk.c:303
static BOOL GetDiskUsbStatus(UINT32 diskID)
Definition: disk.c:257
static VOID DiskCacheThreadInit(UINT32 diskID, OsBcache *bc)
Definition: disk.c:1283
static VOID DiskPartDelFromDisk(los_disk *disk, los_part *part)
从磁盘上删除分区
Definition: disk.c:297
static INT32 OsGPTPartitionRecognitionSub(struct disk_divide_info *info, const CHAR *partitionBuf, UINT32 *partitionCount, UINT64 partitionStart, UINT64 partitionEnd)
解析GPT分区内容
Definition: disk.c:498
static INT32 OsEBRInfoGet(struct Vnode *blkDrv, const struct disk_divide_info *info, CHAR *ebrBuf, const CHAR *mbrBuf)
Definition: disk.c:641
static VOID DiskPartAddToDisk(los_disk *disk, los_part *part)
磁盘增加一个分区
Definition: disk.c:289
static INT32 DiskGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info)
Definition: disk.c:567
UINT32 g_uwFatBlockNums
块数量 默认28
Definition: disk.c:80
static UINT32 OsReHookFuncDelDiskRef(StorageHookFunction handler) __attribute__((weakref("osReHookFuncDel")))
static INT32 disk_write_directly(los_disk *disk, const VOID *buf, UINT64 sector, UINT32 count)
Definition: disk.c:875
VOID SetFatSectorsPerBlock(UINT32 sectorsPerBlock)
设置FAR每块扇区数
Definition: disk.c:125
static VOID DiskStructInit(const CHAR *diskName, INT32 diskID, const struct geometry *diskInfo, struct Vnode *blkDriver, los_disk *disk)
磁盘结构体初始化,初始化 los_disk 结构体
Definition: disk.c:1347
UINT32 GetFatBlockNums(VOID)
Definition: disk.c:110
los_part g_sysPart[SYS_MAX_PART]
支持磁盘的分区总数量 5*16,每个磁盘最大分16个区
Definition: disk.c:77
UINT32 g_usbMode
Definition: disk.c:85
spinlock_t g_diskFatBlockSpinlock
磁盘Fat块自旋锁
Definition: disk.c:83
static VOID DiskPartRelease(los_part *part)
清空分区信息
Definition: disk.c:330
UINT32 g_uwFatSectorsPerBlock
每块支持扇区数 默认64个扇区
Definition: disk.c:79
static INT32 DiskDeinit(los_disk *disk)
磁盘反初始化
Definition: disk.c:1400
VOID *(* StorageHookFunction)(VOID *)
Definition: disk.c:102
INT32 SetDiskPartName(los_part *part, const CHAR *src)
设置分区名称
Definition: disk.c:1726
VOID SetFatBlockNums(UINT32 blockNums)
Definition: disk.c:115
UINT32 GetFatSectorsPerBlock(VOID)
Definition: disk.c:120
static INT32 OsLogicalPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info, UINT32 extendedAddress, CHAR *ebrBuf, INT32 mbrCount)
识别扩展分区
Definition: disk.c:689
static los_part * OsPartFind(los_disk *disk, const struct Vnode *blkDriver)
通过索引节点从磁盘中找分区信息
Definition: disk.c:1656
INT32 DiskPartitionRegister(los_disk *disk)
磁盘分区注册
Definition: disk.c:786
static INT32 DiskDivide(los_disk *disk, struct disk_divide_info *info)
磁盘分区
Definition: disk.c:405
static INT32 DiskDivideAndPartitionRegister(struct disk_divide_info *info, los_disk *disk)
磁盘分区和注册分区
Definition: disk.c:1380
static UINT64 GetFirstPartStart(const los_part *part)
Definition: disk.c:281
static INT32 disk_read_directly(los_disk *disk, VOID *buf, UINT64 sector, UINT32 count)
Definition: disk.c:840
static INT32 OsGPTPartitionRecognition(struct Vnode *blkDrv, struct disk_divide_info *info, const CHAR *gptBuf, CHAR *partitionBuf, UINT32 *partitionCount)
识别GPT分区内容
Definition: disk.c:522
spinlock_t g_diskSpinlock
磁盘自锁锁
Definition: disk.c:82
@ STAT_UNUSED
Definition: disk.h:171
@ STAT_INUSED
Definition: disk.h:172
@ STAT_UNREADY
Definition: disk.h:173
INT32 add_mmc_partition(struct disk_divide_info *info, size_t sectorStart, size_t sectorCount)
添加 MMC分区 MMC, 是一种闪存卡(Flash Memory Card)标准,它定义了 MMC 的架构以及访问 Flash Memory 的接口和协议。 而eMMC 则是对 MMC 的一个...
Definition: disk.c:1779
INT32 los_disk_write(INT32 drvID, const VOID *buf, UINT64 sector, UINT32 count)
将buf内容写到指定扇区,
Definition: disk.c:970
INT32 los_disk_read(INT32 drvID, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
读磁盘数据
Definition: disk.c:911
INT32 los_disk_cache_clear(INT32 drvID)
Clear the bcache data
Definition: disk.c:1254
INT32 los_disk_init(const CHAR *diskName, const struct block_operations *bops, VOID *priv, INT32 diskID, VOID *info)
磁盘初始化
Definition: disk.c:1481
INT32 los_part_read(INT32 pt, VOID *buf, UINT64 sector, UINT32 count, BOOL useRead)
读分区上扇区内容
Definition: disk.c:1080
los_disk * get_disk(INT32 id)
Find disk driver.
Definition: disk.c:263
INT32 los_disk_set_bcache(INT32 drvID, UINT32 sectorPerBlock, UINT32 blockNum)
设置磁盘块缓存
Definition: disk.c:1591
INT32 los_get_diskid_byname(const CHAR *diskName)
通过名称查询使用中(STAT_INUSED)磁盘ID
Definition: disk.c:191
VOID OsSetUsbStatus(UINT32 diskID)
Set usb mode.
Definition: disk.c:242
INT32 los_disk_deinit(INT32 diskID)
磁盘反初始化
Definition: disk.c:1544
VOID show_part(los_part *part)
OHOS #partinfo /dev/mmcblk0p0 命令输出信息
Definition: disk.c:1810
los_part * get_part(INT32 id)
获取某个分区的描述符
Definition: disk.c:272
los_part * los_part_find(struct Vnode *blkDriver)
通过索引节点找到分区信息
Definition: disk.c:1682
INT32 los_part_access(const CHAR *dev, mode_t mode)
访问分区
Definition: disk.c:1706
INT32 los_disk_ioctl(INT32 drvID, INT32 cmd, VOID *buf)
Get information of disk driver.
Definition: disk.c:1027
INT32 los_alloc_diskid_byname(const CHAR *diskName)
通过名称分配磁盘ID
Definition: disk.c:134
INT32 los_part_write(INT32 pt, const VOID *buf, UINT64 sector, UINT32 count)
将数据写入指定分区的指定扇区
Definition: disk.c:1136
VOID OsClearUsbStatus(UINT32 diskID)
Set usb mode.
Definition: disk.c:249
INT32 los_part_ioctl(INT32 pt, INT32 cmd, VOID *buf)
Get information of chosen partition.
Definition: disk.c:1193
INT32 los_disk_sync(INT32 drvID)
磁盘同步,同步指的是缓存同步
Definition: disk.c:1567
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
Definition: los_list.h:104
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListTailInsert(LOS_DL_LIST *list, LOS_DL_LIST *node)
Insert a node to the tail of a doubly linked list.
Definition: los_list.h:244
LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListDelete(LOS_DL_LIST *node)
Definition: los_list.h:292
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
Identify whether a specified doubly linked list is empty. | 判断链表是否为空
Definition: los_list.h:321
VOID * LOS_MemAlloc(VOID *pool, UINT32 size)
从指定内存池中申请size长度的内存,注意这可不是从内核堆空间中申请内存
Definition: los_memory.c:1123
UINT32 LOS_MemFree(VOID *pool, VOID *ptr)
释放从指定动态内存中申请的内存
Definition: los_memory.c:1369
UINT8 * m_aucSysMem0
异常交互动态内存池地址的起始地址,当不支持异常交互特性时,m_aucSysMem0等于m_aucSysMem1。
Definition: los_memory.c:107
__attribute__((aligned(MMU_DESCRIPTOR_L1_SMALL_ENTRY_NUMBERS)))
Definition: los_arch_mmu.c:98
signed int INT32
Definition: los_typedef.h:60
unsigned long VADDR_T
Definition: los_typedef.h:208
long unsigned int UINT64
Definition: los_typedef.h:66
INT64 ssize_t
Definition: los_typedef.h:79
unsigned char UINT8
Definition: los_typedef.h:55
unsigned long UINTPTR
Definition: los_typedef.h:68
unsigned int UINT32
Definition: los_typedef.h:57
char CHAR
Definition: los_typedef.h:63
size_t BOOL
Definition: los_typedef.h:88
STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len)
虚拟地址[vaddr,vaddr + len]是否在用户空间
Definition: los_vm_map.h:281
void * zalloc(size_t size)
Definition: malloc.c:91
void * memalign(size_t boundary, size_t size)
Definition: malloc.c:112
void * malloc(size_t size)
动态分配内存块大小
Definition: malloc.c:81
void free(void *ptr)
释放ptr所指向的内存空间
Definition: malloc.c:66
int ForceUmountDev(struct Vnode *dev)
int pthread_mutex_destroy(pthread_mutex_t *mutex)
销毁互斥锁
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexAttr)
初始化互斥锁。 如果 mutexAttr 为 NULL,则使用默认属性。
int pthread_mutexattr_init(pthread_mutexattr_t *attr)
初始化互斥锁属性
Definition: pthread_mutex.c:65
struct pthread_mutex disk_mutex
Definition: disk.h:191
CHAR * disk_name
Definition: disk.h:189
OsBcache * bcache
Definition: disk.h:183
UINT32 disk_id
Definition: disk.h:177
UINT8 type
Definition: disk.h:188
LOS_DL_LIST head
Definition: disk.h:190
UINT64 sector_start
Definition: disk.h:186
UINT32 sector_size
Definition: disk.h:185
struct Vnode * dev
Definition: disk.h:181
UINT32 disk_status
Definition: disk.h:178
UINT32 part_count
Definition: disk.h:179
UINT8 * buff
Definition: disk.h:193
UINT64 sector_count
Definition: disk.h:187
UINT32 part_id
Definition: disk.h:199
UINT32 disk_id
Definition: disk.h:198
UINT32 part_no_disk
Definition: disk.h:200
LOS_DL_LIST list
Definition: disk.h:215
struct Vnode * dev
Definition: disk.h:205
UINT64 sector_count
Definition: disk.h:211
CHAR * part_name
Definition: disk.h:206
UINT8 filesystem_type
Definition: disk.h:203
UINT32 part_no_mbr
Definition: disk.h:201
UINT64 sector_start
Definition: disk.h:207
UINT8 type
Definition: disk.h:204
struct LOS_DL_LIST * pstNext
Definition: los_list.h:84
vnode并不包含文件名,因为 vnode和文件名是 1:N 的关系
Definition: vnode.h:164
void * data
Definition: vnode.h:176
UINT32 part_count
Definition: disk.h:227
UINT64 sector_count
Definition: disk.h:225
struct partition_info part[MAX_DIVIDE_PART_PER_DISK+MAX_PRIMARY_PART_PER_DISK]
Definition: disk.h:232
UINT32 sector_size
Definition: disk.h:226
UINT8 type
Definition: disk.h:219
UINT64 sector_count
Definition: disk.h:221
UINT64 sector_start
Definition: disk.h:220
BcachePrereadFun prereadFun
Definition: bcache.h:109
UINT32 sectorSize
Definition: bcache.h:101
ARG_NUM_3 ARG_NUM_1 ARG_NUM_2 ARG_NUM_2 ARG_NUM_3 ARG_NUM_1 ARG_NUM_4 ARG_NUM_2 ARG_NUM_2 ARG_NUM_5 ARG_NUM_2 ARG_NUM_0 ARG_NUM_2 ARG_NUM_1 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_4 ARG_NUM_5 ARG_NUM_6 ARG_NUM_3 ARG_NUM_5 ARG_NUM_7 ARG_NUM_1 ARG_NUM_4 ARG_NUM_5 ARG_NUM_4 ARG_NUM_7 ARG_NUM_2 ARG_NUM_3 ARG_NUM_7 ARG_NUM_7 ARG_NUM_3 ARG_NUM_3 ARG_NUM_3 ARG_NUM_7 ARG_NUM_3 ARG_NUM_2 char ARG_NUM_2 ARG_NUM_1 ARG_NUM_0 ARG_NUM_0 ARG_NUM_3 void ARG_NUM_1 ARG_NUM_0 unsigned ARG_NUM_0 ARG_NUM_2 ARG_NUM_3 ARG_NUM_2 ARG_NUM_5 ARG_NUM_3 ARG_NUM_3 ARG_NUM_4 ARG_NUM_1 ARG_NUM_1 ARG_NUM_3 ARG_NUM_2 mode_t
if(tv==NULL)
Definition: time.c:430
INT32 LOS_CopyToKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
将用户空间的数据拷贝到内核空间
Definition: user_copy.c:101
INT32 LOS_CopyFromKernel(VOID *dest, UINT32 max, const VOID *src, UINT32 count)
将内核数据拷贝到用户空间
Definition: user_copy.c:88
int VnodeDrop(void)
归还锁
Definition: vnode.c:292
int VnodeHold(void)
拿锁,封装互斥量
Definition: vnode.c:283
int VnodeLookup(const char *path, struct Vnode **vnode, uint32_t flags)
通过路径查询vnode节点
Definition: vnode.c:491