📄 fatfilt.c
字号:
/****************************************************************************** * * * Project: DOC Driver for Linux 2.4 Block device driver for mDOC H3 family * * of devices under Linux kernel 2.4. * * * * Version: 1.0 * * Email questions to: oemsupport@sandisk.com * * Copyright (C) SanDisk IL Ltd. 1995 - 2007 * * SanDisk IL Ltd., 7 Atir Yeda Street, Kfar Saba 44425, Israel * * * ****************************************************************************** * * * This program is free software; you can redistribute it and/or modify it * * under the terms of the GNU General Public License as published by the Free * * Software Foundation; either version 2 of the License, or any later version.* * This program is distributed in the hope that it will be useful, but WITHOUT* * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * * more details, which is set forth in the readme.txt file. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., 51 * * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * * * This License does not grant you any right to use the trademarks, service * * marks or logos of SanDisk IL Ltd. or SanDisk Corporation. * * Subject to the foregoing, SanDisk IL Ltd., for itself and on behalf of its * * licensors, hereby reserves all intellectual property rights in the program,* * except for the rights expressly granted in this License. * * * ******************************************************************************//*
* $Log: V:/PVCSDB/DiskOnChip/archives/Testing/TrueFFS 6.3/Drop 2.5/3/bddoc/src/fatfilt.c-arc $
*
* Rev 1.8.1.1 Sep 11 2006 13:45:20 yaniv.iarovici
* Legal header added
*
* Rev 1.8.1.0 Aug 08 2006 15:55:28 Polina.Marimont
* DOC Driver 1.0 initial
*/
/*******************************************************************************
* *
* *
* Module: FATFILT *
* *
* This module implements installable FAT12/16 filters. It supports up to *
* SOCKETS sockets, with up to FL_MAX_TL_PARTITIONS disks per socket. *
* Each disk can contain up to FL_MAX_PARTS_PER_DISK partitions on it, with *
* maximum depth of partition nesting in extended partitions equal to *
* MAX_PARTITION_DEPTH. *
* *
* In order for this module to work, disks must be abs.mounted rather then *
* mounted. In latter case, this module won't detect any of disk's *
* partitions, and won't install FAT filters. *
* *
* This module uses more then 512 bytes of stack space in case if MALLOC is *
* not enabled. *
* *
*******************************************************************************/
/*
* Includes
*/
#include "fatfilt.h"
#include "blockdev.h"
#include "defs.h"
#if defined(FL_ABS_READ_WRITE) && !defined(FL_READ_ONLY)
/*
* Module configuration
*/
#define FL_INCLUDE_FAT_MONITOR /* undefine it to remove FAT filter code */
#undef FL_INCLUDE_FAT32 /* define after support for FAT32 is added */
#define FL_DEL_SECTOR_SETS /* undefine to delete single cluster at a time */
#undef FL_DEL_SECTOR_STATS /* gather sector deletion statistics */
/*
* Defines
*/
/* extract pointer to user's buffer from IOreq */
#ifdef SCATTER_GATHER
#define FLBUF(ioreq,i) (*((FLSByte FAR1 **)((ioreq)->irData) + (int)(i)))
#else
#define FLBUF(ioreq,i) ((FLSByte FAR1 *)(ioreq->irData) + (FL_SECTOR_SIZE * ((int)(i))))
#endif
/* extract socket# and disk# from TFFS handle */
#define H2S(handle) (((int)(handle)) & 0xf)
#define H2D(handle) ((((int)(handle)) >> 4) & 0xf)
/* construct TFFS handle from socket# and disk# */
#define SD2H(socNo,diskNo) ((int)((((diskNo) & 0xf) << 4) | ((socNo) & 0xf)))
/* unformatted ("raw") disk partition */
#define FL_RAW_PART (-1)
/*
* Global vars
*/
#ifdef FL_DEL_SECTOR_SETS
FLBoolean del_sect_sets = TRUE; /* try to delete sectors in larger sets */
#endif
/*
* Local routines
*/
static FLStatus reset (void);
static FLStatus discardDisk (int handle);
static FLStatus newDisk (int handle);
static FLStatus parseDisk (int handle);
static FLStatus discardDiskParts (FLffDisk *pd);
static FLStatus addDiskPart (FLffDisk *pd, int partNo);
static FLStatus addNewDiskPart (FLffDisk *pd);
static FLBoolean isPartTableWrite (FLffDisk *pd, IOreq FAR2 *ioreq);
static FLStatus isExtPartPresent (FLSByte FAR1 *buf, SectorNo *nextExtPartSec);
static FLBoolean isBPBchanged (FLffVol *pv, FLSByte FAR1 *buf);
#ifdef FL_INCLUDE_FAT_MONITOR
static FLStatus partEnableFF (FLffVol* pv);
static FLStatus partFreeDelClusters (FLffVol *pv, SectorNo secNo,
FLSByte FAR1 *newFAT, IOreq *ioreq_delete);
#endif
/*
* Local data
*/
/* module reset flag */
static FLBoolean resetDone = FALSE;
/* disks (BDTL partitions in OSAK terminology) */
static FLffDisk* ffDisk[FL_SOCKETS][FL_MAX_TL_PARTITIONS] = { { NULL } };
#ifndef FL_MALLOC
/*
* WARNING: Large static arrays !
*
* sizeof(ffAllDisks[x][y]) is 64 bytes.
* sizeof(ffAllParts[x][y][z]) is 40 bytes.
*
*/
static FLffDisk ffAllDisks[FL_SOCKETS][FL_MAX_TL_PARTITIONS];
static FLffVol ffAllParts[FL_SOCKETS][FL_MAX_TL_PARTITIONS][FL_MAX_PARTS_PER_DISK];
#endif /* FL_MALLOC */
static const FLSByte zeroes[FL_SECTOR_SIZE] = {0};
#if (defined(FL_DEL_SECTOR_SETS) && defined(FL_DEL_SECTOR_STATS))
static FLDword del_sect_stats[16] = {0}; /* sector deletion statistics */
#endif
/* --------------------------------------------------------------------------- *
* *
* d i s c a r d D i s k P a r t s *
* *
* Discard all the partition info (if any) associated with particular disk. *
* *
* Parameters: *
* pd : disk (BDTL volume) *
* *
* Returns: *
* Always flOK. *
* *
* --------------------------------------------------------------------------- */
static FLStatus discardDiskParts ( FLffDisk * pd )
{
register int i;
if (pd != NULL) {
for (i = 0; i < FL_MAX_PARTS_PER_DISK; i++) {
#ifdef FL_MALLOC
if (pd->part[i] != NULL) {
FL_FREE(pd->part[i]);
}
#endif
pd->part[i] = NULL;
}
pd->parts = 0;
}
return flOK;
}
/* --------------------------------------------------------------------------- *
* *
* a d d D i s k P a r t *
* *
* If there is partition record #partNo associated with the disk, discard *
* this info. Attach new partition record #partNo. *
* *
* Parameters: *
* pd : disk (BDTL volume) *
* partNo : partition (0 ... FL_MAX_PARTS_PER_DISK-1) *
* *
* Returns: *
* flOK if success, otherwise respective error code *
* *
* --------------------------------------------------------------------------- */
static FLStatus addDiskPart ( FLffDisk * pd,
int partNo )
{
FLffVol * pv;
FLStatus status;
int socNo, diskNo;
/* arg. sanity check */
if ((pd == NULL) || (partNo >= FL_MAX_PARTS_PER_DISK))
return flBadDriveHandle;
/* break TFFS handle into socket# and disk#, and do sanity check */
socNo = H2S(pd->handle);
diskNo = H2D(pd->handle);
if ((socNo >= FL_SOCKETS) || (diskNo >= FL_MAX_TL_PARTITIONS))
return flBadDriveHandle;
status = flNotEnoughMemory;
#ifdef FL_MALLOC
pv = (FLffVol *)FL_MALLOC( sizeof(FLffVol) );
#else
pv = &ffAllParts[socNo][diskNo][partNo];
#endif
if (pv != NULL) {
/* initialize fields in struct FLffDisk to safe values */
pv->handle = pd->handle;
pv->type = FL_RAW_PART;
pv->flags = 0;
pv->ffEnabled = FALSE; /* turn off FAT minitor */
pv->sectors = (SectorNo) 0;
pv->firstFATsecNo = (SectorNo) -1; /* none */
pv->lastFATsecNo = pv->firstFATsecNo; /* none */
pv->firstDataSecNo = (SectorNo) 0;
pv->clusterSize = (unsigned) 0;
#ifdef FL_MALLOC
if( pd->part[partNo] != NULL ) {
FL_FREE(pd->part[partNo]);
pd->part[partNo] = NULL;
}
#endif
pd->part[partNo] = pv;
status = flOK;
}
return status;
}
/* --------------------------------------------------------------------------- *
* *
* a d d N e w D i s k P a r t *
* *
* Add one more partition record to the disk. *
* *
* Parameters: *
* pd : disk (BDTL volume) *
* *
* Returns: *
* flOK if success, otherwise respective error code *
* *
* --------------------------------------------------------------------------- */
static FLStatus addNewDiskPart ( FLffDisk * pd )
{
if (pd->parts < FL_MAX_PARTS_PER_DISK) {
checkStatus( addDiskPart (pd, pd->parts) );
pd->parts++;
}
return flOK;
}
/* --------------------------------------------------------------------------- *
* *
* d i s c a r d D i s k *
* *
* Remove disk record (with all the associated partition records). *
* *
* Parameters: *
* handle : TFFS handle *
* *
* Returns: *
* flOK if success, otherwise respective error code *
* *
* --------------------------------------------------------------------------- */
static FLStatus discardDisk ( int handle )
{
int socNo, diskNo;
/* break TFFS handle into socket# and disk#, and do sanity check */
socNo = H2S(handle);
diskNo = H2D(handle);
if ((socNo >= FL_SOCKETS) || (diskNo >= FL_MAX_TL_PARTITIONS))
return flBadDriveHandle;
if( ffDisk[socNo][diskNo] != NULL ) {
/* discard associated partition info */
(void) discardDiskParts( ffDisk[socNo][diskNo] );
#ifdef FL_MALLOC
/* release disk's scratch buffer */
if( (ffDisk[socNo][diskNo])->buf != NULL) {
FL_FREE( (ffDisk[socNo][diskNo])->buf );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -