Module Name:    src
Committed By:   dholland
Date:           Tue Sep 15 15:01:22 UTC 2015

Modified Files:
        src/sbin/fsck_lfs: dir.c inode.c pass2.c
        src/sys/ufs/lfs: ulfs_lookup.c

Log Message:
Tidyups/fixes preparatory to making d_name[] in struct lfs_direct size
0 instead of size LFS_MAXNAMLEN+1, and preparatory to having accessor
functions for d_name. In particular, don't create prototype entries
and copy them, and access the name field only for directory structures
that are in buffers with space for the name to exist.


To generate a diff of this commit:
cvs rdiff -u -r1.39 -r1.40 src/sbin/fsck_lfs/dir.c
cvs rdiff -u -r1.64 -r1.65 src/sbin/fsck_lfs/inode.c
cvs rdiff -u -r1.28 -r1.29 src/sbin/fsck_lfs/pass2.c
cvs rdiff -u -r1.29 -r1.30 src/sys/ufs/lfs/ulfs_lookup.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sbin/fsck_lfs/dir.c
diff -u src/sbin/fsck_lfs/dir.c:1.39 src/sbin/fsck_lfs/dir.c:1.40
--- src/sbin/fsck_lfs/dir.c:1.39	Tue Sep 15 14:58:05 2015
+++ src/sbin/fsck_lfs/dir.c	Tue Sep 15 15:01:22 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: dir.c,v 1.39 2015/09/15 14:58:05 dholland Exp $	 */
+/* $NetBSD: dir.c,v 1.40 2015/09/15 15:01:22 dholland Exp $	 */
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -193,10 +193,11 @@ fsck_readdir(struct uvnode *vp, struct i
 		fix = dofix(idesc, "DIRECTORY CORRUPTED");
 		bread(vp, idesc->id_lblkno, blksiz, 0, &bp);
 		dp = (struct lfs_direct *) (bp->b_data + idesc->id_loc);
-		lfs_dir_setreclen(fs, dp, LFS_DIRBLKSIZ);
 		lfs_dir_setino(fs, dp, 0);
 		lfs_dir_settype(fs, dp, LFS_DT_UNKNOWN);
 		lfs_dir_setnamlen(fs, dp, 0);
+		lfs_dir_setreclen(fs, dp, LFS_DIRBLKSIZ);
+		/* for now at least, don't zero the old contents */
 		dp->d_name[0] = '\0';
 		if (fix)
 			VOP_BWRITE(bp);
@@ -250,7 +251,7 @@ int
 dircheck(struct inodesc *idesc, struct lfs_direct *dp)
 {
 	int size;
-	char *cp;
+	const char *cp;
 	u_char namlen, type;
 	int spaceleft;
 
@@ -279,7 +280,8 @@ dircheck(struct inodesc *idesc, struct l
 		printf("reclen<size, filesize<size, namlen too large, or type>15\n");
 		return (0);
 	}
-	for (cp = dp->d_name, size = 0; size < namlen; size++)
+	cp = dp->d_name;
+	for (size = 0; size < namlen; size++)
 		if (*cp == '\0' || (*cp++ == '/')) {
 			printf("name contains NUL or /\n");
 			return (0);
@@ -368,25 +370,33 @@ static int
 mkentry(struct inodesc *idesc)
 {
 	struct lfs_direct *dirp = idesc->id_dirp;
-	struct lfs_direct newent;
 	unsigned namlen;
-	int newlen, oldlen;
+	unsigned newreclen, oldreclen;
 
+	/* figure the length needed for id_name */
 	namlen = strlen(idesc->id_name);
-	lfs_dir_setnamlen(fs, &newent, namlen);
-	newlen = LFS_DIRSIZ(fs, &newent);
+	newreclen = LFS_DIRECTSIZ(namlen);
+
+	/* find the minimum record length for the existing name */
 	if (lfs_dir_getino(fs, dirp) != 0)
-		oldlen = LFS_DIRSIZ(fs, dirp);
+		oldreclen = LFS_DIRSIZ(fs, dirp);
 	else
-		oldlen = 0;
-	if (lfs_dir_getreclen(fs, dirp) - oldlen < newlen)
+		oldreclen = 0;
+
+	/* Can we insert here? */
+	if (lfs_dir_getreclen(fs, dirp) - oldreclen < newreclen)
 		return (KEEPON);
-	lfs_dir_setreclen(fs, &newent, lfs_dir_getreclen(fs, dirp) - oldlen);
-	lfs_dir_setreclen(fs, dirp, oldlen);
-	dirp = (struct lfs_direct *) (((char *) dirp) + oldlen);
-	/* ino to be entered is in id_parent */
+
+	/* Divide the record; all but oldreclen goes to the new record */
+	newreclen = lfs_dir_getreclen(fs, dirp) - oldreclen;
+	lfs_dir_setreclen(fs, dirp, oldreclen);
+
+	/* advance the pointer to the new record */
+	dirp = LFS_NEXTDIR(fs, dirp);
+
+	/* write record; ino to be entered is in id_parent */
 	lfs_dir_setino(fs, dirp, idesc->id_parent);
-	lfs_dir_setreclen(fs, dirp, lfs_dir_getreclen(fs, &newent));
+	lfs_dir_setreclen(fs, dirp, newreclen);
 	lfs_dir_settype(fs, dirp, typemap[idesc->id_parent]);
 	lfs_dir_setnamlen(fs, dirp, namlen);
 	memcpy(dirp->d_name, idesc->id_name, (size_t)namlen + 1);

Index: src/sbin/fsck_lfs/inode.c
diff -u src/sbin/fsck_lfs/inode.c:1.64 src/sbin/fsck_lfs/inode.c:1.65
--- src/sbin/fsck_lfs/inode.c:1.64	Tue Sep 15 14:58:05 2015
+++ src/sbin/fsck_lfs/inode.c	Tue Sep 15 15:01:22 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: inode.c,v 1.64 2015/09/15 14:58:05 dholland Exp $	 */
+/* $NetBSD: inode.c,v 1.65 2015/09/15 15:01:22 dholland Exp $	 */
 
 /*-
  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@@ -508,7 +508,6 @@ findname(struct inodesc * idesc)
 	if (lfs_dir_getino(fs, dirp) != idesc->id_parent)
 		return (KEEPON);
 	len = lfs_dir_getnamlen(fs, dirp) + 1;
-	/* XXX this is wrong: namlen+1 can be up to MAXPATHLEN+1 */
 	if (len > MAXPATHLEN) {
 		/* Truncate it but don't overflow the buffer */
 		/* XXX: this case doesn't null-terminate the result */

Index: src/sbin/fsck_lfs/pass2.c
diff -u src/sbin/fsck_lfs/pass2.c:1.28 src/sbin/fsck_lfs/pass2.c:1.29
--- src/sbin/fsck_lfs/pass2.c:1.28	Tue Sep 15 14:58:05 2015
+++ src/sbin/fsck_lfs/pass2.c	Tue Sep 15 15:01:22 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: pass2.c,v 1.28 2015/09/15 14:58:05 dholland Exp $	 */
+/* $NetBSD: pass2.c,v 1.29 2015/09/15 15:01:22 dholland Exp $	 */
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -247,25 +247,30 @@ pass2check(struct inodesc * idesc)
 	lfs_dir_setino(fs, &proto, idesc->id_number);
 	lfs_dir_settype(fs, &proto, LFS_DT_DIR);
 	lfs_dir_setnamlen(fs, &proto, 1);
-	(void) strlcpy(proto.d_name, ".", sizeof(proto.d_name));
-	entrysize = LFS_DIRSIZ(fs, &proto);
+	entrysize = LFS_DIRECTSIZ(1);
+	lfs_dir_setreclen(fs, &proto, entrysize);
 	if (lfs_dir_getino(fs, dirp) != 0 && strcmp(dirp->d_name, "..") != 0) {
 		pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
 		    dirp->d_name);
 	} else if (lfs_dir_getreclen(fs, dirp) < entrysize) {
 		pfatal("CANNOT FIX, INSUFFICIENT SPACE TO ADD '.'\n");
 	} else if (lfs_dir_getreclen(fs, dirp) < 2 * entrysize) {
+		/* convert this entry to a . entry */
 		lfs_dir_setreclen(fs, &proto, lfs_dir_getreclen(fs, dirp));
-		memcpy(dirp, &proto, (size_t) entrysize);
+		memcpy(dirp, &proto, sizeof(proto));
+		/* 4 is entrysize - headersize (XXX: clean up) */
+		(void) strlcpy(dirp->d_name, ".", 4);
 		if (reply("FIX") == 1)
 			ret |= ALTERED;
 	} else {
+		/* split this entry and use the beginning for the . entry */
 		n = lfs_dir_getreclen(fs, dirp) - entrysize;
-		lfs_dir_setreclen(fs, &proto, entrysize);
-		memcpy(dirp, &proto, (size_t) entrysize);
+		memcpy(dirp, &proto, sizeof(proto));
+		/* XXX see case above */
+		(void) strlcpy(dirp->d_name, ".", 4);
 		idesc->id_entryno++;
 		lncntp[lfs_dir_getino(fs, dirp)]--;
-		dirp = (struct lfs_direct *) ((char *) (dirp) + entrysize);
+		dirp = LFS_NEXTDIR(fs, dirp);
 		memset(dirp, 0, (size_t) n);
 		lfs_dir_setreclen(fs, dirp, n);
 		if (reply("FIX") == 1)
@@ -278,8 +283,8 @@ chk1:
 	lfs_dir_setino(fs, &proto, inp->i_parent);
 	lfs_dir_settype(fs, &proto, LFS_DT_DIR);
 	lfs_dir_setnamlen(fs, &proto, 2);
-	(void) strlcpy(proto.d_name, "..", sizeof(proto.d_name));
-	entrysize = LFS_DIRSIZ(fs, &proto);
+	entrysize = LFS_DIRECTSIZ(2);
+	lfs_dir_setreclen(fs, &proto, entrysize);
 	if (idesc->id_entryno == 0) {
 		n = LFS_DIRSIZ(fs, dirp);
 		if (lfs_dir_getreclen(fs, dirp) < n + entrysize)
@@ -319,6 +324,8 @@ chk1:
 		fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
 		lfs_dir_setreclen(fs, &proto, lfs_dir_getreclen(fs, dirp));
 		memcpy(dirp, &proto, (size_t) entrysize);
+		/* 4 is entrysize - headersize (XXX: clean up) */
+		(void) strlcpy(proto.d_name, "..", 4);
 		if (reply("FIX") == 1)
 			ret |= ALTERED;
 	}

Index: src/sys/ufs/lfs/ulfs_lookup.c
diff -u src/sys/ufs/lfs/ulfs_lookup.c:1.29 src/sys/ufs/lfs/ulfs_lookup.c:1.30
--- src/sys/ufs/lfs/ulfs_lookup.c:1.29	Tue Sep 15 15:00:49 2015
+++ src/sys/ufs/lfs/ulfs_lookup.c	Tue Sep 15 15:01:22 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: ulfs_lookup.c,v 1.29 2015/09/15 15:00:49 dholland Exp $	*/
+/*	$NetBSD: ulfs_lookup.c,v 1.30 2015/09/15 15:01:22 dholland Exp $	*/
 /*  from NetBSD: ufs_lookup.c,v 1.122 2013/01/22 09:39:18 dholland Exp  */
 
 /*
@@ -38,7 +38,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ulfs_lookup.c,v 1.29 2015/09/15 15:00:49 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ulfs_lookup.c,v 1.30 2015/09/15 15:01:22 dholland Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_lfs.h"
@@ -665,6 +665,7 @@ ulfs_dirbadentry(struct vnode *dp, struc
 	struct ulfsmount *ump = VFSTOULFS(dp->v_mount);
 	struct lfs *fs = ump->um_lfs;
 	int dirblksiz = fs->um_dirblksiz;
+	const char *name;
 
 	namlen = lfs_dir_getnamlen(fs, ep);
 	reclen = lfs_dir_getreclen(fs, ep);
@@ -682,13 +683,14 @@ ulfs_dirbadentry(struct vnode *dp, struc
 	}
 	if (lfs_dir_getino(fs, ep) == 0)
 		return (0);
+	name = ep->d_name;
 	for (i = 0; i < namlen; i++)
-		if (ep->d_name[i] == '\0') {
+		if (name[i] == '\0') {
 			/*return (1); */
 			printf("Second bad\n");
 			goto bad;
 	}
-	if (ep->d_name[i])
+	if (name[i])
 		goto bad;
 	return (0);
 bad:
@@ -1136,6 +1138,7 @@ ulfs_dirempty(struct inode *ip, ino_t pa
 	struct lfs_dirtemplate dbuf;
 	struct lfs_direct *dp = (struct lfs_direct *)&dbuf;
 	int error, namlen;
+	const char *name;
 	size_t count;
 #define	MINDIRSIZ (sizeof (struct lfs_dirtemplate) / 2)
 
@@ -1157,9 +1160,10 @@ ulfs_dirempty(struct inode *ip, ino_t pa
 			continue;
 		/* accept only "." and ".." */
 		namlen = lfs_dir_getnamlen(fs, dp);
+		name = dp->d_name;
 		if (namlen > 2)
 			return (0);
-		if (dp->d_name[0] != '.')
+		if (name[0] != '.')
 			return (0);
 		/*
 		 * At this point namlen must be 1 or 2.
@@ -1168,7 +1172,7 @@ ulfs_dirempty(struct inode *ip, ino_t pa
 		 */
 		if (namlen == 1 && lfs_dir_getino(fs, dp) == ip->i_number)
 			continue;
-		if (dp->d_name[1] == '.' && lfs_dir_getino(fs, dp) == parentino)
+		if (name[1] == '.' && lfs_dir_getino(fs, dp) == parentino)
 			continue;
 		return (0);
 	}

Reply via email to