Article View: comp.unix.wizards
Article #6325Re: file system layout
From: Larry McVoy
Date: Thu, 31 Dec 1992 22:47
Date: Thu, 31 Dec 1992 22:47
265 lines
6522 bytes
6522 bytes
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
Technical Details
Message-ID:
<lk6u47INN47f@appserv.Eng.Sun.COM>Path:
arc1-ca.pugleaf.net!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!lmReferences:
<1992Dec30.163131.17280@ll.mit.edu>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!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