mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-29 08:08:37 +00:00
Check the inode type and only attempt to print block lists for
regular files, directories, and symbolic links that require external storage. Correct the handling of files with holes and files that have one or more large blocks and end with a fragment. Reported by: bde
This commit is contained in:
parent
b940886338
commit
15e4030e9e
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=332741
@ -49,21 +49,65 @@ prtblknos(disk, dp)
|
||||
struct uufsd *disk;
|
||||
union dinode *dp;
|
||||
{
|
||||
int i, len, lbn, frags, numblks, blksperindir;
|
||||
int i, len, lbn, mode, frags, numblks, blksperindir;
|
||||
ufs2_daddr_t blkno;
|
||||
struct fs *fs;
|
||||
off_t size;
|
||||
|
||||
fs = (struct fs *)&disk->d_sb;
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC)
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC) {
|
||||
size = dp->dp1.di_size;
|
||||
else
|
||||
mode = dp->dp1.di_mode;
|
||||
} else {
|
||||
size = dp->dp2.di_size;
|
||||
numblks = howmany(size, fs->fs_bsize);
|
||||
if (numblks == 0) {
|
||||
printf(" empty file\n");
|
||||
return;
|
||||
mode = dp->dp2.di_mode;
|
||||
}
|
||||
switch (mode & IFMT) {
|
||||
case IFIFO:
|
||||
printf("fifo\n");
|
||||
return;
|
||||
case IFCHR:
|
||||
printf("character device\n");
|
||||
return;
|
||||
case IFBLK:
|
||||
printf("block device\n");
|
||||
return;
|
||||
case IFSOCK:
|
||||
printf("socket\n");
|
||||
return;
|
||||
case IFWHT:
|
||||
printf("whiteout\n");
|
||||
return;
|
||||
case IFLNK:
|
||||
if (size == 0) {
|
||||
printf("empty symbolic link\n");
|
||||
return;
|
||||
}
|
||||
if (size < fs->fs_maxsymlinklen) {
|
||||
printf("symbolic link referencing %s\n",
|
||||
(fs->fs_magic == FS_UFS1_MAGIC) ?
|
||||
(char *)dp->dp1.di_db :
|
||||
(char *)dp->dp2.di_db);
|
||||
return;
|
||||
}
|
||||
printf("symbolic link\n");
|
||||
break;
|
||||
case IFREG:
|
||||
if (size == 0) {
|
||||
printf("empty file\n");
|
||||
return;
|
||||
}
|
||||
printf("regular file, size %ld\n", size);
|
||||
break;
|
||||
case IFDIR:
|
||||
if (size == 0) {
|
||||
printf("empty directory\n");
|
||||
return;
|
||||
}
|
||||
printf("directory, size %ld\n", size);
|
||||
break;
|
||||
}
|
||||
numblks = howmany(size, fs->fs_bsize);
|
||||
len = numblks < UFS_NDADDR ? numblks : UFS_NDADDR;
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i < numblks - 1)
|
||||
@ -110,6 +154,11 @@ indirprt(disk, level, blksperindir, lbn, blkno, lastlbn)
|
||||
int i, last;
|
||||
|
||||
fs = (struct fs *)&disk->d_sb;
|
||||
if (blkno == 0) {
|
||||
printblk(fs, lbn, blkno,
|
||||
blksperindir * NINDIR(fs) * fs->fs_frag, lastlbn);
|
||||
return;
|
||||
}
|
||||
printblk(fs, lbn, blkno, fs->fs_frag, -level);
|
||||
/* read in the indirect block. */
|
||||
if (bread(disk, fsbtodb(fs, blkno), indir, fs->fs_bsize) == -1)
|
||||
@ -178,12 +227,12 @@ printblk(fs, lbn, blkno, numblks, lastlbn)
|
||||
if (lastlbn <= 0)
|
||||
goto flush;
|
||||
if (seq == 0) {
|
||||
seq = 1;
|
||||
seq = howmany(numblks, fs->fs_frag);
|
||||
firstblk = blkno;
|
||||
return;
|
||||
}
|
||||
if (lbn == 0) {
|
||||
seq = 1;
|
||||
seq = howmany(numblks, fs->fs_frag);
|
||||
lastblk = 0;
|
||||
firstblk = blkno;
|
||||
lastindirblk = 0;
|
||||
@ -192,8 +241,8 @@ printblk(fs, lbn, blkno, numblks, lastlbn)
|
||||
if (lbn < lastlbn && ((firstblk == 0 && blkno == 0) ||
|
||||
(firstblk == BLK_NOCOPY && blkno == BLK_NOCOPY) ||
|
||||
(firstblk == BLK_SNAP && blkno == BLK_SNAP) ||
|
||||
blkno == firstblk + seq * numblks)) {
|
||||
seq++;
|
||||
blkno == firstblk + seq * fs->fs_frag)) {
|
||||
seq += howmany(numblks, fs->fs_frag);
|
||||
return;
|
||||
}
|
||||
flush:
|
||||
|
Loading…
Reference in New Issue
Block a user