home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!cs.utexas.edu!sun-barr!male.EBay.Sun.COM!jethro.Corp.Sun.COM!exodus.Eng.Sun.COM!appserv.Eng.Sun.COM!slovax.Eng.Sun.COM!lm
- From: lm@slovax.Eng.Sun.COM (Larry McVoy)
- Newsgroups: comp.unix.wizards
- Subject: Re: file system layout
- Date: 31 Dec 1992 22:47:35 GMT
- Organization: Sun Microsystems, Inc. Mt. View, Ca.
- Lines: 265
- Message-ID: <lk6u47INN47f@appserv.Eng.Sun.COM>
- References: <1992Dec30.163131.17280@ll.mit.edu>
- NNTP-Posting-Host: slovax
-
- singer@ll.mit.edu (Matthew R. Singer) writes:
- : If I were to pre-write a file a Sun disk, is there a simple way to find out
- : what blocks on the disk the file system has allocated for it.
-
- Yup. Source included below. This is essentialy the read path of UFS.
- Pretty simple, eh? I saw a perl script that did this once - now that's
- cool.
-
- : Since I
- : am writing just one big file on a newly formatted disk, it should be
- : contiguous (right?).
-
- Nope. Even though I wacked it to do contig allocation when it can, it
- still switches cylinder groups every meg or so. I suppose you could
- dick around with the tuning parameters to make one mondo cyl group.
-
-
- If you want more info on the SunOS UFS, send mail like so
-
- Mail archives@slovax.eng.sun.com
- Subject: fs_cluster
- ^D
-
- That will send you the clustering paper. (Yeah, I gotta get netlib.)
-
- --lm
-
- Here's the code.
-
-
- #include <stdio.h>
- #include <sys/param.h>
- #include <sys/time.h>
- #include <sys/vnode.h>
- #ifdef svr4
- #include <sys/fs/ufs_fs.h>
- #include <sys/fs/ufs_inode.h>
- #define DEV
- #else
- #include <ufs/fs.h>
- #include <ufs/inode.h>
- #include <sys/dir.h>
- #endif
- #include <sys/stat.h>
-
- #define SECTORSIZE 512
- #define SUPERADDR (16*SECTORSIZE)
-
- union {
- char sb_buffer[SBSIZE];
- struct fs fs;
- } sb;
- union {
- char i_buffer[MAXBSIZE];
- struct dinode dinode[MAXBSIZE/sizeof(struct dinode)];
- } di;
- char *cmdname;
- void *malloc();
- int block; /* global because I'm too lazy to pass a pointer */
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- struct stat statb;
- struct fs *fsp;
- struct dinode *ip;
- char *file;
- int *blk;
- int size;
- int devfd;
- int inode;
- int offset;
- int seekaddr;
- int i, j;
- int extent;
-
- cmdname = argv[0];
- if (argc != 2 && argc != 3) {
- fprintf(stderr, "Usage: %s file [diskdev]\n", cmdname);
- exit(1);
- }
- file = argv[1];
- if (stat(file, &statb) == -1) {
- fprintf(stderr, "File %s not found\n", file);
- exit(1);
- }
- sync();
- inode = statb.st_ino;
- if (argc == 3) {
- devfd = open(argv[2], 0);
- #ifndef DEV
- } else {
- devfd = getdev(statb.st_dev);
- #endif
- }
- if (lseek(devfd, SUPERADDR, 0) == -1) {
- fprintf(stderr, "Seek to superblock failed\n");
- exit(1);
- }
- fsp = &sb.fs;
- if (read(devfd, sb.sb_buffer, SBSIZE) == -1) {
- fprintf(stderr, "Read of superblock failed\n");
- exit(1);
- }
- if (fsp->fs_magic != FS_MAGIC) {
- fprintf(stderr, "Not a superblock\n");
- exit(1);
- }
- block = itod(fsp, inode);
- offset = itoo(fsp, inode);
- seekaddr = fsbtodb(fsp, block) * SECTORSIZE;
- if (lseek(devfd, seekaddr, 0) == -1) {
- fprintf(stderr, "Seek to block %d offset %d failed\n",
- block, offset);
- exit(1);
- }
- if (read(devfd, di.i_buffer, fsp->fs_bsize) == -1) {
- fprintf(stderr, "Read of inode %d failed\n", inode);
- exit(1);
- }
- ip = &di.dinode[offset];
- /* fprintf(stderr, "ncg %d rotor %d\n", fsp->fs_ncg, fsp->fs_cgrotor);*/
- /* printf("%d\n", fsp->fs_fpg); */
- size = ip->di_size;
- for (i = 0; i < NDADDR && size > 0; ) {
- extent = findextent(fsp, &ip->di_db[i], NDADDR - i);
- printf("off=%dK block=%d extent=%dK\n",
- i * fsp->fs_bsize / 1024, ip->di_db[i],
- extent * fsp->fs_bsize / 1024);
- i += extent ? extent : 1;
- if (i * fsp->fs_bsize >= size)
- exit(0);
- }
- block = NDADDR;
- blk = (int *) malloc(fsp->fs_bsize);
- /*
- * block of pointers
- */
- doblk(devfd, fsbtodb(fsp, ip->di_ib[0]) * SECTORSIZE, fsp, size);
- /*
- * Block of pointers to pointers
- */
- if (lseek(devfd, fsbtodb(fsp, ip->di_ib[1]) * SECTORSIZE, 0) == -1) {
- fprintf(stderr, "Seek to indirect block %d failed\n",
- fsbtodb(fsp, ip->di_ib[1]));
- exit(1);
- }
- if (read(devfd, (char *) blk, fsp->fs_bsize) != fsp->fs_bsize) {
- fprintf(stderr, "Read of indirect block %d failed\n",
- fsbtodb(fsp, ip->di_ib[1]));
- exit(1);
- }
- for (j = 0; j < NINDIR(fsp); j++) {
- doblk(devfd, fsbtodb(fsp, blk[j]) * SECTORSIZE, fsp, size);
- }
- /*
- * Too lazy to do this
- */
- printf("Quitting early\n");
- exit(0);
- /*NOTREACHED*/
- }
-
- doblk(fd, loc, fsp, size)
- struct fs *fsp;
- {
- int *blk;
- int j;
- int extent;
-
- if (lseek(fd, loc, 0) != loc) {
- perror("lseek");
- exit(0);
- }
- blk = (int*)malloc(fsp->fs_bsize);
- if (read(fd, (char*)blk, fsp->fs_bsize) != fsp->fs_bsize) {
- perror("read");
- exit(0);
- }
- for (j = 0; j < NINDIR(fsp); ) {
- if (extent = findextent(fsp, &blk[j], NINDIR(fsp) - j)) {
- printf("off=%dK block=%d extent=%dK\n",
- block * fsp->fs_bsize / 1024,
- blk[j], extent * fsp->fs_bsize / 1024);
- block += extent;
- j += extent;
- } else {
- printf("off=%dK HOLE\n", block * fsp->fs_bsize / 1024);
- block += 1;
- j += 1;
- }
- if (block * fsp->fs_bsize >= size)
- exit(0);
- }
- }
-
- #ifndef DEV
- getdev(dev)
- dev_t dev;
- {
- DIR *dirp;
- struct direct *dp;
- struct stat statb;
- char buf[100];
- int fd;
-
- dirp = opendir("/dev");
- if (dirp == NULL) {
- fprintf(stderr, "cannot open /dev\n");
- exit(1);
- }
- while (dp = readdir(dirp)) {
- if (dp->d_fileno == 0) {
- continue;
- }
- sprintf(buf, "/dev/%s", dp->d_name);
- if (stat(buf, &statb) == -1) {
- continue;
- }
- if (statb.st_rdev == dev && (statb.st_mode & IFMT) == IFBLK) {
- sprintf(buf, "/dev/r%s", dp->d_name);
- fd = open(buf, 0);
- if (fd < 0) {
- fprintf(stderr, "cannot open %s\n", buf);
- exit(1);
- }
- closedir(dirp);
- return (fd);
- }
- }
- fprintf(stderr, "Device %x not found (NFS file?).\n", dev & 0xffff);
- exit(1);
- /*NOTREACHED*/
- }
- #endif
-
- static int
- findextent(fs, sbp, n)
- struct fs *fs;
- daddr_t *sbp;
- register int n;
- {
- register daddr_t bn, nextbn;
- register daddr_t *bp;
- register int diff;
-
- if (n <= 0)
- return (0);
- bn = *sbp;
- if (bn == 0)
- return (0);
- diff = fs->fs_frag;
- bp = sbp;
- while (--n > 0) {
- nextbn = *(bp + 1);
- if (nextbn == 0 || bn + diff != nextbn)
- break;
- bn = nextbn;
- bp++;
- }
- return ((int)(bp - sbp) + 1);
- }
- ---
- Larry McVoy (415) 336-7627 lm@sun.com
-