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

📄 segio.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	}	/* Register newly */	free->tid    = mytid;	free->errhdr = errhdr;	UnlockSEG();	return E_OK;err_ret:	UnlockSEG();	DEBUG_PRINT(("_NotifyDiskErr err = %d\n", err));	return err;}/* ------------------------------------------------------------------------ *//* *	Disk I/0 routine */EXPORT	UW	MaxPageIO;	/* Maximum number of pages available for consecutive input/output */LOCAL	VP	DiskIOSpace;	/* Disk I/O space *//* * Read/write pfe page frames *	cmd = TDC_READ	read *	cmd = TDC_WRITE	write */EXPORT ER ReadWritePFE( PFE *pfe, W cmd ){	DBN	dbn;	DE	*de;	VB	*adr;	PTE	pte;	W	n, sz;	ER	err;	/* Disk blocks to be used */	dbn.id = pfe->dbn_id;	dbn.no = pfe->dbn_no;	if ( dbn.id == PAGEFILE_ID ) {		/* In the case of page file, convert into real disk block numbers. */		dbn = PageFileDBN(dbn);	}	de = toDiskEntry(dbn.id);	/* Map page frames to input/output space. */	pte.w = PTE_DISKIO;	pte.c.pfa = PFEtoPFA(pfe);	(void)CHG_PTE(DiskIOSpace, 0, pte.w, 0, TRUE);	adr = DiskIOSpace;	n = (W)de->blkcnt;	/* Limit to blocks within the real disk. */	if ( dbn.no < 0 ) {		adr -= de->info.blocksize * dbn.no;		n += dbn.no;		dbn.no = 0;	}	if ( (dbn.no + n) > de->info.blockcont ) {		n = de->info.blockcont - dbn.no;	}	/* Read/write */	if ( cmd == TDC_READ ) {		err = tk_srea_dev(de->devid, dbn.no, adr, n, &sz);	} else {		err = tk_swri_dev(de->devid, dbn.no, adr, n, &sz);	}	/* Flush cache */	if ( cmd == TDC_READ ) {		WriteBackDCachePage(adr, 0);	} else {		InvalidateCachePage(adr, 0);	}	if ( err < E_OK ) {		goto err_ret;	}	if ( sz != n ) {		err = E_IO;		goto err_ret;	}	pfe->upd = FALSE;  /* Disk content matches memory content. */	return E_OK;err_ret:	/* Record error in PFE. */	pfe->err = TRUE;	if ( pfe->dbn_id != PAGEFILE_ID ) {		/* Call error handler */		CallErrHdr(pfe, err);	}	DEBUG_PRINT(("ReadWritePFE err = %d\n", err));	return err;}/* * Read/write pfe page frames linked to pfe_q *	cmd = TDC_READ	read *	cmd = TDC_WRITE	write *	All page frames must be read/written to/from the *	same disk (same pfe->dbn.id). */EXPORT ER ReadWritePFE_IndQue( IndQueTop *pfe_q, W cmd ){	IndQue	*q;	PFE	*pfe;	DE	*de;	DBN	dbn, top_dbn, prev_dbn;	VB	*adr, *end_adr;	W	blk, cnt, sz;	PTH	pth;	PTE	pte;	ER	err, error = E_OK;	q = NextIndQue(pfe_q, NULL);	if ( q == NULL ) {		return E_OK;  /* Queue is empty. */	}	pfe = q->ent;	if ( pfe->dbn_id == PAGEFILE_ID ) {		/* Page file */		de = PageFileDE();	} else {		/* Disk map */		de = toDiskEntry(pfe->dbn_id);	}	/* Map page frames to input/output space. */	InitPTH(&pth, DiskIOSpace, 0);	pte.w = PTE_DISKIO;	q = NULL;	while ( (q = NextIndQue(pfe_q, q)) != NULL ) {		pfe = q->ent;		err = NextPTE(&pth);		if ( err < E_OK ) {			EndPTH(&pth, FALSE);			goto err_ret1;		}		pte.c.pfa = PFEtoPFA(pfe);		SetPTE(&pth, pte.w, FALSE);	}	EndPTH(&pth, TRUE);	/* Input/output consecutive disk blocks as a whole. */	prev_dbn.id = 0;	q = NULL;	end_adr = (adr = DiskIOSpace) + (pfe_q->num * PAGESIZE);	while ( adr < end_adr ) {		q = NextIndQue(pfe_q, q);		if ( q != NULL ) {			pfe = q->ent;			dbn.id = pfe->dbn_id;			dbn.no = pfe->dbn_no;			if ( dbn.id == PAGEFILE_ID ) {				dbn = PageFileDBN(dbn);			}			if ( prev_dbn.id == 0 ) {				/* First */				top_dbn = prev_dbn = dbn;				continue;			}			if ( (prev_dbn.no + de->blkcnt) == dbn.no ) {				/* Consecutive */				prev_dbn = dbn;				continue;			}		}		blk = top_dbn.no;		cnt = prev_dbn.no - top_dbn.no + de->blkcnt;		/* Limit to blocks within the real disk. */		if ( blk < 0 ) {			adr -= de->info.blocksize * blk;			cnt += blk;			blk = 0;		}		if ( (blk + cnt) > de->info.blockcont ) {			cnt = de->info.blockcont - blk;		}		/* Read/write */		if ( cmd == TDC_READ ) {			err = tk_srea_dev(de->devid, blk, adr, cnt, &sz);		} else {			err = tk_swri_dev(de->devid, blk, adr, cnt, &sz);		}		if ( err < E_OK ) {			goto err_ret2;		}		if ( sz != cnt ) {			err = E_IO;			goto err_ret2;		}		cnt = prev_dbn.no - blk + de->blkcnt;		adr += cnt * de->info.blocksize;		top_dbn = prev_dbn = dbn;	}	/* Set update flag */	adr = DiskIOSpace;	q = NULL;	while ( (q = NextIndQue(pfe_q, q)) != NULL ) {		pfe = q->ent;		pfe->upd = FALSE;  /* Disk content matches memory content. */		/* Flush cache */		if ( cmd == TDC_READ ) {			WriteBackDCachePage(adr, 0);		} else {			InvalidateCachePage(adr, 0);		}		adr += PAGESIZE;	}	return E_OK;err_ret2:	adr = DiskIOSpace;	q = NULL;	while ( (q = NextIndQue(pfe_q, q)) != NULL ) {		if ( cmd == TDC_READ ) {			WriteBackDCachePage(adr, 0);		} else {			InvalidateCachePage(adr, 0);		}		adr += PAGESIZE;	}err_ret1:	DEBUG_PRINT(("ReadWritePFE_IndQue err = %d\n", err));	/* Retry page by page */	q = NULL;	while ( (q = NextIndQue(pfe_q, q)) != NULL ) {		pfe = q->ent;		err = ReadWritePFE(pfe, cmd);		if ( err < E_OK ) {			error = err;		}	}	return error;}/* ------------------------------------------------------------------------ *//* *	DiskEntry-related *//* * Obtain free DiskEntry. */LOCAL DE* getDiskEntry( void ){	DE	*de;	for ( de = &DiskEntryTable[0];		de < &DiskEntryTable[MaxDiskEntry]; de++ ) {		if ( de->devid == 0 ) {			return de;		}	}	return NULL;  /* No free space. */}/* * Check DiskID. */EXPORT DE* checkDiskID( ID diskid ){	DE	*de;	if ( (diskid < 1) || (diskid > (W)MaxDiskEntry) ) {		return NULL;  /* Out of range */	}	de = toDiskEntry(diskid);	if ( de->devid == 0 ) {		return NULL;  /* Unused entry */	}	return de;}/* * Release DiskEntry. */Inline void releaseDiskEntry( DE *de ){	de->devid = 0;  /* Indicate unused state. */}/* * Connect to file system *	Open (connect) a logical device (disk) specified *	by devname[L_DEVNM] in omode-specified mode. *	When "pinfo != NULL", check if *pinfo process has a right to access *	the devname logical device in omode-specified mode, and open the disk *	only if it has the access right. *	Return information on the connected disk as diskinfo. *	Return diskid (> 0) as a function value. * *	(*) Note that page fault may occur when access is made to *devname *	   or *diskinfo. *	(*) The current version does not include checking of access right in omode. */EXPORT WER _AttachFS( TC *devname, UW omode, PINFO *pinfo, DiskInfo *diskinfo ){	UB		devnm[L_DEVNM + 1];	DE		*de;	ID		devid;	DiskInfo	dinfo;	VP		memadr;	W		sz;	ER		err;	/* Convert device name: TC -> ASCII */	if ( (tcstoeucs(NULL, devname) > L_DEVNM)	  || (tcstoeucs(devnm, devname) < 0) ) {		err = E_PAR;		goto err_ret1;	}	/* Disk connection */	devid = tk_opn_dev(devnm, TD_UPDATE|TD_WEXCL|TD_NOLOCK);	if (( devid == E_RONLY )&&( (omode & D_WRITE) == 0U )) {		devid = tk_opn_dev(devnm, TD_READ|TD_WEXCL|TD_NOLOCK);	}	if ( devid < E_OK ) {		err = ERtoERR(devid);		goto err_ret1;	}	/* Obtain disk information */	err = tk_srea_dev(devid, DN_DISKINFO, &dinfo, sizeof(DiskInfo), &sz);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret2;	}	if ( dinfo.blocksize == 0 ) {		/* Unformatted */		err = E_IO;		goto err_ret2;	}	/* Obtain the first address of memory disk area. */	err = tk_srea_dev(devid, DN_DISKMEMADR, &memadr, sizeof(memadr), &sz);	if ( err < E_OK ) {		/* Not memory disk/not supported */		memadr = INVADR;	} else {		if ( ((UW)memadr % (UW)PAGESIZE) != 0U ) {			/* First address is not located on a page boundary; unable to support. */			memadr = INVADR;		}	}	LockFS();	LockSEG();	/* Obtain free DiskEntry */	de = getDiskEntry();	if ( de == NULL ) {		err = E_LIMIT;		goto err_ret3;	}	/* Set disk management information */	de->devid  = devid;	de->info   = dinfo;	de->memadr = memadr;	de->blkcnt = (UH)(PAGESIZE / dinfo.blocksize);	de->lbsz   = 0;	de->pbadj  = 0;	if ( de->blkcnt <= 0 ) {		err = E_SYS;		goto err_ret4;	}	UnlockSEG();	UnlockFS();	*diskinfo = dinfo;	return toDiskID(de);err_ret4:	releaseDiskEntry(de);err_ret3:	UnlockSEG();	UnlockFS();err_ret2:	(void)tk_cls_dev(devid, 0) ;err_ret1:	DEBUG_PRINT(("_AttachFS err = %d\n", err));	return err;}/* * Disconnect file system *	Close (disconnect) disk specified by diskid. *	When "pinfo != NULL", close the disk only if *pinfo process has a right *	to access the specified disk. *	Unmap all areas mapped for specified disks and perform synchronous *	processing of the disks (SyncFS). *	If the device is ejectable, eject it when set at "eject = TRUE". * *	(*) The current version does not include checking of access right. */EXPORT ER _DetachFS( ID diskid, PINFO *pinfo, BOOL eject ){	DE	*de;	ID	devid;	ER	err, error = E_OK;	LockFS();	LockSEG();	de = checkDiskID(diskid);	if ( de == NULL ) {		error = E_ID;		goto err_ret2;	}	if ( ((pfinfo.fd > 0) && (pfinfo.de == de))#if USE_PROCESS_MANAGER	     || (ChkSysProgMap(diskid) != 0)#endif	     ) {		/* Disk cannot be disconnected while page files are		 * still in use or a system program is mapped.		 * In such a case, perform disk synchronization only.		 */		err = SyncDisk(de, 0, SYNCONLY);		error = ( err < E_OK )? ERtoERR(err): E_BUSY;		goto err_ret2;	}	/* Synchronize file system and cancel page frame. */	err = SyncDisk(de, 0, FORCEDEL);	if ( err < E_OK ) {		error = ERtoERR(err);	}	devid = de->devid;	/* Release DiskEntry */	releaseDiskEntry(de);	UnlockSEG();	UnlockFS();	/* Disconnect disk */	err = tk_cls_dev(devid, ( eject != 0 )? TD_EJECT: 0);	if ( err < E_OK ) {		error = ERtoERR(err);	}	if ( error < E_OK ) {		goto err_ret1;	}	return E_OK;err_ret2:	UnlockSEG();	UnlockFS();err_ret1:	DEBUG_PRINT(("_DetachFS err = %d\n", error));	return error;}/* * Check right to access file system *	Check if *pinfo process has a right to access the devname *	logical device in omode-specified mode. */EXPORT ER _CheckFS( TC *devname, UW omode, PINFO *pinfo ){	/* The current version does not include checking of access right. */	return E_OK;}/* * Notify file system information *	Notify the file management of information on the file system of *	diskid disk. *	If mapping is performed to diskid disk, *	E_BUSY is returned. *	If yet-to-be-written disk blocks remain, write them all to the disk. *	Discard all of cached disk blocks. * *	(*) Note that page fault may occur when access is made to *spec. */EXPORT ER _InformFS( ID diskid, FsSpec *spec ){	FsSpec	fspec;	DE	*de;	ER	err;	fspec = *spec;	LockFS();	LockSEG();	de = checkDiskID(diskid);	if ( de == NULL ) {		err = E_ID;		goto err_ret;	}	/* Parameter check */	if (( (fspec.lbsz % de->info.blocksize) != 0 )	  ||( (fspec.btsz % de->info.blocksize) != 0 )) {		err = E_PAR;		goto err_ret;	}	/* Synchronize file system and cancel cache. */	err = SyncDisk(de, 0, DISCARD);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret;	}	/* Set file system information.	 *	In the case of memory disk, alignment of logical blocks cannot be corrected,	 *	so pbadj is always 0.	 */	de->lbsz = fspec.lbsz;	de->pbadj = ( de->memadr != INVADR )? (H)0:		(H)(((W)fspec.lbsz - (W)fspec.btsz) / de->info.blocksize);	UnlockSEG();	UnlockFS();	return E_OK;err_ret:	UnlockSEG();	UnlockFS();	DEBUG_PRINT(("_InformFS err = %d\n", err));	return err;}/* * Synchronize file system *	Write yet-to-be-written data in a file system specified diskid *	to the disk. *	info == 0: Write all yet-to-be-written data. *	info != 0: Write yet-to-be-written data that meets the following conditions: *			(mode.info == info || mode.info == 0) *			mode.info : Map information specified during mapping */EXPORT ER _SyncFS( ID diskid, VW info ){	DE	*de;	ER	err;	LockFS();	LockSEG();	de = checkDiskID(diskid);	if ( de == NULL ) {		err = E_ID;		goto err_ret;	}	err = SyncDisk(de, info, SYNCONLY);	if ( err < E_OK ) {		err = ERtoERR(err);		goto err_ret;	}	UnlockSEG();	UnlockFS();	return E_OK;err_ret:	UnlockSEG();	UnlockFS();	DEBUG_PRINT(("_SyncFS err = %d\n", err));	return err;}/* ------------------------------------------------------------------------ *//* * Disk I/O related initialization *	(Immediately after kernel startup) */EXPORT ER InitSegIO( void ){	W	val[TSD_ISI_VAL_5];	VP	p;	ER	err;	/* Obtain SYSCONF definition information. */	err = GetSysConf_bms((UB*)"MaxDiskID", val, 1);	if ( err < E_OK ) {		goto err_ret;	}	MaxDiskEntry = (UW)val[0];	err = GetSysConf_bms((UB*)"MaxMapEH", val, 1);	if ( err < E_OK ) {		goto err_ret;	}	MaxErrHdrEntry = (UW)val[0];	err = GetSysConf_bms((UB*)"MaxPageIO", val, 1);	if ( err < E_OK ) {		goto err_ret;	}	MaxPageIO = (UW)val[0];	if ( MaxPageIO <= 0U ) {		MaxPageIO = 1;  /* At least one page */	}	/* Create/initialize disk management information table */	p = Icalloc(MaxDiskEntry, sizeof(DE));	if ( p == NULL ) {		err = E_NOMEM;		goto err_ret;	}	DiskEntryTable = p;	/* Create/initialize error handler management information table */	p = Icalloc(MaxErrHdrEntry, sizeof(EHE));	if ( p == NULL ) {		err = E_NOMEM;		goto err_ret;	}	ErrHdrEntryTable = p;	/* Obtain disk I/O space */	p = AllocMemorySpace((W)MaxPageIO, 0);	if ( p == NULL ) {		err = E_NOMEM;		goto err_ret;	}	err = __MakeSpace(p, (W)MaxPageIO, 0, PTE_DISKIO);	if ( err < E_OK ) {		goto err_ret;	}	DiskIOSpace = p;	return E_OK;err_ret:	BMS_DEBUG_PRINT(("InitSegIO err = %d\n", err));	return err;}/* ======================================================================== *//* *	Debug support function */#if DEBUGFUNC_SUPPORT/* * Indicate state of page file */EXPORT void DumpPageFile( void ){	W	used;	used = ( pfinfo.npage == 0 )? 0:			pfinfo.use * TSD_DPF_VAL_100 / pfinfo.npage;	printf("PAGE FILE: Total %d  Use %d  [%d%% used]\n",		pfinfo.npage, pfinfo.use, used);}#endif /* DEBUGFUNC_SUPPORT */

⌨️ 快捷键说明

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