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

📄 dir.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	struct inodesc *idesc;{	register struct direct *dirp = idesc->id_dirp;	if (bcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))		return (KEEPON);	dirp->d_ino = idesc->id_parent;	if (newinofmt)		dirp->d_type = typemap[idesc->id_parent];	else		dirp->d_type = 0;	return (ALTERED|STOP);}linkup(orphan, parentdir)	ino_t orphan;	ino_t parentdir;{	register struct dinode *dp;	int lostdir;	ino_t oldlfdir;	struct inodesc idesc;	char tempname[BUFSIZ];	extern int pass4check();	bzero((char *)&idesc, sizeof(struct inodesc));	dp = ginode(orphan);	lostdir = (dp->di_mode & IFMT) == IFDIR;	pwarn("UNREF %s ", lostdir ? "DIR" : "FILE");	pinode(orphan);	if (preen && dp->di_size == 0)		return (0);	if (preen)		printf(" (RECONNECTED)\n");	else		if (reply("RECONNECT") == 0)			return (0);	if (lfdir == 0) {		dp = ginode(ROOTINO);		idesc.id_name = lfname;		idesc.id_type = DATA;		idesc.id_func = findino;		idesc.id_number = ROOTINO;		if ((ckinode(dp, &idesc) & FOUND) != 0) {			lfdir = idesc.id_parent;		} else {			pwarn("NO lost+found DIRECTORY");			if (preen || reply("CREATE")) {				lfdir = allocdir(ROOTINO, (ino_t)0, lfmode);				if (lfdir != 0) {					if (makeentry(ROOTINO, lfdir, lfname) != 0) {						if (preen)							printf(" (CREATED)\n");					} else {						freedir(lfdir, ROOTINO);						lfdir = 0;						if (preen)							printf("\n");					}				}			}		}		if (lfdir == 0) {			pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY");			printf("\n\n");			return (0);		}	}	dp = ginode(lfdir);	if ((dp->di_mode & IFMT) != IFDIR) {		pfatal("lost+found IS NOT A DIRECTORY");		if (reply("REALLOCATE") == 0)			return (0);		oldlfdir = lfdir;		if ((lfdir = allocdir(ROOTINO, (ino_t)0, lfmode)) == 0) {			pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n");			return (0);		}		if ((changeino(ROOTINO, lfname, lfdir) & ALTERED) == 0) {			pfatal("SORRY. CANNOT CREATE lost+found DIRECTORY\n\n");			return (0);		}		inodirty();		idesc.id_type = ADDR;		idesc.id_func = pass4check;		idesc.id_number = oldlfdir;		adjust(&idesc, lncntp[oldlfdir] + 1);		lncntp[oldlfdir] = 0;		dp = ginode(lfdir);	}	if (statemap[lfdir] != DFOUND) {		pfatal("SORRY. NO lost+found DIRECTORY\n\n");		return (0);	}	(void)lftempname(tempname, orphan);	if (makeentry(lfdir, orphan, tempname) == 0) {		pfatal("SORRY. NO SPACE IN lost+found DIRECTORY");		printf("\n\n");		return (0);	}	lncntp[orphan]--;	if (lostdir) {		if ((changeino(orphan, "..", lfdir) & ALTERED) == 0 &&		    parentdir != (ino_t)-1)			(void)makeentry(orphan, lfdir, "..");		dp = ginode(lfdir);		dp->di_nlink++;		inodirty();		lncntp[lfdir]++;		pwarn("DIR I=%lu CONNECTED. ", orphan);		if (parentdir != (ino_t)-1)			printf("PARENT WAS I=%lu\n", parentdir);		if (preen == 0)			printf("\n");	}	return (1);}/* * fix an entry in a directory. */changeino(dir, name, newnum)	ino_t dir;	char *name;	ino_t newnum;{	struct inodesc idesc;	bzero((char *)&idesc, sizeof(struct inodesc));	idesc.id_type = DATA;	idesc.id_func = chgino;	idesc.id_number = dir;	idesc.id_fix = DONTKNOW;	idesc.id_name = name;	idesc.id_parent = newnum;	/* new value for name */	return (ckinode(ginode(dir), &idesc));}/* * make an entry in a directory */makeentry(parent, ino, name)	ino_t parent, ino;	char *name;{	struct dinode *dp;	struct inodesc idesc;	char pathbuf[MAXPATHLEN + 1];		if (parent < ROOTINO || parent >= maxino ||	    ino < ROOTINO || ino >= maxino)		return (0);	bzero((char *)&idesc, sizeof(struct inodesc));	idesc.id_type = DATA;	idesc.id_func = mkentry;	idesc.id_number = parent;	idesc.id_parent = ino;	/* this is the inode to enter */	idesc.id_fix = DONTKNOW;	idesc.id_name = name;	dp = ginode(parent);	if (dp->di_size % DIRBLKSIZ) {		dp->di_size = roundup(dp->di_size, DIRBLKSIZ);		inodirty();	}	if ((ckinode(dp, &idesc) & ALTERED) != 0)		return (1);	getpathname(pathbuf, parent, parent);	dp = ginode(parent);	if (expanddir(dp, pathbuf) == 0)		return (0);	return (ckinode(dp, &idesc) & ALTERED);}/* * Attempt to expand the size of a directory */expanddir(dp, name)	register struct dinode *dp;	char *name;{	daddr_t lastbn, newblk;	register struct bufarea *bp;	char *cp, firstblk[DIRBLKSIZ];	lastbn = lblkno(&sblock, dp->di_size);	if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0)		return (0);	if ((newblk = allocblk(sblock.fs_frag)) == 0)		return (0);	dp->di_db[lastbn + 1] = dp->di_db[lastbn];	dp->di_db[lastbn] = newblk;	dp->di_size += sblock.fs_bsize;	dp->di_blocks += btodb(sblock.fs_bsize);	bp = getdirblk(dp->di_db[lastbn + 1],		(long)dblksize(&sblock, dp, lastbn + 1));	if (bp->b_errs)		goto bad;	bcopy(bp->b_un.b_buf, firstblk, DIRBLKSIZ);	bp = getdirblk(newblk, sblock.fs_bsize);	if (bp->b_errs)		goto bad;	bcopy(firstblk, bp->b_un.b_buf, DIRBLKSIZ);	for (cp = &bp->b_un.b_buf[DIRBLKSIZ];	     cp < &bp->b_un.b_buf[sblock.fs_bsize];	     cp += DIRBLKSIZ)		bcopy((char *)&emptydir, cp, sizeof emptydir);	dirty(bp);	bp = getdirblk(dp->di_db[lastbn + 1],		(long)dblksize(&sblock, dp, lastbn + 1));	if (bp->b_errs)		goto bad;	bcopy((char *)&emptydir, bp->b_un.b_buf, sizeof emptydir);	pwarn("NO SPACE LEFT IN %s", name);	if (preen)		printf(" (EXPANDED)\n");	else if (reply("EXPAND") == 0)		goto bad;	dirty(bp);	inodirty();	return (1);bad:	dp->di_db[lastbn] = dp->di_db[lastbn + 1];	dp->di_db[lastbn + 1] = 0;	dp->di_size -= sblock.fs_bsize;	dp->di_blocks -= btodb(sblock.fs_bsize);	freeblk(newblk, sblock.fs_frag);	return (0);}/* * allocate a new directory */allocdir(parent, request, mode)	ino_t parent, request;	int mode;{	ino_t ino;	char *cp;	struct dinode *dp;	register struct bufarea *bp;	struct dirtemplate *dirp;	ino = allocino(request, IFDIR|mode);	if (newinofmt)		dirp = &dirhead;	else		dirp = (struct dirtemplate *)&odirhead;	dirp->dot_ino = ino;	dirp->dotdot_ino = parent;	dp = ginode(ino);	bp = getdirblk(dp->di_db[0], sblock.fs_fsize);	if (bp->b_errs) {		freeino(ino);		return (0);	}	bcopy((char *)dirp, bp->b_un.b_buf, sizeof(struct dirtemplate));	for (cp = &bp->b_un.b_buf[DIRBLKSIZ];	     cp < &bp->b_un.b_buf[sblock.fs_fsize];	     cp += DIRBLKSIZ)		bcopy((char *)&emptydir, cp, sizeof emptydir);	dirty(bp);	dp->di_nlink = 2;	inodirty();	if (ino == ROOTINO) {		lncntp[ino] = dp->di_nlink;		cacheino(dp, ino);		return(ino);	}	if (statemap[parent] != DSTATE && statemap[parent] != DFOUND) {		freeino(ino);		return (0);	}	cacheino(dp, ino);	statemap[ino] = statemap[parent];	if (statemap[ino] == DSTATE) {		lncntp[ino] = dp->di_nlink;		lncntp[parent]++;	}	dp = ginode(parent);	dp->di_nlink++;	inodirty();	return (ino);}/* * free a directory inode */freedir(ino, parent)	ino_t ino, parent;{	struct dinode *dp;	if (ino != parent) {		dp = ginode(parent);		dp->di_nlink--;		inodirty();	}	freeino(ino);}/* * generate a temporary name for the lost+found directory. */lftempname(bufp, ino)	char *bufp;	ino_t ino;{	register ino_t in;	register char *cp;	int namlen;	cp = bufp + 2;	for (in = maxino; in > 0; in /= 10)		cp++;	*--cp = 0;	namlen = cp - bufp;	in = ino;	while (cp > bufp) {		*--cp = (in % 10) + '0';		in /= 10;	}	*cp = '#';	return (namlen);}/* * Get a directory block. * Insure that it is held until another is requested. */struct bufarea *getdirblk(blkno, size)	daddr_t blkno;	long size;{	if (pdirbp != 0)		pdirbp->b_flags &= ~B_INUSE;	pdirbp = getdatablk(blkno, size);	return (pdirbp);}

⌨️ 快捷键说明

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