support huge directories
This commit is contained in:
parent
ee8dce893b
commit
2bd8cca428
66
dump_inode.c
66
dump_inode.c
|
@ -267,8 +267,8 @@ void dump_dirblk(int deleted, void *dirblk, size_t size) {
|
||||||
char name[MAXNAMLEN + 1];
|
char name[MAXNAMLEN + 1];
|
||||||
memcpy(name, d->d_name, d->d_namlen);
|
memcpy(name, d->d_name, d->d_namlen);
|
||||||
name[d->d_namlen] = '\0';
|
name[d->d_namlen] = '\0';
|
||||||
printf("deleted:%d inode:%" PRIu32 " type:%c name:%s\n", deleted, d->d_ino,
|
printf("deleted:%d inode:%" PRIu32 " type:%c name:%s\n",
|
||||||
type, name);
|
deleted || !d->d_ino, d->d_ino, type, name);
|
||||||
d->d_reclen = MIN(d->d_reclen, end - (char *)d);
|
d->d_reclen = MIN(d->d_reclen, end - (char *)d);
|
||||||
d->d_reclen &= ~3;
|
d->d_reclen &= ~3;
|
||||||
if (!d->d_reclen) {
|
if (!d->d_reclen) {
|
||||||
|
@ -284,6 +284,54 @@ void dump_dirblk(int deleted, void *dirblk, size_t size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dump_directory_indirect(union dinode *dp, void *indirblock, int level, off_t *filesize) {
|
||||||
|
void *datablock = xmalloc(sblock->fs_bsize);
|
||||||
|
if (!level) {
|
||||||
|
for (int i = 0; *filesize > 0 && i < NINDIR(sblock);
|
||||||
|
*filesize -= sblock->fs_bsize, i++) {
|
||||||
|
daddr_t fsblkno;
|
||||||
|
if (sblock->fs_magic == FS_UFS1_MAGIC) {
|
||||||
|
fsblkno = ((uint32_t *)indirblock)[i];
|
||||||
|
} else {
|
||||||
|
fsblkno = ((uint64_t *)indirblock)[i];
|
||||||
|
}
|
||||||
|
if (!fsblkno) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
size_t blksize = sblock->fs_bsize;
|
||||||
|
daddr_t blkno = fsbtodb(sblock, fsblkno);
|
||||||
|
xpread(diskfd, datablock, blksize, blkno * DEV_BSIZE);
|
||||||
|
if (*filesize < blksize) {
|
||||||
|
blksize = *filesize;
|
||||||
|
}
|
||||||
|
for (size_t j = 0; j < blksize; j += DIRBLKSIZ) {
|
||||||
|
dump_dirblk(0, datablock + j, MIN(blksize - j, DIRBLKSIZ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; *filesize > 0 && i < NINDIR(sblock); i++) {
|
||||||
|
daddr_t fsblkno;
|
||||||
|
if (sblock->fs_magic == FS_UFS1_MAGIC) {
|
||||||
|
fsblkno = ((uint32_t *)indirblock)[i];
|
||||||
|
} else {
|
||||||
|
fsblkno = ((uint64_t *)indirblock)[i];
|
||||||
|
}
|
||||||
|
if (!fsblkno) {
|
||||||
|
size_t gapsize = NINDIR(sblock) * sblock->fs_bsize;
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
gapsize *= NINDIR(sblock);
|
||||||
|
}
|
||||||
|
*filesize -= gapsize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
daddr_t blkno = fsbtodb(sblock, fsblkno);
|
||||||
|
xpread(diskfd, datablock, sblock->fs_bsize, blkno * DEV_BSIZE);
|
||||||
|
dump_directory_indirect(dp, datablock, level - 1, filesize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(datablock);
|
||||||
|
}
|
||||||
|
|
||||||
void dump_directory(union dinode *dp) {
|
void dump_directory(union dinode *dp) {
|
||||||
if ((DIP(dp, di_mode) & IFMT) != IFDIR) {
|
if ((DIP(dp, di_mode) & IFMT) != IFDIR) {
|
||||||
return;
|
return;
|
||||||
|
@ -305,8 +353,18 @@ void dump_directory(union dinode *dp) {
|
||||||
dump_dirblk(0, datablock + j, MIN(blksize - j, DIRBLKSIZ));
|
dump_dirblk(0, datablock + j, MIN(blksize - j, DIRBLKSIZ));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (filesize > 0) {
|
for (int i = 0; filesize > 0 && i < NIADDR; i++) {
|
||||||
errx(1, "Indirect blocks not implemented");
|
if (!DIP(dp, di_ib[i])) {
|
||||||
|
size_t gapsize = NINDIR(sblock) * sblock->fs_bsize;
|
||||||
|
for (int j = 0; j < i; j++) {
|
||||||
|
gapsize *= NINDIR(sblock);
|
||||||
|
}
|
||||||
|
filesize -= gapsize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
daddr_t blkno = fsbtodb(sblock, DIP(dp, di_ib[i]));
|
||||||
|
xpread(diskfd, datablock, sblock->fs_bsize, blkno * DEV_BSIZE);
|
||||||
|
dump_directory_indirect(dp, datablock, i, &filesize);
|
||||||
}
|
}
|
||||||
free(datablock);
|
free(datablock);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue