Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 24 Jan 2010 15:20:12 -0800 (PST)
From:      "Pedro F. Giffuni" <giffunip@tutopia.com>
To:        FreeBSD-gnats-submit@FreeBSD.org, freebsd-bugs@FreeBSD.org
Subject:   Re: kern/142924: Small cleanup for the inode struct in ext2fs (based on UFS)
Message-ID:  <746370.24175.qm@web113517.mail.gq1.yahoo.com>

next in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
I added the equivalent to ufs_lookup.c 1.34:
Bug fixes for currently harmless bugs that could rise to bite
the unwary if the code were called in slightly different ways.

- In ufs_lookup() there is an off-by-one error in the test that checks
if dp->i_diroff is outside the range of the the current directory size.
This is completely harmless, since the following while-loop condition
'dp->i_offset < endsearch' is never met, so the code immediately
does a second pass starting at dp->i_offset = 0.

- Again in ufs_lookup(), the condition in a sanity check is wrong
for directories that are longer than one block. This bug means that



      
[-- Attachment #2 --]
diff -ru ext2fs.bsd/ext2_lookup.c ext2fs/ext2_lookup.c
--- ext2fs.bsd/ext2_lookup.c	2010-01-17 19:02:30.000000000 +0000
+++ ext2fs/ext2_lookup.c	2010-01-24 18:10:12.000000000 +0000
@@ -347,6 +347,7 @@
 		slotneeded = (sizeof(struct direct) - MAXNAMLEN +
 			cnp->cn_namelen + 3) &~ 3; */
 	}
+	bmask = VFSTOEXT2(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
 
 	/*
 	 * If there is cached information on a previous search of
@@ -359,9 +360,8 @@
 	 * profiling time and hence has been removed in the interest
 	 * of simplicity.
 	 */
-	bmask = VFSTOEXT2(vdp->v_mount)->um_mountp->mnt_stat.f_iosize - 1;
 	if (nameiop != LOOKUP || i_diroff == 0 ||
-	    i_diroff > dp->i_size) {
+	    i_diroff >= dp->i_size) {
 		entryoffsetinblock = 0;
 		i_offset = 0;
 		numdirpasses = 1;
@@ -550,10 +550,10 @@
 	 * Check that directory length properly reflects presence
 	 * of this entry.
 	 */
-	if (entryoffsetinblock + EXT2_DIR_REC_LEN(ep->e2d_namlen)
+	if (dp->i_offset + EXT2_DIR_REC_LEN(ep->e2d_namlen)
 		> dp->i_size) {
 		ext2_dirbad(dp, i_offset, "i_size too small");
-		dp->i_size = entryoffsetinblock+EXT2_DIR_REC_LEN(ep->e2d_namlen);
+		dp->i_size = dp->i_offset+EXT2_DIR_REC_LEN(ep->e2d_namlen);
 		dp->i_flag |= IN_CHANGE | IN_UPDATE;
 	}
 	brelse(bp);
diff -ru ext2fs.bsd/ext2_vfsops.c ext2fs/ext2_vfsops.c
--- ext2fs.bsd/ext2_vfsops.c	2010-01-17 19:02:56.000000000 +0000
+++ ext2fs/ext2_vfsops.c	2010-01-18 15:43:20.000000000 +0000
@@ -945,9 +945,8 @@
 	}
 
 	/*
-	 * Finish inode initialization now that aliasing has been resolved.
+	 * Finish inode initialization.
 	 */
-	ip->i_devvp = ump->um_devvp;
 
 	/*
 	 * Set up a generation number for this inode if it does not
diff -ru ext2fs.bsd/inode.h ext2fs/inode.h
--- ext2fs.bsd/inode.h	2010-01-17 19:03:21.000000000 +0000
+++ ext2fs/inode.h	2010-01-18 15:43:20.000000000 +0000
@@ -62,7 +62,6 @@
  */
 struct inode {
 	struct	vnode  *i_vnode;/* Vnode associated with this inode. */
-	struct	vnode  *i_devvp;/* Vnode for block I/O. */
 	struct	ext2mount *i_ump;
 	u_int32_t i_flag;	/* flags, see below */
 	ino_t	  i_number;	/* The identity of the inode. */
@@ -143,6 +142,9 @@
 #define	IN_SPACECOUNTED	0x0080		/* Blocks to be freed in free count. */
 #define IN_LAZYACCESS   0x0100		/* Process IN_ACCESS after the
 					    suspension finished */
+
+#define i_devvp i_ump->um_devvp
+
 #ifdef _KERNEL
 /*
  * Structure used to pass around logical block paths generated by

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?746370.24175.qm>