root / Whitix / branches / hybrid / fs / fat / super.c

Revision 1, 4.2 kB (checked in by mtw07, 9 months ago)

Initial import of projects.

Line 
1/*  This file is part of Whitix.
2 *
3 *  Whitix is free software; you can redistribute it and/or modify
4 *  it under the terms of the GNU General Public License as published by
5 *  the Free Software Foundation; either version 2 of the License, or
6 *  (at your option) any later version.
7 *
8 *  Whitix is distributed in the hope that it will be useful,
9 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *  GNU General Public License for more details.
12 *
13 *  You should have received a copy of the GNU General Public License
14 *  along with Whitix; if not, write to the Free Software
15 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
16 *
17 */
18
19#include <console.h>
20#include <typedefs.h>
21#include <fs/vfs.h>
22#include <malloc.h>
23#include <error.h>
24#include <init.h>
25#include "fat.h"
26
27struct SuperBlockOps fatSbOps=
28{
29        .allocVNode = NULL,
30        .readVNode = FatReadVNode,
31        .writeVNode = FatWriteVNode,
32};
33
34struct VNodeOps fatVNodeOps=
35{
36        .create = FatCreate,
37        .remove = FatRemove,
38        .lookup = FatLookup,
39        .mkDir = FatMkDir,
40        .rmDir = FatRmDir,
41        .truncate = FatTruncate,
42        .blockMap= FatBlockMap,
43};
44
45struct VfsSuperBlock* FatReadSuper(struct StorageDevice* dev,int flags,char* data)
46{
47        struct FatBootSector* bootSec;
48        struct Buffer* buff;
49        struct VfsSuperBlock* retVal;
50        struct FatSbInfo* fatSbInfo;
51        DWORD clusterCount,totalSectors;
52
53        if (!dev)
54                return NULL;
55
56        /* The soft block size at the start does not matter, so long as it is above 512,
57         * which is guaranteed. */
58
59        buff=BlockRead(dev,0);
60        if (!buff)
61        {
62                printf("FAT: Failed to read superblock\n");
63                return NULL;
64        }
65
66        bootSec=(struct FatBootSector*)(buff->data);
67
68        if (bootSec->bytesPerSec != 512 && bootSec->bytesPerSec != 1024 && bootSec->bytesPerSec != 2048 && bootSec->bytesPerSec
69                != 4096)
70        {
71                BlockFree(buff);
72                return NULL;
73        }
74
75        retVal=VfsAllocSuper(dev,flags);
76        if (!retVal)
77                goto end;
78
79        retVal->sbOps=&fatSbOps;
80
81        /* Allocate the FAT-specific superblock structure */
82        fatSbInfo=(struct FatSbInfo*)malloc(sizeof(struct FatSbInfo));
83        if (!fatSbInfo)
84                goto fail;
85
86        retVal->privData=(void*)fatSbInfo;
87
88        /* Fill the structure with info */
89        fatSbInfo->fatStart=bootSec->reservedSectorCnt;
90
91        if (!bootSec->secsPerFat && bootSec->secsPerFat32)
92        {
93                /* Must be FAT32 then */
94                fatSbInfo->rootDirStart=bootSec->rootClus;
95                fatSbInfo->fatLength=bootSec->secsPerFat32;
96        }else{
97                fatSbInfo->rootDirStart=bootSec->reservedSectorCnt+(bootSec->numFats*bootSec->secsPerFat);
98                fatSbInfo->fatLength=bootSec->secsPerFat;
99        }
100
101        totalSectors=(bootSec->totalSecSmall) ? bootSec->totalSecSmall : bootSec->totalSectorsLarge;
102        fatSbInfo->rootDirLength=(bootSec->numRootDirEnts*sizeof(struct FatDirEntry))/bootSec->bytesPerSec; /* FAT32 doesn't use this */
103        fatSbInfo->firstDataSector=bootSec->reservedSectorCnt+(bootSec->numFats*fatSbInfo->fatLength)+fatSbInfo->rootDirLength;
104        fatSbInfo->clusterLength=bootSec->bytesPerSec*bootSec->sectorsPerClus;
105        fatSbInfo->secsPerClus=bootSec->sectorsPerClus;
106        fatSbInfo->totalDataSectors=totalSectors-fatSbInfo->firstDataSector;
107        fatSbInfo->numFats=bootSec->numFats;
108
109        clusterCount=fatSbInfo->totalDataSectors/bootSec->sectorsPerClus;
110
111        /* Set the FAT type and end of cluster marker, depending on the number of clusters */
112        if (clusterCount < 4085)
113        {
114                fatSbInfo->fatType=12;
115                fatSbInfo->invalidCluster=0xFF8;
116        }else if (clusterCount < 65525)
117        {
118                fatSbInfo->fatType=16;
119                fatSbInfo->invalidCluster=0xFFF8;
120        }else{
121                fatSbInfo->fatType=32;
122                fatSbInfo->invalidCluster=0xFFFFFF8;
123        }
124
125        printf("Drive is a FAT%u volume\n",(DWORD)fatSbInfo->fatType);
126
127        if (BlockSetSize(dev,bootSec->bytesPerSec))
128                goto fail;
129
130        retVal->mount=VNodeGet(retVal,FAT_ROOT_ID);
131
132        if (!retVal->mount)
133                goto fail;
134
135end:
136        if (buff->refs)
137                BlockFree(buff);
138        return retVal;
139
140fail:
141        /* privData is freed in VfsFreeSuper */
142        VfsFreeSuper(retVal);
143        retVal=NULL;
144        goto end;
145}
146
147static struct FileSystem fatFileSystem={
148        .name="FAT",
149        .readSuper=FatReadSuper,
150};
151
152int FatInit()
153{
154        return VfsRegisterFileSystem(&fatFileSystem);
155}
156
157void FatExit()
158{
159        VfsDeregisterFileSystem(&fatFileSystem);
160}
161
162FsInit(FatInit);
Note: See TracBrowser for help on using the browser.