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); }