Changeset 1912
- Timestamp:
- 02/24/09 20:57:26 (3 years ago)
- Location:
- Whitix/trunk/fs/fat
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
Whitix/trunk/fs/fat/fat.c
r1909 r1912 229 229 struct Buffer* buff; 230 230 231 DWORD freeClusters = sbInfo->freeClusters; 232 231 233 /* Cannot allocate clusters to the root directory in FAT12/16 */ 232 234 if (sbInfo->fatType != 32 && vNode->id == FAT_ROOT_ID) … … 283 285 *lastCluster=ret; 284 286 287 freeClusters--; 288 289 /* If we've got FAT32 and a valid number of free clusters, update it. */ 290 if (sbInfo->fatType == 32 && sbInfo->freeClusters != -1) 291 { 292 sbInfo->freeClusters = freeClusters; 293 SuperSetDirty(vNode->superBlock); 294 } 295 285 296 return 0; 286 297 } … … 294 305 int fromNum = number; 295 306 307 DWORD freeClusters = sbInfo->freeClusters; 308 296 309 if (sbInfo->fatType != 32 && !vNode->id) 297 310 return -EPERM; … … 307 320 { 308 321 cluster=FatAccess(vNode->superBlock, cluster,-1); 322 323 freeClusters++; 324 309 325 if (cluster >= sbInfo->invalidCluster) 310 {311 KePrint("FatRemoveClusters: %d\n",number);312 326 return -EINVAL; 313 }314 327 315 328 --number; … … 331 344 fatVNodeInfo->startCluster=0; /* Since it doesn't have one anymore */ 332 345 346 /* If we've got FAT32 and a valid number of free clusters, update it. */ 347 if (sbInfo->fatType == 32 && sbInfo->freeClusters != -1) 348 { 349 sbInfo->freeClusters = freeClusters; 350 SuperSetDirty(vNode->superBlock); 351 } 352 333 353 return 0; 334 354 } -
Whitix/trunk/fs/fat/fat.h
r1668 r1912 125 125 }PACKED; 126 126 127 struct FatFsInfo 128 { 129 DWORD reserved1; 130 DWORD signature; 131 DWORD freeClusters; 132 DWORD nextCluster; 133 DWORD reserved2; 134 }; 135 127 136 struct FatDirEntry 128 137 { … … 155 164 struct FatSbInfo 156 165 { 157 DWORD fatStart,fatLength,rootDirStart,rootDirLength, rootDirEnts; 158 DWORD firstDataSector,totalDataSectors,clusterLength,secsPerClus; 159 DWORD fatType,invalidCluster,numFats; 166 /* FAT information */ 167 DWORD fatStart, fatLength, fatType, invalidCluster, numFats; 168 169 /* Root directory information */ 170 DWORD rootDirStart, rootDirLength, rootDirEnts; 171 172 /* Data sector and cluster layout */ 173 DWORD firstDataSector,totalDataSectors, clusterLength, secsPerClus; 174 175 /* Values that are only updated on FAT32 */ 176 DWORD freeClusters, fsInfoSector; 160 177 }; 161 178 -
Whitix/trunk/fs/fat/super.c
r1909 r1912 27 27 #include "fat.h" 28 28 29 int FatWriteSuper(struct VfsSuperBlock* superBlock); 30 29 31 struct SuperBlockOps fatSbOps= 30 32 { 31 33 .readVNode = FatReadVNode, 32 34 .writeVNode = FatWriteVNode, 35 .writeSuper = FatWriteSuper, 33 36 }; 34 37 … … 44 47 }; 45 48 49 /* Update the freeClusters in the FsInfo sector on FAT32 */ 50 int FatWriteSuper(struct VfsSuperBlock* superBlock) 51 { 52 struct FatSbInfo* sbInfo; 53 struct FatFsInfo* info; 54 struct Buffer* buff; 55 DWORD prevSize = superBlock->sDevice->softBlockSize; 56 57 sbInfo = FatGetSbPriv(superBlock); 58 59 if (sbInfo->fatType != 32) 60 return 0; 61 62 /* Need this to write the correct FsInfo sector. It will throw all blocks 63 * out of cache, but if we're calling this, we're either syncing or 64 * freeing the super typically. 65 */ 66 67 BlockSetSize(superBlock->sDevice, superBlock->sDevice->blockSize); 68 69 buff = BlockRead(superBlock->sDevice, sbInfo->fsInfoSector); 70 71 info = (struct FatFsInfo*)(buff->data + 0x1E0); 72 info->freeClusters = sbInfo->freeClusters; 73 74 BlockWrite(buff->device, buff); 75 76 BlockSetSize(superBlock->sDevice, prevSize); 77 78 return 0; 79 } 80 81 int FatReadFsInfo(struct VfsSuperBlock* superBlock, unsigned long fsInfoSector) 82 { 83 struct Buffer* buff; 84 struct FatFsInfo* info; 85 struct FatSbInfo* sbInfo; 86 BYTE* data; 87 int ret = 0; 88 89 buff = BlockRead(superBlock->sDevice, fsInfoSector); 90 91 if (!buff) 92 return -EIO; 93 94 data = (BYTE*)(buff->data); 95 info = (struct FatFsInfo*)(data + 0x1E0); 96 97 /* Four byte signature at start of fsInfo sector. */ 98 if (data[0] != 0x52 || data[1] != 0x52 || data[2] != 0x61 || data[3] != 0x41) 99 { 100 ret = -EINVAL; 101 goto out; 102 } 103 104 /* TODO: Check info->signature? */ 105 106 /* Boot record signature at end of fsInfo sector. */ 107 if (data[510] != 0x55 || data[511] != 0xAA) 108 { 109 ret = -EINVAL; 110 goto out; 111 } 112 113 /* Store the number of free clusters, and update it again in WriteSuper. */ 114 sbInfo = FatGetSbPriv(superBlock); 115 116 sbInfo->freeClusters = info->freeClusters; 117 sbInfo->fsInfoSector = fsInfoSector; 118 119 KePrint("sbInfo->freeClusters = %#X\n", sbInfo->freeClusters); 120 121 out: 122 if (ret) 123 KePrint(KERN_DEBUG "FAT: Invalid FAT32 filesystem.\n"); 124 125 BlockFree(buff); 126 return ret; 127 } 128 46 129 struct VfsSuperBlock* FatReadSuper(struct StorageDevice* dev,int flags,char* data) 47 130 { … … 55 138 return NULL; 56 139 57 /* The soft block size at the start does not matter, so long as it is above 512, 58 * which is guaranteed. */ 59 60 buff=BlockRead(dev, 0); 140 /* This fixes issue #110. The soft block size at the start should be the 141 * device's sector size as we may read the second sector of the disk in 142 * FatReadFsInfo. */ 143 144 if (BlockSetSize(dev, dev->blockSize)) 145 return NULL; 146 147 buff = BlockRead(dev, 0); 148 61 149 if (!buff) 62 150 { … … 67 155 bootSec=(struct FatBootSector*)(buff->data); 68 156 69 if (bootSec->bytesPerSec != 512 && bootSec->bytesPerSec != 1024 && bootSec->bytesPerSec != 2048 && bootSec->bytesPerSec 70 != 4096) 157 if (bootSec->bytesPerSec != 512 && bootSec->bytesPerSec != 1024 && bootSec->bytesPerSec != 2048 && bootSec->bytesPerSec != 4096) 71 158 { 72 159 BlockFree(buff); … … 125 212 fatSbInfo->invalidCluster=0x0FFFFFF8; 126 213 } 127 214 215 /* Read the FsInfo structure if this is a FAT32 filesystem, so we can keep 216 * track of the free clusters and update it when necessary. */ 217 if (fatSbInfo->fatType == 32) 218 { 219 if (FatReadFsInfo(retVal, bootSec->fsInfo)) 220 goto fail; 221 } 222 128 223 KePrint(KERN_DEBUG "FAT: drive is a FAT%u volume\n",(DWORD)fatSbInfo->fatType); 129 224 … … 131 226 goto fail; 132 227 133 retVal->mount =VNodeGet(retVal, FAT_ROOT_ID);228 retVal->mount = VNodeGet(retVal, FAT_ROOT_ID); 134 229 135 230 if (!retVal->mount)
