📄 mkfs.c
字号:
printf("May write to replicated superblock.\n"); if (!recover_option && fs->fs_replsb && (c_writeb(fs_fd, &sblock, fs->fs_replsb, 1) != 1)) { fprintf(stderr,"%s: Can't write to %s\n", progname, realpath); exit(-1); }}ask_confirm(){char rb[100];#ifndef SVR0 if (!isatty(0)) return; /* don't hang if stdin isn't a tty! */ printf("%s: is %s correct? (y/n?) ", progname, special); fflush(stdout); gets(rb); if ((*rb != 'y') && (*rb != 'Y')) exit(0);#endif}ismounted(name)char *name;{ struct ustat ustatarea; struct stat sb; if (stat(name, &sb) < 0) return (0); if (((sb.st_mode & S_IFMT) != S_IFCHR) && ((sb.st_mode & S_IFMT) != S_IFBLK)) return (0); if (ustat(sb.st_rdev,&ustatarea) >= 0) return (1); else return (0);}userr(){fprintf(stderr, "Usage: %s [-q] [-a] [-i] [-r] [-n inodes] special [proto]\n", progname);fprintf(stderr, " %s [-q] [-i] [-r] special blocks inodes heads sectors cgfsize cgalign ialign [proto]\n", progname); exit(-1);}/* clear out any potential superblocks in partitions which have their superblock overlapped by the one we are making. This is primarily for the benefit of the disk tools, so that we don't tell the user one of the overlapped partitions is a valid mount point. It's only an issue when the other partition had a filesystem, and none of the info we write happens to clobber it. If we can't do it for some reason, be silent about it, since this is just icing on the cake... Also, only try on regular disks, not floppies & logical volumes.*/voidclear_other_sb(){ struct stat sb; unsigned token; struct ptinfo *pt; struct ustat ustatarea; /* libdisk.a code needs to have name starting with /dev/rdsk */ if(stat(special, &sb) == -1) return;#ifdef notdef This does not seem to be necessary. If there are no complaints, the next person to see this should go ahead and remove it. jh - Oct 1992 /* this is gross, in that new disk drivers need to be added. * the extra dksc and jag got missed. someday... */ switch (major( sb.st_rdev)) { case DKIP_MAJOR : case DKSC_MAJOR : case DKSC1_MAJOR : case DKSC2_MAJOR : case DKSC3_MAJOR : case JAG0_MAJOR : case JAG1_MAJOR : case JAG2_MAJOR : case JAG3_MAJOR : case JAG4_MAJOR : case JAG5_MAJOR : case JAG6_MAJOR : case JAG7_MAJOR : case XYL_MAJOR : case IPI_MAJOR : case IPI1_MAJOR : case IPI2_MAJOR : case IPI3_MAJOR : break; default : return; };#endif /* libdisk.a code needs to have name starting with /dev/rdsk */ if (!rawpath) rawpath = findrawpath(special); if (!rawpath) return; /* too bad... */ if((token=setdiskinfo(rawpath, "/etc/fstab", 0)) == 0) return; while(pt = getpartition(token)) { struct stat sb2; if(stat(partname(rawpath, pt->ptnum), &sb2) == 0 && sb2.st_rdev == sb.st_rdev) { register struct ptinfo **pover; for(pover=pt->overlaps; pover && *pover; pover++) { char *pn; if(stat((pn=partname(rawpath, (*pover)->ptnum)), &sb2) == 0) { if(ustat(sb2.st_rdev,&ustatarea) == 0) { fprintf(stderr, "%s overlaps a mounted filesystem on partition %d\n", special, (*pover)->ptnum); exit(1); } if(((*pover)->pstartblk+EFS_SUPERBOFF) >= pt->pstartblk && ((*pover)->pstartblk+EFS_SUPERBOFF) <= (pt->pstartblk+pt->psize)) zap_sb(pn); } } enddiskinfo(token); return; } } enddiskinfo(token);}/* zap a superblock on an overlapped partition; see comments at clear_other_sb().*/zap_sb(name) char *name;{ struct efs e; int fd; bzero(&e, sizeof(e)); fd = open(name, O_WRONLY); if(fd == -1) { /* shouldn't happen, but perhaps done by non-super user */ return; } /* it's conceivable that this could fail if a vh is bad, since the sb isn't necessarily inside the fs we are making */ if(lseek(fd, (long) EFS_SUPERBOFF, 0) == EFS_SUPERBOFF) (void)write(fd, (char *) &e, BBTOB(BTOBB(sizeof(e)))); close(fd);}/* To retain backward compatibility of the 3.3 executable on a 3.2 kernel, * we'll use regular writes unless we know we have to go over 2 gig. */c_writeb(fd, buf, block, nblocks) int fd; char *buf; int block, nblocks;{ int bytes; if (use_writeb) { if (writeb(fd, buf, block, nblocks) == nblocks) return (nblocks); } else { lseek(fd, block * BBSIZE, 0); bytes = nblocks * BBSIZE; if (write(fd, buf, bytes) == bytes) return (nblocks); } return (-1);}/* Now a new function efs_newregfile(). This creates a new regular file * of the given size; this file may have indirect extents. * This is done to avoid rehacking the * whole of libefs to know about indirect extents! * Basically to get round the size limitations when a mkfs proto specifies * a humongo file! Rather than successive extends, we allocate the space * all at once (since we're working from a regular file we already * know the size). * * Assumptions: * * efs_mknod has been called to allocate & initialize the dinode. * * The bitmap is in core and is correctly representative of blocks * used so far. */struct extent * findex();char *malloc();void busyout();voidefs_newregfile(ino, name)ino_t ino;char *name;{ struct stat sb; int len; daddr_t blocks, allocblocks; int fd; register struct efs_dinode *di; register daddr_t bn; register struct extent *exbase = NULL; register struct extent *ex, *foundex; int extents, exbufsize; int copysize, copyoffset, copied; char *copybuf = NULL; static daddr_t curblock = 2; /* starting place to search for * free blocks */ int largestextent; register int i; int numindirs = 0; int indirblocks; if ((fd = open(name, O_RDONLY)) < 0) { fprintf(stderr,"%s: can't open %s\n", progname, name); exit(-1); } if (fstat(fd, &sb) < 0) { fprintf(stderr,"%s: cannot stat %s\n",progname, name); exit(-1); } if ((sb.st_mode & S_IFMT) != S_IFREG) { fprintf(stderr,"%s: %s is not a regular file\n",progname, name); exit(-1); } len = sb.st_size; blocks = (len + (BBSIZE - 1)) / BBSIZE; di = efs_iget(ino); /* Guess at number of extents & allocate space for them. We will * realloc later if it turns out we need more; however since it's * assumed we're creating in a virgin fs that is unlikely. */ exbufsize = blocks / 64; exbase = (struct extent *)malloc(BBSIZE + exbufsize * sizeof (struct extent)); /* now allocate extent space from the bitmap until we've got enough * extents to hold the file. */ allocblocks = 0; extents = 0; largestextent = 0; while (allocblocks < blocks) { if ((foundex = findex(curblock, (blocks - allocblocks))) == NULL) { fprintf(stderr,"%s: cannot allocate space for file: %s\n", progname, name); exit(-1); } if (foundex->ex_length > largestextent) largestextent = foundex->ex_length; curblock = foundex->ex_bn + foundex->ex_length; ex = (exbase + extents); ex->ex_magic = 0; ex->ex_bn = foundex->ex_bn; ex->ex_length = foundex->ex_length; ex->ex_offset = allocblocks; allocblocks += foundex->ex_length; if (++extents == exbufsize) { exbufsize += 10; if ((exbase = (struct extent *)realloc((char *)exbase, (BBSIZE + exbufsize * sizeof (struct extent)))) == NULL) { fprintf(stderr,"%s: cannot allocate space for file: %s\n", progname, name); exit(-1); } } } if (extents > EFS_DIRECTEXTENTS) { indirblocks = ((BBSIZE - 1 + (extents * sizeof(struct extent))) / BBSIZE); allocblocks = 0; while (allocblocks < indirblocks) { if ((foundex = findex(curblock, (indirblocks - allocblocks))) == NULL) { fprintf(stderr,"%s: cannot allocate space for file: %s\n", progname, name); exit(-1); } curblock = foundex->ex_bn + foundex->ex_length; ex = &di->di_u.di_extents[numindirs]; ex->ex_magic = 0; ex->ex_bn = foundex->ex_bn; ex->ex_length = foundex->ex_length; allocblocks += foundex->ex_length; if (++numindirs == EFS_DIRECTEXTENTS) { fprintf(stderr,"%s: cannot allocate space for file: %s\n", progname, name); exit(-1); } } di->di_u.di_extents[0].ex_offset = numindirs; } /* Hokay. Now we've allocated all the extents needed to hold the new * file's data (including indirect ones if any). Copy the data to the * appropriate places. */ if ((copybuf = malloc(largestextent * BBSIZE)) == NULL) { fprintf(stderr,"%s: can't get buffer memory for file copy\n", progname); exit(-1); } for (i = 0, ex = exbase, copied = 0; i < extents; i++) { copysize = ex->ex_length * BBSIZE; copyoffset = ex->ex_bn * BBSIZE; bzero(copybuf, copysize); if ((len - copied) < copysize) /* partial last block */ copysize = len - copied; if (read(fd, copybuf, copysize) != copysize) { fprintf(stderr, "%s: error reading %s\n", progname, name); exit(-1); } /* set copysize back to BBSIZE multiple: we may be working * on a raw device! */ copysize = ex->ex_length * BBSIZE; lseek(fs_fd, copyoffset, 0); if (write(fs_fd, copybuf, copysize) != copysize) { fprintf(stderr, "%s: error writing %s\n", progname, name); exit(-1); } copied += copysize; ex++; } free (copybuf); copybuf = NULL; /* Data copied. Now the extents: if < EFS_DIRECTEXTENTS, they go * in the dinode. If greater, they must be written to the indirect * extents allocated for them; pointers to these are already in * the dinode in that case. */ if (extents <= EFS_DIRECTEXTENTS) { for (i = 0, foundex = exbase, ex = di->di_u.di_extents; i < extents; i++, ex++, foundex++) { ex->ex_bn = foundex->ex_bn; ex->ex_length = foundex->ex_length; ex->ex_offset = foundex->ex_offset; ex->ex_magic = 0; } } else { copybuf = (char *)exbase; for (i = 0, ex = di->di_u.di_extents; i < numindirs; i++, ex++) { copysize = ex->ex_length * BBSIZE; copyoffset = ex->ex_bn * BBSIZE; lseek(fs_fd, copyoffset, 0); if (write(fs_fd, copybuf, copysize) != copysize) { fprintf(stderr, "%s: error writing %s\n", progname, name); exit(-1); } copybuf += copysize; } copybuf = NULL; } /* Busy out the appropriate parts of the bitmap. */ for (i = 0, ex = exbase; i < extents; i++, ex++) busyout(ex->ex_bn, ex->ex_length); if (numindirs) for (i = 0, ex = di->di_u.di_extents; i < numindirs; i++, ex++) busyout(ex->ex_bn, ex->ex_length); di->di_size = len; di->di_numextents = extents; efs_iput(di, ino); close (fd); if (exbase) free ((char *)exbase); if (copybuf) free ((char *)copybuf); return;}static struct extent *findex(block, nblocks)register daddr_t block;register int nblocks;{static struct extent ex;register daddr_t nextblock = block;register int foundblocks = 0; if (nblocks > EFS_MAXEXTENTLEN) nblocks = EFS_MAXEXTENTLEN; /* first skip any nonfree blocks */ while (!btst(bitmap, nextblock)) { nextblock++; /* side effect warning: btst is a macro! */ if (nextblock == (fs_blocks - 1)) return (NULL); } block = nextblock; while ((foundblocks < nblocks) && (nextblock < fs_blocks) && btst(bitmap, nextblock)) { foundblocks++; nextblock++; } if (!foundblocks) return (NULL); ex.ex_bn = block; ex.ex_length = foundblocks; return (&ex);}static voidbusyout(bn, len)register daddr_t bn;register int len;{ while (len--) { bclr(bitmap, bn); bn++; /* can't do it inside bclr: side effects!! */ fs->fs_tfree--; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -