First cut at ext2fs rev 1 support (as of mke2fs 1.18): supports the filetype

option read/write and the sparse option read-only.
This commit is contained in:
bouyer 2000-01-26 16:21:31 +00:00
parent 063cb5e5dc
commit 5fb6bc4e18
14 changed files with 296 additions and 146 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: dir.c,v 1.3 1997/10/09 13:19:34 bouyer Exp $ */ /* $NetBSD: dir.c,v 1.4 2000/01/26 16:21:31 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,12 +39,13 @@
#if 0 #if 0
static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94"; static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94";
#else #else
__RCSID("$NetBSD: dir.c,v 1.3 1997/10/09 13:19:34 bouyer Exp $"); __RCSID("$NetBSD: dir.c,v 1.4 2000/01/26 16:21:31 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
#include <sys/param.h> #include <sys/param.h>
#include <sys/time.h> #include <sys/time.h>
#include <ufs/ufs/dir.h>
#include <ufs/ext2fs/ext2fs_dinode.h> #include <ufs/ext2fs/ext2fs_dinode.h>
#include <ufs/ext2fs/ext2fs_dir.h> #include <ufs/ext2fs/ext2fs_dir.h>
#include <ufs/ext2fs/ext2fs.h> #include <ufs/ext2fs/ext2fs.h>
@ -61,12 +62,10 @@ __RCSID("$NetBSD: dir.c,v 1.3 1997/10/09 13:19:34 bouyer Exp $");
char *lfname = "lost+found"; char *lfname = "lost+found";
int lfmode = 01777; int lfmode = 01777;
/* XXX DIRBLKSIZ id bsize ! */
#define DIRBLKSIZ 0 /* just for now */
struct ext2fs_dirtemplate emptydir = { 0, DIRBLKSIZ }; struct ext2fs_dirtemplate emptydir = { 0, DIRBLKSIZ };
struct ext2fs_dirtemplate dirhead = { struct ext2fs_dirtemplate dirhead = {
0, 12, 1, ".", 0, 12, 1, IFTODT(EXT2_IFDIR), ".",
0, DIRBLKSIZ - 12, 2, ".." 0, DIRBLKSIZ - 12, 2, IFTODT(EXT2_IFDIR), ".."
}; };
#undef DIRBLKSIZ #undef DIRBLKSIZ
@ -189,6 +188,7 @@ fsck_readdir(idesc)
dp->e2d_reclen = h2fs16(sblock.e2fs_bsize); dp->e2d_reclen = h2fs16(sblock.e2fs_bsize);
dp->e2d_ino = 0; dp->e2d_ino = 0;
dp->e2d_namlen = 0; dp->e2d_namlen = 0;
dp->e2d_type = 0;
dp->e2d_name[0] = '\0'; dp->e2d_name[0] = '\0';
if (fix) if (fix)
dirty(bp); dirty(bp);
@ -235,7 +235,6 @@ dircheck(idesc, dp)
int size; int size;
char *cp; char *cp;
int spaceleft; int spaceleft;
u_int16_t namlen;
u_int16_t reclen = fs2h16(dp->e2d_reclen); u_int16_t reclen = fs2h16(dp->e2d_reclen);
spaceleft = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize); spaceleft = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize);
@ -246,13 +245,16 @@ dircheck(idesc, dp)
return (0); return (0);
if (dp->e2d_ino == 0) if (dp->e2d_ino == 0)
return (1); return (1);
namlen = fs2h16(dp->e2d_namlen); if (sblock.e2fs.e2fs_rev < E2FS_REV0 ||
size = EXT2FS_DIRSIZ(namlen); (sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE) == 0)
if (dp->e2d_type != 0)
return (1);
size = EXT2FS_DIRSIZ(dp->e2d_namlen);
if (reclen < size || if (reclen < size ||
idesc->id_filesize < size || idesc->id_filesize < size ||
namlen > EXT2FS_MAXNAMLEN) dp->e2d_namlen > EXT2FS_MAXNAMLEN)
return (0); return (0);
for (cp = dp->e2d_name, size = 0; size < namlen; size++) for (cp = dp->e2d_name, size = 0; size < dp->e2d_namlen; size++)
if (*cp == '\0' || (*cp++ == '/')) if (*cp == '\0' || (*cp++ == '/'))
return (0); return (0);
return (1); return (1);
@ -330,10 +332,13 @@ mkentry(idesc)
struct ext2fs_direct newent; struct ext2fs_direct newent;
int newlen, oldlen; int newlen, oldlen;
newent.e2d_namlen = h2fs16(strlen(idesc->id_name)); newent.e2d_namlen = strlen(idesc->id_name);
newlen = EXT2FS_DIRSIZ(fs2h16(newent.e2d_namlen)); if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
newent.e2d_type = typemap[idesc->id_parent];
newlen = EXT2FS_DIRSIZ(newent.e2d_namlen);
if (dirp->e2d_ino != 0) if (dirp->e2d_ino != 0)
oldlen = EXT2FS_DIRSIZ(fs2h16(dirp->e2d_namlen)); oldlen = EXT2FS_DIRSIZ(dirp->e2d_namlen);
else else
oldlen = 0; oldlen = 0;
if (fs2h16(dirp->e2d_reclen) - oldlen < newlen) if (fs2h16(dirp->e2d_reclen) - oldlen < newlen)
@ -344,7 +349,8 @@ mkentry(idesc)
dirp->e2d_ino = h2fs32(idesc->id_parent); /* ino to be entered is in id_parent */ dirp->e2d_ino = h2fs32(idesc->id_parent); /* ino to be entered is in id_parent */
dirp->e2d_reclen = newent.e2d_reclen; dirp->e2d_reclen = newent.e2d_reclen;
dirp->e2d_namlen = newent.e2d_namlen; dirp->e2d_namlen = newent.e2d_namlen;
memcpy(dirp->e2d_name, idesc->id_name, (size_t)fs2h16(dirp->e2d_namlen)); dirp->e2d_type = newent.e2d_type;
memcpy(dirp->e2d_name, idesc->id_name, (size_t)(dirp->e2d_namlen));
return (ALTERED|STOP); return (ALTERED|STOP);
} }
@ -353,12 +359,17 @@ chgino(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
struct ext2fs_direct *dirp = idesc->id_dirp; struct ext2fs_direct *dirp = idesc->id_dirp;
u_int16_t namlen = fs2h16(dirp->e2d_namlen); u_int16_t namlen = dirp->e2d_namlen;
if (strlen(idesc->id_name) != namlen || if (strlen(idesc->id_name) != namlen ||
strncmp(dirp->e2d_name, idesc->id_name, (int)namlen)) strncmp(dirp->e2d_name, idesc->id_name, (int)namlen))
return (KEEPON); return (KEEPON);
dirp->e2d_ino = h2fs32(idesc->id_parent); dirp->e2d_ino = h2fs32(idesc->id_parent);
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
dirp->e2d_type = typemap[idesc->id_parent];
else
dirp->e2d_type = 0;
return (ALTERED|STOP); return (ALTERED|STOP);
} }
@ -601,8 +612,18 @@ allocdir(parent, request, mode)
ino = allocino(request, IFDIR|mode); ino = allocino(request, IFDIR|mode);
dirhead.dot_reclen = h2fs16(12); /* XXX */ dirhead.dot_reclen = h2fs16(12); /* XXX */
dirhead.dotdot_reclen = h2fs16(sblock.e2fs_bsize - 12); /* XXX */ dirhead.dotdot_reclen = h2fs16(sblock.e2fs_bsize - 12); /* XXX */
dirhead.dot_namlen = h2fs16(1); dirhead.dot_namlen = 1;
dirhead.dotdot_namlen = h2fs16(2); if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
dirhead.dot_type = IFTODT(EXT2_IFDIR);
else
dirhead.dot_type = 0;
dirhead.dotdot_namlen = 2;
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
dirhead.dotdot_type = IFTODT(EXT2_IFDIR);
else
dirhead.dotdot_type = 0;
dirp = &dirhead; dirp = &dirhead;
dirp->dot_ino = h2fs32(ino); dirp->dot_ino = h2fs32(ino);
dirp->dotdot_ino = h2fs32(parent); dirp->dotdot_ino = h2fs32(parent);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsck.h,v 1.2 1997/10/09 13:19:35 bouyer Exp $ */ /* $NetBSD: fsck.h,v 1.3 2000/01/26 16:21:31 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -184,6 +184,7 @@ char *blockmap; /* ptr to primary blk allocation map */
ino_t maxino; /* number of inodes in file system */ ino_t maxino; /* number of inodes in file system */
ino_t lastino; /* last inode in use */ ino_t lastino; /* last inode in use */
char *statemap; /* ptr to inode state table */ char *statemap; /* ptr to inode state table */
u_char *typemap; /* ptr to inode type table */
int16_t *lncntp; /* ptr to link count table */ int16_t *lncntp; /* ptr to link count table */
ino_t lfdir; /* lost & found directory inode number */ ino_t lfdir; /* lost & found directory inode number */

