/* If possible, merge segment with its neighbours - some segments, including s, may be destroyed in the process */ static void merge_segments(Addr a, UInt len) { Segment *s; Segment *next; vg_assert((a & (VKI_BYTES_PER_PAGE-1)) == 0); vg_assert((len & (VKI_BYTES_PER_PAGE-1)) == 0); a -= VKI_BYTES_PER_PAGE; len += VKI_BYTES_PER_PAGE; for(s = VG_(SkipList_Find)(&sk_segments, &a); s != NULL && s->addr < (a+len);) { next = VG_(SkipNode_Next)(&sk_segments, s); if (next && neighbours(s, next)) { Segment *rs; if (0) VG_(printf)("merge %p-%p with %p-%p\n", s->addr, s->addr+s->len, next->addr, next->addr+next->len); s->len += next->len; s = VG_(SkipNode_Next)(&sk_segments, next); rs = VG_(SkipList_Remove)(&sk_segments, &next->addr); vg_assert(next == rs); freeseg(next); } else s = next; } }
void do_logfs_journal_wl_pass(struct super_block *sb) { struct logfs_super *super = logfs_super(sb); struct logfs_area *area = super->s_journal_area; struct btree_head32 *head = &super->s_reserved_segments; u32 segno, ec; int i, err; log_journal("Journal requires wear-leveling.\n"); journal_for_each(i) if (super->s_journal_seg[i]) { btree_remove32(head, super->s_journal_seg[i]); logfs_set_segment_unreserved(sb, super->s_journal_seg[i], super->s_journal_ec[i]); super->s_journal_seg[i] = 0; super->s_journal_ec[i] = 0; } for (i = 0; i < super->s_no_journal_segs; i++) { segno = get_best_cand(sb, &super->s_reserve_list, &ec); super->s_journal_seg[i] = segno; super->s_journal_ec[i] = ec; logfs_set_segment_reserved(sb, segno); err = btree_insert32(head, segno, (void *)1, GFP_NOFS); BUG_ON(err); err = logfs_erase_segment(sb, segno, 1); BUG_ON(err); } freeseg(sb, area->a_segno); area->a_segno = super->s_journal_seg[0]; area->a_is_open = 0; area->a_used_bytes = 0; logfs_write_anchor(sb); err = logfs_write_sb(sb); BUG_ON(err); }
void do_logfs_journal_wl_pass(struct super_block *sb) { struct logfs_super *super = logfs_super(sb); struct logfs_area *area = super->s_journal_area; struct btree_head32 *head = &super->s_reserved_segments; u32 segno, ec; int i, err; log_journal("Journal requires wear-leveling.\n"); /* Drop old segments */ journal_for_each(i) if (super->s_journal_seg[i]) { btree_remove32(head, super->s_journal_seg[i]); logfs_set_segment_unreserved(sb, super->s_journal_seg[i], super->s_journal_ec[i]); super->s_journal_seg[i] = 0; super->s_journal_ec[i] = 0; } /* Get new segments */ for (i = 0; i < super->s_no_journal_segs; i++) { segno = get_best_cand(sb, &super->s_reserve_list, &ec); super->s_journal_seg[i] = segno; super->s_journal_ec[i] = ec; logfs_set_segment_reserved(sb, segno); err = btree_insert32(head, segno, (void *)1, GFP_KERNEL); BUG_ON(err); /* mempool should prevent this */ err = logfs_erase_segment(sb, segno, 1); BUG_ON(err); /* FIXME: remount-ro would be nicer */ } /* Manually move journal_area */ freeseg(sb, area->a_segno); area->a_segno = super->s_journal_seg[0]; area->a_is_open = 0; area->a_used_bytes = 0; /* Write journal */ logfs_write_anchor(sb); /* Write superblocks */ err = logfs_write_sb(sb); BUG_ON(err); }
int far pascal __loadds FS_MOUNT(unsigned short usFlag, /* flag */ struct vpfsi far * pvpfsi, /* pvpfsi */ struct vpfsd far * pvpfsd, /* pvpfsd */ unsigned short hVBP, /* hVPB */ char far * pBoot /* pBoot */) { PBOOTSECT pSect; PVOLINFO pVolInfo; PVOLINFO pNext, pPrev; USHORT usVolCount; USHORT hDupVBP; USHORT rc; P_DriverCaps pDevCaps; P_VolChars pVolChars; _asm push es; //_asm push bx; if (f32Parms.fMessageActive & LOG_FS) Message("FS_MOUNT for %c (%d):, flag = %d", pvpfsi->vpi_drive + 'A', pvpfsi->vpi_unit, usFlag); switch (usFlag) { case MOUNT_MOUNT : if (FSH_FINDDUPHVPB(hVBP, &hDupVBP)) hDupVBP = 0; pSect = (PBOOTSECT)pBoot; if (memicmp(pSect->FileSystem, "FAT32", 5)) { rc = ERROR_VOLUME_NOT_MOUNTED; goto FS_MOUNT_EXIT; } if (pSect->bpb.BytesPerSector != SECTOR_SIZE) { rc = ERROR_VOLUME_NOT_MOUNTED; goto FS_MOUNT_EXIT; } if(( ULONG )pSect->bpb.BytesPerSector * pSect->bpb.SectorsPerCluster > MAX_CLUSTER_SIZE ) { rc = ERROR_VOLUME_NOT_MOUNTED; goto FS_MOUNT_EXIT; } pvpfsi->vpi_vid = pSect->ulVolSerial; pvpfsi->vpi_bsize = pSect->bpb.BytesPerSector; pvpfsi->vpi_totsec = pSect->bpb.BigTotalSectors; pvpfsi->vpi_trksec = pSect->bpb.SectorsPerTrack; pvpfsi->vpi_nhead = pSect->bpb.Heads; memset(pvpfsi->vpi_text, 0, sizeof pvpfsi->vpi_text); memcpy(pvpfsi->vpi_text, pSect->VolumeLabel, sizeof pSect->VolumeLabel); pVolInfo = gdtAlloc(STORAGE_NEEDED, FALSE); if (!pVolInfo) { rc = ERROR_NOT_ENOUGH_MEMORY; goto FS_MOUNT_EXIT; } rc = FSH_FORCENOSWAP(SELECTOROF(pVolInfo)); if (rc) FatalMessage("FSH_FORCENOSWAP on VOLINFO Segment failed, rc=%u", rc); memset(pVolInfo, 0, (size_t)STORAGE_NEEDED); InitCache(ulCacheSectors); memcpy(&pVolInfo->BootSect, pSect, sizeof (BOOTSECT)); pVolInfo->ulActiveFatStart = pSect->bpb.ReservedSectors; if (pSect->bpb.ExtFlags & 0x0080) pVolInfo->ulActiveFatStart += pSect->bpb.BigSectorsPerFat * (pSect->bpb.ExtFlags & 0x000F); pVolInfo->ulStartOfData = pSect->bpb.ReservedSectors + pSect->bpb.BigSectorsPerFat * pSect->bpb.NumberOfFATs; pVolInfo->pBootFSInfo = (PBOOTFSINFO)(pVolInfo + 1); pVolInfo->pbFatSector = (PBYTE)(pVolInfo->pBootFSInfo + 1); pVolInfo->ulCurFatSector = -1L; pVolInfo->usClusterSize = pSect->bpb.BytesPerSector * pSect->bpb.SectorsPerCluster; pVolInfo->ulTotalClusters = (pSect->bpb.BigTotalSectors - pVolInfo->ulStartOfData) / pSect->bpb.SectorsPerCluster; pVolInfo->hVBP = hVBP; pVolInfo->hDupVBP = hDupVBP; pVolInfo->bDrive = pvpfsi->vpi_drive; pVolInfo->bUnit = pvpfsi->vpi_unit; pVolInfo->pNextVolInfo = NULL; pVolInfo->fFormatInProgress = FALSE; if (usDefaultRASectors == 0xFFFF) pVolInfo->usRASectors = (pVolInfo->usClusterSize / SECTOR_SIZE ) * 2; else pVolInfo->usRASectors = usDefaultRASectors; #if 1 if( pVolInfo->usRASectors > MAX_RASECTORS ) pVolInfo->usRASectors = MAX_RASECTORS; #else if (pVolInfo->usRASectors > (pVolInfo->usClusterSize / SECTOR_SIZE) * 4) pVolInfo->usRASectors = (pVolInfo->usClusterSize / SECTOR_SIZE ) * 4; #endif if (pSect->bpb.FSinfoSec != 0xFFFF) { ReadSector(pVolInfo, pSect->bpb.FSinfoSec, 1, pVolInfo->pbFatSector, DVIO_OPNCACHE); memcpy(pVolInfo->pBootFSInfo, pVolInfo->pbFatSector + FSINFO_OFFSET, sizeof (BOOTFSINFO)); } else memset(pVolInfo->pBootFSInfo, 0, sizeof (BOOTFSINFO)); *((PVOLINFO *)(pvpfsd->vpd_work)) = pVolInfo; if (!pGlobVolInfo) { pGlobVolInfo = pVolInfo; usVolCount = 1; } else { pNext = pGlobVolInfo; usVolCount = 1; if (pNext->bDrive == pvpfsi->vpi_drive && !pVolInfo->hDupVBP) pVolInfo->hDupVBP = pNext->hVBP; while (pNext->pNextVolInfo) { pNext = (PVOLINFO)pNext->pNextVolInfo; if (pNext->bDrive == pvpfsi->vpi_drive && !pVolInfo->hDupVBP) pVolInfo->hDupVBP = pNext->hVBP; usVolCount++; } pNext->pNextVolInfo = pVolInfo; usVolCount++; } if (f32Parms.fMessageActive & LOG_FS) Message("%u Volumes mounted!", usVolCount); rc = CheckWriteProtect(pVolInfo); if (rc && rc != ERROR_WRITE_PROTECT) { Message("Cannot access drive, rc = %u", rc); goto FS_MOUNT_EXIT; } if (rc == ERROR_WRITE_PROTECT) pVolInfo->fWriteProtected = TRUE; pVolInfo->fDiskCleanOnMount = pVolInfo->fDiskClean = GetDiskStatus(pVolInfo); if (!pVolInfo->fDiskCleanOnMount) Message("DISK IS DIRTY!"); if (pVolInfo->fWriteProtected) pVolInfo->fDiskCleanOnMount = TRUE; if (!pVolInfo->hDupVBP && (f32Parms.fCalcFree || pVolInfo->pBootFSInfo->ulFreeClusters == 0xFFFFFFFF || /*!pVolInfo->fDiskClean ||*/ pVolInfo->BootSect.bpb.FSinfoSec == 0xFFFF)) GetFreeSpace(pVolInfo); pDevCaps = pvpfsi->vpi_pDCS; pVolChars = pvpfsi->vpi_pVCS; if (pDevCaps->Capabilities & GDC_DD_Read2) Message("Read2 supported"); if (pDevCaps->Capabilities & GDC_DD_DMA_Word) Message("DMA on word alligned buffers supported"); if (pDevCaps->Capabilities & GDC_DD_DMA_Byte) Message("DMA on byte alligned buffers supported"); if (pDevCaps->Capabilities & GDC_DD_Mirror) Message("Disk Mirroring supported"); if (pDevCaps->Capabilities & GDC_DD_Duplex) Message("Disk Duplexing supported"); if (pDevCaps->Capabilities & GDC_DD_No_Block) Message("Strategy2 does not block"); if (pDevCaps->Capabilities & GDC_DD_16M) Message(">16M supported"); if (pDevCaps->Strategy2) { Message("Strategy2 address at %lX", pDevCaps->Strategy2); Message("ChgPriority address at %lX", pDevCaps->ChgPriority); pVolInfo->pfnStrategy = (STRATFUNC)pDevCaps->Strategy2; pVolInfo->pfnPriority = (STRATFUNC)pDevCaps->ChgPriority; } rc = 0; break; case MOUNT_ACCEPT : if (FSH_FINDDUPHVPB(hVBP, &hDupVBP)) hDupVBP = 0; if (pvpfsi->vpi_bsize != SECTOR_SIZE) { rc = ERROR_VOLUME_NOT_MOUNTED; goto FS_MOUNT_EXIT; } pVolInfo = gdtAlloc(STORAGE_NEEDED, FALSE); if (!pVolInfo) { rc = ERROR_NOT_ENOUGH_MEMORY; goto FS_MOUNT_EXIT; } rc = FSH_FORCENOSWAP(SELECTOROF(pVolInfo)); if (rc) FatalMessage("FSH_FORCENOSWAP on VOLINFO Segment failed, rc=%u", rc); memset(pVolInfo, 0, (size_t)STORAGE_NEEDED); //InitCache(ulCacheSectors); memset(&pVolInfo->BootSect, 0, sizeof (BOOTSECT)); pVolInfo->BootSect.bpb.BigTotalSectors = pvpfsi->vpi_totsec; pVolInfo->BootSect.bpb.BytesPerSector = pvpfsi->vpi_bsize; pVolInfo->fWriteProtected = FALSE; pVolInfo->fDiskCleanOnMount = FALSE; pVolInfo->hVBP = hVBP; pVolInfo->hDupVBP = hDupVBP; pVolInfo->bDrive = pvpfsi->vpi_drive; pVolInfo->bUnit = pvpfsi->vpi_unit; pVolInfo->pNextVolInfo = NULL; // the volume is being formatted pVolInfo->fFormatInProgress = TRUE; // fake values assuming sector == cluster pVolInfo->usClusterSize = pvpfsi->vpi_bsize; pVolInfo->ulTotalClusters = pvpfsi->vpi_totsec; pVolInfo->usRASectors = usDefaultRASectors; // undefined pVolInfo->ulStartOfData = 0; //*((PVOLINFO *)(pvpfsd->vpd_work)) = pVolInfo; if (!pGlobVolInfo) { pGlobVolInfo = pVolInfo; usVolCount = 1; } else { pNext = pGlobVolInfo; usVolCount = 1; if (pNext->bDrive == pvpfsi->vpi_drive && !pVolInfo->hDupVBP) pVolInfo->hDupVBP = pNext->hVBP; while (pNext->pNextVolInfo) { pNext = (PVOLINFO)pNext->pNextVolInfo; if (pNext->bDrive == pvpfsi->vpi_drive && !pVolInfo->hDupVBP) pVolInfo->hDupVBP = pNext->hVBP; usVolCount++; } pNext->pNextVolInfo = pVolInfo; usVolCount++; } if (f32Parms.fMessageActive & LOG_FS) Message("%u Volumes mounted!", usVolCount); pDevCaps = pvpfsi->vpi_pDCS; pVolChars = pvpfsi->vpi_pVCS; if (pDevCaps->Capabilities & GDC_DD_Read2) Message("Read2 supported"); if (pDevCaps->Capabilities & GDC_DD_DMA_Word) Message("DMA on word alligned buffers supported"); if (pDevCaps->Capabilities & GDC_DD_DMA_Byte) Message("DMA on byte alligned buffers supported"); if (pDevCaps->Capabilities & GDC_DD_Mirror) Message("Disk Mirroring supported"); if (pDevCaps->Capabilities & GDC_DD_Duplex) Message("Disk Duplexing supported"); if (pDevCaps->Capabilities & GDC_DD_No_Block) Message("Strategy2 does not block"); if (pDevCaps->Capabilities & GDC_DD_16M) Message(">16M supported"); if (pDevCaps->Strategy2) { Message("Strategy2 address at %lX", pDevCaps->Strategy2); Message("ChgPriority address at %lX", pDevCaps->ChgPriority); pVolInfo->pfnStrategy = (STRATFUNC)pDevCaps->Strategy2; pVolInfo->pfnPriority = (STRATFUNC)pDevCaps->ChgPriority; } rc = 0; break; case MOUNT_VOL_REMOVED: case MOUNT_RELEASE: pVolInfo = GetVolInfo(hVBP); if (!pVolInfo) { rc = ERROR_VOLUME_NOT_MOUNTED; goto FS_MOUNT_EXIT; } //if (!pVolInfo->hDupVBP) //{ usFlushVolume( pVolInfo, FLUSH_DISCARD, TRUE, PRIO_URGENT ); if (f32Parms.usDirtySectors) // vs UpdateFSInfo(pVolInfo); // MarkDiskStatus(pVolInfo, TRUE); //} // delete pVolInfo from the list if (pGlobVolInfo) { pNext = pPrev = pGlobVolInfo; // search for pVolInfo in the list while (pNext != pVolInfo) { pPrev = pNext; pNext = (PVOLINFO)pNext->pNextVolInfo; } // found if (pNext == pVolInfo) { if (pPrev == pVolInfo) // the very 1st list item pGlobVolInfo = NULL; else { // delete it pNext = pNext->pNextVolInfo; pPrev->pNextVolInfo = pNext; } usVolCount--; } } RemoveVolume(pVolInfo); freeseg(pVolInfo); rc = 0; break; default : rc = ERROR_NOT_SUPPORTED; break; } FS_MOUNT_EXIT: if (f32Parms.fMessageActive & LOG_FS) Message("FS_MOUNT returned %u\n", rc); //_asm int 3 //_asm pop bx; _asm pop es; return rc; }
/* This unmaps all the segments in the range [addr, addr+len); any partial mappings at the ends are truncated. */ void VG_(unmap_range)(Addr addr, UInt len) { Segment *s; Segment *next; static const Bool debug = False || mem_debug; Addr end; if (len == 0) return; len = PGROUNDUP(len); vg_assert(addr == PGROUNDDN(addr)); if (debug) VG_(printf)("unmap_range(%p, %d)\n", addr, len); end = addr+len; /* Everything must be page-aligned */ vg_assert((addr & (VKI_BYTES_PER_PAGE-1)) == 0); vg_assert((len & (VKI_BYTES_PER_PAGE-1)) == 0); for(s = VG_(SkipList_Find)(&sk_segments, &addr); s != NULL && s->addr < (addr+len); s = next) { Addr seg_end = s->addr + s->len; /* fetch next now in case we end up deleting this segment */ next = VG_(SkipNode_Next)(&sk_segments, s); if (debug) VG_(printf)("unmap: addr=%p-%p s=%p ->addr=%p-%p len=%d\n", addr, end, s, s->addr, seg_end, s->len); if (!VG_(seg_overlaps)(s, addr, len)) { if (debug) VG_(printf)(" (no overlap)\n"); continue; } /* 4 cases: */ if (addr > s->addr && addr < seg_end && end >= seg_end) { /* this segment's tail is truncated by [addr, addr+len) -> truncate tail */ s->len = addr - s->addr; if (debug) VG_(printf)(" case 1: s->len=%d\n", s->len); } else if (addr <= s->addr && end > s->addr && end < seg_end) { /* this segment's head is truncated by [addr, addr+len) -> truncate head */ Int delta = end - s->addr; if (debug) VG_(printf)(" case 2: s->addr=%p s->len=%d delta=%d\n", s->addr, s->len, delta); s->addr += delta; s->offset += delta; s->len -= delta; vg_assert(s->len != 0); } else if (addr <= s->addr && end >= seg_end) { /* this segment is completely contained within [addr, addr+len) -> delete segment */ Segment *rs = VG_(SkipList_Remove)(&sk_segments, &s->addr); vg_assert(rs == s); freeseg(s); if (debug) VG_(printf)(" case 3: s==%p deleted\n", s); } else if (addr > s->addr && end < seg_end) { /* [addr, addr+len) is contained within a single segment -> split segment into 3, delete middle portion */ Segment *middle, *rs; middle = VG_(split_segment)(addr); VG_(split_segment)(addr+len); vg_assert(middle->addr == addr); rs = VG_(SkipList_Remove)(&sk_segments, &addr); vg_assert(rs == middle); freeseg(rs); if (debug) VG_(printf)(" case 4: subrange %p-%p deleted\n", addr, addr+len); } } }
int far pascal FS_MOUNT(unsigned short usFlag, /* flag */ struct vpfsi far * pvpfsi, /* pvpfsi */ struct vpfsd far * pvpfsd, /* pvpfsd */ unsigned short hVBP, /* hVPB */ char far * pBoot /* pBoot */) { PBOOTSECT pSect; PVOLINFO pVolInfo; PVOLINFO pNext; USHORT usVolCount; USHORT hDupVBP; USHORT rc; P_DriverCaps pDevCaps; P_VolChars pVolChars; if (f32Parms.fMessageActive & LOG_FS) Message("FS_MOUNT for %c (%d):, flag = %d", pvpfsi->vpi_drive + 'A', pvpfsi->vpi_unit, usFlag); switch (usFlag) { case MOUNT_MOUNT : if (FSH_FINDDUPHVPB(hVBP, &hDupVBP)) hDupVBP = 0; pSect = (PBOOTSECT)pBoot; if (memicmp(pSect->FileSystem, "FAT32", 5)) { rc = ERROR_VOLUME_NOT_MOUNTED; goto FS_MOUNT_EXIT; } if (pSect->bpb.BytesPerSector != SECTOR_SIZE) { rc = ERROR_VOLUME_NOT_MOUNTED; goto FS_MOUNT_EXIT; } pvpfsi->vpi_vid = pSect->ulVolSerial; pvpfsi->vpi_bsize = pSect->bpb.BytesPerSector; pvpfsi->vpi_totsec = pSect->bpb.BigTotalSectors; pvpfsi->vpi_trksec = pSect->bpb.SectorsPerTrack; pvpfsi->vpi_nhead = pSect->bpb.Heads; memset(pvpfsi->vpi_text, 0, sizeof pvpfsi->vpi_text); memcpy(pvpfsi->vpi_text, pSect->VolumeLabel, sizeof pSect->VolumeLabel); pVolInfo = gdtAlloc(STORAGE_NEEDED, FALSE); if (!pVolInfo) { rc = ERROR_NOT_ENOUGH_MEMORY; goto FS_MOUNT_EXIT; } rc = FSH_FORCENOSWAP(SELECTOROF(pVolInfo)); if (rc) FatalMessage("FSH_FORCENOSWAP on VOLINFO Segment failed, rc=%u", rc); memset(pVolInfo, 0, (size_t)STORAGE_NEEDED); InitCache(ulCacheSectors); memcpy(&pVolInfo->BootSect, pSect, sizeof (BOOTSECT)); pVolInfo->ulActiveFatStart = pSect->bpb.ReservedSectors; if (pSect->bpb.ExtFlags & 0x0080) pVolInfo->ulActiveFatStart += pSect->bpb.BigSectorsPerFat * (pSect->bpb.ExtFlags & 0x000F); pVolInfo->ulStartOfData = pSect->bpb.ReservedSectors + pSect->bpb.BigSectorsPerFat * pSect->bpb.NumberOfFATs; pVolInfo->pBootFSInfo = (PBOOTFSINFO)(pVolInfo + 1); pVolInfo->pbFatSector = (PBYTE)(pVolInfo->pBootFSInfo + 1); pVolInfo->ulCurFatSector = -1L; pVolInfo->usClusterSize = pSect->bpb.BytesPerSector * pSect->bpb.SectorsPerCluster; pVolInfo->ulTotalClusters = (pSect->bpb.BigTotalSectors - pVolInfo->ulStartOfData) / pSect->bpb.SectorsPerCluster; pVolInfo->hVBP = hVBP; pVolInfo->hDupVBP = hDupVBP; pVolInfo->bDrive = pvpfsi->vpi_drive; pVolInfo->bUnit = pvpfsi->vpi_unit; pVolInfo->pNextVolInfo = NULL; if (usDefaultRASectors == 0xFFFF) pVolInfo->usRASectors = (pVolInfo->usClusterSize * 2) / SECTOR_SIZE; else pVolInfo->usRASectors = usDefaultRASectors; if (pVolInfo->usRASectors > (pVolInfo->usClusterSize * 4) / SECTOR_SIZE) pVolInfo->usRASectors = (pVolInfo->usClusterSize * 4) / SECTOR_SIZE; if (pSect->bpb.FSinfoSec != 0xFFFF) { ReadSector(pVolInfo, pSect->bpb.FSinfoSec, 1, pVolInfo->pbFatSector, DVIO_OPNCACHE); memcpy(pVolInfo->pBootFSInfo, pVolInfo->pbFatSector + FSINFO_OFFSET, sizeof (BOOTFSINFO)); } else memset(pVolInfo->pBootFSInfo, 0, sizeof (BOOTFSINFO)); *((PVOLINFO *)(pvpfsd->vpd_work)) = pVolInfo; if (!pGlobVolInfo) { pGlobVolInfo = pVolInfo; usVolCount = 1; } else { pNext = pGlobVolInfo; usVolCount = 1; if (pNext->bDrive == pvpfsi->vpi_drive && !pVolInfo->hDupVBP) pVolInfo->hDupVBP = pNext->hVBP; while (pNext->pNextVolInfo) { pNext = (PVOLINFO)pNext->pNextVolInfo; if (pNext->bDrive == pvpfsi->vpi_drive && !pVolInfo->hDupVBP) pVolInfo->hDupVBP = pNext->hVBP; usVolCount++; } pNext->pNextVolInfo = pVolInfo; usVolCount++; } if (f32Parms.fMessageActive & LOG_FS) Message("%u Volumes mounted!", usVolCount); rc = CheckWriteProtect(pVolInfo); if (rc && rc != ERROR_WRITE_PROTECT) { Message("Cannot access drive, rc = %u", rc); goto FS_MOUNT_EXIT; } if (rc == ERROR_WRITE_PROTECT) pVolInfo->fWriteProtected = TRUE; pVolInfo->fDiskCleanOnMount = pVolInfo->fDiskClean = GetDiskStatus(pVolInfo); if (!pVolInfo->fDiskCleanOnMount) Message("DISK IS DIRTY!"); if (pVolInfo->fWriteProtected) pVolInfo->fDiskCleanOnMount = TRUE; if (!pVolInfo->hDupVBP && (pVolInfo->pBootFSInfo->ulFreeClusters == 0xFFFFFFFF || !pVolInfo->fDiskClean || pVolInfo->BootSect.bpb.FSinfoSec == 0xFFFF)) GetFreeSpace(pVolInfo); pDevCaps = pvpfsi->vpi_pDCS; pVolChars = pvpfsi->vpi_pVCS; if (pDevCaps->Capabilities & GDC_DD_Read2) Message("Read2 supported"); if (pDevCaps->Capabilities & GDC_DD_DMA_Word) Message("DMA on word alligned buffers supported"); if (pDevCaps->Capabilities & GDC_DD_DMA_Byte) Message("DMA on byte alligned buffers supported"); if (pDevCaps->Capabilities & GDC_DD_Mirror) Message("Disk Mirroring supported"); if (pDevCaps->Capabilities & GDC_DD_Duplex) Message("Disk Duplexing supported"); if (pDevCaps->Capabilities & GDC_DD_No_Block) Message("Strategy2 does not block"); if (pDevCaps->Capabilities & GDC_DD_16M) Message(">16M supported"); if (pDevCaps->Strategy2) { Message("Strategy2 address at %lX", pDevCaps->Strategy2); Message("ChgPriority address at %lX", pDevCaps->ChgPriority); pVolInfo->pfnStrategy = (STRATFUNC)pDevCaps->Strategy2; pVolInfo->pfnPriority = (STRATFUNC)pDevCaps->ChgPriority; } rc = 0; break; case MOUNT_VOL_REMOVED: case MOUNT_RELEASE: pVolInfo = GetVolInfo(hVBP); if (!pVolInfo->hDupVBP) UpdateFSInfo(pVolInfo); RemoveVolume(pVolInfo); freeseg(pVolInfo); rc = 0; break; default : rc = ERROR_NOT_SUPPORTED; break; } FS_MOUNT_EXIT: if (f32Parms.fMessageActive & LOG_FS) Message("FS_MOUNT returned %u\n", rc); return rc; }
void cdecl free(void * pntr) #endif { USHORT usSel; BYTE _huge * pHeapStart; BYTE _huge * pHeapEnd; BYTE _huge * pWork; BYTE _huge * pToFree = pntr; BYTE _huge * pPrev; BYTE _huge * pNext; USHORT rc; if (f32Parms.fMessageActive & LOG_MEM) Message("free %lX", pntr); // CheckHeap(); if (OFFSETOF(pntr) == 0) { freeseg(pntr); return; } GetMemAccess(); for (usSel = 0; usSel < MAX_SELECTORS; usSel++) { if (SELECTOROF(pntr) == SELECTOROF(rgpSegment[usSel])) break; } if (usSel == MAX_SELECTORS) { CritMessage("FAT32: %lX not found in free!", pntr); Message("FAT32: %lX not found in free!", pntr); ReleaseMemAccess(); return; } pHeapStart = rgpSegment[usSel]; pHeapEnd = pHeapStart + HEAP_SIZE; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pHeapStart, HEAP_SIZE); if (rc) { CritMessage("FAT32: Protection VIOLATION in free (SYS%d)", rc); Message("FAT32: Protection VIOLATION in free (SYS%d)", rc); ReleaseMemAccess(); return; } pWork = pHeapStart; pPrev = NULL; while (pWork < pHeapEnd) { if (pWork + sizeof (ULONG) == pToFree) { if (pPrev && IsBlockFree(pPrev)) { SetBlockSize(pPrev, BlockSize(pPrev) + BlockSize(pWork) + sizeof (ULONG)); pWork = pPrev; } pNext = pWork + BlockSize(pWork) + sizeof (ULONG); if (pNext < pHeapEnd && IsBlockFree(pNext)) SetBlockSize(pWork, BlockSize(pWork) + BlockSize(pNext) + sizeof (ULONG)); SetFree(pWork); break; } else pPrev = pWork; pWork += BlockSize(pWork) + sizeof (ULONG); } if (pWork >= pHeapEnd) { CritMessage("FAT32: ERROR: Address not found in free"); Message("ERROR: Address not found in free"); ReleaseMemAccess(); return; } /* free selector if no longer needed */ if (usSel > 0 && BlockSize(rgpSegment[usSel]) == (HEAP_SIZE - sizeof (ULONG)) && IsBlockFree(rgpSegment[usSel])) { PBYTE p = rgpSegment[usSel]; rgpSegment[usSel] = NULL; freeseg(p); } ReleaseMemAccess(); }
USHORT usReadEAS(PVOLINFO pVolInfo, ULONG ulDirCluster, PSZ pszFileName, PFEALIST * ppFEAL, BOOL fCreate) { PFEALIST pFEAL; ULONG ulCluster; PBYTE pszEAName; PBYTE pRead; USHORT rc; USHORT usClustersUsed; *ppFEAL = NULL; rc = GetEASName(pVolInfo, ulDirCluster, pszFileName, &pszEAName); if (rc) return rc; ulCluster = FindPathCluster(pVolInfo, ulDirCluster, pszEAName, NULL, NULL); free(pszEAName); if ((ulCluster && ulCluster != FAT_EOF) || fCreate) { pFEAL = gdtAlloc(MAX_EA_SIZE, FALSE); if (!pFEAL) return ERROR_NOT_ENOUGH_MEMORY; memset(pFEAL, 0, (size_t) MAX_EA_SIZE); pFEAL->cbList = sizeof (ULONG); } else pFEAL = NULL; if (!ulCluster || ulCluster == FAT_EOF) { *ppFEAL = pFEAL; return 0; } pRead = (PBYTE)pFEAL; if (f32Parms.fMessageActive & LOG_EAS) Message("usReadEAS: Reading (1) cluster %lu", ulCluster); rc = ReadCluster(pVolInfo, ulCluster, pRead, 0); if (rc) { freeseg(pFEAL); return rc; } if (pFEAL->cbList > MAX_EA_SIZE) { freeseg(pFEAL); return ERROR_EAS_DIDNT_FIT; } usClustersUsed = (USHORT)(pFEAL->cbList / pVolInfo->usClusterSize); if (pFEAL->cbList % pVolInfo->usClusterSize) usClustersUsed++; /* vreemd: zonder deze Messages lijkt deze routine mis te gaan. Optimalisatie? */ if (f32Parms.fMessageActive & LOG_EAS) Message("usReadEAS: %u clusters used", usClustersUsed); usClustersUsed--; pRead += pVolInfo->usClusterSize; while (usClustersUsed) { ulCluster = GetNextCluster(pVolInfo, ulCluster); if (!ulCluster) ulCluster = FAT_EOF; if (ulCluster == FAT_EOF) { freeseg(pFEAL); return ERROR_EA_FILE_CORRUPT; } /* vreemd: zonder deze Messages lijkt deze routine mis te gaan. Optimalisatie? */ if (f32Parms.fMessageActive & LOG_EAS) Message("usReadEAS: Reading (2) cluster %lu", ulCluster); rc = ReadCluster(pVolInfo, ulCluster, pRead, 0); if (rc) { freeseg(pFEAL); return rc; } usClustersUsed--; pRead += pVolInfo->usClusterSize; } *ppFEAL = pFEAL; return 0; }
USHORT usModifyEAS(PVOLINFO pVolInfo, ULONG ulDirCluster, PSZ pszFileName, PEAOP pEAOP) { USHORT rc; PFEALIST pTarFeal; PFEALIST pSrcFeal; PBYTE pSrcMax; PFEA pSrcFea; PFEA pTarFea; if (f32Parms.fMessageActive & LOG_EAS) Message("usModifyEAS for %s", pszFileName); /* Do not allow ea's file files with no filename (root) */ if (!strlen(pszFileName)) return 284; rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pEAOP, sizeof (EAOP)); if (rc) { Message("Protection violation in usModifyEAS (1) at %lX", pEAOP); return rc; } pSrcFeal = pEAOP->fpFEAList; if (pSrcFeal->cbList > MAX_EA_SIZE) return ERROR_EA_LIST_TOO_LONG; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pSrcFeal, (USHORT)pSrcFeal->cbList); if (rc) { Message("Protection violation in usModifyEAS (2) at %lX", pSrcFeal); return rc; } if (pSrcFeal->cbList <= sizeof (ULONG)) return 0; rc = usReadEAS(pVolInfo, ulDirCluster, pszFileName, &pTarFeal, TRUE); if (rc) return rc; if (f32Parms.fMessageActive & LOG_EAS) Message("cbList before = %lu", pTarFeal->cbList); pSrcMax = (PBYTE)pSrcFeal + pSrcFeal->cbList; pSrcFea = pSrcFeal->list; while ((PBYTE)pSrcFea + sizeof (FEA) < pSrcMax) { PBYTE pName; USHORT usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; if ((PBYTE)pSrcFea + usNewSize > pSrcMax) { pEAOP->oError = (PBYTE)pSrcFea - (PBYTE)pEAOP; rc = ERROR_EA_LIST_INCONSISTENT; goto usStoreEASExit; } pName = (PBYTE)(pSrcFea + 1); rc = FSH_CHECKEANAME(0x0001, pSrcFea->cbName, pName); if (rc && pSrcFea->cbValue) { pEAOP->oError = (PBYTE)pSrcFea - (PBYTE)pEAOP; goto usStoreEASExit; } if (!pSrcFea->cbValue || !pSrcFea->cbName) usNewSize = 0; else usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; pTarFea = FindEA(pTarFeal, pName, pSrcFea->cbName); if (!pTarFea) { pTarFea = (PFEA)((PBYTE)pTarFeal + pTarFeal->cbList); if (MAX_EA_SIZE - pTarFeal->cbList < (ULONG)usNewSize) { rc = ERROR_EAS_DIDNT_FIT; goto usStoreEASExit; } memcpy(pTarFea, pSrcFea, usNewSize); pTarFeal->cbList += usNewSize; if (f32Parms.fMessageActive & LOG_EAS) Message("Inserting EA '%s' (%u,%u)", pName, pSrcFea->cbName, pSrcFea->cbValue); } else { USHORT usOldSize = sizeof (FEA) + (USHORT)pTarFea->cbName + 1 + pTarFea->cbValue; USHORT usMoveSize = (USHORT)pTarFeal->cbList - ((PBYTE)pTarFea - (PBYTE)pTarFeal); usMoveSize -= usOldSize; if (usOldSize < usNewSize) { if (MAX_EA_SIZE - pTarFeal->cbList < (ULONG)(usNewSize - usOldSize)) { rc = ERROR_EAS_DIDNT_FIT; goto usStoreEASExit; } } memmove((PBYTE)pTarFea + usNewSize, (PBYTE)pTarFea + usOldSize, usMoveSize); memcpy(pTarFea, pSrcFea, usNewSize); pTarFeal->cbList -= usOldSize; pTarFeal->cbList += usNewSize; if (f32Parms.fMessageActive & LOG_EAS) Message("Updating EA '%s' (%u,%u)", pName, pSrcFea->cbName, pSrcFea->cbValue); } usNewSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; pSrcFea = (PFEA)((PBYTE)pSrcFea + usNewSize); } if (f32Parms.fMessageActive & LOG_EAS) Message("cbList after = %lu", pTarFeal->cbList); if (pTarFeal->cbList > 4) rc = usWriteEAS(pVolInfo, ulDirCluster, pszFileName, pTarFeal); else rc = usDeleteEAS(pVolInfo, ulDirCluster, pszFileName); usStoreEASExit: freeseg(pTarFeal); if (f32Parms.fMessageActive & LOG_EAS) Message("usModifyEAS for %s returned %d", pszFileName, rc); return rc; }
USHORT usGetEAS(PVOLINFO pVolInfo, USHORT usLevel, ULONG ulDirCluster, PSZ pszFileName, PEAOP pEAOP) { USHORT rc; PFEALIST pTarFeal; PFEALIST pSrcFeal; PFEA pSrcFea; PFEA pTarFea; PGEALIST pGeaList; USHORT usMaxSize; if (f32Parms.fMessageActive & LOG_EAS) Message("usGetEAS for %s Level %d", pszFileName, usLevel); /* Checking all the arguments */ rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pEAOP, sizeof (EAOP)); if (rc) { Message("Protection violation in usGetEAS (1) at %lX", pEAOP); return rc; } pTarFeal = pEAOP->fpFEAList; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pTarFeal, sizeof (ULONG)); if (rc) { Message("Protection violation in usGetEAS (2) at %lX", pTarFeal); return rc; } if (pTarFeal->cbList > MAX_EA_SIZE) usMaxSize = (USHORT)MAX_EA_SIZE; else usMaxSize = (USHORT)pTarFeal->cbList; if (usMaxSize < sizeof (ULONG)) return ERROR_BUFFER_OVERFLOW; rc = MY_PROBEBUF(PB_OPWRITE, (PBYTE)pTarFeal, (USHORT)usMaxSize); if (rc) return rc; if (usLevel == FIL_QUERYEASFROMLIST) { pGeaList = pEAOP->fpGEAList; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pGeaList, sizeof (ULONG)); if (rc) return rc; if (pGeaList->cbList > MAX_EA_SIZE) return ERROR_EA_LIST_TOO_LONG; rc = MY_PROBEBUF(PB_OPREAD, (PBYTE)pGeaList, (USHORT)pGeaList->cbList); if (rc) return rc; } else pGeaList = NULL; /* Initialize the FEALIST */ memset(pTarFeal, 0, usMaxSize); pTarFeal->cbList = sizeof (ULONG); usMaxSize -= sizeof (ULONG); pTarFea = pTarFeal->list; /* Does the EA Exist? */ rc = usReadEAS(pVolInfo, ulDirCluster, pszFileName, &pSrcFeal, FALSE); if (rc) goto usGetEASExit; /* If not, return */ if (usLevel == FIL_QUERYEASFROMLIST) { PBYTE pGeaMax; PGEA pGea; pGeaMax = (PBYTE)pGeaList + pGeaList->cbList; pGea = pGeaList->list; while ((PBYTE)pGea + sizeof (GEA) < pGeaMax) { USHORT usGeaSize = sizeof (GEA) + (USHORT)pGea->cbName; USHORT usFeaSize; if (pGea->szName + (USHORT)pGea->cbName > pGeaMax) { rc = ERROR_EA_LIST_INCONSISTENT; goto usGetEASExit; } pSrcFea = FindEA(pSrcFeal, pGea->szName, pGea->cbName); if (pSrcFea) { usFeaSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; if (usFeaSize > usMaxSize) { rc = ERROR_BUFFER_OVERFLOW; pTarFeal->cbList = pSrcFeal->cbList; goto usGetEASExit; } if (f32Parms.fMessageActive & LOG_EAS) Message("Found %s", pSrcFea + 1); memcpy(pTarFea, pSrcFea, usFeaSize); } else { usFeaSize = sizeof (FEA) + (USHORT)pGea->cbName + 1; if (usFeaSize > usMaxSize) { rc = ERROR_BUFFER_OVERFLOW; if (pSrcFeal) pTarFeal->cbList = pSrcFeal->cbList; else pTarFeal->cbList = 4; goto usGetEASExit; } if (f32Parms.fMessageActive & LOG_EAS) Message("usGetEAS: %s not found!", pGea->szName); pTarFea->fEA = 0x00; pTarFea->cbName = pGea->cbName; pTarFea->cbValue = 0; strcpy((PBYTE)(pTarFea + 1), pGea->szName); } pTarFea = (PFEA)((PBYTE)pTarFea + usFeaSize); pTarFeal->cbList += usFeaSize; usMaxSize -= usFeaSize; pGea = (PGEA)((PBYTE)pGea + usGeaSize); } } else if (pSrcFeal) { PBYTE pSrcMax = (PBYTE)pSrcFeal + pSrcFeal->cbList; pSrcFea = pSrcFeal->list; while ((PBYTE)pSrcFea + sizeof (FEA) < pSrcMax) { USHORT usFeaSize = sizeof (FEA) + (USHORT)pSrcFea->cbName + 1 + pSrcFea->cbValue; if (usFeaSize > usMaxSize) { rc = ERROR_BUFFER_OVERFLOW; pTarFeal->cbList = pSrcFeal->cbList; goto usGetEASExit; } if (f32Parms.fMessageActive & LOG_EAS) Message("Found %s (%u,%u)", pSrcFea + 1, (USHORT)pSrcFea->cbName, pSrcFea->cbValue); memcpy(pTarFea, pSrcFea, usFeaSize); pTarFea = (PFEA)((PBYTE)pTarFea + usFeaSize); pTarFeal->cbList += usFeaSize; pSrcFea = (PFEA)((PBYTE)pSrcFea + usFeaSize); usMaxSize -= usFeaSize; } } rc = 0; usGetEASExit: if (pSrcFeal) freeseg(pSrcFeal); if (f32Parms.fMessageActive & LOG_EAS) Message("usGetEAS for %s returned %d (%lu bytes in EAS)", pszFileName, rc, pTarFeal->cbList); return rc; }