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

📄 create.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	create.c (file) * *	File management *	File creation/deletion */#include "fileio.h"#include "diskio.h"#include "dskalloc.h"LOCAL	void		setLinkFileState( F_STATE *fstate, UH atype, STIME ctime );LOCAL	void		setLinkFileState( F_STATE *fstate, UH atype, STIME ctime );LOCAL	void		setUserName( UserName dst, UserName src, W acclv );LOCAL	void		setFileState( F_STATE *fstate, A_MODE *mode, UH atype,PINFO *pinfo, FsInfo *fsinfo );LOCAL	DfFileID*	allocateFID( W *fid, ID_ERR *mid, FsInfo *fsinfo );LOCAL	DfFileID*	checkFID( W fid, ID_ERR *mid, FsInfo *fsinfo );LOCAL	UH		std_ridxofs( FsInfo *fsinfo );LOCAL	void		setNewFileHeader( DfFileHeader *fh,FID fid, TC *name, F_STATE *fstate, FsInfo *fsinfo );LOCAL	void		setLinkFile( DfLinkFile *lh, F_LINK *ref, FsInfo *fsinfo );LOCAL	WER		createFile( W mkfid, TC *name, F_STATE *fstate, F_LINK *ref,FsInfo *fsinfo );LOCAL	ER		checkFileDeleteOK( FID fid, UH ftype, FsInfo *fsinfo );LOCAL	ER		checkRecordDeleteOK( RCB *rcb );LOCAL	ER		deleteFileID( FID fid, FsInfo *fsinfo );LOCAL	WER		deleteAllRecordData( OFCB *ofcb );LOCAL	ER		deleteIndexBlock( UW delblk, W lv, OFCB *ofcb );LOCAL	WER		deleteFile( OFCB *ofcb );LOCAL	ER		deleteLinkFile( FID fid, UW hdblk, FsInfo *fsinfo );#define TSD_SFS_FLT_M1		(-1)#define TSD_SFS_OWN_0X0000	0x0000U#define TSD_SFS_GRP_0X0000	0x0000U#define TSD_FMF_MKF_M1		(-1)#define TSD_SRF_VAL_24		24#define TSD_DAR_VAL_0X80	(UB)0x80#define TSD_SFS_PUB_0X0FFF	0x0fffU#define TSD_SFS_CAS_1		1#define TSD_SFS_CAS_2		2#define TSD_SFS_CAS_3		3#define TSD_SFS_CAS_4		4#define TSD_FCR_VAL_4		4U#define TSD_GRC_VAL_255		255/* * Set the file management information of the link file. */LOCAL void setLinkFileState( F_STATE *fstate, UH atype, STIME ctime ){	memset(fstate, 0, (size_t)sizeof(F_STATE));	fstate->f_atype = atype;	fstate->f_nblk = 1;	fstate->f_ltime	= TSD_SFS_FLT_M1;	fstate->f_atime = ctime;	fstate->f_mtime = ctime;	fstate->f_ctime = ctime;}/* * Set the owner name/group name based on the access level. */LOCAL void setUserName( UserName dst, UserName src, W acclv ){	if ( (src != NULL) && (acclv > 0) ) {		if ( acclv == 1 ) {			/* Hidden name is always 0. */			memcpy(dst, src, (size_t)(sizeof(UserName)-sizeof(HideName)));			memset(dst + OpenNameLen, 0, (size_t)sizeof(HideName));		} else {			/* All valid */			memcpy(dst, src, (size_t)sizeof(UserName));		}	} else {		/* Always no name (0) */		memset(dst, 0, (size_t)sizeof(UserName));	}}/* * Set the file management information of the normal file. *	Set fstate from mode and atype. */LOCAL void setFileState( F_STATE *fstate, A_MODE *mode, UH atype,					PINFO *pinfo, FsInfo *fsinfo ){	W		acclv = fsinfo->acclv;	A_MODE		m;	P_USER		*user;	STIME		now;	TC		*gname;	if ( acclv == 0 ) {		/* Fixed to the specification below when the access management level is 0. */		m.f_ownacc = TSD_SFS_OWN_0X0000;		m.f_grpacc = TSD_SFS_GRP_0X0000;		m.f_pubacc = TSD_SFS_PUB_0X0FFF;		m.f_grpno  = 0;	} else if ( mode == NULL ) {		/* Use the default access mode. */		DA_MODE		*dm;		LOCK_PINFO_SECTION(			dm = &pinfo->user->mode;			m.f_ownacc = dm->f_ownacc;			m.f_grpacc = dm->f_grpacc;			m.f_pubacc = dm->f_pubacc;			m.f_grpno  = dm->f_grpno;		);	} else {		m = *mode;	}	fstate->f_type = F_FILE | m.f_ownacc;	fstate->f_atype = atype;	LOCK_PINFO_SECTION(		user = &pinfo->user->user;		setUserName(fstate->f_owner, user->usr_name, acclv);		switch( m.f_grpno ) {		  case TSD_SFS_CAS_1:			gname = user->grp_name1;			break;		  case TSD_SFS_CAS_2:			gname = user->grp_name2;			break;		  case TSD_SFS_CAS_3:			gname = user->grp_name3;			break;		  case TSD_SFS_CAS_4:			gname = user->grp_name4;			break;		  default:			gname = NULL;			break;		}		setUserName(fstate->f_group, gname, acclv);	);	fstate->f_grpacc = m.f_grpacc;	fstate->f_pubacc = m.f_pubacc;	now = fmGetTime();	fstate->f_atime = now;	fstate->f_mtime = now;	fstate->f_ctime = now;	fstate->f_ltime = TSD_SFS_FLT_M1;}/* * Find a free file ID. */LOCAL DfFileID* allocateFID( W *fid, ID_ERR *mid, FsInfo *fsinfo ){	DfFileID	*p = NULL;	DskAdrS		fidt;	W		i, n;	ER		err;	fidt = fsinfo->fidt;	n = 0;	for ( i = 0; i < fsinfo->nfmax; ++i ) {		if ( --n <= 0 ) {			if ( p != NULL ) {				fmpUnmapDisk(*mid, MD_RDONLY);			}			/* Map the file ID table by one logical block. */			p = fmpMapDskAdrS(fidt, (W)fsinfo->sblk,						MAP_SYS(fsinfo), mid, fsinfo);			if ( p == NULL ) {				err = (ER)*mid;				goto err_ret;			}			fidt = (DskAdrS)((VB*)fidt + fsinfo->sblk);			n = (W)((UW)fsinfo->sblk / sizeof(DfFileID));		}		if ( p->w == 0U ) {			break;  /* The free ID found. */		}		p++;	}	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	if ( i >= fsinfo->nfmax ) {		err = E_LIMIT;		goto err_ret;	}	*fid = i;	return p;err_ret:	if ( p != NULL ) {		fmpUnmapDisk(*mid, MD_RDONLY);	}	DEBUG_PRINT(("allocateFID err = %d\n", err));	*mid = err;	return NULL;}/* * Check whether the specified file ID is free. */LOCAL DfFileID* checkFID( W fid, ID_ERR *mid, FsInfo *fsinfo ){	DfFileID	*fidt;	ER		err;	/* Map the file ID table. */	fidt = fmpMapFileID((FID)fid, mid, fsinfo);	if ( fidt == NULL ) {		err = (ER)*mid;		goto err_ret;	}	if ( fidt->w != 0U ) {		/* It is already used. */		err = E_OBJ;		goto err_ret;	}	return fidt;err_ret:	fmpUnmapDisk(*mid, MD_RDONLY);	DEBUG_PRINT(("checkFID err = %d\n", err));	*mid = err;	return NULL;}/* * Return the location of the standard record index. */LOCAL UH std_ridxofs( FsInfo *fsinfo ){	W	n;	/* Because the location of the record index is fixed and the index is not specified	   in the file header before the extended format 2, return 0. */	if ( fsinfo->diskform < DiskForm_C ) {		return 0;	}	/* Reserve the fragment table area of 24 entries	   per 1 KB logical block size. */	n = fsinfo->sblk / KB;	if ( n < 1 ) {		n = 1;	}	n *= TSD_SRF_VAL_24;	return (UH)offsetof(DfFileHeaderBlock, f.frag2[n]);}/* * Initialize the new file header. */LOCAL void setNewFileHeader( DfFileHeader *fh,			FID fid, TC *name, F_STATE *fstate, FsInfo *fsinfo ){	BOOL	big = fsinfo->bigEndian;	fh->startid	= fmConvEndianW(FileHeaderTopID, big);	fh->ftype	= fmConvEndianH(fstate->f_type, big);	fh->atype	= fmConvEndianH(fstate->f_atype, big);	fmConvEndianHs((UH*)fh->own, (UH*)fstate->f_owner, UserNameLen, big);	fmConvEndianHs((UH*)fh->grp, (UH*)fstate->f_group, UserNameLen, big);	fh->gacclv	= fmConvEndianH(fstate->f_grpacc, big);	fh->pacclv	= fmConvEndianH(fstate->f_pubacc, big);	fh->nlnk	= 0;	fh->idxlv	= 0;	fh->size	= 0;	fh->nblk	= (W)fmConvEndianW(1, big);	fh->nrec	= 0;	fh->ltime	= (W)fmConvEndianW((UW)fstate->f_ltime, big);	fh->atime	= (W)fmConvEndianW((UW)fstate->f_atime, big);	fh->mtime	= (W)fmConvEndianW((UW)fstate->f_mtime, big);	fh->ctime	= (W)fmConvEndianW((UW)fstate->f_ctime, big);	fmConvEndianTC((TC*)fh->name, name, FileNameLen, big);	fh->refcnt	= 0;	fh->ridxofs	= fmConvEndianH(std_ridxofs(fsinfo), big);	fh->fid		= fmConvEndianH(fid, big);	fh->endid	= fmConvEndianW(FileHeaderEndID, big);}/* * Set the file location data. */LOCAL void setLinkFile( DfLinkFile *lh, F_LINK *ref, FsInfo *fsinfo ){	BOOL	big = fsinfo->bigEndian;	lh->fid = fmConvEndianH(ref->f_id, big);	setMisalignW(lh->ctime, fmConvEndianW((UW)ref->rf_ctime, big));	(void)fmConvEndianTC((TC*)lh->fsnm, ref->fs_name, L_FSNM, big);	(void)fmConvEndianTC((TC*)lh->devnm, ref->fs_locat, L_DLNM, big);}/* * Set the file abbreviated name. */EXPORT ER fmpSetShortFileName( FID fid, TC *name, FsInfo *fsinfo ){	DfShortName	*fsnt, *dadr;	ID		mid;	ER		err;	/* Map the file abbreviated name table. */	dadr = (DfShortName*)fsinfo->fsnt;	fsnt = fmpMapDskAdrS(&dadr[fid], sizeof(DfShortName),				MAP_SYS(fsinfo), &mid, fsinfo);	if ( fsnt == NULL ) {		err = (ER)mid;		goto err_ret;	}	/* Set the abbreviated name. */	*fsnt = fmpConvEndianW(fmShortFileName(name), fsinfo);	fmpUnmapDisk(mid, MD_WRITE);	err = fmpCheckDiskError(NULL, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpSetShortFileName err = %d\n", err));	return err;}/* * File generation */LOCAL WER createFile( W mkfid, TC *name, F_STATE *fstate, F_LINK *ref,							FsInfo *fsinfo ){	DfFileID		*fidt;	DfFileHeaderBlock	*fh;	W			hdblk;	ID			idmid, hdmid;	ER			err;	if ( mkfid < 0 ) {		/* Find a free file ID. */		fidt = allocateFID(&mkfid, &idmid, fsinfo);		if ( fidt == NULL ) {			err = (ER)idmid;			goto err_ret1;		}	} else {		/* Check whether the specified file ID is free. */		fidt = checkFID(mkfid, &idmid, fsinfo);		if ( fidt == NULL ) {			err = (ER)idmid;			goto err_ret1;		}	}	/* Reserve one block for the file header. */	hdblk = fmpAllocateOneBlock(0, NULL, fsinfo);	if ( hdblk < E_OK ) {		err = (ER)hdblk;		goto err_ret2;	}	fh = fmpMapAndClearLogBlk((UW)hdblk, MAP_FSTSK, &hdmid, fsinfo);	if ( fh == NULL ) {		err = (ER)hdmid;		goto err_ret2;	}	/* Set the file header. */	setNewFileHeader(&fh->head, (UH)mkfid, name, fstate, fsinfo);	if ( ref != NULL ) {		/* Set the file location. */		setLinkFile(&fh->f.link, ref, fsinfo);	}	fmpUnmapDisk(hdmid, MD_WRITE);	/* Set the file abbreviated name. */	err = fmpSetShortFileName((FID)mkfid, name, fsinfo);	if ( err < E_OK ) {		goto err_ret2;	}	/* Set to the file ID table. */	fidt->s.refcnt = 0;	fidt->s.blkadr = hdblk;	*fidt = fmpConvEndianFileID(*fidt, fsinfo);	fmpUnmapDisk(idmid, MD_WRITE);	err = fmpSyncFile(MAP_FSTSK, fsinfo);	if ( err < E_OK ) {		goto err_ret0;	}	return mkfid;err_ret2:	fmpUnmapDisk(idmid, MD_RDONLY);err_ret1:	(void)fmpSyncFile(MAP_FSTSK, fsinfo);err_ret0:	DEBUG_PRINT(("createFile err = %d\n", err));	return err;}/* * Normal file generation *	Return MD_WRITE when writing is performed to opara->fhd. *	Otherwise, return MD_RDONLY. */EXPORT UW fmpCreateFile( FmCmdPkt *pkt, OpenPara *opara, FsInfo *fsinfo ){	FM_CRE_FIL_PARA	*cmdPara = (FM_CRE_FIL_PARA*)pkt->cmd.para;	LINK		*lnk   = cmdPara->lnk;	A_MODE		*mode  = cmdPara->mode;	PINFO		*pinfo = pkt->wrk.pinfo;	OFCB		*rf;	W		mkfid;	F_STATE		fstate;	FD		*fd;	ER		err;	err = CheckSpaceRW(lnk, sizeof(LINK));	if ( err < E_OK ) {		goto err_ret1;	}	/* mode parameter check */	if ( mode != NULL ) {		err = CheckSpaceR(mode, sizeof(A_MODE));		if ( err < E_OK ) {			goto err_ret1;		}		if ( ((UH)mode->f_grpno > TSD_FCR_VAL_4)		  || ((mode->f_ownacc & ~F_OWNACC) != 0U) ){			err = E_PAR;			goto err_ret1;		}	}	/* 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 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;	}	/* Set the normal file management information. */	setFileState(&fstate, mode, cmdPara->atype, pinfo, fsinfo);	/* Normal file generation */	err = createFile(mkfid, cmdPara->name, &fstate, 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;		}	}	/* 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(("fmpCreateFile err = %d\n", err));	pkt->cmd.ret = err;	return MD_RDONLY;}/* * Link file generation. *	Return MD_WRITE when writing is performed to opara->fhd. *	Otherwise, return MD_RDONLY. */EXPORT UW fmpCreateLinkFile( FmCmdPkt *pkt, OpenPara *opara, FsInfo *fsinfo ){	FM_CRE_LNK_PARA	*cmdPara = (FM_CRE_LNK_PARA*)pkt->cmd.para;	LINK		*lnk   = cmdPara->lnk;	F_LINK		*ref   = cmdPara->ref;	F_STATE		fstate;	PINFO		*pinfo = pkt->wrk.pinfo;	OFCB		*rf;	W		mkfid;	ER		err;	err = CheckSpaceRW(lnk, sizeof(LINK));	if ( err < E_OK ) {		goto err_ret1;	}	/* 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;	}	/* 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;	}	/* Set the link file management information. */	setLinkFileState(&fstate, ref->f_atype, fmGetTime());	/* Link file generation */	err = createFile(mkfid, ref->f_name, &fstate, ref, 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;		}	}

⌨️ 快捷键说明

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