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.
This commit is contained in:
dholland 2015-09-15 15:01:22 +00:00
parent c96fd3a912
commit 06be19e226
4 changed files with 53 additions and 33 deletions

View File

@ -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 inodesc *idesc)
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 lfs_direct *dp)
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);

View File

@ -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 */

View File

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

View File

@ -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, struct lfs_direct *ep, int entryoffsetinblock
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, struct lfs_direct *ep, int entryoffsetinblock
}
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 parentino, kauth_cred_t cred)
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 parentino, kauth_cred_t cred)
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 parentino, kauth_cred_t cred)
*/
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);
}