View File

@ -1,4 +1,4 @@
/* $NetBSD: inode.c,v 1.6 1999/02/17 13:11:19 bouyer Exp $ */ /* $NetBSD: inode.c,v 1.7 2000/01/26 16:21:32 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95"; static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95";
#else #else
__RCSID("$NetBSD: inode.c,v 1.6 1999/02/17 13:11:19 bouyer Exp $"); __RCSID("$NetBSD: inode.c,v 1.7 2000/01/26 16:21:32 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -50,6 +50,7 @@ __RCSID("$NetBSD: inode.c,v 1.6 1999/02/17 13:11:19 bouyer Exp $");
#include <ufs/ext2fs/ext2fs.h> #include <ufs/ext2fs/ext2fs.h>
#include <ufs/ufs/dinode.h> /* for IFMT & friends */ #include <ufs/ufs/dinode.h> /* for IFMT & friends */
#include <ufs/ufs/dir.h> /* for IFTODT & friends */
#ifndef SMALL #ifndef SMALL
#include <pwd.h> #include <pwd.h>
#endif #endif
@ -502,7 +503,7 @@ findname(idesc)
struct inodesc *idesc; struct inodesc *idesc;
{ {
struct ext2fs_direct *dirp = idesc->id_dirp; struct ext2fs_direct *dirp = idesc->id_dirp;
u_int16_t namlen = fs2h16(dirp->e2d_namlen); u_int16_t namlen = dirp->e2d_namlen;
if (fs2h32(dirp->e2d_ino) != idesc->id_parent) if (fs2h32(dirp->e2d_ino) != idesc->id_parent)
return (KEEPON); return (KEEPON);
@ -637,6 +638,7 @@ allocino(request, type)
dp->e2di_nblock = h2fs32(btodb(sblock.e2fs_bsize)); dp->e2di_nblock = h2fs32(btodb(sblock.e2fs_bsize));
n_files++; n_files++;
inodirty(); inodirty();
typemap[ino] = IFTODT(type);
return (ino); return (ino);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.6 1998/07/26 20:27:20 mycroft Exp $ */ /* $NetBSD: main.c,v 1.7 2000/01/26 16:21:32 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -44,7 +44,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1993\n\
#if 0 #if 0
static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94"; static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94";
#else #else
__RCSID("$NetBSD: main.c,v 1.6 1998/07/26 20:27:20 mycroft Exp $"); __RCSID("$NetBSD: main.c,v 1.7 2000/01/26 16:21:32 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -193,6 +193,10 @@ checkfilesys(filesys, mntpt, auxdata, child)
* 1: scan inodes tallying blocks used * 1: scan inodes tallying blocks used
*/ */
if (preen == 0) { if (preen == 0) {
if (sblock.e2fs.e2fs_rev > E2FS_REV0) {
printf("** Last Mounted on %s\n",
sblock.e2fs.e2fs_fsmnt);
}
if (hotroot()) if (hotroot())
printf("** Root file system\n"); printf("** Root file system\n");
printf("** Phase 1 - Check Blocks and Sizes\n"); printf("** Phase 1 - Check Blocks and Sizes\n");

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass1.c,v 1.6 1999/02/17 13:11:19 bouyer Exp $ */ /* $NetBSD: pass1.c,v 1.7 2000/01/26 16:21:32 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93"; static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93";
#else #else
__RCSID("$NetBSD: pass1.c,v 1.6 1999/02/17 13:11:19 bouyer Exp $"); __RCSID("$NetBSD: pass1.c,v 1.7 2000/01/26 16:21:32 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -50,6 +50,7 @@ __RCSID("$NetBSD: pass1.c,v 1.6 1999/02/17 13:11:19 bouyer Exp $");
#include <ufs/ext2fs/ext2fs.h> #include <ufs/ext2fs/ext2fs.h>
#include <ufs/ufs/dinode.h> /* for IFMT & friends */ #include <ufs/ufs/dinode.h> /* for IFMT & friends */
#include <ufs/ufs/dir.h> /* for IFTODT & friends */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -247,6 +248,7 @@ checkinode(inumber, idesc)
} else { } else {
statemap[inumber] = FSTATE; statemap[inumber] = FSTATE;
} }
typemap[inumber] = IFTODT(mode);
badblk = dupblk = 0; badblk = dupblk = 0;
idesc->id_number = inumber; idesc->id_number = inumber;
(void)ckinode(dp, idesc); (void)ckinode(dp, idesc);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass2.c,v 1.4 1997/10/09 13:19:38 bouyer Exp $ */ /* $NetBSD: pass2.c,v 1.5 2000/01/26 16:21:32 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94"; static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94";
#else #else
__RCSID("$NetBSD: pass2.c,v 1.4 1997/10/09 13:19:38 bouyer Exp $"); __RCSID("$NetBSD: pass2.c,v 1.5 2000/01/26 16:21:32 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -50,6 +50,7 @@ __RCSID("$NetBSD: pass2.c,v 1.4 1997/10/09 13:19:38 bouyer Exp $");
#include <ufs/ext2fs/ext2fs.h> #include <ufs/ext2fs/ext2fs.h>
#include <ufs/ufs/dinode.h> /* for IFMT & friends */ #include <ufs/ufs/dinode.h> /* for IFMT & friends */
#include <ufs/ufs/dir.h> /* for IFTODT & friends */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -216,7 +217,7 @@ pass2check(idesc)
*/ */
if (idesc->id_entryno != 0) if (idesc->id_entryno != 0)
goto chk1; goto chk1;
if (fs2h32(dirp->e2d_ino) != 0 && fs2h16(dirp->e2d_namlen) == 1 && if (fs2h32(dirp->e2d_ino) != 0 && dirp->e2d_namlen == 1 &&
dirp->e2d_name[0] == '.') { dirp->e2d_name[0] == '.') {
if (fs2h32(dirp->e2d_ino) != idesc->id_number) { if (fs2h32(dirp->e2d_ino) != idesc->id_number) {
direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'"); direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
@ -224,13 +225,26 @@ pass2check(idesc)
if (reply("FIX") == 1) if (reply("FIX") == 1)
ret |= ALTERED; ret |= ALTERED;
} }
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)
&& (dirp->e2d_type != IFTODT(EXT2_IFDIR))) {
direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
dirp->e2d_type = IFTODT(EXT2_IFDIR);
if (reply("FIX") == 1)
ret |= ALTERED;
}
goto chk1; goto chk1;
} }
direrror(idesc->id_number, "MISSING '.'"); direrror(idesc->id_number, "MISSING '.'");
proto.e2d_ino = h2fs32(idesc->id_number); proto.e2d_ino = h2fs32(idesc->id_number);
proto.e2d_namlen = h2fs16(1); proto.e2d_namlen = 1;
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
proto.e2d_type = IFTODT(EXT2_IFDIR);
else
proto.e2d_type = 0;
(void)strcpy(proto.e2d_name, "."); (void)strcpy(proto.e2d_name, ".");
entrysize = EXT2FS_DIRSIZ(fs2h16(proto.e2d_namlen)); entrysize = EXT2FS_DIRSIZ(proto.e2d_namlen);
if (fs2h32(dirp->e2d_ino) != 0 && strcmp(dirp->e2d_name, "..") != 0) { if (fs2h32(dirp->e2d_ino) != 0 && strcmp(dirp->e2d_name, "..") != 0) {
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n", pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
dirp->e2d_name); dirp->e2d_name);
@ -258,11 +272,16 @@ chk1:
goto chk2; goto chk2;
inp = getinoinfo(idesc->id_number); inp = getinoinfo(idesc->id_number);
proto.e2d_ino = h2fs32(inp->i_parent); proto.e2d_ino = h2fs32(inp->i_parent);
proto.e2d_namlen = h2fs16(2); proto.e2d_namlen = 2;
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE))
proto.e2d_type = IFTODT(EXT2_IFDIR);
else
proto.e2d_type = 0;
(void)strcpy(proto.e2d_name, ".."); (void)strcpy(proto.e2d_name, "..");
entrysize = EXT2FS_DIRSIZ(2); entrysize = EXT2FS_DIRSIZ(2);
if (idesc->id_entryno == 0) { if (idesc->id_entryno == 0) {
n = EXT2FS_DIRSIZ(fs2h16(dirp->e2d_namlen)); n = EXT2FS_DIRSIZ(dirp->e2d_namlen);
if (fs2h16(dirp->e2d_reclen) < n + entrysize) if (fs2h16(dirp->e2d_reclen) < n + entrysize)
goto chk2; goto chk2;
proto.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - n); proto.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - n);
@ -274,13 +293,21 @@ chk1:
dirp->e2d_reclen = proto.e2d_reclen; dirp->e2d_reclen = proto.e2d_reclen;
} }
if (fs2h32(dirp->e2d_ino) != 0 && if (fs2h32(dirp->e2d_ino) != 0 &&
fs2h16(dirp->e2d_namlen) == 2 && dirp->e2d_namlen == 2 &&
strncmp(dirp->e2d_name, "..", 2) == 0) { strncmp(dirp->e2d_name, "..", 2) == 0) {
inp->i_dotdot = fs2h32(dirp->e2d_ino); inp->i_dotdot = fs2h32(dirp->e2d_ino);
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)
&& dirp->e2d_type != IFTODT(EXT2_IFDIR)) {
direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
dirp->e2d_type = IFTODT(EXT2_IFDIR);
if (reply("FIX") == 1)
ret |= ALTERED;
}
goto chk2; goto chk2;
} }
if (fs2h32(dirp->e2d_ino) != 0 && if (fs2h32(dirp->e2d_ino) != 0 &&
fs2h16(dirp->e2d_namlen) == 1 && dirp->e2d_namlen == 1 &&
strncmp(dirp->e2d_name, ".", 1) != 0) { strncmp(dirp->e2d_name, ".", 1) != 0) {
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'"); fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n", pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
@ -308,10 +335,10 @@ chk1:
chk2: chk2:
if (fs2h32(dirp->e2d_ino) == 0) if (fs2h32(dirp->e2d_ino) == 0)
return (ret|KEEPON); return (ret|KEEPON);
if (fs2h16(dirp->e2d_namlen) <= 2 && if (dirp->e2d_namlen <= 2 &&
dirp->e2d_name[0] == '.' && dirp->e2d_name[0] == '.' &&
idesc->id_entryno >= 2) { idesc->id_entryno >= 2) {
if (fs2h16(dirp->e2d_namlen) == 1) { if (dirp->e2d_namlen == 1) {
direrror(idesc->id_number, "EXTRA '.' ENTRY"); direrror(idesc->id_number, "EXTRA '.' ENTRY");
dirp->e2d_ino = 0; dirp->e2d_ino = 0;
if (reply("FIX") == 1) if (reply("FIX") == 1)
@ -385,6 +412,17 @@ again:
/* fall through */ /* fall through */
case FSTATE: case FSTATE:
if (sblock.e2fs.e2fs_rev > E2FS_REV0 &&
(sblock.e2fs.e2fs_features_incompat &
EXT2F_INCOMPAT_FTYPE) &&
dirp->e2d_type != typemap[fs2h32(dirp->e2d_ino)]) {
dirp->e2d_type = typemap[fs2h32(dirp->e2d_ino)];
fileerror(idesc->id_number,
fs2h32(dirp->e2d_ino),
"BAD TYPE VALUE");
if (reply("FIX") == 1)
ret |= ALTERED;
}
lncntp[fs2h32(dirp->e2d_ino)]--; lncntp[fs2h32(dirp->e2d_ino)]--;
break; break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: setup.c,v 1.10 1999/02/17 13:11:19 bouyer Exp $ */ /* $NetBSD: setup.c,v 1.11 2000/01/26 16:21:32 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -39,7 +39,7 @@
#if 0 #if 0
static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94"; static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94";
#else #else
__RCSID("$NetBSD: setup.c,v 1.10 1999/02/17 13:11:19 bouyer Exp $"); __RCSID("$NetBSD: setup.c,v 1.11 2000/01/26 16:21:32 bouyer Exp $");
#endif #endif
#endif /* not lint */ #endif /* not lint */
@ -224,6 +224,12 @@ setup(dev)
(unsigned)(maxino + 1)); (unsigned)(maxino + 1));
goto badsblabel; goto badsblabel;
} }
typemap = calloc((unsigned)(maxino + 1), sizeof(char));
if (typemap == NULL) {
printf("cannot alloc %u bytes for typemap\n",
(unsigned)(maxino + 1));
goto badsblabel;
}
lncntp = (int16_t *)calloc((unsigned)(maxino + 1), sizeof(int16_t)); lncntp = (int16_t *)calloc((unsigned)(maxino + 1), sizeof(int16_t));
if (lncntp == NULL) { if (lncntp == NULL) {
printf("cannot alloc %u bytes for lncntp\n", printf("cannot alloc %u bytes for lncntp\n",
@ -364,17 +370,17 @@ readsb(listerr)
asblk.b_un.b_fs->e2fs_rgid = sblk.b_un.b_fs->e2fs_rgid; asblk.b_un.b_fs->e2fs_rgid = sblk.b_un.b_fs->e2fs_rgid;
asblk.b_un.b_fs->e2fs_block_group_nr = asblk.b_un.b_fs->e2fs_block_group_nr =
sblk.b_un.b_fs->e2fs_block_group_nr; sblk.b_un.b_fs->e2fs_block_group_nr;
if (sblk.b_un.b_fs->e2fs_features_compat != 0 || if (sblk.b_un.b_fs->e2fs_rev > E2FS_REV0 &&
sblk.b_un.b_fs->e2fs_features_incompat != 0 || ((sblk.b_un.b_fs->e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) ||
sblk.b_un.b_fs->e2fs_features_compat_ro != 0) { (sblk.b_un.b_fs->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP))) {
if (debug) { if (debug) {
printf("compat 0x%08x, incompat 0x%08x, compat_ro " printf("compat 0x%08x, incompat 0x%08x, compat_ro "
"0x%08x\n", "0x%08x\n",
sblk.b_un.b_fs->e2fs_features_compat, sblk.b_un.b_fs->e2fs_features_compat,
sblk.b_un.b_fs->e2fs_features_incompat, sblk.b_un.b_fs->e2fs_features_incompat,
sblk.b_un.b_fs->e2fs_features_compat_ro); sblk.b_un.b_fs->e2fs_features_rocompat);
} }
badsb(listerr,"UNKNOWN FEATURE BITS IN SUPER BLOCK"); badsb(listerr,"INCOMPATIBLE FEATURE BITS IN SUPER BLOCK");
return 0; return 0;
} }
if (memcmp(sblk.b_un.b_fs, asblk.b_un.b_fs, SBSIZE)) { if (memcmp(sblk.b_un.b_fs, asblk.b_un.b_fs, SBSIZE)) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs.h,v 1.8 1999/02/17 13:09:43 bouyer Exp $ */ /* $NetBSD: ext2fs.h,v 1.9 2000/01/26 16:21:33 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -119,7 +119,7 @@ struct ext2fs {
u_int16_t e2fs_magic; /* magic number */ u_int16_t e2fs_magic; /* magic number */
u_int16_t e2fs_state; /* file system state */ u_int16_t e2fs_state; /* file system state */
u_int16_t e2fs_beh; /* behavior on errors */ u_int16_t e2fs_beh; /* behavior on errors */
u_int16_t reserved; u_int16_t e2fs_minrev; /* minor revision level */
u_int32_t e2fs_lastfsck; /* time of last fsck */ u_int32_t e2fs_lastfsck; /* time of last fsck */
u_int32_t e2fs_fsckintv; /* max time between fscks */ u_int32_t e2fs_fsckintv; /* max time between fscks */
u_int32_t e2fs_creator; /* creator OS */ u_int32_t e2fs_creator; /* creator OS */
@ -130,10 +130,17 @@ struct ext2fs {
u_int32_t e2fs_first_ino; /* first non-reserved inode */ u_int32_t e2fs_first_ino; /* first non-reserved inode */
u_int16_t e2fs_inode_size; /* size of inode structure */ u_int16_t e2fs_inode_size; /* size of inode structure */
u_int16_t e2fs_block_group_nr; /* block grp number of this sblk*/ u_int16_t e2fs_block_group_nr; /* block grp number of this sblk*/
u_int32_t e2fs_features_compat; /* OK to mount if unknown */ u_int32_t e2fs_features_compat; /* compatible feature set */
u_int32_t e2fs_features_incompat; /* not OK to mount if unknown */ u_int32_t e2fs_features_incompat; /* incompatible feature set */
u_int32_t e2fs_features_compat_ro; /* OK to mount ro if unknown */ u_int32_t e2fs_features_rocompat; /* RO-compatible feature set */
u_int32_t reserved2[230]; u_int8_t e2fs_uuid[16]; /* 128-bit uuid for volume */
char e2fs_vname[16]; /* volume name */
char e2fs_fsmnt[64]; /* name mounted on */
u_int32_t e2fs_algo; /* For compression */
u_int8_t e2fs_prealloc; /* # of blocks to preallocate */
u_int8_t e2fs_dir_prealloc; /* # of blocks to preallocate for dir */
u_int16_t pad1;
u_int32_t reserved2[204];
}; };
@ -161,7 +168,23 @@ struct m_ext2fs {
* Filesystem identification * Filesystem identification
*/ */
#define E2FS_MAGIC 0xef53 /* the ext2fs magic number */ #define E2FS_MAGIC 0xef53 /* the ext2fs magic number */
#define E2FS_REV 0 /* revision level */ #define E2FS_REV0 0 /* revision levels */
#define E2FS_REV1 1 /* revision levels */
/* compatible/imcompatible features */
#define EXT2F_COMPAT_PREALLOC 0x0001
#define EXT2F_ROCOMPAT_SPARSESUPER 0x0001
#define EXT2F_ROCOMPAT_LARGEFILE 0x0002
#define EXT2F_ROCOMPAT_BTREE_DIR 0x0004
#define EXT2F_INCOMPAT_COMP 0x0001
#define EXT2F_INCOMPAT_FTYPE 0x0002
/* features supported in this implementation */
#define EXT2F_COMPAT_SUPP 0x0000
#define EXT2F_ROCOMPAT_SUPP 0x0000
#define EXT2F_INCOMPAT_SUPP EXT2F_INCOMPAT_FTYPE
/* /*
* OS identification * OS identification
@ -174,7 +197,7 @@ struct m_ext2fs {
* Filesystem clean flags * Filesystem clean flags
*/ */
#define E2FS_ISCLEAN 0x01 #define E2FS_ISCLEAN 0x01
#define E2FS_ERRORS 0x02 #define E2FS_ERRORS 0x02
/* ext2 file system block group descriptor */ /* ext2 file system block group descriptor */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_bswap.c,v 1.2 1998/08/09 20:15:38 perry Exp $ */ /* $NetBSD: ext2fs_bswap.c,v 1.3 2000/01/26 16:21:33 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -46,30 +46,38 @@ e2fs_sb_bswap(old, new)
{ {
/* preserve unused fields */ /* preserve unused fields */
memcpy(new, old, sizeof(struct ext2fs)); memcpy(new, old, sizeof(struct ext2fs));
new->e2fs_icount = bswap32(old->e2fs_icount); new->e2fs_icount = bswap32(old->e2fs_icount);
new->e2fs_bcount = bswap32(old->e2fs_bcount); new->e2fs_bcount = bswap32(old->e2fs_bcount);
new->e2fs_rbcount = bswap32(old->e2fs_rbcount); new->e2fs_rbcount = bswap32(old->e2fs_rbcount);
new->e2fs_fbcount = bswap32(old->e2fs_fbcount); new->e2fs_fbcount = bswap32(old->e2fs_fbcount);
new->e2fs_ficount = bswap32(old->e2fs_ficount); new->e2fs_ficount = bswap32(old->e2fs_ficount);
new->e2fs_first_dblock = bswap32(old->e2fs_first_dblock); new->e2fs_first_dblock = bswap32(old->e2fs_first_dblock);
new->e2fs_log_bsize = bswap32(old->e2fs_log_bsize); new->e2fs_log_bsize = bswap32(old->e2fs_log_bsize);
new->e2fs_fsize = bswap32(old->e2fs_fsize); new->e2fs_fsize = bswap32(old->e2fs_fsize);
new->e2fs_bpg = bswap32(old->e2fs_bpg); new->e2fs_bpg = bswap32(old->e2fs_bpg);
new->e2fs_fpg = bswap32(old->e2fs_fpg); new->e2fs_fpg = bswap32(old->e2fs_fpg);
new->e2fs_ipg = bswap32(old->e2fs_ipg); new->e2fs_ipg = bswap32(old->e2fs_ipg);
new->e2fs_mtime = bswap32(old->e2fs_mtime); new->e2fs_mtime = bswap32(old->e2fs_mtime);
new->e2fs_wtime = bswap32(old->e2fs_wtime); new->e2fs_wtime = bswap32(old->e2fs_wtime);
new->e2fs_lastfsck = bswap32(old->e2fs_lastfsck); new->e2fs_mnt_count = bswap16(old->e2fs_mnt_count);
new->e2fs_fsckintv = bswap32(old->e2fs_fsckintv); new->e2fs_max_mnt_count = bswap16(old->e2fs_max_mnt_count);
new->e2fs_creator = bswap32(old->e2fs_creator); new->e2fs_magic = bswap16(old->e2fs_magic);
new->e2fs_rev = bswap32(old->e2fs_rev); new->e2fs_state = bswap16(old->e2fs_state);
new->e2fs_mnt_count = bswap16(old->e2fs_mnt_count); new->e2fs_beh = bswap16(old->e2fs_beh);
new->e2fs_max_mnt_count = bswap16(old->e2fs_max_mnt_count); new->e2fs_minrev = bswap16(old->e2fs_minrev);
new->e2fs_magic = bswap16(old->e2fs_magic); new->e2fs_lastfsck = bswap32(old->e2fs_lastfsck);
new->e2fs_state = bswap16(old->e2fs_state); new->e2fs_fsckintv = bswap32(old->e2fs_fsckintv);
new->e2fs_beh = bswap16(old->e2fs_beh); new->e2fs_creator = bswap32(old->e2fs_creator);
new->e2fs_ruid = bswap16(old->e2fs_ruid); new->e2fs_rev = bswap32(old->e2fs_rev);
new->e2fs_rgid = bswap16(old->e2fs_rgid); new->e2fs_ruid = bswap16(old->e2fs_ruid);
new->e2fs_rgid = bswap16(old->e2fs_rgid);
new->e2fs_first_ino = bswap32(old->e2fs_first_ino);
new->e2fs_inode_size = bswap16(old->e2fs_inode_size);
new->e2fs_block_group_nr = bswap16(old->e2fs_block_group_nr);
new->e2fs_features_compat = bswap32(old->e2fs_features_compat);
new->e2fs_features_incompat = bswap32(old->e2fs_features_incompat);
new->e2fs_features_rocompat = bswap32(old->e2fs_features_rocompat);
new->e2fs_algo = bswap32(old->e2fs_algo);
} }
void e2fs_cg_bswap(old, new, size) void e2fs_cg_bswap(old, new, size)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_dinode.h,v 1.5 1998/10/23 00:33:24 thorpej Exp $ */ /* $NetBSD: ext2fs_dinode.h,v 1.6 2000/01/26 16:21:33 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -75,16 +75,16 @@ struct ext2fs_dinode {
u_int32_t e2di_dtime; /* 20: Deletion time */ u_int32_t e2di_dtime; /* 20: Deletion time */
u_int16_t e2di_gid; /* 24: Owner GID */ u_int16_t e2di_gid; /* 24: Owner GID */
u_int16_t e2di_nlink; /* 26: File link count */ u_int16_t e2di_nlink; /* 26: File link count */
u_int32_t e2di_nblock;/* 28: Blocks count */ u_int32_t e2di_nblock; /* 28: Blocks count */
u_int32_t e2di_flags; /* 32: Status flags (chflags) */ u_int32_t e2di_flags; /* 32: Status flags (chflags) */
u_int32_t e2di_linux_reserved1; /* 36 */ u_int32_t e2di_linux_reserved1; /* 36 */
u_int32_t e2di_blocks[NDADDR+NIADDR]; /* 40: disk blocks */ u_int32_t e2di_blocks[NDADDR+NIADDR]; /* 40: disk blocks */
u_int32_t e2di_gen; /* 100: generation number (file version) */ u_int32_t e2di_gen; /* 100: generation number */
u_int32_t e2di_facl; /* 104: file ACL (not implemented) */ u_int32_t e2di_facl; /* 104: file ACL (not implemented) */
u_int32_t e2di_dacl; /* 108: dir ACL (not implemented) */ u_int32_t e2di_dacl; /* 108: dir ACL (not implemented) */
u_int32_t e2di_faddr; /* 112: fragment address */ u_int32_t e2di_faddr; /* 112: fragment address */
u_int8_t e2di_nfrag; /* 116: fragment number */ u_int8_t e2di_nfrag; /* 116: fragment number */
u_int8_t e2di_fsize; /* 117: fragment size */ u_int8_t e2di_fsize; /* 117: fragment size */
u_int16_t e2di_linux_reserved2; /* 118 */ u_int16_t e2di_linux_reserved2; /* 118 */
u_int32_t e2di_linux_reserved3[2]; /* 120 */ u_int32_t e2di_linux_reserved3[2]; /* 120 */
}; };

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_dir.h,v 1.2 1998/09/13 15:14:40 christos Exp $ */ /* $NetBSD: ext2fs_dir.h,v 1.3 2000/01/26 16:21:33 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -75,6 +75,9 @@
* a directory block is free, then its dp->e2d_ino is set to 0. * a directory block is free, then its dp->e2d_ino is set to 0.
* Entries other than the first in a directory do not normally have * Entries other than the first in a directory do not normally have
* dp->e2d_ino set to 0. * dp->e2d_ino set to 0.
* Ext2 rev 0 has a 16 bits e2d_namlen. For Ext2 vev 1 this has been split
* into a 8 bits e2d_namlen and 8 bits e2d_type (looks like ffs, isnt't it ? :)
* It's safe to use this for rev 0 as well because all ext2 are little-endian.
*/ */
#define EXT2FS_MAXNAMLEN 255 #define EXT2FS_MAXNAMLEN 255
@ -82,7 +85,8 @@
struct ext2fs_direct { struct ext2fs_direct {
u_int32_t e2d_ino; /* inode number of entry */ u_int32_t e2d_ino; /* inode number of entry */
u_int16_t e2d_reclen; /* length of this record */ u_int16_t e2d_reclen; /* length of this record */
u_int16_t e2d_namlen; /* length of string in d_name */ u_int8_t e2d_namlen; /* length of string in d_name */
u_int8_t e2d_type; /* file type */
char e2d_name[EXT2FS_MAXNAMLEN];/* name with length <= EXT2FS_MAXNAMLEN */ char e2d_name[EXT2FS_MAXNAMLEN];/* name with length <= EXT2FS_MAXNAMLEN */
}; };
@ -103,11 +107,13 @@ struct ext2fs_direct {
struct ext2fs_dirtemplate { struct ext2fs_dirtemplate {
u_int32_t dot_ino; u_int32_t dot_ino;
int16_t dot_reclen; int16_t dot_reclen;
u_int16_t dot_namlen; u_int8_t dot_namlen;
u_int8_t dot_type;
char dot_name[4]; /* must be multiple of 4 */ char dot_name[4]; /* must be multiple of 4 */
u_int32_t dotdot_ino; u_int32_t dotdot_ino;
int16_t dotdot_reclen; int16_t dotdot_reclen;
u_int16_t dotdot_namlen; u_int8_t dotdot_namlen;
u_int8_t dotdot_type;
char dotdot_name[4]; /* ditto */ char dotdot_name[4]; /* ditto */
}; };

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_lookup.c,v 1.12 1999/09/05 14:26:34 jdolecek Exp $ */ /* $NetBSD: ext2fs_lookup.c,v 1.13 2000/01/26 16:21:33 bouyer Exp $ */
/* /*
* Modified for NetBSD 1.2E * Modified for NetBSD 1.2E
@ -95,7 +95,7 @@ ext2fs_dirconv2ffs( e2dir, ffsdir)
{ {
memset(ffsdir, 0, sizeof(struct dirent)); memset(ffsdir, 0, sizeof(struct dirent));
ffsdir->d_fileno = fs2h32(e2dir->e2d_ino); ffsdir->d_fileno = fs2h32(e2dir->e2d_ino);
ffsdir->d_namlen = fs2h16(e2dir->e2d_namlen); ffsdir->d_namlen = e2dir->e2d_namlen;
ffsdir->d_type = DT_UNKNOWN; /* don't know more here */ ffsdir->d_type = DT_UNKNOWN; /* don't know more here */
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
@ -103,7 +103,7 @@ ext2fs_dirconv2ffs( e2dir, ffsdir)
* XXX Rigth now this can't happen, but if one day * XXX Rigth now this can't happen, but if one day
* MAXNAMLEN != E2FS_MAXNAMLEN we should handle this more gracefully ! * MAXNAMLEN != E2FS_MAXNAMLEN we should handle this more gracefully !
*/ */
if (fs2h16(e2dir->e2d_namlen) > MAXNAMLEN) if (e2dir->e2d_namlen > MAXNAMLEN)
panic("ext2fs: e2dir->e2d_namlen\n"); panic("ext2fs: e2dir->e2d_namlen\n");
#endif #endif
strncpy(ffsdir->d_name, e2dir->e2d_name, ffsdir->d_namlen); strncpy(ffsdir->d_name, e2dir->e2d_name, ffsdir->d_namlen);
@ -415,7 +415,7 @@ searchloop:
int size = fs2h16(ep->e2d_reclen); int size = fs2h16(ep->e2d_reclen);
if (ep->e2d_ino != 0) if (ep->e2d_ino != 0)
size -= EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen)); size -= EXT2FS_DIRSIZ(ep->e2d_namlen);
if (size > 0) { if (size > 0) {
if (size >= slotneeded) { if (size >= slotneeded) {
slotstatus = FOUND; slotstatus = FOUND;
@ -438,7 +438,7 @@ searchloop:
* Check for a name match. * Check for a name match.
*/ */
if (ep->e2d_ino) { if (ep->e2d_ino) {
namlen = fs2h16(ep->e2d_namlen); namlen = ep->e2d_namlen;
if (namlen == cnp->cn_namelen && if (namlen == cnp->cn_namelen &&
!memcmp(cnp->cn_nameptr, ep->e2d_name, !memcmp(cnp->cn_nameptr, ep->e2d_name,
(unsigned)namlen)) { (unsigned)namlen)) {
@ -538,11 +538,11 @@ found:
* Check that directory length properly reflects presence * Check that directory length properly reflects presence
* of this entry. * of this entry.
*/ */
if (entryoffsetinblock + EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen)) if (entryoffsetinblock + EXT2FS_DIRSIZ(ep->e2d_namlen)
> dp->i_e2fs_size) { > dp->i_e2fs_size) {
ufs_dirbad(dp, dp->i_offset, "i_size too small"); ufs_dirbad(dp, dp->i_offset, "i_size too small");
dp->i_e2fs_size = entryoffsetinblock + dp->i_e2fs_size = entryoffsetinblock +
EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen)); EXT2FS_DIRSIZ(ep->e2d_namlen);
dp->i_flag |= IN_CHANGE | IN_UPDATE; dp->i_flag |= IN_CHANGE | IN_UPDATE;
} }
@ -713,7 +713,7 @@ ext2fs_dirbadentry(dp, de, entryoffsetinblock)
char * error_msg = NULL; char * error_msg = NULL;
int reclen = fs2h16(de->e2d_reclen); int reclen = fs2h16(de->e2d_reclen);
int namlen = fs2h16(de->e2d_namlen); int namlen = de->e2d_namlen;
if (reclen < EXT2FS_DIRSIZ(1)) /* e2d_namlen = 1 */ if (reclen < EXT2FS_DIRSIZ(1)) /* e2d_namlen = 1 */
error_msg = "rec_len is smaller than minimal"; error_msg = "rec_len is smaller than minimal";
@ -770,7 +770,13 @@ ext2fs_direnter(ip, dvp, cnp)
#endif #endif
dp = VTOI(dvp); dp = VTOI(dvp);
newdir.e2d_ino = h2fs32(ip->i_number); newdir.e2d_ino = h2fs32(ip->i_number);
newdir.e2d_namlen = h2fs16(cnp->cn_namelen); newdir.e2d_namlen = cnp->cn_namelen;
if (ip->i_e2fs->e2fs.e2fs_rev > E2FS_REV0 &&
(ip->i_e2fs->e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) {
newdir.e2d_type = IFTODT(ip->i_ffs_mode);
} else {
newdir.e2d_type = 0;
};
memcpy(newdir.e2d_name, cnp->cn_nameptr, (unsigned)cnp->cn_namelen + 1); memcpy(newdir.e2d_name, cnp->cn_nameptr, (unsigned)cnp->cn_namelen + 1);
newentrysize = EXT2FS_DIRSIZ(cnp->cn_namelen); newentrysize = EXT2FS_DIRSIZ(cnp->cn_namelen);
if (dp->i_count == 0) { if (dp->i_count == 0) {
@ -826,7 +832,7 @@ ext2fs_direnter(ip, dvp, cnp)
* space. * space.
*/ */
ep = (struct ext2fs_direct *)dirbuf; ep = (struct ext2fs_direct *)dirbuf;
dsize = EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen)); dsize = EXT2FS_DIRSIZ(ep->e2d_namlen);
spacefree = fs2h16(ep->e2d_reclen) - dsize; spacefree = fs2h16(ep->e2d_reclen) - dsize;
for (loc = fs2h16(ep->e2d_reclen); loc < dp->i_count; ) { for (loc = fs2h16(ep->e2d_reclen); loc < dp->i_count; ) {
nep = (struct ext2fs_direct *)(dirbuf + loc); nep = (struct ext2fs_direct *)(dirbuf + loc);
@ -838,7 +844,7 @@ ext2fs_direnter(ip, dvp, cnp)
/* overwrite; nothing there; header is ours */ /* overwrite; nothing there; header is ours */
spacefree += dsize; spacefree += dsize;
} }
dsize = EXT2FS_DIRSIZ(fs2h16(nep->e2d_namlen)); dsize = EXT2FS_DIRSIZ(nep->e2d_namlen);
spacefree += fs2h16(nep->e2d_reclen) - dsize; spacefree += fs2h16(nep->e2d_reclen) - dsize;
loc += fs2h16(nep->e2d_reclen); loc += fs2h16(nep->e2d_reclen);
memcpy((caddr_t)ep, (caddr_t)nep, dsize); memcpy((caddr_t)ep, (caddr_t)nep, dsize);
@ -942,6 +948,12 @@ ext2fs_dirrewrite(dp, ip, cnp)
if (error != 0) if (error != 0)
return (error); return (error);
ep->e2d_ino = h2fs32(ip->i_number); ep->e2d_ino = h2fs32(ip->i_number);
if (ip->i_e2fs->e2fs.e2fs_rev > E2FS_REV0 &&
(ip->i_e2fs->e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) {
ep->e2d_type = IFTODT(ip->i_ffs_mode);
} else {
ep->e2d_type = 0;
}
error = VOP_BWRITE(bp); error = VOP_BWRITE(bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE; dp->i_flag |= IN_CHANGE | IN_UPDATE;
return (error); return (error);
@ -986,7 +998,7 @@ ext2fs_dirempty(ip, parentino, cred)
if (dp->e2d_ino == 0) if (dp->e2d_ino == 0)
continue; continue;
/* accept only "." and ".." */ /* accept only "." and ".." */
namlen = fs2h16(dp->e2d_namlen); namlen = dp->e2d_namlen;
if (namlen > 2) if (namlen > 2)
return (0); return (0);
if (dp->e2d_name[0] != '.') if (dp->e2d_name[0] != '.')
@ -1041,7 +1053,7 @@ ext2fs_checkpath(source, target, cred)
(struct proc *)0); (struct proc *)0);
if (error != 0) if (error != 0)
break; break;
namlen = fs2h16(dirbuf.dotdot_namlen); namlen = dirbuf.dotdot_namlen;
if (namlen != 2 || if (namlen != 2 ||
dirbuf.dotdot_name[0] != '.' || dirbuf.dotdot_name[0] != '.' ||
dirbuf.dotdot_name[1] != '.') { dirbuf.dotdot_name[1] != '.') {

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_vfsops.c,v 1.30 1999/11/15 18:49:13 fvdl Exp $ */ /* $NetBSD: ext2fs_vfsops.c,v 1.31 2000/01/26 16:21:34 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -74,6 +74,7 @@
extern struct lock ufs_hashlock; extern struct lock ufs_hashlock;
int ext2fs_sbupdate __P((struct ufsmount *, int)); int ext2fs_sbupdate __P((struct ufsmount *, int));
static int ext2fs_checksb __P((struct ext2fs *, int));
extern struct vnodeopv_desc ext2fs_vnodeop_opv_desc; extern struct vnodeopv_desc ext2fs_vnodeop_opv_desc;
extern struct vnodeopv_desc ext2fs_specop_opv_desc; extern struct vnodeopv_desc ext2fs_specop_opv_desc;
@ -168,7 +169,12 @@ ext2fs_mountroot()
fs = ump->um_e2fs; fs = ump->um_e2fs;
memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt)); memset(fs->e2fs_fsmnt, 0, sizeof(fs->e2fs_fsmnt));
(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt, (void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt,
MNAMELEN - 1, 0); sizeof(fs->e2fs_fsmnt) - 1, 0);
if (fs->e2fs.e2fs_rev > E2FS_REV0) {
memset(fs->e2fs.e2fs_fsmnt, 0, sizeof(fs->e2fs.e2fs_fsmnt));
(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt,
sizeof(fs->e2fs.e2fs_fsmnt) - 1, 0);
}
(void)ext2fs_statfs(mp, &mp->mnt_stat, p); (void)ext2fs_statfs(mp, &mp->mnt_stat, p);
vfs_unbusy(mp); vfs_unbusy(mp);
inittodr(fs->e2fs.e2fs_wtime); inittodr(fs->e2fs.e2fs_wtime);
@ -301,8 +307,15 @@ ext2fs_mount(mp, path, data, ndp, p)
} }
ump = VFSTOUFS(mp); ump = VFSTOUFS(mp);
fs = ump->um_e2fs; fs = ump->um_e2fs;
(void) copyinstr(path, fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt) - 1, &size); (void) copyinstr(path, fs->e2fs_fsmnt, sizeof(fs->e2fs_fsmnt) - 1,
&size);
memset(fs->e2fs_fsmnt + size, 0, sizeof(fs->e2fs_fsmnt) - size); memset(fs->e2fs_fsmnt + size, 0, sizeof(fs->e2fs_fsmnt) - size);
if (fs->e2fs.e2fs_rev > E2FS_REV0) {
(void) copystr(mp->mnt_stat.f_mntonname, fs->e2fs.e2fs_fsmnt,
sizeof(fs->e2fs.e2fs_fsmnt) - 1, &size);
memset(fs->e2fs.e2fs_fsmnt, 0,
sizeof(fs->e2fs.e2fs_fsmnt) - size);
}
memcpy(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt, MNAMELEN); memcpy(mp->mnt_stat.f_mntonname, fs->e2fs_fsmnt, MNAMELEN);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, (void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size); &size);
@ -368,27 +381,11 @@ ext2fs_reload(mountp, cred, p)
return (error); return (error);
} }
newfs = (struct ext2fs *)bp->b_data; newfs = (struct ext2fs *)bp->b_data;
if (fs2h16(newfs->e2fs_magic) != E2FS_MAGIC) { error = ext2fs_checksb(newfs, (mountp->mnt_flag & MNT_RDONLY) != 0);
if (error) {
brelse(bp); brelse(bp);
return (EIO); /* XXX needs translation */ return (error);
} }
if (fs2h32(newfs->e2fs_rev) != E2FS_REV) {
#ifdef DIAGNOSTIC
printf("Ext2 fs: unsupported revision number: %x (expected %x)\n",
fs2h32(newfs->e2fs_rev), E2FS_REV);
#endif
brelse(bp);
return (EIO); /* XXX needs translation */
}
if (fs2h32(newfs->e2fs_log_bsize) > 2) { /* block size = 1024|2048|4096 */
#ifdef DIAGNOSTIC
printf("Ext2 fs: bad block size: %d (expected <=2 for ext2 fs)\n",
fs2h32(newfs->e2fs_log_bsize));
#endif
brelse(bp);
return (EIO); /* XXX needs translation */
}
fs = VFSTOUFS(mountp)->um_e2fs; fs = VFSTOUFS(mountp)->um_e2fs;
/* /*
@ -528,23 +525,9 @@ ext2fs_mountfs(devvp, mp, p)
error = EINVAL; /* XXX needs translation */ error = EINVAL; /* XXX needs translation */
goto out; goto out;
} }
if (fs2h32(fs->e2fs_rev) != E2FS_REV) { error = ext2fs_checksb(fs, ronly);
#ifdef DIAGNOSTIC if (error)
printf("Ext2 fs: unsupported revision number: %x (expected %x)\n",
fs2h32(fs->e2fs_rev), E2FS_REV);
#endif
error = EINVAL; /* XXX needs translation */
goto out; goto out;
}
if (fs2h32(fs->e2fs_log_bsize) > 2) { /* block size = 1024|2048|4096 */
#ifdef DIAGNOSTIC
printf("Ext2 fs: bad block size: %d (expected <=2 for ext2 fs)\n",
fs2h32(fs->e2fs_log_bsize));
#endif
error = EINVAL; /* XXX needs translation */
goto out;
}
ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK); ump = malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
memset((caddr_t)ump, 0, sizeof *ump); memset((caddr_t)ump, 0, sizeof *ump);
ump->um_e2fs = malloc(sizeof(struct m_ext2fs), M_UFSMNT, M_WAITOK); ump->um_e2fs = malloc(sizeof(struct m_ext2fs), M_UFSMNT, M_WAITOK);
@ -1045,3 +1028,39 @@ ext2fs_cgupdate(mp, waitfor)
allerror = error; allerror = error;
return (allerror); return (allerror);
} }
static int
ext2fs_checksb(fs, ronly)
struct ext2fs *fs;
int ronly;
{
if (fs2h16(fs->e2fs_magic) != E2FS_MAGIC) {
return (EIO); /* XXX needs translation */
}
if (fs2h32(fs->e2fs_rev) > E2FS_REV1) {
#ifdef DIAGNOSTIC
printf("Ext2 fs: unsupported revision number: %x\n",
fs2h32(fs->e2fs_rev));
#endif
return (EIO); /* XXX needs translation */
}
if (fs2h32(fs->e2fs_log_bsize) > 2) { /* block size = 1024|2048|4096 */
#ifdef DIAGNOSTIC
printf("Ext2 fs: bad block size: %d (expected <=2 for ext2 fs)\n",
fs2h32(fs->e2fs_log_bsize));
#endif
return (EIO); /* XXX needs translation */
}
if (fs2h32(fs->e2fs_rev) > E2FS_REV0) {
if (fs2h32(fs->e2fs_features_incompat) &
~EXT2F_INCOMPAT_SUPP) {
printf("Ext2 fs: unsupported optionnal feature\n");
return (EIO); /* XXX needs translation */
}
if (!ronly && fs2h32(fs->e2fs_features_rocompat) &
~EXT2F_ROCOMPAT_SUPP) {
return (EROFS); /* XXX needs translation */
}
}
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ext2fs_vnops.c,v 1.21 1999/08/03 20:19:21 wrstuden Exp $ */ /* $NetBSD: ext2fs_vnops.c,v 1.22 2000/01/26 16:21:34 bouyer Exp $ */
/* /*
* Copyright (c) 1997 Manuel Bouyer. * Copyright (c) 1997 Manuel Bouyer.
@ -930,7 +930,7 @@ abortit:
UIO_SYSSPACE, IO_NODELOCKED, UIO_SYSSPACE, IO_NODELOCKED,
tcnp->cn_cred, (size_t *)0, (struct proc *)0); tcnp->cn_cred, (size_t *)0, (struct proc *)0);
if (error == 0) { if (error == 0) {
namlen = fs2h16(dirbuf.dotdot_namlen); namlen = dirbuf.dotdot_namlen;
if (namlen != 2 || if (namlen != 2 ||
dirbuf.dotdot_name[0] != '.' || dirbuf.dotdot_name[0] != '.' ||
dirbuf.dotdot_name[1] != '.') { dirbuf.dotdot_name[1] != '.') {
@ -1042,11 +1042,19 @@ ext2fs_mkdir(v)
memset(&dirtemplate, 0, sizeof(dirtemplate)); memset(&dirtemplate, 0, sizeof(dirtemplate));
dirtemplate.dot_ino = h2fs32(ip->i_number); dirtemplate.dot_ino = h2fs32(ip->i_number);
dirtemplate.dot_reclen = h2fs16(12); dirtemplate.dot_reclen = h2fs16(12);
dirtemplate.dot_namlen = h2fs16(1); dirtemplate.dot_namlen = 1;
if (ip->i_e2fs->e2fs.e2fs_rev > E2FS_REV0 &&
(ip->i_e2fs->e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) {
dirtemplate.dot_type = IFTODT(EXT2_IFDIR);
}
dirtemplate.dot_name[0] = '.'; dirtemplate.dot_name[0] = '.';
dirtemplate.dotdot_ino = h2fs32(dp->i_number); dirtemplate.dotdot_ino = h2fs32(dp->i_number);
dirtemplate.dotdot_reclen = h2fs16(VTOI(dvp)->i_e2fs->e2fs_bsize - 12); dirtemplate.dotdot_reclen = h2fs16(VTOI(dvp)->i_e2fs->e2fs_bsize - 12);
dirtemplate.dotdot_namlen = h2fs16(2); dirtemplate.dotdot_namlen = 2;
if (ip->i_e2fs->e2fs.e2fs_rev > E2FS_REV0 &&
(ip->i_e2fs->e2fs.e2fs_features_incompat & EXT2F_INCOMPAT_FTYPE)) {
dirtemplate.dotdot_type = IFTODT(EXT2_IFDIR);
}
dirtemplate.dotdot_name[0] = dirtemplate.dotdot_name[1] = '.'; dirtemplate.dotdot_name[0] = dirtemplate.dotdot_name[1] = '.';
error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate, error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE, sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,