Пример #1
0
/* 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;
   }
}
Пример #2
0
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);
}
Пример #3
0
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);
}
Пример #4
0
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;
}
Пример #5
0
/* 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);
      }
   }
}
Пример #6
0
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;
}
Пример #7
0
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();
}
Пример #8
0
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;
}
Пример #9
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;
}
Пример #10
0
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;
}