Add new accessors for the d_type and d_namlen fields of struct lfs_direct.

Napalm the old byteswap access logic for these.
This commit is contained in:
dholland 2015-09-01 06:16:58 +00:00
parent 8b103a9c19
commit ec175d5025
18 changed files with 399 additions and 252 deletions

View File

@ -21,7 +21,8 @@ struct clfs {
struct dlfs64 u_64;
} lfs_dlfs_u;
unsigned lfs_is64 : 1,
lfs_dobyteswap : 1;
lfs_dobyteswap : 1,
lfs_hasolddirfmt : 1;
/* Ifile */
int clfs_ifilefd; /* Ifile file descriptor */

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_cleanerd.c,v 1.52 2015/09/01 06:12:04 dholland Exp $ */
/* $NetBSD: lfs_cleanerd.c,v 1.53 2015/09/01 06:16:58 dholland Exp $ */
/*-
* Copyright (c) 2005 The NetBSD Foundation, Inc.
@ -270,6 +270,8 @@ init_fs(struct clfs *fs, char *fsname)
}
fs->lfs_is64 = 0; /* XXX notyet */
fs->lfs_dobyteswap = 0; /* XXX notyet */
/* XXX: can this ever need to be set? does the cleaner even care? */
fs->lfs_hasolddirfmt = 0;
/* If this is not a version 2 filesystem, complain and exit */
if (lfs_sb_getversion(fs) != 2) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.37 2015/09/01 06:08:37 dholland Exp $ */
/* $NetBSD: dir.c,v 1.38 2015/09/01 06:16:58 dholland Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -70,6 +70,7 @@ struct lfs_dirtemplate dirhead = {
.dotdot_namlen = 2,
.dotdot_name = ".."
};
#if 0
struct lfs_odirtemplate odirhead = {
.dot_ino = 0,
.dot_reclen = 12,
@ -80,6 +81,7 @@ struct lfs_odirtemplate odirhead = {
.dotdot_namlen = 2,
.dotdot_name = ".."
};
#endif
static int expanddir(struct uvnode *, union lfs_dinode *, char *);
static void freedir(ino_t, ino_t);
@ -193,8 +195,8 @@ fsck_readdir(struct uvnode *vp, struct inodesc *idesc)
dp = (struct lfs_direct *) (bp->b_data + idesc->id_loc);
dp->d_reclen = LFS_DIRBLKSIZ;
dp->d_ino = 0;
dp->d_type = 0;
dp->d_namlen = 0;
lfs_dir_settype(fs, dp, LFS_DT_UNKNOWN);
lfs_dir_setnamlen(fs, dp, 0);
dp->d_name[0] = '\0';
if (fix)
VOP_BWRITE(bp);
@ -266,9 +268,9 @@ dircheck(struct inodesc *idesc, struct lfs_direct *dp)
}
if (dp->d_ino == 0)
return (1);
size = LFS_DIRSIZ(0, dp, 0);
namlen = dp->d_namlen;
type = dp->d_type;
size = LFS_DIRSIZ(fs, dp);
namlen = lfs_dir_getnamlen(fs, dp);
type = lfs_dir_gettype(fs, dp);
if (dp->d_reclen < size ||
idesc->id_filesize < size ||
/* namlen > MAXNAMLEN || */
@ -366,12 +368,14 @@ mkentry(struct inodesc *idesc)
{
struct lfs_direct *dirp = idesc->id_dirp;
struct lfs_direct newent;
unsigned namlen;
int newlen, oldlen;
newent.d_namlen = strlen(idesc->id_name);
newlen = LFS_DIRSIZ(0, &newent, 0);
namlen = strlen(idesc->id_name);
lfs_dir_setnamlen(fs, &newent, namlen);
newlen = LFS_DIRSIZ(fs, &newent);
if (dirp->d_ino != 0)
oldlen = LFS_DIRSIZ(0, dirp, 0);
oldlen = LFS_DIRSIZ(fs, dirp);
else
oldlen = 0;
if (dirp->d_reclen - oldlen < newlen)
@ -381,9 +385,9 @@ mkentry(struct inodesc *idesc)
dirp = (struct lfs_direct *) (((char *) dirp) + oldlen);
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
dirp->d_reclen = newent.d_reclen;
dirp->d_type = typemap[idesc->id_parent];
dirp->d_namlen = newent.d_namlen;
memcpy(dirp->d_name, idesc->id_name, (size_t) dirp->d_namlen + 1);
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);
return (ALTERED | STOP);
}
@ -391,11 +395,13 @@ static int
chgino(struct inodesc *idesc)
{
struct lfs_direct *dirp = idesc->id_dirp;
int namlen;
if (memcmp(dirp->d_name, idesc->id_name, (int) dirp->d_namlen + 1))
namlen = lfs_dir_getnamlen(fs, dirp);
if (memcmp(dirp->d_name, idesc->id_name, namlen + 1))
return (KEEPON);
dirp->d_ino = idesc->id_parent;
dirp->d_type = typemap[idesc->id_parent];
lfs_dir_settype(fs, dirp, typemap[idesc->id_parent]);
return (ALTERED | STOP);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: inode.c,v 1.62 2015/09/01 06:15:02 dholland Exp $ */
/* $NetBSD: inode.c,v 1.63 2015/09/01 06:16:58 dholland Exp $ */
/*-
* Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
@ -507,8 +507,11 @@ findname(struct inodesc * idesc)
if (dirp->d_ino != idesc->id_parent)
return (KEEPON);
if ((len = dirp->d_namlen + 1) > MAXPATHLEN) {
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 */
len = MAXPATHLEN;
}
/* this is namebuf with utils.h */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass2.c,v 1.26 2015/08/12 18:28:00 dholland Exp $ */
/* $NetBSD: pass2.c,v 1.27 2015/09/01 06:16:58 dholland Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -229,24 +229,26 @@ pass2check(struct inodesc * idesc)
if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") == 0) {
if (dirp->d_ino != idesc->id_number) {
direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
dirp->d_ino = idesc->id_number;
if (reply("FIX") == 1)
if (reply("FIX") == 1) {
dirp->d_ino = idesc->id_number;
ret |= ALTERED;
}
}
if (dirp->d_type != LFS_DT_DIR) {
if (lfs_dir_gettype(fs, dirp) != LFS_DT_DIR) {
direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
dirp->d_type = LFS_DT_DIR;
if (reply("FIX") == 1)
if (reply("FIX") == 1) {
lfs_dir_settype(fs, dirp, LFS_DT_DIR);
ret |= ALTERED;
}
}
goto chk1;
}
direrror(idesc->id_number, "MISSING '.'");
proto.d_ino = idesc->id_number;
proto.d_type = LFS_DT_DIR;
proto.d_namlen = 1;
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(0, &proto, 0);
entrysize = LFS_DIRSIZ(fs, &proto);
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
dirp->d_name);
@ -274,12 +276,12 @@ chk1:
goto chk2;
inp = getinoinfo(idesc->id_number);
proto.d_ino = inp->i_parent;
proto.d_type = LFS_DT_DIR;
proto.d_namlen = 2;
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(0, &proto, 0);
entrysize = LFS_DIRSIZ(fs, &proto);
if (idesc->id_entryno == 0) {
n = LFS_DIRSIZ(0, dirp, 0);
n = LFS_DIRSIZ(fs, dirp);
if (dirp->d_reclen < n + entrysize)
goto chk2;
proto.d_reclen = dirp->d_reclen - n;
@ -292,9 +294,9 @@ chk1:
}
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
inp->i_dotdot = dirp->d_ino;
if (dirp->d_type != LFS_DT_DIR) {
if (lfs_dir_gettype(fs, dirp) != LFS_DT_DIR) {
direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
dirp->d_type = LFS_DT_DIR;
lfs_dir_settype(fs, dirp, LFS_DT_DIR);
if (reply("FIX") == 1)
ret |= ALTERED;
}
@ -327,21 +329,23 @@ chk1:
chk2:
if (dirp->d_ino == 0)
return (ret | KEEPON);
if (dirp->d_namlen <= 2 &&
if (lfs_dir_getnamlen(fs, dirp) <= 2 &&
dirp->d_name[0] == '.' &&
idesc->id_entryno >= 2) {
if (dirp->d_namlen == 1) {
if (lfs_dir_getnamlen(fs, dirp) == 1) {
direrror(idesc->id_number, "EXTRA '.' ENTRY");
dirp->d_ino = 0;
if (reply("FIX") == 1)
if (reply("FIX") == 1) {
dirp->d_ino = 0;
ret |= ALTERED;
}
return (KEEPON | ret);
}
if (dirp->d_name[1] == '.') {
direrror(idesc->id_number, "EXTRA '..' ENTRY");
dirp->d_ino = 0;
if (reply("FIX") == 1)
if (reply("FIX") == 1) {
dirp->d_ino = 0;
ret |= ALTERED;
}
return (KEEPON | ret);
}
}
@ -352,20 +356,22 @@ chk2:
n = reply("REMOVE");
} else if (dirp->d_ino == LFS_IFILE_INUM &&
idesc->id_number == ULFS_ROOTINO) {
if (dirp->d_type != LFS_DT_REG) {
if (lfs_dir_gettype(fs, dirp) != LFS_DT_REG) {
fileerror(idesc->id_number, dirp->d_ino,
"BAD TYPE FOR IFILE");
dirp->d_type = LFS_DT_REG;
if (reply("FIX") == 1)
if (reply("FIX") == 1) {
lfs_dir_settype(fs, dirp, LFS_DT_REG);
ret |= ALTERED;
}
}
} else if (((dirp->d_ino == ULFS_WINO && (dirp->d_type != LFS_DT_WHT)) ||
(dirp->d_ino != ULFS_WINO && dirp->d_type == LFS_DT_WHT))) {
} else if (((dirp->d_ino == ULFS_WINO && lfs_dir_gettype(fs, dirp) != LFS_DT_WHT) ||
(dirp->d_ino != ULFS_WINO && lfs_dir_gettype(fs, dirp) == LFS_DT_WHT))) {
fileerror(idesc->id_number, dirp->d_ino, "BAD WHITEOUT ENTRY");
dirp->d_ino = ULFS_WINO;
dirp->d_type = LFS_DT_WHT;
if (reply("FIX") == 1)
if (reply("FIX") == 1) {
lfs_dir_settype(fs, dirp, LFS_DT_WHT);
ret |= ALTERED;
}
} else {
again:
switch (statemap[dirp->d_ino]) {
@ -418,13 +424,13 @@ again:
/* fall through */
case FSTATE:
if (dirp->d_type != typemap[dirp->d_ino]) {
if (lfs_dir_gettype(fs, dirp) != typemap[dirp->d_ino]) {
fileerror(idesc->id_number, dirp->d_ino,
"BAD TYPE VALUE");
if (debug)
pwarn("dir has %d, typemap has %d\n",
dirp->d_type, typemap[dirp->d_ino]);
dirp->d_type = typemap[dirp->d_ino];
lfs_dir_gettype(fs, dirp), typemap[dirp->d_ino]);
lfs_dir_settype(fs, dirp, typemap[dirp->d_ino]);
if (reply("FIX") == 1)
ret |= ALTERED;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: make_lfs.c,v 1.48 2015/09/01 06:15:02 dholland Exp $ */
/* $NetBSD: make_lfs.c,v 1.49 2015/09/01 06:16:58 dholland Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -62,7 +62,7 @@
#if 0
static char sccsid[] = "@(#)lfs.c 8.5 (Berkeley) 5/24/95";
#else
__RCSID("$NetBSD: make_lfs.c,v 1.48 2015/09/01 06:15:02 dholland Exp $");
__RCSID("$NetBSD: make_lfs.c,v 1.49 2015/09/01 06:16:58 dholland Exp $");
#endif
#endif /* not lint */
@ -243,24 +243,62 @@ static const struct lfs lfs_default;
#define UMASK 0755
struct lfs_direct lfs_root_dir[] = {
{ ULFS_ROOTINO, sizeof(struct lfs_direct), LFS_DT_DIR, 1, "."},
{ ULFS_ROOTINO, sizeof(struct lfs_direct), LFS_DT_DIR, 2, ".."},
/* { LFS_IFILE_INUM, sizeof(struct lfs_direct), LFS_DT_REG, 5, "ifile"}, */
{
.d_ino = ULFS_ROOTINO,
.d_reclen = sizeof(struct lfs_direct),
.d_type = LFS_DT_DIR,
.d_namlen = 1,
.d_name = "."
},
{
.d_ino = ULFS_ROOTINO,
.d_reclen = sizeof(struct lfs_direct),
.d_type = LFS_DT_DIR,
.d_namlen = 2,
.d_name = ".."
},
/*
{
.d_ino = LFS_IFILE_INUM,
.d_reclen = sizeof(struct lfs_direct),
.d_type = LFS_DT_REG,
.d_namlen = 5,
.d_name = "ifile"
},
*/
#ifdef MAKE_LF_DIR
{ LOSTFOUNDINO, sizeof(struct lfs_direct), LFS_DT_DIR, 10, "lost+found"},
{
.d_ino = LOSTFOUNDINO,
.d_reclen = sizeof(struct lfs_direct),
.d_type = LFS_DT_DIR,
.d_namlen = 10,
.d_name = "lost+found"
},
#endif
};
#ifdef MAKE_LF_DIR
struct lfs_direct lfs_lf_dir[] = {
{ LOSTFOUNDINO, sizeof(struct lfs_direct), LFS_DT_DIR, 1, "." },
{ ULFS_ROOTINO, sizeof(struct lfs_direct), LFS_DT_DIR, 2, ".." },
{
.d_ino = LOSTFOUNDINO,
.d_reclen = sizeof(struct lfs_direct),
.d_type = LFS_DT_DIR,
.d_reclen = 1,
.d_name = "."
},
{
.d_ino = ULFS_ROOTINO,
.d_reclen = sizeof(struct lfs_direct),
.d_type = LFS_DT_DIR,
.d_reclen = 2,
.d_name = ".."
},
};
#endif
void pwarn(const char *, ...);
static void make_dinode(ino_t, union lfs_dinode *, int, struct lfs *);
static void make_dir( void *, struct lfs_direct *, int);
static void make_dir(struct lfs *, void *, struct lfs_direct *, int);
static uint64_t maxfilesize(int);
/*
@ -347,21 +385,21 @@ make_dinode(ino_t ino, union lfs_dinode *dip, int nfrags, struct lfs *fs)
* entries in protodir fit in the first DIRBLKSIZ.
*/
static void
make_dir(void *bufp, struct lfs_direct *protodir, int entries)
make_dir(struct lfs *fs, void *bufp, struct lfs_direct *protodir, int entries)
{
char *cp;
int i, spcleft;
spcleft = LFS_DIRBLKSIZ;
for (cp = bufp, i = 0; i < entries - 1; i++) {
protodir[i].d_reclen = LFS_DIRSIZ(LFS_NEWDIRFMT, &protodir[i], 0);
protodir[i].d_reclen = LFS_DIRSIZ(fs, &protodir[i]);
memmove(cp, &protodir[i], protodir[i].d_reclen);
cp += protodir[i].d_reclen;
if ((spcleft -= protodir[i].d_reclen) < 0)
fatal("%s: %s", special, "directory too big");
}
protodir[i].d_reclen = spcleft;
memmove(cp, &protodir[i], LFS_DIRSIZ(LFS_NEWDIRFMT, &protodir[i], 0));
memmove(cp, &protodir[i], LFS_DIRSIZ(fs, &protodir[i]));
}
int
@ -423,6 +461,7 @@ make_lfs(int devfd, uint secsize, struct dkwedge_info *dkw, int minfree,
}
fs->lfs_is64 = is64;
fs->lfs_dobyteswap = dobyteswap;
fs->lfs_hasolddirfmt = false;
fs->lfs_ivnode = vp;
fs->lfs_devvp = save_devvp;
@ -797,7 +836,7 @@ make_lfs(int devfd, uint secsize, struct dkwedge_info *dkw, int minfree,
VTOI(vp)->i_lfs_fragsize[i - 1] =
roundup(LFS_DIRBLKSIZ, lfs_sb_getfsize(fs));
bread(vp, 0, lfs_sb_getfsize(fs), 0, &bp);
make_dir(bp->b_data, lfs_root_dir,
make_dir(fs, bp->b_data, lfs_root_dir,
sizeof(lfs_root_dir) / sizeof(struct lfs_direct));
VOP_BWRITE(bp);
@ -817,7 +856,7 @@ make_lfs(int devfd, uint secsize, struct dkwedge_info *dkw, int minfree,
VTOI(vp)->i_lfs_fragsize[i - 1] =
roundup(DIRBLKSIZ,fs->lfs_fsize);
bread(vp, 0, fs->lfs_fsize, 0, &bp);
make_dir(bp->b_data, lfs_lf_dir,
make_dir(fs, bp->b_data, lfs_lf_dir,
sizeof(lfs_lf_dir) / sizeof(struct lfs_direct));
VOP_BWRITE(bp);
#endif /* MAKE_LF_DIR */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs.c,v 1.73 2015/09/01 06:12:04 dholland Exp $ */
/* $NetBSD: ufs.c,v 1.74 2015/09/01 06:16:58 dholland Exp $ */
/*-
* Copyright (c) 1993
@ -108,7 +108,9 @@ struct salfs {
struct dlfs u_32;
struct dlfs64 u_64;
} lfs_dlfs_u;
unsigned lfs_is64 : 1;
unsigned lfs_is64 : 1,
lfs_dobyteswap : 1,
lfs_hasolddirfmt : 1;
};
/* Get lfs accessors that use struct salfs. */
#define STRUCT_LFS struct salfs
@ -598,6 +600,8 @@ ufs_open(const char *path, struct open_file *f)
#endif
#if defined(LIBSA_LFS)
fs->lfs_is64 = 0;
fs->lfs_dobyteswap = 0;
fs->lfs_hasolddirfmt = (fs->fs_maxsymlinklen <= 0);
#endif
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs.h,v 1.184 2015/09/01 06:15:46 dholland Exp $ */
/* $NetBSD: lfs.h,v 1.185 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */
/* from NetBSD: dir.h,v 1.21 2009/07/22 04:49:19 dholland Exp */
@ -340,29 +340,6 @@
#define LFS_IFTODT(mode) (((mode) & 0170000) >> 12)
#define LFS_DTTOIF(dirtype) ((dirtype) << 12)
/*
* The LFS_DIRSIZ macro gives the minimum record length which will hold
* the directory entry. This requires the amount of space in struct lfs_direct
* without the d_name field, plus enough space for the name with a terminating
* null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
*/
#define LFS_DIRECTSIZ(namlen) \
((sizeof(struct lfs_direct) - (LFS_MAXNAMLEN+1)) + (((namlen)+1 + 3) &~ 3))
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define LFS_DIRSIZ(oldfmt, dp, needswap) \
(((oldfmt) && !(needswap)) ? \
LFS_DIRECTSIZ((dp)->d_type) : LFS_DIRECTSIZ((dp)->d_namlen))
#else
#define LFS_DIRSIZ(oldfmt, dp, needswap) \
(((oldfmt) && (needswap)) ? \
LFS_DIRECTSIZ((dp)->d_type) : LFS_DIRECTSIZ((dp)->d_namlen))
#endif
/* Constants for the first argument of LFS_DIRSIZ */
#define LFS_OLDDIRFMT 1
#define LFS_NEWDIRFMT 0
/*
* Theoretically, directories can be more than 2Gb in length; however, in
* practice this seems unlikely. So, we define the type doff_t as a 32-bit
@ -960,7 +937,8 @@ struct lfs {
/* These fields are set at mount time and are meaningless on disk. */
unsigned lfs_is64 : 1, /* are we lfs64 or lfs32? */
lfs_dobyteswap : 1; /* are we opposite-endian? */
lfs_dobyteswap : 1, /* are we opposite-endian? */
lfs_hasolddirfmt : 1; /* dir entries have no d_type */
struct segment *lfs_sp; /* current segment being written */
struct vnode *lfs_ivnode; /* vnode for the ifile */

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_accessors.h,v 1.21 2015/09/01 06:13:09 dholland Exp $ */
/* $NetBSD: lfs_accessors.h,v 1.22 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: lfs.h,v 1.165 2015/07/24 06:59:32 dholland Exp */
/* from NetBSD: dinode.h,v 1.22 2013/01/22 09:39:18 dholland Exp */
@ -201,6 +201,157 @@
((fs)->lfs_dobyteswap ? bswap64(val) : (val))
#endif
/*
* For handling directories we will need to know if the volume is
* little-endian.
*/
#if BYTE_ORDER == LITTLE_ENDIAN
#define LFS_LITTLE_ENDIAN_ONDISK(fs) (!(fs)->lfs_dobyteswap)
#else
#define LFS_LITTLE_ENDIAN_ONDISK(fs) ((fs)->lfs_dobyteswap)
#endif
/*
* directories
*/
/*
* The LFS_DIRSIZ macro gives the minimum record length which will hold
* the directory entry. This requires the amount of space in struct lfs_direct
* without the d_name field, plus enough space for the name with a terminating
* null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
*/
#define LFS_DIRECTSIZ(namlen) \
((sizeof(struct lfs_direct) - (LFS_MAXNAMLEN+1)) + (((namlen)+1 + 3) &~ 3))
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define LFS_OLDDIRSIZ(oldfmt, dp, needswap) \
(((oldfmt) && !(needswap)) ? \
LFS_DIRECTSIZ((dp)->d_type) : LFS_DIRECTSIZ((dp)->d_namlen))
#else
#define LFS_OLDDIRSIZ(oldfmt, dp, needswap) \
(((oldfmt) && (needswap)) ? \
LFS_DIRECTSIZ((dp)->d_type) : LFS_DIRECTSIZ((dp)->d_namlen))
#endif
#define LFS_DIRSIZ(fs, dp) LFS_DIRECTSIZ(lfs_dir_getnamlen(fs, dp))
/* Constants for the first argument of LFS_OLDDIRSIZ */
#define LFS_OLDDIRFMT 1
#define LFS_NEWDIRFMT 0
static __unused inline uint8_t
lfs_dir_gettype(const STRUCT_LFS *fs, const struct lfs_direct *dp)
{
if (fs->lfs_hasolddirfmt) {
return LFS_DT_UNKNOWN;
}
return dp->d_type;
}
static __unused inline uint8_t
lfs_dir_getnamlen(const STRUCT_LFS *fs, const struct lfs_direct *dp)
{
if (fs->lfs_hasolddirfmt && LFS_LITTLE_ENDIAN_ONDISK(fs)) {
/* low-order byte of old 16-bit namlen field */
return dp->d_type;
}
return dp->d_namlen;
}
static __unused inline void
lfs_dir_settype(const STRUCT_LFS *fs, struct lfs_direct *dp, uint8_t type)
{
if (fs->lfs_hasolddirfmt) {
/* do nothing */
return;
}
dp->d_type = type;
}
static __unused inline void
lfs_dir_setnamlen(const STRUCT_LFS *fs, struct lfs_direct *dp, uint8_t namlen)
{
if (fs->lfs_hasolddirfmt && LFS_LITTLE_ENDIAN_ONDISK(fs)) {
/* low-order byte of old 16-bit namlen field */
dp->d_type = namlen;
}
dp->d_namlen = namlen;
}
/*
* These are called "dirt" because they ought to be cleaned up.
*/
static __unused inline uint8_t
lfs_dirt_getdottype(const STRUCT_LFS *fs, const struct lfs_dirtemplate *dp)
{
if (fs->lfs_hasolddirfmt) {
return LFS_DT_UNKNOWN;
}
return dp->dot_type;
}
static __unused inline uint8_t
lfs_dirt_getdotnamlen(const STRUCT_LFS *fs, const struct lfs_dirtemplate *dp)
{
if (fs->lfs_hasolddirfmt && LFS_LITTLE_ENDIAN_ONDISK(fs)) {
/* low-order byte of old 16-bit namlen field */
return dp->dot_type;
}
return dp->dot_namlen;
}
static __unused inline uint8_t
lfs_dirt_getdotdottype(const STRUCT_LFS *fs, const struct lfs_dirtemplate *dp)
{
if (fs->lfs_hasolddirfmt) {
return LFS_DT_UNKNOWN;
}
return dp->dotdot_type;
}
static __unused inline uint8_t
lfs_dirt_getdotdotnamlen(const STRUCT_LFS *fs, const struct lfs_dirtemplate *dp)
{
if (fs->lfs_hasolddirfmt && LFS_LITTLE_ENDIAN_ONDISK(fs)) {
/* low-order byte of old 16-bit namlen field */
return dp->dotdot_type;
}
return dp->dotdot_namlen;
}
static __unused inline void
lfs_dirt_settypes(const STRUCT_LFS *fs, struct lfs_dirtemplate *dtp,
unsigned dt1, unsigned dt2)
{
if (fs->lfs_hasolddirfmt) {
/* do nothing */
return;
}
dtp->dot_type = dt1;
dtp->dotdot_type = dt2;
}
static __unused inline void
lfs_dirt_setnamlens(const STRUCT_LFS *fs, struct lfs_dirtemplate *dtp,
unsigned len1, unsigned len2)
{
if (fs->lfs_hasolddirfmt && LFS_LITTLE_ENDIAN_ONDISK(fs)) {
/* low-order bytes of old 16-bit namlen field */
dtp->dot_type = len1;
dtp->dotdot_type = len2;
/* clear the high-order bytes */
dtp->dot_namlen = 0;
dtp->dotdot_namlen = 0;
return;
}
dtp->dot_namlen = len1;
dtp->dotdot_namlen = len2;
}
/*
* dinodes
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_rename.c,v 1.8 2015/03/27 17:27:56 riastradh Exp $ */
/* $NetBSD: lfs_rename.c,v 1.9 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: ufs_rename.c,v 1.6 2013/01/22 09:39:18 dholland Exp */
/*-
@ -89,7 +89,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_rename.c,v 1.8 2015/03/27 17:27:56 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_rename.c,v 1.9 2015/09/01 06:16:59 dholland Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -124,6 +124,7 @@ __KERNEL_RCSID(0, "$NetBSD: lfs_rename.c,v 1.8 2015/03/27 17:27:56 riastradh Exp
#include <ufs/lfs/ulfs_extern.h>
#include <ufs/lfs/lfs.h>
#include <ufs/lfs/lfs_accessors.h>
#include <ufs/lfs/lfs_extern.h>
/*
@ -329,20 +330,16 @@ ulfs_rename_ulr_overlap_p(const struct ulfs_lookup_results *fulr,
static int /* XXX int? uint8_t? */
ulfs_direct_namlen(const struct lfs_direct *ep, const struct vnode *vp)
{
bool swap;
struct lfs *fs;
KASSERT(ep != NULL);
KASSERT(vp != NULL);
KASSERT(VTOI(vp) != NULL);
KASSERT(VTOI(vp)->i_ump != NULL);
KASSERT(VTOI(vp)->i_lfs != NULL);
fs = VTOI(vp)->i_lfs;
#if (BYTE_ORDER == LITTLE_ENDIAN)
swap = (ULFS_IPNEEDSWAP(VTOI(vp)) == 0);
#else
swap = (ULFS_IPNEEDSWAP(VTOI(vp)) != 0);
#endif
return ((FSFMT(vp) && swap)? ep->d_type : ep->d_namlen);
return lfs_dir_getnamlen(fs, ep);
}
/*
@ -598,21 +595,16 @@ static int /* XXX int? uint8_t? */
ulfs_dirbuf_dotdot_namlen(const struct lfs_dirtemplate *dirbuf,
const struct vnode *vp)
{
bool swap;
struct lfs *fs;
KASSERT(dirbuf != NULL);
KASSERT(vp != NULL);
KASSERT(VTOI(vp) != NULL);
KASSERT(VTOI(vp)->i_ump != NULL);
KASSERT(VTOI(vp)->i_lfs != NULL);
fs = VTOI(vp)->i_lfs;
#if (BYTE_ORDER == LITTLE_ENDIAN)
swap = (ULFS_IPNEEDSWAP(VTOI(vp)) == 0);
#else
swap = (ULFS_IPNEEDSWAP(VTOI(vp)) != 0);
#endif
return ((FSFMT(vp) && swap)?
dirbuf->dotdot_type : dirbuf->dotdot_namlen);
return lfs_dirt_getdotdotnamlen(fs, dirbuf);
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vfsops.c,v 1.344 2015/09/01 06:11:06 dholland Exp $ */
/* $NetBSD: lfs_vfsops.c,v 1.345 2015/09/01 06:16:59 dholland Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.344 2015/09/01 06:11:06 dholland Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.345 2015/09/01 06:16:59 dholland Exp $");
#if defined(_KERNEL_OPT)
#include "opt_lfs.h"
@ -958,6 +958,7 @@ lfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
memcpy(&fs->lfs_dlfs_u.u_32, tdfs, sizeof(struct dlfs));
fs->lfs_is64 = false; /* XXX notyet */
fs->lfs_dobyteswap = false; /* XXX notyet */
fs->lfs_hasolddirfmt = false; /* set for real below */
/* Compatibility */
if (lfs_sb_getversion(fs) < 2) {
@ -1065,6 +1066,8 @@ lfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
mp->mnt_fs_bshift = lfs_sb_getbshift(fs);
if (fs->um_maxsymlinklen > 0)
mp->mnt_iflag |= IMNT_DTYPE;
else
fs->lfs_hasolddirfmt = true;
ump->um_mountp = mp;
ump->um_dev = dev;

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vnops.c,v 1.288 2015/09/01 06:08:37 dholland Exp $ */
/* $NetBSD: lfs_vnops.c,v 1.289 2015/09/01 06:16:59 dholland Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
@ -125,7 +125,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.288 2015/09/01 06:08:37 dholland Exp $");
__KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.289 2015/09/01 06:16:59 dholland Exp $");
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
@ -944,19 +944,8 @@ lfs_mkdir(void *v)
ULFS_MPNEEDSWAP(fs));
dirtemplate.dotdot_reclen = ulfs_rw16(dirtemplate.dotdot_reclen,
ULFS_MPNEEDSWAP(fs));
if (fs->um_maxsymlinklen <= 0) {
#if BYTE_ORDER == LITTLE_ENDIAN
if (ULFS_MPNEEDSWAP(fs) == 0)
#else
if (ULFS_MPNEEDSWAP(fs) != 0)
#endif
{
dirtemplate.dot_type = dirtemplate.dot_namlen;
dirtemplate.dotdot_type = dirtemplate.dotdot_namlen;
dirtemplate.dot_namlen = dirtemplate.dotdot_namlen = 0;
} else
dirtemplate.dot_type = dirtemplate.dotdot_type = 0;
}
lfs_dirt_settypes(fs, &dirtemplate, LFS_DT_DIR, LFS_DT_DIR);
lfs_dirt_setnamlens(fs, &dirtemplate, 1, 2);
if ((error = lfs_balloc(tvp, (off_t)0, dirblksiz, cnp->cn_cred,
B_CLRBUF, &bp)) != 0)
goto bad;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulfs_dirhash.c,v 1.8 2014/02/25 18:30:13 pooka Exp $ */
/* $NetBSD: ulfs_dirhash.c,v 1.9 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: ufs_dirhash.c,v 1.34 2009/10/05 23:48:08 rmind Exp */
/*
@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ulfs_dirhash.c,v 1.8 2014/02/25 18:30:13 pooka Exp $");
__KERNEL_RCSID(0, "$NetBSD: ulfs_dirhash.c,v 1.9 2015/09/01 06:16:59 dholland Exp $");
/*
* This implements a hash-based lookup scheme for ULFS directories.
@ -49,6 +49,8 @@ __KERNEL_RCSID(0, "$NetBSD: ulfs_dirhash.c,v 1.8 2014/02/25 18:30:13 pooka Exp $
#include <sys/sysctl.h>
#include <sys/atomic.h>
#include <ufs/lfs/lfs.h>
#include <ufs/lfs/lfs_accessors.h>
#include <ufs/lfs/ulfs_inode.h>
#include <ufs/lfs/ulfs_dirhash.h>
#include <ufs/lfs/ulfsmount.h>
@ -112,13 +114,13 @@ static struct sysctllog *ulfsdirhash_sysctl_log;
int
ulfsdirhash_build(struct inode *ip)
{
struct lfs *fs = ip->i_lfs;
struct dirhash *dh;
struct buf *bp = NULL;
struct lfs_direct *ep;
struct vnode *vp;
doff_t bmask, pos;
int dirblocks, i, j, memreqd, nblocks, narrays, nslots, slot;
const int needswap = ULFS_IPNEEDSWAP(ip);
int dirblksiz = ip->i_lfs->um_dirblksiz;
/* Check if we can/should use dirhash. */
@ -234,12 +236,13 @@ ulfsdirhash_build(struct inode *ip)
}
if (ep->d_ino != 0) {
/* Add the entry (simplified ulfsdirhash_add). */
slot = ulfsdirhash_hash(dh, ep->d_name, ep->d_namlen);
slot = ulfsdirhash_hash(dh, ep->d_name,
lfs_dir_getnamlen(fs, ep));
while (DH_ENTRY(dh, slot) != DIRHASH_EMPTY)
slot = WRAPINCR(slot, dh->dh_hlen);
dh->dh_hused++;
DH_ENTRY(dh, slot) = pos;
ulfsdirhash_adjfree(dh, pos, -LFS_DIRSIZ(0, ep, needswap),
ulfsdirhash_adjfree(dh, pos, -LFS_DIRSIZ(fs, ep),
dirblksiz);
}
pos += ep->d_reclen;
@ -323,13 +326,13 @@ int
ulfsdirhash_lookup(struct inode *ip, const char *name, int namelen, doff_t *offp,
struct buf **bpp, doff_t *prevoffp)
{
struct lfs *fs = ip->i_lfs;
struct dirhash *dh, *dh_next;
struct lfs_direct *dp;
struct vnode *vp;
struct buf *bp;
doff_t blkoff, bmask, offset, prevoff;
int i, slot;
const int needswap = ULFS_IPNEEDSWAP(ip);
int dirblksiz = ip->i_lfs->um_dirblksiz;
if ((dh = ip->i_dirhash) == NULL)
@ -429,7 +432,7 @@ restart:
brelse(bp, 0);
return (EJUSTRETURN);
}
if (dp->d_namlen == namelen &&
if (lfs_dir_getnamlen(fs, dp) == namelen &&
memcmp(dp->d_name, name, namelen) == 0) {
/* Found. Get the prev offset if needed. */
if (prevoffp != NULL) {
@ -448,7 +451,7 @@ restart:
/* Check for sequential access, and update offset. */
if (dh->dh_seqopt == 0 && dh->dh_seqoff == offset)
dh->dh_seqopt = 1;
dh->dh_seqoff = offset + LFS_DIRSIZ(0, dp, needswap);
dh->dh_seqoff = offset + LFS_DIRSIZ(fs, dp);
DIRHASH_UNLOCK(dh);
*bpp = bp;
@ -497,12 +500,12 @@ restart:
doff_t
ulfsdirhash_findfree(struct inode *ip, int slotneeded, int *slotsize)
{
struct lfs *fs = ip->i_lfs;
struct lfs_direct *dp;
struct dirhash *dh;
struct buf *bp;
doff_t pos, slotstart;
int dirblock, error, freebytes, i;
const int needswap = ULFS_IPNEEDSWAP(ip);
int dirblksiz = ip->i_lfs->um_dirblksiz;
if ((dh = ip->i_dirhash) == NULL)
@ -540,7 +543,7 @@ ulfsdirhash_findfree(struct inode *ip, int slotneeded, int *slotsize)
brelse(bp, 0);
return (-1);
}
if (dp->d_ino == 0 || dp->d_reclen > LFS_DIRSIZ(0, dp, needswap))
if (dp->d_ino == 0 || dp->d_reclen > LFS_DIRSIZ(fs, dp))
break;
i += dp->d_reclen;
dp = (struct lfs_direct *)((char *)dp + dp->d_reclen);
@ -557,7 +560,7 @@ ulfsdirhash_findfree(struct inode *ip, int slotneeded, int *slotsize)
while (i < dirblksiz && freebytes < slotneeded) {
freebytes += dp->d_reclen;
if (dp->d_ino != 0)
freebytes -= LFS_DIRSIZ(0, dp, needswap);
freebytes -= LFS_DIRSIZ(fs, dp);
if (dp->d_reclen == 0) {
DIRHASH_UNLOCK(dh);
brelse(bp, 0);
@ -620,9 +623,9 @@ ulfsdirhash_enduseful(struct inode *ip)
void
ulfsdirhash_add(struct inode *ip, struct lfs_direct *dirp, doff_t offset)
{
struct lfs *fs = ip->i_lfs;
struct dirhash *dh;
int slot;
const int needswap = ULFS_IPNEEDSWAP(ip);
int dirblksiz = ip->i_lfs->um_dirblksiz;
if ((dh = ip->i_dirhash) == NULL)
@ -647,7 +650,7 @@ ulfsdirhash_add(struct inode *ip, struct lfs_direct *dirp, doff_t offset)
}
/* Find a free hash slot (empty or deleted), and add the entry. */
slot = ulfsdirhash_hash(dh, dirp->d_name, dirp->d_namlen);
slot = ulfsdirhash_hash(dh, dirp->d_name, lfs_dir_getnamlen(fs, dirp));
while (DH_ENTRY(dh, slot) >= 0)
slot = WRAPINCR(slot, dh->dh_hlen);
if (DH_ENTRY(dh, slot) == DIRHASH_EMPTY)
@ -655,7 +658,7 @@ ulfsdirhash_add(struct inode *ip, struct lfs_direct *dirp, doff_t offset)
DH_ENTRY(dh, slot) = offset;
/* Update the per-block summary info. */
ulfsdirhash_adjfree(dh, offset, -LFS_DIRSIZ(0, dirp, needswap), dirblksiz);
ulfsdirhash_adjfree(dh, offset, -LFS_DIRSIZ(fs, dirp), dirblksiz);
DIRHASH_UNLOCK(dh);
}
@ -667,9 +670,9 @@ ulfsdirhash_add(struct inode *ip, struct lfs_direct *dirp, doff_t offset)
void
ulfsdirhash_remove(struct inode *ip, struct lfs_direct *dirp, doff_t offset)
{
struct lfs *fs = ip->i_lfs;
struct dirhash *dh;
int slot;
const int needswap = ULFS_IPNEEDSWAP(ip);
int dirblksiz = ip->i_lfs->um_dirblksiz;
if ((dh = ip->i_dirhash) == NULL)
@ -684,13 +687,14 @@ ulfsdirhash_remove(struct inode *ip, struct lfs_direct *dirp, doff_t offset)
KASSERT(offset < dh->dh_dirblks * dirblksiz);
/* Find the entry */
slot = ulfsdirhash_findslot(dh, dirp->d_name, dirp->d_namlen, offset);
slot = ulfsdirhash_findslot(dh, dirp->d_name,
lfs_dir_getnamlen(fs, dirp), offset);
/* Remove the hash entry. */
ulfsdirhash_delslot(dh, slot);
/* Update the per-block summary info. */
ulfsdirhash_adjfree(dh, offset, LFS_DIRSIZ(0, dirp, needswap), dirblksiz);
ulfsdirhash_adjfree(dh, offset, LFS_DIRSIZ(fs, dirp), dirblksiz);
DIRHASH_UNLOCK(dh);
}
@ -702,6 +706,7 @@ void
ulfsdirhash_move(struct inode *ip, struct lfs_direct *dirp, doff_t oldoff,
doff_t newoff)
{
struct lfs *fs = ip->i_lfs;
struct dirhash *dh;
int slot;
@ -717,7 +722,8 @@ ulfsdirhash_move(struct inode *ip, struct lfs_direct *dirp, doff_t oldoff,
KASSERT(oldoff < dh->dh_dirblks * ip->i_lfs->um_dirblksiz &&
newoff < dh->dh_dirblks * ip->i_lfs->um_dirblksiz);
/* Find the entry, and update the offset. */
slot = ulfsdirhash_findslot(dh, dirp->d_name, dirp->d_namlen, oldoff);
slot = ulfsdirhash_findslot(dh, dirp->d_name,
lfs_dir_getnamlen(fs, dirp), oldoff);
DH_ENTRY(dh, slot) = newoff;
DIRHASH_UNLOCK(dh);
}
@ -822,10 +828,10 @@ ulfsdirhash_dirtrunc(struct inode *ip, doff_t offset)
void
ulfsdirhash_checkblock(struct inode *ip, char *sbuf, doff_t offset)
{
struct lfs *fs = ip->i_lfs;
struct dirhash *dh;
struct lfs_direct *dp;
int block, ffslot, i, nfree;
const int needswap = ULFS_IPNEEDSWAP(ip);
int dirblksiz = ip->i_lfs->um_dirblksiz;
if (!ulfs_dirhashcheck)
@ -866,9 +872,10 @@ ulfsdirhash_checkblock(struct inode *ip, char *sbuf, doff_t offset)
}
/* Check that the entry exists (will panic if it doesn't). */
ulfsdirhash_findslot(dh, dp->d_name, dp->d_namlen, offset + i);
ulfsdirhash_findslot(dh, dp->d_name, lfs_dir_getnamlen(fs, dp),
offset + i);
nfree += dp->d_reclen - LFS_DIRSIZ(0, dp, needswap);
nfree += dp->d_reclen - LFS_DIRSIZ(fs, dp);
}
if (i != dirblksiz)
panic("ulfsdirhash_checkblock: bad dir end");

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulfs_extern.h,v 1.15 2015/05/31 15:48:03 hannken Exp $ */
/* $NetBSD: ulfs_extern.h,v 1.16 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: ufs_extern.h,v 1.72 2012/05/09 00:21:18 riastradh Exp */
/*-
@ -114,6 +114,8 @@ void ulfs_dirbad(struct inode *, doff_t, const char *);
int ulfs_dirbadentry(struct vnode *, struct lfs_direct *, int);
void ulfs_makedirentry(struct inode *, struct componentname *,
struct lfs_direct *);
void ulfs_makedirentry_bytype(struct lfs *, struct componentname *,
ino_t, unsigned /*dtype*/, struct lfs_direct *);
int ulfs_direnter(struct vnode *, const struct ulfs_lookup_results *,
struct vnode *, struct lfs_direct *,
struct componentname *, struct buf *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulfs_inode.c,v 1.10 2015/05/31 15:48:03 hannken Exp $ */
/* $NetBSD: ulfs_inode.c,v 1.11 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: ufs_inode.c,v 1.89 2013/01/22 09:39:18 dholland Exp */
/*
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ulfs_inode.c,v 1.10 2015/05/31 15:48:03 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: ulfs_inode.c,v 1.11 2015/09/01 06:16:59 dholland Exp $");
#if defined(_KERNEL_OPT)
#include "opt_lfs.h"
@ -58,6 +58,8 @@ __KERNEL_RCSID(0, "$NetBSD: ulfs_inode.c,v 1.10 2015/05/31 15:48:03 hannken Exp
#include <sys/fstrans.h>
#include <sys/kmem.h>
#include <ufs/lfs/lfs.h>
#include <ufs/lfs/lfs_accessors.h>
#include <ufs/lfs/lfs_extern.h>
#include <ufs/lfs/ulfs_inode.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulfs_lookup.c,v 1.25 2015/07/11 11:04:48 mlelstv Exp $ */
/* $NetBSD: ulfs_lookup.c,v 1.26 2015/09/01 06:16:59 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.25 2015/07/11 11:04:48 mlelstv Exp $");
__KERNEL_RCSID(0, "$NetBSD: ulfs_lookup.c,v 1.26 2015/09/01 06:16:59 dholland Exp $");
#ifdef _KERNEL_OPT
#include "opt_lfs.h"
@ -59,6 +59,8 @@ __KERNEL_RCSID(0, "$NetBSD: ulfs_lookup.c,v 1.25 2015/07/11 11:04:48 mlelstv Exp
#include <sys/proc.h>
#include <sys/kmem.h>
#include <ufs/lfs/lfs.h>
#include <ufs/lfs/lfs_accessors.h>
#include <ufs/lfs/lfs_extern.h>
#include <ufs/lfs/ulfs_inode.h>
@ -348,7 +350,7 @@ searchloop:
int size = ulfs_rw16(ep->d_reclen, needswap);
if (ep->d_ino != 0)
size -= LFS_DIRSIZ(FSFMT(vdp), ep, needswap);
size -= LFS_DIRSIZ(fs, ep);
if (size > 0) {
if (size >= slotneeded) {
slotstatus = FOUND;
@ -376,17 +378,7 @@ searchloop:
if (ep->d_ino) {
int namlen;
#if (BYTE_ORDER == LITTLE_ENDIAN)
if (FSFMT(vdp) && needswap == 0)
namlen = ep->d_type;
else
namlen = ep->d_namlen;
#else
if (FSFMT(vdp) && needswap != 0)
namlen = ep->d_type;
else
namlen = ep->d_namlen;
#endif
namlen = lfs_dir_getnamlen(fs, ep);
if (namlen == cnp->cn_namelen &&
!memcmp(cnp->cn_nameptr, ep->d_name,
(unsigned)namlen)) {
@ -397,7 +389,7 @@ foundentry:
* Save directory entry's inode number and
* reclen, and release directory buffer.
*/
if (!FSFMT(vdp) && ep->d_type == LFS_DT_WHT) {
if (!FSFMT(vdp) && lfs_dir_gettype(fs, ep) == LFS_DT_WHT) {
slotstatus = FOUND;
slotoffset = results->ulr_offset;
slotsize = ulfs_rw16(ep->d_reclen,
@ -528,10 +520,10 @@ found:
* Check that directory length properly reflects presence
* of this entry.
*/
if (results->ulr_offset + LFS_DIRSIZ(FSFMT(vdp), ep, needswap) > dp->i_size) {
if (results->ulr_offset + LFS_DIRSIZ(fs, ep) > dp->i_size) {
ulfs_dirbad(dp, results->ulr_offset, "i_size too small");
dp->i_size =
results->ulr_offset + LFS_DIRSIZ(FSFMT(vdp), ep, needswap);
results->ulr_offset + LFS_DIRSIZ(fs, ep);
DIP_ASSIGN(dp, size, dp->i_size);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
}
@ -679,28 +671,17 @@ ulfs_dirbadentry(struct vnode *dp, struct lfs_direct *ep, int entryoffsetinblock
const int needswap = ULFS_MPNEEDSWAP(fs);
int dirblksiz = fs->um_dirblksiz;
#if (BYTE_ORDER == LITTLE_ENDIAN)
if (FSFMT(dp) && needswap == 0)
namlen = ep->d_type;
else
namlen = ep->d_namlen;
#else
if (FSFMT(dp) && needswap != 0)
namlen = ep->d_type;
else
namlen = ep->d_namlen;
#endif
namlen = lfs_dir_getnamlen(fs, ep);
if ((ulfs_rw16(ep->d_reclen, needswap) & 0x3) != 0 ||
ulfs_rw16(ep->d_reclen, needswap) >
dirblksiz - (entryoffsetinblock & (dirblksiz - 1)) ||
ulfs_rw16(ep->d_reclen, needswap) <
LFS_DIRSIZ(FSFMT(dp), ep, needswap) ||
ulfs_rw16(ep->d_reclen, needswap) < LFS_DIRSIZ(fs, ep) ||
namlen > LFS_MAXNAMLEN) {
/*return (1); */
printf("First bad, reclen=%#x, DIRSIZ=%lu, namlen=%d, "
"flags=%#x, entryoffsetinblock=%d, dirblksiz = %d\n",
ulfs_rw16(ep->d_reclen, needswap),
(u_long)LFS_DIRSIZ(FSFMT(dp), ep, needswap),
(u_long)LFS_DIRSIZ(fs, ep),
namlen, dp->v_mount->mnt_flag, entryoffsetinblock,
dirblksiz);
goto bad;
@ -724,19 +705,34 @@ bad:
* Construct a new directory entry after a call to namei, using the
* name in the componentname argument cnp. The argument ip is the
* inode to which the new directory entry will refer.
*
* Does not set d_reclen.
*/
void
ulfs_makedirentry(struct inode *ip, struct componentname *cnp,
struct lfs_direct *newdirp)
{
struct lfs *fs = ip->i_lfs;
newdirp->d_ino = ip->i_number;
newdirp->d_namlen = cnp->cn_namelen;
memcpy(newdirp->d_name, cnp->cn_nameptr, (size_t)cnp->cn_namelen);
newdirp->d_name[cnp->cn_namelen] = '\0';
if (FSFMT(ITOV(ip)))
newdirp->d_type = 0;
else
newdirp->d_type = LFS_IFTODT(ip->i_mode);
lfs_dir_setnamlen(fs, newdirp, cnp->cn_namelen);
lfs_dir_settype(fs, newdirp, LFS_IFTODT(ip->i_mode));
}
/*
* Similar but for special inodes.
*/
void
ulfs_makedirentry_bytype(struct lfs *fs, struct componentname *cnp,
ino_t inum, unsigned dtype, struct lfs_direct *newdirp)
{
newdirp->d_ino = inum;
memcpy(newdirp->d_name, cnp->cn_nameptr, (size_t)cnp->cn_namelen);
newdirp->d_name[cnp->cn_namelen] = '\0';
lfs_dir_setnamlen(fs, newdirp, cnp->cn_namelen);
lfs_dir_settype(fs, newdirp, dtype);
}
/*
@ -754,6 +750,12 @@ ulfs_makedirentry(struct inode *ip, struct componentname *cnp,
* The link count of the target inode is *not* incremented; the
* caller does that.
*
* DIRP should have been filled in by ulfs_makedirentry(). Manual
* initialization should be avoided, but if needed should be
* equivalent to ulfs_makedirentry in byteswapping, use of accessor
* functions, etc.; otherwise we might byteswap too many times or not
* enough.
*
* If ulr->ulr_count is 0, ulfs_lookup did not find space to insert the
* directory entry. ulr_offset, which is the place to put the entry,
* should be on a block boundary (and should be at the end of the
@ -791,7 +793,7 @@ ulfs_direnter(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
cr = cnp->cn_cred;
dp = VTOI(dvp);
newentrysize = LFS_DIRSIZ(0, dirp, 0);
newentrysize = LFS_DIRSIZ(fs, dirp);
if (ulr->ulr_count == 0) {
/*
@ -812,17 +814,7 @@ ulfs_direnter(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
uvm_vnp_setsize(dvp, dp->i_size);
dirp->d_reclen = ulfs_rw16(dirblksiz, needswap);
dirp->d_ino = ulfs_rw32(dirp->d_ino, needswap);
if (FSFMT(dvp)) {
#if (BYTE_ORDER == LITTLE_ENDIAN)
if (needswap == 0) {
#else
if (needswap != 0) {
#endif
u_char tmp = dirp->d_namlen;
dirp->d_namlen = dirp->d_type;
dirp->d_type = tmp;
}
}
/* d_type/d_namlen are handled in ulfs_makedirentry */
lfs_blkoff = ulr->ulr_offset & (ump->um_mountp->mnt_stat.f_iosize - 1);
memcpy((char *)bp->b_data + lfs_blkoff, dirp, newentrysize);
#ifdef LFS_DIRHASH
@ -880,7 +872,7 @@ ulfs_direnter(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
* ulr_offset + ulr_count would yield the space.
*/
ep = (struct lfs_direct *)dirbuf;
dsize = (ep->d_ino != 0) ? LFS_DIRSIZ(FSFMT(dvp), ep, needswap) : 0;
dsize = (ep->d_ino != 0) ? LFS_DIRSIZ(fs, ep) : 0;
spacefree = ulfs_rw16(ep->d_reclen, needswap) - dsize;
for (loc = ulfs_rw16(ep->d_reclen, needswap); loc < ulr->ulr_count; ) {
uint16_t reclen;
@ -907,7 +899,7 @@ ulfs_direnter(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
dsize = 0;
continue;
}
dsize = LFS_DIRSIZ(FSFMT(dvp), nep, needswap);
dsize = LFS_DIRSIZ(fs, nep);
spacefree += reclen - dsize;
#ifdef LFS_DIRHASH
if (dp->i_dirhash != NULL)
@ -928,7 +920,7 @@ ulfs_direnter(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
*/
if (ep->d_ino == 0 ||
(ulfs_rw32(ep->d_ino, needswap) == ULFS_WINO &&
memcmp(ep->d_name, dirp->d_name, dirp->d_namlen) == 0)) {
memcmp(ep->d_name, dirp->d_name, lfs_dir_getnamlen(fs, dirp)) == 0)) {
if (spacefree + dsize < newentrysize)
panic("ulfs_direnter: compact1");
dirp->d_reclen = spacefree + dsize;
@ -941,17 +933,7 @@ ulfs_direnter(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
}
dirp->d_reclen = ulfs_rw16(dirp->d_reclen, needswap);
dirp->d_ino = ulfs_rw32(dirp->d_ino, needswap);
if (FSFMT(dvp)) {
#if (BYTE_ORDER == LITTLE_ENDIAN)
if (needswap == 0) {
#else
if (needswap != 0) {
#endif
u_char tmp = dirp->d_namlen;
dirp->d_namlen = dirp->d_type;
dirp->d_type = tmp;
}
}
/* d_type/d_namlen are handled in ulfs_makedirentry */
#ifdef LFS_DIRHASH
if (dp->i_dirhash != NULL && (ep->d_ino == 0 ||
dirp->d_reclen == spacefree))
@ -1023,6 +1005,7 @@ ulfs_dirremove(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
struct inode *ip, int flags, int isrmdir)
{
struct inode *dp = VTOI(dvp);
struct lfs *fs = dp->i_lfs;
struct lfs_direct *ep;
struct buf *bp;
int error;
@ -1037,7 +1020,7 @@ ulfs_dirremove(struct vnode *dvp, const struct ulfs_lookup_results *ulr,
if (error)
return (error);
ep->d_ino = ulfs_rw32(ULFS_WINO, needswap);
ep->d_type = LFS_DT_WHT;
lfs_dir_settype(fs, ep, LFS_DT_WHT);
goto out;
}
@ -1126,6 +1109,7 @@ ulfs_dirrewrite(struct inode *dp, off_t offset,
struct inode *oip, ino_t newinum, int newtype,
int isrmdir, int iflags)
{
struct lfs *fs = dp->i_lfs;
struct buf *bp;
struct lfs_direct *ep;
struct vnode *vdp = ITOV(dp);
@ -1135,8 +1119,7 @@ ulfs_dirrewrite(struct inode *dp, off_t offset,
if (error)
return (error);
ep->d_ino = ulfs_rw32(newinum, ULFS_IPNEEDSWAP(dp));
if (!FSFMT(vdp))
ep->d_type = newtype;
lfs_dir_settype(fs, ep, newtype);
oip->i_nlink--;
DIP_ASSIGN(oip, nlink, oip->i_nlink);
oip->i_flag |= IN_CHANGE;
@ -1164,6 +1147,7 @@ ulfs_dirrewrite(struct inode *dp, off_t offset,
int
ulfs_dirempty(struct inode *ip, ino_t parentino, kauth_cred_t cred)
{
struct lfs *fs = ip->i_lfs;
doff_t off;
struct lfs_dirtemplate dbuf;
struct lfs_direct *dp = (struct lfs_direct *)&dbuf;
@ -1189,17 +1173,7 @@ ulfs_dirempty(struct inode *ip, ino_t parentino, kauth_cred_t cred)
if (dp->d_ino == 0 || ulfs_rw32(dp->d_ino, needswap) == ULFS_WINO)
continue;
/* accept only "." and ".." */
#if (BYTE_ORDER == LITTLE_ENDIAN)
if (FSFMT(ITOV(ip)) && needswap == 0)
namlen = dp->d_type;
else
namlen = dp->d_namlen;
#else
if (FSFMT(ITOV(ip)) && needswap != 0)
namlen = dp->d_type;
else
namlen = dp->d_namlen;
#endif
namlen = lfs_dir_getnamlen(fs, dp);
if (namlen > 2)
return (0);
if (dp->d_name[0] != '.')

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulfs_vfsops.c,v 1.9 2015/05/31 15:48:03 hannken Exp $ */
/* $NetBSD: ulfs_vfsops.c,v 1.10 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: ufs_vfsops.c,v 1.52 2013/01/22 09:39:18 dholland Exp */
/*
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ulfs_vfsops.c,v 1.9 2015/05/31 15:48:03 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: ulfs_vfsops.c,v 1.10 2015/09/01 06:16:59 dholland Exp $");
#if defined(_KERNEL_OPT)
#include "opt_lfs.h"
@ -58,6 +58,7 @@ __KERNEL_RCSID(0, "$NetBSD: ulfs_vfsops.c,v 1.9 2015/05/31 15:48:03 hannken Exp
#include <miscfs/specfs/specdev.h>
#include <ufs/lfs/lfs.h>
#include <ufs/lfs/lfs_accessors.h>
#include <ufs/lfs/ulfs_quotacommon.h>
#include <ufs/lfs/ulfs_inode.h>
#include <ufs/lfs/ulfsmount.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: ulfs_vnops.c,v 1.27 2015/09/01 06:08:37 dholland Exp $ */
/* $NetBSD: ulfs_vnops.c,v 1.28 2015/09/01 06:16:59 dholland Exp $ */
/* from NetBSD: ufs_vnops.c,v 1.213 2013/06/08 05:47:02 kardel Exp */
/*-
@ -67,7 +67,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.27 2015/09/01 06:08:37 dholland Exp $");
__KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.28 2015/09/01 06:16:59 dholland Exp $");
#if defined(_KERNEL_OPT)
#include "opt_lfs.h"
@ -97,6 +97,10 @@ __KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.27 2015/09/01 06:08:37 dholland Exp
#include <miscfs/fifofs/fifo.h>
#include <miscfs/genfs/genfs.h>
#include <ufs/lfs/lfs_extern.h>
#include <ufs/lfs/lfs.h>
#include <ufs/lfs/lfs_accessors.h>
#include <ufs/lfs/ulfs_inode.h>
#include <ufs/lfs/ulfsmount.h>
#include <ufs/lfs/ulfs_bswap.h>
@ -104,9 +108,6 @@ __KERNEL_RCSID(0, "$NetBSD: ulfs_vnops.c,v 1.27 2015/09/01 06:08:37 dholland Exp
#ifdef LFS_DIRHASH
#include <ufs/lfs/ulfs_dirhash.h>
#endif
#include <ufs/lfs/lfs_extern.h>
#include <ufs/lfs/lfs.h>
#include <ufs/lfs/lfs_accessors.h>
#include <uvm/uvm.h>
@ -646,12 +647,8 @@ ulfs_whiteout(void *v)
#endif
newdir = pool_cache_get(ulfs_direct_cache, PR_WAITOK);
newdir->d_ino = ULFS_WINO;
newdir->d_namlen = cnp->cn_namelen;
memcpy(newdir->d_name, cnp->cn_nameptr,
(size_t)cnp->cn_namelen);
newdir->d_name[cnp->cn_namelen] = '\0';
newdir->d_type = LFS_DT_WHT;
ulfs_makedirentry_bytype(fs, cnp, ULFS_WINO, LFS_DT_WHT,
newdir);
error = ulfs_direnter(dvp, ulr, NULL, newdir, cnp, NULL);
pool_cache_put(ulfs_direct_cache, newdir);
break;
@ -798,11 +795,6 @@ ulfs_readdir(void *v)
struct ulfsmount *ump = VFSTOULFS(vp->v_mount);
struct lfs *fs = ump->um_lfs;
int nswap = ULFS_MPNEEDSWAP(fs);
#if BYTE_ORDER == LITTLE_ENDIAN
int needswap = fs->um_maxsymlinklen <= 0 && nswap == 0;
#else
int needswap = fs->um_maxsymlinklen <= 0 && nswap != 0;
#endif
uio = ap->a_uio;
count = uio->uio_resid;
rcount = count - ((uio->uio_offset + count) & (fs->um_dirblksiz - 1));
@ -873,13 +865,8 @@ ulfs_readdir(void *v)
cdp = ecdp;
break;
}
if (needswap) {
ndp->d_type = cdp->d_namlen;
ndp->d_namlen = cdp->d_type;
} else {
ndp->d_type = cdp->d_type;
ndp->d_namlen = cdp->d_namlen;
}
ndp->d_type = lfs_dir_gettype(fs, cdp);
ndp->d_namlen = lfs_dir_getnamlen(fs, cdp);
ndp->d_reclen = _DIRENT_RECLEN(ndp, ndp->d_namlen);
if ((char *)(void *)ndp + ndp->d_reclen +
_DIRENT_MINSIZE(ndp) > endp)