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:
parent
063cb5e5dc
commit
5fb6bc4e18
@ -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.
|
||||
@ -39,12 +39,13 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)dir.c 8.5 (Berkeley) 12/8/94";
|
||||
#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 /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ext2fs/ext2fs_dinode.h>
|
||||
#include <ufs/ext2fs/ext2fs_dir.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";
|
||||
int lfmode = 01777;
|
||||
/* XXX DIRBLKSIZ id bsize ! */
|
||||
#define DIRBLKSIZ 0 /* just for now */
|
||||
struct ext2fs_dirtemplate emptydir = { 0, DIRBLKSIZ };
|
||||
struct ext2fs_dirtemplate dirhead = {
|
||||
0, 12, 1, ".",
|
||||
0, DIRBLKSIZ - 12, 2, ".."
|
||||
0, 12, 1, IFTODT(EXT2_IFDIR), ".",
|
||||
0, DIRBLKSIZ - 12, 2, IFTODT(EXT2_IFDIR), ".."
|
||||
};
|
||||
#undef DIRBLKSIZ
|
||||
|
||||
@ -189,6 +188,7 @@ fsck_readdir(idesc)
|
||||
dp->e2d_reclen = h2fs16(sblock.e2fs_bsize);
|
||||
dp->e2d_ino = 0;
|
||||
dp->e2d_namlen = 0;
|
||||
dp->e2d_type = 0;
|
||||
dp->e2d_name[0] = '\0';
|
||||
if (fix)
|
||||
dirty(bp);
|
||||
@ -235,7 +235,6 @@ dircheck(idesc, dp)
|
||||
int size;
|
||||
char *cp;
|
||||
int spaceleft;
|
||||
u_int16_t namlen;
|
||||
u_int16_t reclen = fs2h16(dp->e2d_reclen);
|
||||
|
||||
spaceleft = sblock.e2fs_bsize - (idesc->id_loc % sblock.e2fs_bsize);
|
||||
@ -246,13 +245,16 @@ dircheck(idesc, dp)
|
||||
return (0);
|
||||
if (dp->e2d_ino == 0)
|
||||
return (1);
|
||||
namlen = fs2h16(dp->e2d_namlen);
|
||||
size = EXT2FS_DIRSIZ(namlen);
|
||||
if (sblock.e2fs.e2fs_rev < E2FS_REV0 ||
|
||||
(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 ||
|
||||
idesc->id_filesize < size ||
|
||||
namlen > EXT2FS_MAXNAMLEN)
|
||||
dp->e2d_namlen > EXT2FS_MAXNAMLEN)
|
||||
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++ == '/'))
|
||||
return (0);
|
||||
return (1);
|
||||
@ -330,10 +332,13 @@ mkentry(idesc)
|
||||
struct ext2fs_direct newent;
|
||||
int newlen, oldlen;
|
||||
|
||||
newent.e2d_namlen = h2fs16(strlen(idesc->id_name));
|
||||
newlen = EXT2FS_DIRSIZ(fs2h16(newent.e2d_namlen));
|
||||
newent.e2d_namlen = strlen(idesc->id_name);
|
||||
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)
|
||||
oldlen = EXT2FS_DIRSIZ(fs2h16(dirp->e2d_namlen));
|
||||
oldlen = EXT2FS_DIRSIZ(dirp->e2d_namlen);
|
||||
else
|
||||
oldlen = 0;
|
||||
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_reclen = newent.e2d_reclen;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -353,12 +359,17 @@ chgino(idesc)
|
||||
struct inodesc *idesc;
|
||||
{
|
||||
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 ||
|
||||
strncmp(dirp->e2d_name, idesc->id_name, (int)namlen))
|
||||
return (KEEPON);
|
||||
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);
|
||||
}
|
||||
|
||||
@ -601,8 +612,18 @@ allocdir(parent, request, mode)
|
||||
ino = allocino(request, IFDIR|mode);
|
||||
dirhead.dot_reclen = h2fs16(12); /* XXX */
|
||||
dirhead.dotdot_reclen = h2fs16(sblock.e2fs_bsize - 12); /* XXX */
|
||||
dirhead.dot_namlen = h2fs16(1);
|
||||
dirhead.dotdot_namlen = h2fs16(2);
|
||||
dirhead.dot_namlen = 1;
|
||||
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->dot_ino = h2fs32(ino);
|
||||
dirp->dotdot_ino = h2fs32(parent);
|
||||
|
@ -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.
|
||||
@ -184,6 +184,7 @@ char *blockmap; /* ptr to primary blk allocation map */
|
||||
ino_t maxino; /* number of inodes in file system */
|
||||
ino_t lastino; /* last inode in use */
|
||||
char *statemap; /* ptr to inode state table */
|
||||
u_char *typemap; /* ptr to inode type table */
|
||||
int16_t *lncntp; /* ptr to link count table */
|
||||
|
||||
ino_t lfdir; /* lost & found directory inode number */
|
||||
|
@ -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.
|
||||
@ -39,7 +39,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)inode.c 8.5 (Berkeley) 2/8/95";
|
||||
#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 /* 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/ufs/dinode.h> /* for IFMT & friends */
|
||||
#include <ufs/ufs/dir.h> /* for IFTODT & friends */
|
||||
#ifndef SMALL
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@ -502,7 +503,7 @@ findname(idesc)
|
||||
struct inodesc *idesc;
|
||||
{
|
||||
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)
|
||||
return (KEEPON);
|
||||
@ -637,6 +638,7 @@ allocino(request, type)
|
||||
dp->e2di_nblock = h2fs32(btodb(sblock.e2fs_bsize));
|
||||
n_files++;
|
||||
inodirty();
|
||||
typemap[ino] = IFTODT(type);
|
||||
return (ino);
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
@ -44,7 +44,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1993\n\
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)main.c 8.2 (Berkeley) 1/23/94";
|
||||
#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 /* not lint */
|
||||
|
||||
@ -193,6 +193,10 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
* 1: scan inodes tallying blocks used
|
||||
*/
|
||||
if (preen == 0) {
|
||||
if (sblock.e2fs.e2fs_rev > E2FS_REV0) {
|
||||
printf("** Last Mounted on %s\n",
|
||||
sblock.e2fs.e2fs_fsmnt);
|
||||
}
|
||||
if (hotroot())
|
||||
printf("** Root file system\n");
|
||||
printf("** Phase 1 - Check Blocks and Sizes\n");
|
||||
|
@ -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.
|
||||
@ -39,7 +39,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)pass1.c 8.1 (Berkeley) 6/5/93";
|
||||
#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 /* 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/ufs/dinode.h> /* for IFMT & friends */
|
||||
#include <ufs/ufs/dir.h> /* for IFTODT & friends */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -247,6 +248,7 @@ checkinode(inumber, idesc)
|
||||
} else {
|
||||
statemap[inumber] = FSTATE;
|
||||
}
|
||||
typemap[inumber] = IFTODT(mode);
|
||||
badblk = dupblk = 0;
|
||||
idesc->id_number = inumber;
|
||||
(void)ckinode(dp, idesc);
|
||||
|
@ -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.
|
||||
@ -39,7 +39,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)pass2.c 8.6 (Berkeley) 10/27/94";
|
||||
#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 /* 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/ufs/dinode.h> /* for IFMT & friends */
|
||||
#include <ufs/ufs/dir.h> /* for IFTODT & friends */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -216,7 +217,7 @@ pass2check(idesc)
|
||||
*/
|
||||
if (idesc->id_entryno != 0)
|
||||
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] == '.') {
|
||||
if (fs2h32(dirp->e2d_ino) != idesc->id_number) {
|
||||
direrror(idesc->id_number, "BAD INODE NUMBER FOR '.'");
|
||||
@ -224,13 +225,26 @@ pass2check(idesc)
|
||||
if (reply("FIX") == 1)
|
||||
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;
|
||||
}
|
||||
direrror(idesc->id_number, "MISSING '.'");
|
||||
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, ".");
|
||||
entrysize = EXT2FS_DIRSIZ(fs2h16(proto.e2d_namlen));
|
||||
entrysize = EXT2FS_DIRSIZ(proto.e2d_namlen);
|
||||
if (fs2h32(dirp->e2d_ino) != 0 && strcmp(dirp->e2d_name, "..") != 0) {
|
||||
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
|
||||
dirp->e2d_name);
|
||||
@ -258,11 +272,16 @@ chk1:
|
||||
goto chk2;
|
||||
inp = getinoinfo(idesc->id_number);
|
||||
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, "..");
|
||||
entrysize = EXT2FS_DIRSIZ(2);
|
||||
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)
|
||||
goto chk2;
|
||||
proto.e2d_reclen = h2fs16(fs2h16(dirp->e2d_reclen) - n);
|
||||
@ -274,13 +293,21 @@ chk1:
|
||||
dirp->e2d_reclen = proto.e2d_reclen;
|
||||
}
|
||||
if (fs2h32(dirp->e2d_ino) != 0 &&
|
||||
fs2h16(dirp->e2d_namlen) == 2 &&
|
||||
dirp->e2d_namlen == 2 &&
|
||||
strncmp(dirp->e2d_name, "..", 2) == 0) {
|
||||
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;
|
||||
}
|
||||
if (fs2h32(dirp->e2d_ino) != 0 &&
|
||||
fs2h16(dirp->e2d_namlen) == 1 &&
|
||||
dirp->e2d_namlen == 1 &&
|
||||
strncmp(dirp->e2d_name, ".", 1) != 0) {
|
||||
fileerror(inp->i_parent, idesc->id_number, "MISSING '..'");
|
||||
pfatal("CANNOT FIX, SECOND ENTRY IN DIRECTORY CONTAINS %s\n",
|
||||
@ -308,10 +335,10 @@ chk1:
|
||||
chk2:
|
||||
if (fs2h32(dirp->e2d_ino) == 0)
|
||||
return (ret|KEEPON);
|
||||
if (fs2h16(dirp->e2d_namlen) <= 2 &&
|
||||
if (dirp->e2d_namlen <= 2 &&
|
||||
dirp->e2d_name[0] == '.' &&
|
||||
idesc->id_entryno >= 2) {
|
||||
if (fs2h16(dirp->e2d_namlen) == 1) {
|
||||
if (dirp->e2d_namlen == 1) {
|
||||
direrror(idesc->id_number, "EXTRA '.' ENTRY");
|
||||
dirp->e2d_ino = 0;
|
||||
if (reply("FIX") == 1)
|
||||
@ -385,6 +412,17 @@ again:
|
||||
/* fall through */
|
||||
|
||||
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)]--;
|
||||
break;
|
||||
|
||||
|
@ -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.
|
||||
@ -39,7 +39,7 @@
|
||||
#if 0
|
||||
static char sccsid[] = "@(#)setup.c 8.5 (Berkeley) 11/23/94";
|
||||
#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 /* not lint */
|
||||
|
||||
@ -224,6 +224,12 @@ setup(dev)
|
||||
(unsigned)(maxino + 1));
|
||||
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));
|
||||
if (lncntp == NULL) {
|
||||
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_block_group_nr =
|
||||
sblk.b_un.b_fs->e2fs_block_group_nr;
|
||||
if (sblk.b_un.b_fs->e2fs_features_compat != 0 ||
|
||||
sblk.b_un.b_fs->e2fs_features_incompat != 0 ||
|
||||
sblk.b_un.b_fs->e2fs_features_compat_ro != 0) {
|
||||
if (sblk.b_un.b_fs->e2fs_rev > E2FS_REV0 &&
|
||||
((sblk.b_un.b_fs->e2fs_features_incompat & ~EXT2F_INCOMPAT_SUPP) ||
|
||||
(sblk.b_un.b_fs->e2fs_features_rocompat & ~EXT2F_ROCOMPAT_SUPP))) {
|
||||
if (debug) {
|
||||
printf("compat 0x%08x, incompat 0x%08x, compat_ro "
|
||||
"0x%08x\n",
|
||||
sblk.b_un.b_fs->e2fs_features_compat,
|
||||
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;
|
||||
}
|
||||
if (memcmp(sblk.b_un.b_fs, asblk.b_un.b_fs, SBSIZE)) {
|
||||
|
@ -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.
|
||||
@ -119,7 +119,7 @@ struct ext2fs {
|
||||
u_int16_t e2fs_magic; /* magic number */
|
||||
u_int16_t e2fs_state; /* file system state */
|
||||
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_fsckintv; /* max time between fscks */
|
||||
u_int32_t e2fs_creator; /* creator OS */
|
||||
@ -130,10 +130,17 @@ struct ext2fs {
|
||||
u_int32_t e2fs_first_ino; /* first non-reserved inode */
|
||||
u_int16_t e2fs_inode_size; /* size of inode structure */
|
||||
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_incompat; /* not OK to mount if unknown */
|
||||
u_int32_t e2fs_features_compat_ro; /* OK to mount ro if unknown */
|
||||
u_int32_t reserved2[230];
|
||||
u_int32_t e2fs_features_compat; /* compatible feature set */
|
||||
u_int32_t e2fs_features_incompat; /* incompatible feature set */
|
||||
u_int32_t e2fs_features_rocompat; /* RO-compatible feature set */
|
||||
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
|
||||
*/
|
||||
#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
|
||||
|
@ -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.
|
||||
@ -59,17 +59,25 @@ e2fs_sb_bswap(old, new)
|
||||
new->e2fs_ipg = bswap32(old->e2fs_ipg);
|
||||
new->e2fs_mtime = bswap32(old->e2fs_mtime);
|
||||
new->e2fs_wtime = bswap32(old->e2fs_wtime);
|
||||
new->e2fs_lastfsck = bswap32(old->e2fs_lastfsck);
|
||||
new->e2fs_fsckintv = bswap32(old->e2fs_fsckintv);
|
||||
new->e2fs_creator = bswap32(old->e2fs_creator);
|
||||
new->e2fs_rev = bswap32(old->e2fs_rev);
|
||||
new->e2fs_mnt_count = bswap16(old->e2fs_mnt_count);
|
||||
new->e2fs_max_mnt_count = bswap16(old->e2fs_max_mnt_count);
|
||||
new->e2fs_magic = bswap16(old->e2fs_magic);
|
||||
new->e2fs_state = bswap16(old->e2fs_state);
|
||||
new->e2fs_beh = bswap16(old->e2fs_beh);
|
||||
new->e2fs_minrev = bswap16(old->e2fs_minrev);
|
||||
new->e2fs_lastfsck = bswap32(old->e2fs_lastfsck);
|
||||
new->e2fs_fsckintv = bswap32(old->e2fs_fsckintv);
|
||||
new->e2fs_creator = bswap32(old->e2fs_creator);
|
||||
new->e2fs_rev = bswap32(old->e2fs_rev);
|
||||
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)
|
||||
|
@ -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.
|
||||
@ -79,7 +79,7 @@ struct ext2fs_dinode {
|
||||
u_int32_t e2di_flags; /* 32: Status flags (chflags) */
|
||||
u_int32_t e2di_linux_reserved1; /* 36 */
|
||||
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_dacl; /* 108: dir ACL (not implemented) */
|
||||
u_int32_t e2di_faddr; /* 112: fragment address */
|
||||
|
@ -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.
|
||||
@ -75,6 +75,9 @@
|
||||
* 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
|
||||
* 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
|
||||
@ -82,7 +85,8 @@
|
||||
struct ext2fs_direct {
|
||||
u_int32_t e2d_ino; /* inode number of entry */
|
||||
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 */
|
||||
};
|
||||
|
||||
@ -103,11 +107,13 @@ struct ext2fs_direct {
|
||||
struct ext2fs_dirtemplate {
|
||||
u_int32_t dot_ino;
|
||||
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 */
|
||||
u_int32_t dotdot_ino;
|
||||
int16_t dotdot_reclen;
|
||||
u_int16_t dotdot_namlen;
|
||||
u_int8_t dotdot_namlen;
|
||||
u_int8_t dotdot_type;
|
||||
char dotdot_name[4]; /* ditto */
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
@ -95,7 +95,7 @@ ext2fs_dirconv2ffs( e2dir, ffsdir)
|
||||
{
|
||||
memset(ffsdir, 0, sizeof(struct dirent));
|
||||
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 */
|
||||
#ifdef DIAGNOSTIC
|
||||
@ -103,7 +103,7 @@ ext2fs_dirconv2ffs( e2dir, ffsdir)
|
||||
* XXX Rigth now this can't happen, but if one day
|
||||
* 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");
|
||||
#endif
|
||||
strncpy(ffsdir->d_name, e2dir->e2d_name, ffsdir->d_namlen);
|
||||
@ -415,7 +415,7 @@ searchloop:
|
||||
int size = fs2h16(ep->e2d_reclen);
|
||||
|
||||
if (ep->e2d_ino != 0)
|
||||
size -= EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen));
|
||||
size -= EXT2FS_DIRSIZ(ep->e2d_namlen);
|
||||
if (size > 0) {
|
||||
if (size >= slotneeded) {
|
||||
slotstatus = FOUND;
|
||||
@ -438,7 +438,7 @@ searchloop:
|
||||
* Check for a name match.
|
||||
*/
|
||||
if (ep->e2d_ino) {
|
||||
namlen = fs2h16(ep->e2d_namlen);
|
||||
namlen = ep->e2d_namlen;
|
||||
if (namlen == cnp->cn_namelen &&
|
||||
!memcmp(cnp->cn_nameptr, ep->e2d_name,
|
||||
(unsigned)namlen)) {
|
||||
@ -538,11 +538,11 @@ found:
|
||||
* Check that directory length properly reflects presence
|
||||
* of this entry.
|
||||
*/
|
||||
if (entryoffsetinblock + EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen))
|
||||
if (entryoffsetinblock + EXT2FS_DIRSIZ(ep->e2d_namlen)
|
||||
> dp->i_e2fs_size) {
|
||||
ufs_dirbad(dp, dp->i_offset, "i_size too small");
|
||||
dp->i_e2fs_size = entryoffsetinblock +
|
||||
EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen));
|
||||
EXT2FS_DIRSIZ(ep->e2d_namlen);
|
||||
dp->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
}
|
||||
|
||||
@ -713,7 +713,7 @@ ext2fs_dirbadentry(dp, de, entryoffsetinblock)
|
||||
|
||||
char * error_msg = NULL;
|
||||
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 */
|
||||
error_msg = "rec_len is smaller than minimal";
|
||||
@ -770,7 +770,13 @@ ext2fs_direnter(ip, dvp, cnp)
|
||||
#endif
|
||||
dp = VTOI(dvp);
|
||||
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);
|
||||
newentrysize = EXT2FS_DIRSIZ(cnp->cn_namelen);
|
||||
if (dp->i_count == 0) {
|
||||
@ -826,7 +832,7 @@ ext2fs_direnter(ip, dvp, cnp)
|
||||
* space.
|
||||
*/
|
||||
ep = (struct ext2fs_direct *)dirbuf;
|
||||
dsize = EXT2FS_DIRSIZ(fs2h16(ep->e2d_namlen));
|
||||
dsize = EXT2FS_DIRSIZ(ep->e2d_namlen);
|
||||
spacefree = fs2h16(ep->e2d_reclen) - dsize;
|
||||
for (loc = fs2h16(ep->e2d_reclen); loc < dp->i_count; ) {
|
||||
nep = (struct ext2fs_direct *)(dirbuf + loc);
|
||||
@ -838,7 +844,7 @@ ext2fs_direnter(ip, dvp, cnp)
|
||||
/* overwrite; nothing there; header is ours */
|
||||
spacefree += dsize;
|
||||
}
|
||||
dsize = EXT2FS_DIRSIZ(fs2h16(nep->e2d_namlen));
|
||||
dsize = EXT2FS_DIRSIZ(nep->e2d_namlen);
|
||||
spacefree += fs2h16(nep->e2d_reclen) - dsize;
|
||||
loc += fs2h16(nep->e2d_reclen);
|
||||
memcpy((caddr_t)ep, (caddr_t)nep, dsize);
|
||||
@ -942,6 +948,12 @@ ext2fs_dirrewrite(dp, ip, cnp)
|
||||
if (error != 0)
|
||||
return (error);
|
||||
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);
|
||||
dp->i_flag |= IN_CHANGE | IN_UPDATE;
|
||||
return (error);
|
||||
@ -986,7 +998,7 @@ ext2fs_dirempty(ip, parentino, cred)
|
||||
if (dp->e2d_ino == 0)
|
||||
continue;
|
||||
/* accept only "." and ".." */
|
||||
namlen = fs2h16(dp->e2d_namlen);
|
||||
namlen = dp->e2d_namlen;
|
||||
if (namlen > 2)
|
||||
return (0);
|
||||
if (dp->e2d_name[0] != '.')
|
||||
@ -1041,7 +1053,7 @@ ext2fs_checkpath(source, target, cred)
|
||||
(struct proc *)0);
|
||||
if (error != 0)
|
||||
break;
|
||||
namlen = fs2h16(dirbuf.dotdot_namlen);
|
||||
namlen = dirbuf.dotdot_namlen;
|
||||
if (namlen != 2 ||
|
||||
dirbuf.dotdot_name[0] != '.' ||
|
||||
dirbuf.dotdot_name[1] != '.') {
|
||||
|
@ -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.
|
||||
@ -74,6 +74,7 @@
|
||||
extern struct lock ufs_hashlock;
|
||||
|
||||
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_specop_opv_desc;
|
||||
@ -168,7 +169,12 @@ ext2fs_mountroot()
|
||||
fs = ump->um_e2fs;
|
||||
memset(fs->e2fs_fsmnt, 0, sizeof(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);
|
||||
vfs_unbusy(mp);
|
||||
inittodr(fs->e2fs.e2fs_wtime);
|
||||
@ -301,8 +307,15 @@ ext2fs_mount(mp, path, data, ndp, p)
|
||||
}
|
||||
ump = VFSTOUFS(mp);
|
||||
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);
|
||||
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);
|
||||
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
|
||||
&size);
|
||||
@ -368,27 +381,11 @@ ext2fs_reload(mountp, cred, p)
|
||||
return (error);
|
||||
}
|
||||
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);
|
||||
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;
|
||||
/*
|
||||
@ -528,23 +525,9 @@ ext2fs_mountfs(devvp, mp, p)
|
||||
error = EINVAL; /* XXX needs translation */
|
||||
goto out;
|
||||
}
|
||||
if (fs2h32(fs->e2fs_rev) != E2FS_REV) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("Ext2 fs: unsupported revision number: %x (expected %x)\n",
|
||||
fs2h32(fs->e2fs_rev), E2FS_REV);
|
||||
#endif
|
||||
error = EINVAL; /* XXX needs translation */
|
||||
error = ext2fs_checksb(fs, ronly);
|
||||
if (error)
|
||||
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);
|
||||
memset((caddr_t)ump, 0, sizeof *ump);
|
||||
ump->um_e2fs = malloc(sizeof(struct m_ext2fs), M_UFSMNT, M_WAITOK);
|
||||
@ -1045,3 +1028,39 @@ ext2fs_cgupdate(mp, waitfor)
|
||||
allerror = error;
|
||||
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);
|
||||
}
|
||||
|
@ -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.
|
||||
@ -930,7 +930,7 @@ abortit:
|
||||
UIO_SYSSPACE, IO_NODELOCKED,
|
||||
tcnp->cn_cred, (size_t *)0, (struct proc *)0);
|
||||
if (error == 0) {
|
||||
namlen = fs2h16(dirbuf.dotdot_namlen);
|
||||
namlen = dirbuf.dotdot_namlen;
|
||||
if (namlen != 2 ||
|
||||
dirbuf.dotdot_name[0] != '.' ||
|
||||
dirbuf.dotdot_name[1] != '.') {
|
||||
@ -1042,11 +1042,19 @@ ext2fs_mkdir(v)
|
||||
memset(&dirtemplate, 0, sizeof(dirtemplate));
|
||||
dirtemplate.dot_ino = h2fs32(ip->i_number);
|
||||
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.dotdot_ino = h2fs32(dp->i_number);
|
||||
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] = '.';
|
||||
error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
|
||||
sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
|
||||
|
Loading…
Reference in New Issue
Block a user