⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dskalloc.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
					return bno;				}				if ( ++bno >= end ) {					return TSD_DB1_RTN_M1;				}			} while ( (m >>= 1U) != 0U );		}	} else {		for ( ;; ) {			b = *bitMap(bm, (W)((UW)bno >> TSD_DAM_BS_3), MD_RDONLY);			m = (UB)(TSD_DAM_BIT_0X01 << ((UW)bno & TSD_DAM_LSF_7));			do {				if ( (b & m) != 0U ) {					return bno;				}				if ( ++bno >= end ) {					return TSD_DB1_RTN_M1;				}			} while ( (m <<= 1U) != 0U );		}	}}/* * Set the width bits from bno th bit of the block bit map bm to 1. * It must be that width > 0. */LOCAL void bitSet( BitMapIO *bm, W bno, W width ){	W	end = bno + width;	UB	*b, m;	if ( bm->fsinfo->bigEndian != 0U ) {		for ( ;; ) {			b = bitMap(bm, (W)((UW)bno >> TSD_DAM_BSU_3), MD_WRITE);			m = (UB)(TSD_DAM_BIT_0X80 >> ((UW)bno & TSD_DAM_RSF_7));			do {				*b |= m;				if ( ++bno >= end ) {					return;				}			} while ( (m >>= 1U) != 0U );		}	} else {		for ( ;; ) {			b = bitMap(bm, (W)((UW)bno >> TSD_DAM_BSU_3), MD_WRITE);			m = (UB)(TSD_DAM_BIT_0X01 << ((UW)bno & TSD_DAM_LSF_7));			do {				*b |= m;				if ( ++bno >= end ) {					return;				}			} while ( (m <<= 1U) != 0U );		}	}}/* * Set the width bits from bno th bit of the block bit map bm to 0. * It must be that width > 0. */LOCAL void bitClear( BitMapIO *bm, W bno, W width ){	W	end = bno + width;	UB	*b, m;	if ( bm->fsinfo->bigEndian != 0 ) {		for ( ;; ) {			b = bitMap(bm, (W)((UW)bno >> TSD_DAM_BSU_3), MD_WRITE);			m = (UB)(TSD_DAM_BIT_0X80 >> ((UW)bno & TSD_DAM_RSF_7));			do {				*b &= ~m;				if ( ++bno >= end ) {					return;				}			} while ( (m >>= 1) != 0U );		}	} else {		for ( ;; ) {			b = bitMap(bm, (W)((UW)bno >> TSD_DAM_BSU_3), MD_WRITE);			m = (UB)(TSD_DAM_BIT_0X01 << ((UW)bno & TSD_DAM_LSF_7));			do {				*b &= ~m;				if ( ++bno >= end ) {					return;				}			} while ( (m <<= 1U) != 0U );		}	}}/* * Find a contiguous free blocks of between or equal to blkunits and blklimit * in the area from bno th bit to just before end th bit of the block bit map bm, * and return the found blocks to *alloc. * When the free area is not found, return E_NODSK. The *alloc becomes undefined. */LOCAL ER blockSearch( LLogBlk *alloc, BitMapIO *bm, W bno, W end,						W blkunits, W blklimit ){	W	bsz;	W	maxcnt;	while ( bno < end ) {		/* Find a free block. */		bno = bitSearch0(bm, bno, end - bno);		if ( bno < 0 ) {			break;	/* Not found. */		}		/* Check how many blocks are free in a row. */		maxcnt = end - bno;		if ( maxcnt > blklimit ) {			maxcnt = blklimit;		}		bsz = bitSearch1(bm, bno, maxcnt);		bsz = ( bsz < 0 )? (maxcnt): (bsz - bno);		if ( bsz >= blkunits ) {			/* Found. */			alloc->cnt = (UW)bsz;			alloc->adr = (UW)bno;			return E_OK;		}		bno += bsz;	}	/* Not found. */	return E_NODSK;}/* * Update the total number of used blocks. *	Increase/Decrease the total number of used blocks of the file header by diff. *	Update the number of free logical blocks of the system header too. */LOCAL ER changeUseBlockCount( W diff, OFCB *ofcb, FsInfo *fsinfo ){	DfFileHeader	*fh;	DfSystemHeader	*sh;	W		nblk;	STIME		now;	ID		mid;	ER		err;	if ( ofcb != NULL ) {		/* Map the file header. */		fh = fmpMapDskAdr(ofcb->fhead, sizeof(DfFileHeader),						ofcb, &mid, fsinfo);		if ( fh == NULL ) {			err = (ER)mid;			goto err_ret;		}		/* Update the total number of use blocks. */		nblk = (W)fmpConvEndianW((UW)fh->nblk, fsinfo) + diff;		fh->nblk = (W)fmpConvEndianW((UW)nblk, fsinfo);		fmpUnmapDisk(mid, MD_WRITE);	}	/* Map the system header. */	sh = fmpMapDskAdrS(fsinfo->shead, sizeof(DfSystemHeader),					MAP_SYS(fsinfo), &mid, fsinfo);	if ( sh == NULL ) {		err = (ER)mid;		goto err_ret;	}	/* Update the number of free logical blocks. */	nblk = (W)fmpConvEndianW((UW)sh->nflb, fsinfo) - diff;	sh->nflb = (W)fmpConvEndianW((UW)nblk, fsinfo);	/* Update the date/time of the system block update. */	now = fmGetTime();	sh->mtime = (W)fmpConvEndianW((UW)now, fsinfo);	fmpUnmapDisk(mid, MD_WRITE);	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("changeUseBlockCount err = %d\n", err));	return err;}/* * Reserve a contiguous blocks of up to blksize in steps of blkunits just after or near lblk. * Return the reserved logical blocks to *alloc. */LOCAL ER allocateBlock( LLogBlk *alloc, W blksize, W blkunits, UW lblk,						OFCB *ofcb, FsInfo *fsinfo ){	BitMapIO	bm;	ER		err;	/* Prepare to access the use block bit map. */	err = openBitMap(&bm, fsinfo->usebm, fsinfo->nbmp, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	/* Find a free block between lblk + 1 and the end. */	err = blockSearch(alloc, &bm, (W)(lblk + 1U), (W)fsinfo->nlb, blkunits, blksize);	if ( err < E_OK ) {		/* Find a free block between the start and lblk. */		err = blockSearch(alloc, &bm, 0, (W)(lblk + 1U), blkunits, blksize);	}	if ( err < E_OK ) {		goto err_ret2;	}	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret2;	}	if ( (W)alloc->cnt < blksize ) {		/* Round down to the blkunits. */		alloc->cnt -= (alloc->cnt % (UW)blkunits);	}	/* Use bit  ON */	bitSet(&bm, (W)alloc->adr, (W)alloc->cnt);	err = closeBitMap(&bm);	if ( err < E_OK ) {		goto err_ret1;	}	/* Update the total number of use blocks. */	err = changeUseBlockCount((W)+alloc->cnt, ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	return E_OK;err_ret2:	(void)closeBitMap(&bm);err_ret1:	DEBUG_PRINT(("allocateBlock err = %d\n", err));	return err;}/* * Reserve a contiguous logical blocks of size bytes insteps of units bytes * just after or near logical block number lblk. * Register the excess above the size bytes in the fragment table. * Return the reserved logical blocks and the byte count to *alloc and the return value respectively. * ofcb == NULL is not permitted. */EXPORT WER fmpAllocateBlock( LLogBlk *alloc, W size, W units, UW lblk,							OFCB *ofcb ){	FsInfo	*fsinfo = ofcb->fsinfo;	W	sblk = (W)fsinfo->sblk;	W	blksize  = (size  + sblk - 1) / sblk;	W	blkunits = (units + sblk - 1) / sblk;	W	keep;	ER	err;	if ( blkunits > blksize ) {		blkunits = blksize;	}	if ( blkunits < 1 ) {		blkunits = 1;	}	/* Reserve the logical block. */	err = allocateBlock(alloc, blksize, blkunits, lblk, ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	keep = (W)alloc->cnt * sblk;	if ( keep > size ) {		/* Register the excess above the size bytes in the fragment table. */		UW	blk = alloc->adr + alloc->cnt - 1U;		W	use = size % sblk;		err = fmpAddFragment(blk, use, sblk, ofcb);		if ( err < E_OK ) {			goto err_ret;		}		keep = size;	}	return keep;err_ret:	DEBUG_PRINT(("fmpAllocateBlock err = %d\n", err));	return err;}/* * Reserve one block just after or near logical block number lblk. * Return the reserved logical block number. * When ofcb != NULL, reserve it as a block belonging to the file of ofcb. * When ofcb == NULL, reserve it regardless of the file. */EXPORT WER fmpAllocateOneBlock( UW lblk, OFCB *ofcb, FsInfo *fsinfo ){	LLogBlk	alloc;	ER	err;	/* Reserve the logical block. */	err = allocateBlock(&alloc, 1, 1, lblk, ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return (WER)alloc.adr;err_ret:	DEBUG_PRINT(("fmpAllocateOneBlock err = %d\n", err));	return err;}/* * Release cnt logical blocks from lblk. */LOCAL ER freeBlock( UW lblk, W cnt, OFCB *ofcb, FsInfo *fsinfo ){	BitMapIO	bm;	ER		err;	/* Prepare to access the use block bit map. */	err = openBitMap(&bm, fsinfo->usebm, fsinfo->nbmp, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Use bit OFF */	bitClear(&bm, (W)lblk, cnt);	err = closeBitMap(&bm);	if ( err < E_OK ) {		goto err_ret;	}	/* Update the total number of use blocks. */	err = changeUseBlockCount(-cnt, ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("freeBlock err = %d\n", err));	return err;}/* * Release the logical block of free. * If there is an entry corresponding to free in the fragment table, deregister it. * ofcb == NULL is not permitted. */EXPORT ER fmpFreeBlock( LLogBlk free, OFCB *ofcb ){	FsInfo	*fsinfo = ofcb->fsinfo;	DskAdr	top, end;	ER	err;	end = top = fmpLBlkToDAdr(free.adr, fsinfo);	end.lblk += free.cnt;	/* Deregister from the fragment table. */	err = fmpDeleteFragment(top, end, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	/* Release the block. */	err = freeBlock(free.adr, (W)free.cnt, ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpFreeBlock err = %d\n" , err));	return err;}/* * Release one logical block of free. * The fragment table is not changed. * When ofcb != NULL, release it as a block belonging to the file of ofcb. * When ofcb == NULL, release it regardless of the file. */EXPORT ER fmpFreeOneBlock( UW free, OFCB *ofcb, FsInfo *fsinfo ){	ER	err;	/* Release the block. */	err = freeBlock(free, 1, ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpFreeOneBlock err = %d\n" , err));	return err;}/* * Release the data block. *	Release the area from top th byte to just before end th byte of lblk. *	When end is not a boundary of the logical block, *	it must be at the position of separator code of the fragment. *	When top is a boundary of the fragment, topf = TRUE. *	In this case, it is merged with the free area located before top. *	Return the number of unreleased remaining blocks of lblk *	(The number of blocks between the start and top) to the return value. *	ofcb == NULL is not permitted. */EXPORT WER fmpFreeDataBlk( LogBlk lblk, W top, W end, BOOL topf, OFCB *ofcb ){	W	sblk = (W)ofcb->fsinfo->sblk;	W	useblk;	UW	topblk, endblk;	W	fcnt;	ER	err;	/* The number of blocks to be remained. */	useblk = ( topf != 0 )? 0: ((top + sblk - 1) / sblk);	topblk = lblk.adr + (UW)(top / sblk);	endblk = lblk.adr + (UW)(end / sblk);	top %= sblk;	end %= sblk;	if ( topblk != endblk ) {		if ( end > 0 ) {			/* Release up to end of endblk. */			err = fmpMergeFragment(endblk, NULL, 0, end, ofcb);			if ( err < E_OK ) {				goto err_ret;			}		}		end = sblk;		endblk--;	}	if ( (top == 0) || topf ) {		/* Release (Merge) from top to end of topblk. */		err = fmpMergeFragment(topblk, NULL, top, end, ofcb);		if ( err < E_OK ) {			goto err_ret;		}	} else {		/* Release from top to end of topblk */		err = fmpAddFragment(topblk, top, end, ofcb);		if ( err < E_OK ) {			goto err_ret;		}	}	topblk++;	fcnt = (W)(endblk - topblk + 1U);	if ( fcnt > 0 ) {		LLogBlk	free;		/* Release between topblk and endblk. */		free.adr = topblk;		free.cnt = (UW)fcnt;		err = fmpFreeBlock(free, ofcb);		if ( err < E_OK ) {			goto err_ret;		}	}	return useblk;err_ret:	DEBUG_PRINT(("fmpFreeDataBlk err = %d\n", err));	return err;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -