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

📄 create.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	pkt->cmd.ret = E_OK;	return MD_RDONLY;err_ret2:	if ( rf != NULL ) {		(void)fmpICloseFile(rf, F_WRITE);	}err_ret1:	DEBUG_PRINT(("fmpCreateLinkFile err = %d\n", err));	pkt->cmd.ret = err;	return MD_RDONLY;}/* * File generation *	Return MD_WRITE when writing is performed to opara->fhd. *	Otherwise, return MD_RDONLY. */EXPORT UW fmpGenerateFile( FmCmdPkt *pkt, OpenPara *opara, FsInfo *fsinfo ){	FM_GEN_FIL_PARA	*cmdPara = (FM_GEN_FIL_PARA*)pkt->cmd.para;	LINK		*lnk   = cmdPara->lnk;	F_STATE		*stat  = cmdPara->stat;	F_LINK		*ref   = cmdPara->ref;	PINFO		*pinfo = pkt->wrk.pinfo;	OFCB		*rf;	UH		ftype;	W		mkfid;	FD		*fd;	ER		err;	err = CheckSpaceRW(lnk, sizeof(LINK));	if ( err < E_OK ) {		goto err_ret1;	}	/* fstate parameter check */	err = CheckSpaceR(stat, sizeof(F_STATE));	if ( err < E_OK ) {		goto err_ret1;	}	ftype = stat->f_type;	if ( isLinkFile(ftype) != 0 ) {		/* ref parameter check */		err = CheckSpaceR(ref, sizeof(F_LINK));		if ( err < E_OK ) {			goto err_ret1;		}		err = fmCheckFileName(ref->f_name, FileNameLen);		if ( err < E_OK ) {			goto err_ret1;		}		err = fmCheckFileName(ref->fs_name, L_FSNM);		if ( err < E_OK ) {			goto err_ret1;		}		if ( isSameFS(ref->fs_name, fsinfo) != 0 ) {			/* Same file system */			err = E_PAR;			goto err_ret1;		}	} else {		/* name parameter check */		err = CheckStrSpaceR(cmdPara->name, FileNameLen);		if ( err < E_OK ) {			goto err_ret1;		}		err = fmCheckFileName(cmdPara->name, FileNameLen);		if ( err < E_OK ) {			goto err_ret1;		}	}	/* Whether the user level is 0. */	if ( getUserLevel(pinfo) > 0 ) {		err = E_FACV;		goto err_ret1;	}	/* Whether the file system is writable or not. */	if ( isNoWriteFS(fsinfo) != 0 ) {		err = E_RONLY;		goto err_ret1;	}	switch ( cmdPara->opt ) {	  case F_FLOAT:		rf = NULL;		/* No reference file */		mkfid = TSD_FMF_MKF_M1;		/* Automatically select a free file ID. */		break;	  case F_FIX:		/* Open the reference file (The file specified by lnk). */		rf = fmpIOpenFile(opara, F_WRITE, pinfo, fsinfo, &err);		if ( rf == NULL ) {			goto err_ret1;		}		mkfid = TSD_FMF_MKF_M1;		/* Automatically select a free file ID. */		break;	  case F_FILEID:		rf = NULL;		/* No reference file */		mkfid = (W)lnk->f_id;	/* Generate a file with the specified file ID. */		break;	  default:		err = E_PAR;		goto err_ret1;	}	if ( isLinkFile(ftype) != 0 ) {		F_STATE	fstate;		/* Set the link file management information. */		setLinkFileState(&fstate, ref->f_atype, ref->f_ctime);		/* Link file generation */		err = createFile(mkfid, ref->f_name, &fstate, ref, fsinfo);		if ( err < E_OK ) {			goto err_ret2;		}		mkfid = (W)err;	} else {		/* Normal file generation */		err = createFile(mkfid, cmdPara->name, stat, NULL, fsinfo);		if ( err < E_OK ) {			goto err_ret2;		}		mkfid = (W)err;	}	/* LINK generation */	MakeLINK(lnk, (FID)mkfid, fsinfo);	if ( rf != NULL ) {		/* Add the link record of the generated file to the reference file. */		err = fmpIAppendLinkRecord(rf, lnk);		if ( err < E_OK ) {			goto err_ret2;		}		/* Close */		err = fmpICloseFile(rf, F_WRITE);		if ( err < E_OK ) {			goto err_ret1;		}	}	if ( isLinkFile(ftype) != 0 ) {		pkt->cmd.ret = E_OK;	} else {		/* Open the generated file. */		fd = fmpOpenNewFile((FID)mkfid, F_UPDATE, pinfo, fsinfo, &err);		if ( fd == NULL ) {			goto err_ret1;		}		pkt->cmd.ret = getFDno(fd);	}	return MD_RDONLY;err_ret2:	if ( rf != NULL ) {		(void)fmpICloseFile(rf, F_WRITE);	}err_ret1:	DEBUG_PRINT(("fmpGenerateFile err = %d\n", err));	pkt->cmd.ret = err;	return MD_RDONLY;}/* ------------------------------------------------------------------------ *//* * Obtain the reference count of the file of fid. *	When fh == NULL, a reference count more than 255 is returned as 255. */EXPORT WER fmpGetFileReferenceCount( FID fid, DfFileHeader *fh,							FsInfo *fsinfo ){	DfFileID	*fidt, f;	W		refcnt;	ID		mid;	ER		err;	/* Map the file ID table. */	fidt = fmpMapFileID(fid, &mid, fsinfo);	if ( fidt == NULL ) {		err = (ER)mid;		goto err_ret;	}	/* Fetch the reference count. */	f = fmpConvEndianFileID(*fidt, fsinfo);	fmpUnmapDisk(mid, MD_RDONLY);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	refcnt = (W)f.s.refcnt;	if ( (refcnt == TSD_GRC_VAL_255) && (fsinfo->diskform >= DiskForm_B) && (fh != NULL) ) {		/* Reference count of extended format STDFS (>=255) */		refcnt = (W)fmpConvEndianW((UW)fh->refcnt, fsinfo);	}	return refcnt;err_ret:	DEBUG_PRINT(("fmpGetFileReferenceCount err = %d\n", err));	return err;}/* * Whether the file can be deleted. */LOCAL ER checkFileDeleteOK( FID fid, UH ftype, FsInfo *fsinfo ){	QUEUE	*finfo;	QUEUE	*wfl = &fsinfo->wrkFilLst;	W	offset = (W)offsetof(FINFO, workFile.f_id);	/* Whether it is specified as a work file. */	LOCK_PINFO_SECTION( finfo = QueSearchH(wfl, wfl, (H)fid, offset) );	if ( finfo != wfl ) {		return E_BUSY;	}	/* Whether the delete protect attribute is set. */	if ( (ftype & F_PERM) != 0U ) {		return E_PERM;	}	return E_OK;}/* * Whether the record can be deleted. */LOCAL ER checkRecordDeleteOK( RCB *rcb ){	if ( rcb == NULL ) {		return E_OK;	}	/* Whether it is referred as the current record.   */	if ( rcb->ref > 0 ) {		return E_BUSY;	}	/* Whether it is record locked. */	if ( rcb->lkfd != NULL ) {		return E_LOCK;	}	return E_OK;}/* * Delete from the file ID table. */LOCAL ER deleteFileID( FID fid, FsInfo *fsinfo ){	DfFileID	*fidt;	ID		mid;	fidt = fmpMapFileID(fid, &mid, fsinfo);	if ( fidt == NULL ) {		goto err_ret;	}	/* Delete the file ID. */	fidt->w = 0;	fmpUnmapDisk(mid, MD_WRITE);	return E_OK;err_ret:	DEBUG_PRINT(("deleteFileID err = %d\n", mid));	return (ER)mid;}/* * Delete all the record data. *	Reduce the reference count by deleting data of the data record or *	by disconnecting links of the link record. The record index is made unused. *	(The record index blocks are not deleted.) *	Return the number of files whose file reference count became 0 *	as the result of the link of the link record being disconnected. */LOCAL WER deleteAllRecordData( OFCB *ofcb ){	FsInfo		*fsinfo = ofcb->fsinfo;	RIdx		ri;	DfRecordIndex	*ridx;	W		ndel = 0;	W		i;	ER		err;	/* Prepare to obtain the record index. */	err = fmpOpenRIdx(&ri, FIRST_RIdx, ofcb);	if ( err < E_OK ) {		goto err_ret1;	}	for ( i = 0; i < ofcb->nrec; ++i ) {		/* Obtain the record index. */		ridx = fmpGetRecordRIdx(&ri);		if ( ridx == NULL ) {			goto err_ret3;		}		if ( ridx->type[1] == TSD_DAR_VAL_0X80 ) {			/* Link record: Disconnect the link. */			err = fmpDecrementFileReferenceCount(&ridx->l, fsinfo);			if ( err < E_OK ) {				goto err_ret2;			}			ndel += (W)err;		} else {			UW	size;			size = fmpConvEndianW(ridx->n.size, fsinfo);			if ( size > 0U ) {				/* Data record: Delete the data. */				err = fmpITruncateDataRecord(&ri, 0);				if ( err < E_OK ) {					goto err_ret2;				}			}		}	}	err = fmpCloseRIdx(&ri);	if ( err < E_OK ) {		goto err_ret1;	}	return ndel;err_ret3:	err = fmpGetRIdxError(&ri);err_ret2:	(void)fmpCloseRIdx(&ri);err_ret1:	DEBUG_PRINT(("deleteAllRecordData err = %d\n", err));	return err;}/* * Delete the record index/block. */LOCAL ER deleteIndexBlock( UW delblk, W lv, OFCB *ofcb ){	FsInfo		*fsinfo = ofcb->fsinfo;	DfIndirectIndex	*iidx;	W		i, end;	UW		blk;	ID		mid;	ER		err;	if ( lv < ofcb->idxlv ) {		/* Delete the index block the indirect index indicates. */		iidx = fmpMapLogBlk(delblk, ofcb, &mid, fsinfo);		if ( iidx == NULL ) {			err = (ER)mid;			goto err_ret1;		}		end = (W)((UW)fsinfo->sblk / sizeof(DfIndirectIndex));		for ( i = TopIIdx(lv, ofcb); i < end; ++i ) {			blk = fmpConvEndianW(iidx[i].blk, fsinfo);			if ( blk != 0U ) {				err = fmpCheckDiskError(ofcb, fsinfo);				if ( err < E_OK ) {					goto err_ret2;				}				err = deleteIndexBlock(blk, lv + 1, ofcb);				if ( err < E_OK ) {					goto err_ret2;				}			}		}		fmpUnmapDisk(mid, MD_RDONLY);	}	/* Delete its own index block. */	err = fmpFreeOneBlock(delblk, NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret1;	}	return E_OK;err_ret2:	fmpUnmapDisk(mid, MD_RDONLY);err_ret1:	DEBUG_PRINT(("deleteIndexBlock err = %d\n", err));	return err;}/* * Delete the normal file. *	Return the number of files whose file reference count became 0 *	as the result of the link record being deleted. */LOCAL WER deleteFile( OFCB *ofcb ){	FsInfo	*fsinfo = ofcb->fsinfo;	W	ndel;	ER	err;	/* Delete all the record data. */	ndel = deleteAllRecordData(ofcb);	if ( ndel < E_OK ) {		err = (ER)ndel;		goto err_ret;	}	/* Delete from the file ID table. */	err = deleteFileID(ofcb->fid, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Delete all record indexes and file headers. */	err = deleteIndexBlock(fmpDAdrToLBlk(ofcb->fhead, fsinfo), 0, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	return ndel;err_ret:	DEBUG_PRINT(("deleteFile err = %d\n", err));	return err;}/* * Delete the link file. */LOCAL ER deleteLinkFile( FID fid, UW hdblk, FsInfo *fsinfo ){	ER	err;	/* Delete from the file ID table. */	err = deleteFileID(fid, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Delete the file header. */	err = fmpFreeOneBlock(hdblk, NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("deleteLinkFile err = %d\n", err));	return err;}/* * Delete the file. *	Return MD_WRITE when writing is performed to opara->fhd. *	Otherwise, return MD_RDONLY. */EXPORT UW fmpDeleteFile( FmCmdPkt *pkt, OpenPara *opara, FsInfo *fsinfo ){	FM_DEL_FIL_PARA	*cmdPara = (FM_DEL_FIL_PARA*)pkt->cmd.para;	LINK		*org = cmdPara->org;	LINK		*lnk = cmdPara->lnk;	PINFO		*pinfo = pkt->wrk.pinfo;	OFCB		*of = NULL;	OFCB		*lf = NULL;	UH		lnktype = 0;	UW		lnkhblk = 0;	W		nref, ndel;	IdxAdr		delrec;	RCB		*delrcb;	ID		mid;	ER		err;	/* lnk parameter check */	err = CheckSpaceR(lnk, sizeof(LINK));	if ( err < E_OK ) {		goto err_ret1;	}	/* Whether the file system is writable or not. */	if ( isNoWriteFS(fsinfo) != 0 ) {		err = E_RONLY;		goto err_ret1;	}	if ( org != NULL ) {		/* Check the file system name of lnk. */		if ( !isSameFS(lnk->fs_name, fsinfo) ) {			err = E_PAR;			goto err_ret1;		}		/* Open org. */		of = fmpIOpenFile(opara, F_WRITE, pinfo, fsinfo, &err);		if ( of == NULL ) {			goto err_ret1;		}		/* Retrieve the record of lnk. */		err = fmpISearchLinkRecord(of, lnk->f_id, &delrec, &delrcb);		if ( err < E_OK ) {			goto err_ret1;		}		/* Whether the record can be deleted. */		err = checkRecordDeleteOK(delrcb);		if ( err < E_OK ) {			goto err_ret1;		}	}	/* Obtain the reference count of lnk. */	nref = fmpGetFileReferenceCount(lnk->f_id, NULL, fsinfo);	if ( nref < E_OK ) {		err = (ER)nref;		goto err_ret1;	}	if ( org != NULL ) {		nref--;	}	if ( nref <= 0 ) {		OpenPara	op;		W		nlnk;		mid = fmpGetOpenPara(&op, lnk->f_id, fsinfo);		if ( mid < E_OK ) {			err = (ER)mid;			goto err_ret1;		}		/* Link count, file type and header block location of lnk. */		lnkhblk = fmpDAdrToLBlk(op.dadr, fsinfo);		lnktype = fmpConvEndianH(op.fhd->head.ftype, fsinfo);		nlnk = (W)fmpConvEndianH((UH)op.fhd->head.nlnk, fsinfo);		err = fmpCheckDiskError(NULL, fsinfo);		if ( err < E_OK ) {			goto err_ret2;		}		/* Whether lnk can be deleted. */		err = checkFileDeleteOK(lnk->f_id, lnktype, fsinfo);		if ( err < E_OK ) {			goto err_ret2;		}		if ( isNormFile(lnktype) != 0 ) {			/* Open lnk. */			lf = fmpIOpenFile(&op, F_EXCL, pinfo, fsinfo, &err);			if ( lf == NULL ) {				goto err_ret2;			}			/* Check the number of link records included in lnk. */			if ( (cmdPara->force == 0) && (nlnk > 0) ) {				err = E_REC;				goto err_ret2;			}		}		fmpUnmapDisk(mid, MD_RDONLY);		err = fmpCheckDiskError(NULL, fsinfo);		if ( err < E_OK ) {			goto err_ret1;		}	} else {		if ( org == NULL ) {			err = E_BUSY;			goto err_ret1;		}	}	if ( org != NULL ) {		/* Delete the record of lnk from org. */		err = fmpIDeleteLinkRecord(of, &delrec, delrcb);		if ( err < E_OK ) {			goto err_ret1;		}		/* Close org. */		err = fmpICloseFile(of, F_WRITE);		if ( err < E_OK ) {			goto err_ret1;		}	}	if ( nref <= 0 ) {		if ( isNormFile(lnktype) != 0 ) {			/* Delete the normal file (lnk). */			ndel = deleteFile(lf);			if ( ndel < E_OK ) {				err = (ER)ndel;				goto err_ret1;			}			/* Close lnk. */			err = fmpICloseFile(lf, F_UPDATE|F_EXCL);			if ( err < E_OK ) {				goto err_ret1;			}		} else {			/* Delete the link file (lnk). */			err = deleteLinkFile(lnk->f_id, lnkhblk, fsinfo);			if ( err < E_OK ) {				goto err_ret1;			}			ndel = 0;		}	} else {		ndel = 0;	}	pkt->cmd.ret = ndel;	return MD_RDONLY;err_ret2:	fmpUnmapDisk(mid, MD_RDONLY);err_ret1:	if ( of != NULL ) {		(void)fmpICloseFile(of, F_WRITE);	}	if ( lf != NULL ) {		(void)fmpICloseFile(lf, F_UPDATE|F_EXCL);	}	DEBUG_PRINT(("fmpDeleteFile err = %d\n", err));	pkt->cmd.ret = err;	return MD_RDONLY;}

⌨️ 快捷键说明

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