summaryrefslogtreecommitdiffstats
path: root/usr.sbin/quot
diff options
context:
space:
mode:
authordwmalone <dwmalone@FreeBSD.org>2006-02-25 23:50:15 +0000
committerdwmalone <dwmalone@FreeBSD.org>2006-02-25 23:50:15 +0000
commit7c9e42abb8ff3f164843c9c192e95f5d75147f63 (patch)
tree3802358c2cbefb0ef713e431a1ef45dbf8df1298 /usr.sbin/quot
parent2bc6196058d69652ef5cbb29bfbd67c3314ae887 (diff)
downloadFreeBSD-src-7c9e42abb8ff3f164843c9c192e95f5d75147f63.zip
FreeBSD-src-7c9e42abb8ff3f164843c9c192e95f5d75147f63.tar.gz
The quot command expected all inodes contents to be valid, however
on UFS2 inodes are initialised as they are needed, rather than at newfs time. When quot encountered these inodes it could produce crazy results. Now, on UFS2 filesystems, quot's get_inode function will bzero unallicated inodes before passing them back to a caller. This is how UFS2 initialises new inodes, so this should work OK. Also, while I'm here, make quot exit with an error if it finds inodes of an unknown type. This should help catch future problems of this type. Reviewed by: iedowse MFC after: 1 week
Diffstat (limited to 'usr.sbin/quot')
-rw-r--r--usr.sbin/quot/quot.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/usr.sbin/quot/quot.c b/usr.sbin/quot/quot.c
index 42e8f48..7ef4ae8 100644
--- a/usr.sbin/quot/quot.c
+++ b/usr.sbin/quot/quot.c
@@ -112,17 +112,36 @@ get_inode(fd,super,ino)
ino_t ino;
{
static caddr_t ipbuf;
+ static struct cg *cgp;
static ino_t last;
+ static int cg;
+ struct ufs2_dinode *di2;
if (fd < 0) { /* flush cache */
if (ipbuf) {
free(ipbuf);
ipbuf = 0;
+ if (super->fs_magic == FS_UFS2_MAGIC) {
+ free(cgp);
+ cgp = 0;
+ }
}
return 0;
}
if (!ipbuf || ino < last || ino >= last + INOCNT(super)) {
+ if (super->fs_magic == FS_UFS2_MAGIC &&
+ (!cgp || cg != ino_to_cg(super, ino))) {
+ cg = ino_to_cg(super, ino);
+ if (!cgp && !(cgp = malloc(super->fs_cgsize)))
+ errx(1, "allocate cg");
+ if (lseek(fd, (off_t)cgtod(super, cg) << super->fs_fshift, 0) < 0)
+ err(1, "lseek cg");
+ if (read(fd, cgp, super->fs_cgsize) != super->fs_cgsize)
+ err(1, "read cg");
+ if (!cg_chkmagic(cgp))
+ errx(1, "cg has bad magic");
+ }
if (!ipbuf
&& !(ipbuf = malloc(INOSZ(super))))
errx(1, "allocate inodes");
@@ -135,8 +154,11 @@ get_inode(fd,super,ino)
if (super->fs_magic == FS_UFS1_MAGIC)
return ((union dinode *)
&((struct ufs1_dinode *)ipbuf)[ino % INOCNT(super)]);
- return ((union dinode *)
- &((struct ufs2_dinode *)ipbuf)[ino % INOCNT(super)]);
+ di2 = &((struct ufs2_dinode *)ipbuf)[ino % INOCNT(super)];
+ /* If the inode is unused, it might be unallocated too, so zero it. */
+ if (isclr(cg_inosused(cgp), ino % super->fs_ipg))
+ bzero(di2, sizeof (*di2));
+ return ((union dinode *)di2);
}
#ifdef COMPAT
@@ -194,8 +216,14 @@ isfree(super, dp)
case IFDIR:
case IFREG:
return 0;
- default:
+ case IFCHR:
+ case IFBLK:
+ case IFSOCK:
+ case IFWHT:
+ case 0:
return 1;
+ default:
+ errx(1, "unknown IFMT 0%o", DIP(super, dp, di_mode) & IFMT);
}
#endif
}
OpenPOWER on IntegriCloud