Subject: kern/17345: Apple UFS filesystem support, patches included
To: None <gnats-bugs@gnats.netbsd.org>
From: Darrin B.Jewell <dbj@netbsd.org>
List: netbsd-bugs
Date: 06/21/2002 01:52:52
>Number: 17345
>Category: kern
>Synopsis: Apple UFS filesystem support, patches included
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: change-request
>Submitter-Id: net
>Arrival-Date: Thu Jun 20 20:12:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator: Darrin B. Jewell
>Release: NetBSD 1.6_BETA2, cvs branch netbsd-1-6 ~20020616T2139Z
>Organization:
>Environment:
System: NetBSD quiteria 1.6_BETA2 NetBSD 1.6_BETA2 (QUITERIA) #13: Thu Jun 20 17:05:07 EDT 2002 dbj@quiteria:/usr/src/sys/arch/macppc/compile/QUITERIA macppc
Architecture: powerpc
Machine: macppc
>Description:
The included patches add support for Apple UFS filesystems to NetBSD.
This should also support NeXTstep filesystems on disks that use 512
byte sector sizes. The primary difference is to support an alternate
value of 1024 for DIRBLKSIZ, although there are a couple of other
minor differences. My original analsys of these differences can be
found in a post to port-macppc:
http://mail-index.netbsd.org/port-macppc/2001/12/13/0012.html
The general approach is to use a run time deteriminable value
for DIRBLKSIZ. Additional allowances are included for using
MAXSYMLINKLEN with FS_42INODEFMT and a shift in the cylinder group
cluster summary count array. Support is added for managing
the Apple UFS volume label.
Either the apple UFS volume label or the new disklabel fstype
FS_APPLEUFS are used as hints that the filesystem is to be
treated as an Apple UFS filesystem.
These changes are enabled with the APPLE_UFS kernel option.
In combination with FFS_EI, they should work with i386 Darwin
filesystems, but this has not been extensively tested. The
userland utilities that manage filesystems have also been updated.
PR bin/15449 is also needed for use with NeXTstep filesystems.
Additionally the next68k disklabel will need to be updated to
use FS_APPLEUFS since the apple UFS volume label is not present
on NeXTstep disks.
I have been using these changes since January without problem.
They have recently been updated in my tree to the netbsd-1-6 branch,
and minor tweaks have been performed to ready them for general
submission. I plan to pursue discussion of this PR on tech-kern.
and will merge them to the cvs trunk and commit upon approval.
I also recommend that we import the pdisk utility. This is
the same utility as MacOS X ships. The current version can
be found at
http://cantaforda.com/cfcl/eryk/linux/pdisk
it ports trivially to NetBSD and has an MIT style license.
Darrin
>How-To-Repeat:
>Fix:
cvs -f -d cvs.netbsd.org:/cvsroot diff -uN
Index: sbin/disklabel/disklabel.5
===================================================================
RCS file: /cvsroot/basesrc/sbin/disklabel/disklabel.5,v
retrieving revision 1.15
diff -u -r1.15 disklabel.5
--- sbin/disklabel/disklabel.5 2002/02/08 01:30:43 1.15
+++ sbin/disklabel/disklabel.5 2002/06/20 22:40:03
@@ -307,6 +307,7 @@
#define FS_NTFS 18 /* Windows/NT file system */
#define FS_RAID 19 /* RAIDframe component */
#define FS_CCD 20 /* concatenated disk component */
+#define FS_APPLEUFS 21 /* Apple UFS */
#ifdef FSTYPENAMES
static const char *const fstypenames[] = {
@@ -331,6 +332,7 @@
"NTFS",
"RAID",
"ccd",
+ "Apple UFS",
NULL
};
#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
Index: sbin/disklabel/disklabel.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/disklabel/disklabel.c,v
retrieving revision 1.104
diff -u -r1.104 disklabel.c
--- sbin/disklabel/disklabel.c 2002/05/14 21:27:05 1.104
+++ sbin/disklabel/disklabel.c 2002/06/20 22:40:03
@@ -1151,6 +1151,7 @@
case FS_BSDLFS:
case FS_EX2FS:
case FS_ADOS:
+ case FS_APPLEUFS:
(void) fprintf(f, "b%c#%d:", c,
pp->p_fsize * pp->p_frag);
(void) fprintf(f, "f%c#%d:", c, pp->p_fsize);
@@ -1603,6 +1604,7 @@
case FS_BSDFFS:
case FS_ADOS:
+ case FS_APPLEUFS:
NXTNUM(pp->p_fsize);
if (pp->p_fsize == 0)
break;
Index: sbin/disklabel/printlabel.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/disklabel/printlabel.c,v
retrieving revision 1.3
diff -u -r1.3 printlabel.c
--- sbin/disklabel/printlabel.c 2001/10/19 01:16:38 1.3
+++ sbin/disklabel/printlabel.c 2002/06/20 22:40:03
@@ -140,6 +140,7 @@
case FS_BSDFFS:
case FS_ADOS:
+ case FS_APPLEUFS:
(void)fprintf(f, " %5d %5d %5d ",
pp->p_fsize, pp->p_fsize * pp->p_frag, pp->p_cpg);
break;
Index: sbin/fdisk/fdisk.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fdisk/fdisk.c,v
retrieving revision 1.52
diff -u -r1.52 fdisk.c
--- sbin/fdisk/fdisk.c 2002/04/03 03:17:36 1.52
+++ sbin/fdisk/fdisk.c 2002/06/20 22:40:04
@@ -232,6 +232,7 @@
{0xa8, "Apple UFS"},
{0xa9, "NetBSD"},
{0xab, "Apple Boot"},
+ {0xaf, "Apple HFS"},
{0xb1, reserved},
{0xb3, reserved},
{0xb4, reserved},
Index: sbin/fsck_ffs/Makefile
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/Makefile,v
retrieving revision 1.22
diff -u -r1.22 Makefile
--- sbin/fsck_ffs/Makefile 1999/01/15 13:32:06 1.22
+++ sbin/fsck_ffs/Makefile 2002/06/20 22:40:04
@@ -4,7 +4,8 @@
PROG= fsck_ffs
MAN= fsck_ffs.8
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
- pass5.c fsutil.c setup.c utilities.c ffs_bswap.c ffs_subr.c ffs_tables.c
+ pass5.c fsutil.c setup.c utilities.c ffs_bswap.c ffs_subr.c \
+ ffs_tables.c ffs_appleufs.c
FSCK= ${.CURDIR}/../fsck
CPPFLAGS+=-I${FSCK}
.PATH: ${.CURDIR}/../../sys/ufs/ffs ${FSCK}
Index: sbin/fsck_ffs/dir.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/dir.c,v
retrieving revision 1.33
diff -u -r1.33 dir.c
--- sbin/fsck_ffs/dir.c 2002/05/09 02:55:50 1.33
+++ sbin/fsck_ffs/dir.c 2002/06/20 22:40:04
@@ -145,13 +145,17 @@
struct bufarea *bp;
int dsize, n;
long blksiz;
+#if DIRBLKSIZ > APPLEUFS_DIRBLKSIZ
char dbuf[DIRBLKSIZ];
+#else
+ char dbuf[APPLEUFS_DIRBLKSIZ];
+#endif
if (idesc->id_type != DATA)
errx(EEXIT, "wrong type to dirscan %d", idesc->id_type);
if (idesc->id_entryno == 0 &&
- (idesc->id_filesize & (DIRBLKSIZ - 1)) != 0)
- idesc->id_filesize = roundup(idesc->id_filesize, DIRBLKSIZ);
+ (idesc->id_filesize & (dirblksiz - 1)) != 0)
+ idesc->id_filesize = roundup(idesc->id_filesize, dirblksiz);
blksiz = idesc->id_numfrags * sblock->fs_fsize;
if (chkrange(idesc->id_blkno, idesc->id_numfrags)) {
idesc->id_filesize -= blksiz;
@@ -238,7 +242,7 @@
blksiz = idesc->id_numfrags * sblock->fs_fsize;
bp = getdirblk(idesc->id_blkno, blksiz);
- if (idesc->id_loc % DIRBLKSIZ == 0 && idesc->id_filesize > 0 &&
+ if (idesc->id_loc % dirblksiz == 0 && idesc->id_filesize > 0 &&
idesc->id_loc < blksiz) {
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
if (dircheck(idesc, dp))
@@ -248,7 +252,7 @@
fix = dofix(idesc, "DIRECTORY CORRUPTED");
bp = getdirblk(idesc->id_blkno, blksiz);
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
- dp->d_reclen = iswap16(DIRBLKSIZ);
+ dp->d_reclen = iswap16(dirblksiz);
dp->d_ino = 0;
dp->d_type = 0;
dp->d_namlen = 0;
@@ -257,8 +261,8 @@
dirty(bp);
else
markclean= 0;
- idesc->id_loc += DIRBLKSIZ;
- idesc->id_filesize -= DIRBLKSIZ;
+ idesc->id_loc += dirblksiz;
+ idesc->id_filesize -= dirblksiz;
return (dp);
}
dpok:
@@ -268,12 +272,12 @@
dp = (struct direct *)(bp->b_un.b_buf + dploc);
idesc->id_loc += iswap16(dp->d_reclen);
idesc->id_filesize -= iswap16(dp->d_reclen);
- if ((idesc->id_loc % DIRBLKSIZ) == 0)
+ if ((idesc->id_loc % dirblksiz) == 0)
return (dp);
ndp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
if (idesc->id_loc < blksiz && idesc->id_filesize > 0 &&
dircheck(idesc, ndp) == 0) {
- size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
+ size = dirblksiz - (idesc->id_loc % dirblksiz);
idesc->id_loc += size;
idesc->id_filesize -= size;
if (idesc->id_fix == IGNORE)
@@ -304,11 +308,11 @@
u_char namlen, type;
int spaceleft;
- spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
+ spaceleft = dirblksiz - (idesc->id_loc % dirblksiz);
if (iswap32(dp->d_ino) >= maxino ||
dp->d_reclen == 0 ||
iswap16(dp->d_reclen) > spaceleft ||
- (iswap16(dp->d_reclen) & 0x3) != 0)
+ (iswap16(dp->d_reclen) & 0x3) != 0)
return (0);
if (dp->d_ino == 0)
return (1);
@@ -629,8 +633,8 @@
idesc.id_fix = DONTKNOW;
idesc.id_name = name;
dp = ginode(parent);
- if (iswap64(dp->di_size) % DIRBLKSIZ) {
- dp->di_size = iswap64(roundup(iswap64(dp->di_size), DIRBLKSIZ));
+ if (iswap64(dp->di_size) % dirblksiz) {
+ dp->di_size = iswap64(roundup(iswap64(dp->di_size), dirblksiz));
inodirty();
}
if ((ckinode(dp, &idesc) & ALTERED) != 0)
@@ -652,7 +656,12 @@
{
ufs_daddr_t lastbn, newblk;
struct bufarea *bp;
- char *cp, firstblk[DIRBLKSIZ];
+ char *cp;
+#if DIRBLKSIZ > APPLEUFS_DIRBLKSIZ
+ char firstblk[DIRBLKSIZ];
+#else
+ char firstblk[APPLEUFS_DIRBLKSIZ];
+#endif
lastbn = lblkno(sblock, iswap64(dp->di_size));
if (lastbn >= NDADDR - 1 || dp->di_db[lastbn] == 0 || dp->di_size == 0)
@@ -667,15 +676,15 @@
(long)dblksize(sblock, dp, lastbn + 1));
if (bp->b_errs)
goto bad;
- memmove(firstblk, bp->b_un.b_buf, DIRBLKSIZ);
+ memmove(firstblk, bp->b_un.b_buf, dirblksiz);
bp = getdirblk(newblk, sblock->fs_bsize);
if (bp->b_errs)
goto bad;
- memmove(bp->b_un.b_buf, firstblk, DIRBLKSIZ);
- emptydir.dot_reclen = iswap16(DIRBLKSIZ);
- for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
+ memmove(bp->b_un.b_buf, firstblk, dirblksiz);
+ emptydir.dot_reclen = iswap16(dirblksiz);
+ for (cp = &bp->b_un.b_buf[dirblksiz];
cp < &bp->b_un.b_buf[sblock->fs_bsize];
- cp += DIRBLKSIZ)
+ cp += dirblksiz)
memmove(cp, &emptydir, sizeof emptydir);
dirty(bp);
bp = getdirblk(iswap32(dp->di_db[lastbn + 1]),
@@ -717,9 +726,9 @@
ino = allocino(request, IFDIR|mode);
dirhead.dot_reclen = iswap16(12);
- dirhead.dotdot_reclen = iswap16(DIRBLKSIZ - 12);
+ dirhead.dotdot_reclen = iswap16(dirblksiz - 12);
odirhead.dot_reclen = iswap16(12);
- odirhead.dotdot_reclen = iswap16(DIRBLKSIZ - 12);
+ odirhead.dotdot_reclen = iswap16(dirblksiz - 12);
odirhead.dot_namlen = iswap16(1);
odirhead.dotdot_namlen = iswap16(2);
if (newinofmt)
@@ -735,10 +744,10 @@
return (0);
}
memmove(bp->b_un.b_buf, dirp, sizeof(struct dirtemplate));
- emptydir.dot_reclen = iswap16(DIRBLKSIZ);
- for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
+ emptydir.dot_reclen = iswap16(dirblksiz);
+ for (cp = &bp->b_un.b_buf[dirblksiz];
cp < &bp->b_un.b_buf[sblock->fs_fsize];
- cp += DIRBLKSIZ)
+ cp += dirblksiz)
memmove(cp, &emptydir, sizeof emptydir);
dirty(bp);
dp->di_nlink = iswap16(2);
Index: sbin/fsck_ffs/fsck.h
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/fsck.h,v
retrieving revision 1.28
diff -u -r1.28 fsck.h
--- sbin/fsck_ffs/fsck.h 2002/05/06 03:17:43 1.28
+++ sbin/fsck_ffs/fsck.h 2002/06/20 22:40:04
@@ -70,6 +70,7 @@
ufs_daddr_t *b_indir; /* indirect block */
struct fs *b_fs; /* super block */
struct cg *b_cg; /* cylinder group */
+ struct appleufslabel *b_appleufs; /* Apple UFS volume label */
} b_un;
char b_dirty;
};
@@ -81,6 +82,7 @@
struct bufarea sblk; /* file system superblock */
struct bufarea asblk; /* file system superblock */
struct bufarea cgblk; /* cylinder group blocks */
+struct bufarea appleufsblk; /* Apple UFS volume label */
struct bufarea *pdirbp; /* current directory contents */
struct bufarea *pbp; /* current inode block */
@@ -102,6 +104,14 @@
} while (0)
#define cgdirty() do {copyback_cg(&cgblk); cgblk.b_dirty = 1;} while (0)
+#define appleufsdirty() \
+ do { \
+ appleufsblk.b_un.b_appleufs->ul_checksum = 0; \
+ appleufsblk.b_un.b_appleufs->ul_checksum = \
+ ffs_appleufs_cksum(appleufsblk.b_un.b_appleufs); \
+ appleufsblk.b_dirty = 1; \
+ } while (0)
+
enum fixstate {DONTKNOW, NOFIX, FIX, IGNORE};
struct inodesc {
@@ -201,6 +211,7 @@
int fswritefd; /* file descriptor for writing file system */
int rerun; /* rerun fsck. Only used in non-preen mode */
char resolved; /* cleared if unresolved changes => not clean */
+int isappleufs; /* filesystem is Apple UFS */
ufs_daddr_t maxfsblock; /* number of blocks in the file system */
char *blockmap; /* ptr to primary blk allocation map */
@@ -210,6 +221,8 @@
u_char *typemap; /* ptr to inode type table */
int16_t *lncntp; /* ptr to link count table */
+int dirblksiz;
+
extern ino_t lfdir; /* lost & found directory inode number */
extern char *lfname; /* lost & found directory name */
extern int lfmode; /* lost & found directory creation mode */
@@ -262,3 +275,5 @@
return bswap64(x);
else return x;
}
+
+
Index: sbin/fsck_ffs/fsck_ffs.8
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/fsck_ffs.8,v
retrieving revision 1.29
diff -u -r1.29 fsck_ffs.8
--- sbin/fsck_ffs/fsck_ffs.8 2002/05/06 03:17:43 1.29
+++ sbin/fsck_ffs/fsck_ffs.8 2002/06/20 22:40:04
@@ -145,6 +145,9 @@
The following flags are interpreted by
.Nm "" .
.Bl -tag -width indent
+.It Fl a
+Interpret the filesystem as an Apple UFS filesystem, even if
+there is no Apple UFS volume label present.
.It Fl B
Convert the file system metadata to the specified byte order if needed.
Valid byte order are `be' and `le'. If
Index: sbin/fsck_ffs/inode.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/inode.c,v
retrieving revision 1.34
diff -u -r1.34 inode.c
--- sbin/fsck_ffs/inode.c 2001/01/05 02:02:57 1.34
+++ sbin/fsck_ffs/inode.c 2002/06/20 22:40:04
@@ -88,6 +88,7 @@
mode = iswap16(dp->di_mode) & IFMT;
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
(idesc->id_filesize < sblock->fs_maxsymlinklen ||
+ (isappleufs && (idesc->id_filesize < APPLEUFS_MAXSYMLINKLEN)) ||
(sblock->fs_maxsymlinklen == 0 && dp->di_blocks == 0))))
return (KEEPON);
dino = *dp;
@@ -351,6 +352,7 @@
ffs_dinode_swap(dp, dp);
/* ffs_dinode_swap() doesn't swap blocks addrs */
if ((iswap16(dp->di_mode) & IFMT) != IFLNK ||
+ (isappleufs && (iswap64(dp->di_size) > APPLEUFS_MAXSYMLINKLEN)) ||
iswap64(dp->di_size) > sblock->fs_maxsymlinklen) {
for (j=0; j<NDADDR + NIADDR; j++)
dp->di_db[j] = bswap32(dp->di_db[j]);
Index: sbin/fsck_ffs/main.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/main.c,v
retrieving revision 1.41
diff -u -r1.41 main.c
--- sbin/fsck_ffs/main.c 2002/05/06 03:17:43 1.41
+++ sbin/fsck_ffs/main.c 2002/06/20 22:40:04
@@ -97,7 +97,8 @@
markclean = 1;
forceimage = 0;
endian = 0;
- while ((ch = getopt(argc, argv, "B:b:c:dFfm:npy")) != -1) {
+ isappleufs = 0;
+ while ((ch = getopt(argc, argv, "B:b:c:dFfm:npya")) != -1) {
switch (ch) {
case 'B':
if (strcmp(optarg, "be") == 0)
@@ -149,6 +150,10 @@
case 'y':
yflag++;
nflag = 0;
+ break;
+
+ case 'a':
+ isappleufs = 1;
break;
default:
Index: sbin/fsck_ffs/pass1.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/pass1.c,v
retrieving revision 1.24
diff -u -r1.24 pass1.c
--- sbin/fsck_ffs/pass1.c 2002/05/06 03:17:43 1.24
+++ sbin/fsck_ffs/pass1.c 2002/06/20 22:40:04
@@ -199,6 +199,7 @@
* will detect any garbage after symlink string.
*/
if (size < sblock->fs_maxsymlinklen ||
+ (isappleufs && (size < APPLEUFS_MAXSYMLINKLEN)) ||
(sblock->fs_maxsymlinklen == 0 && dp->di_blocks == 0)) {
ndb = howmany(size, sizeof(daddr_t));
if (ndb > NDADDR) {
Index: sbin/fsck_ffs/pass2.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/pass2.c,v
retrieving revision 1.31
diff -u -r1.31 pass2.c
--- sbin/fsck_ffs/pass2.c 2002/05/06 19:37:51 1.31
+++ sbin/fsck_ffs/pass2.c 2002/06/20 22:40:04
@@ -154,26 +154,26 @@
continue;
if (inp->i_isize < MINDIRSIZE) {
direrror(inp->i_number, "DIRECTORY TOO SHORT");
- inp->i_isize = roundup(MINDIRSIZE, DIRBLKSIZ);
+ inp->i_isize = roundup(MINDIRSIZE, dirblksiz);
if (reply("FIX") == 1) {
dp = ginode(inp->i_number);
dp->di_size = iswap64(inp->i_isize);
inodirty();
} else
markclean = 0;
- } else if ((inp->i_isize & (DIRBLKSIZ - 1)) != 0) {
+ } else if ((inp->i_isize & (dirblksiz - 1)) != 0) {
getpathname(pathbuf, inp->i_number, inp->i_number);
if (usedsoftdep)
pfatal("%s %s: LENGTH %lld NOT MULTIPLE OF %d",
"DIRECTORY", pathbuf,
- (long long)inp->i_isize, DIRBLKSIZ);
+ (long long)inp->i_isize, dirblksiz);
else
pwarn("%s %s: LENGTH %lld NOT MULTIPLE OF %d",
"DIRECTORY", pathbuf,
- (long long)inp->i_isize, DIRBLKSIZ);
+ (long long)inp->i_isize, dirblksiz);
if (preen)
printf(" (ADJUSTED)\n");
- inp->i_isize = roundup(inp->i_isize, DIRBLKSIZ);
+ inp->i_isize = roundup(inp->i_isize, dirblksiz);
if (preen || reply("ADJUST") == 1) {
dp = ginode(inp->i_number);
dp->di_size = iswap64(inp->i_isize);
Index: sbin/fsck_ffs/pass5.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/pass5.c,v
retrieving revision 1.29
diff -u -r1.29 pass5.c
--- sbin/fsck_ffs/pass5.c 2002/05/06 03:17:43 1.29
+++ sbin/fsck_ffs/pass5.c 2002/06/20 22:40:05
@@ -155,6 +155,13 @@
if (fs->fs_contigsumsize > 0) {
newcg->cg_clustersumoff = newcg->cg_nextfreeoff -
sizeof(int32_t);
+ if (isappleufs) {
+ /* Apple PR2216969 gives rationale for this change.
+ * I believe they were mistaken, but we need to
+ * duplicate it for compatibility. -- dbj@netbsd.org
+ */
+ newcg->cg_clustersumoff += sizeof(int32_t);
+ }
newcg->cg_clustersumoff =
roundup(newcg->cg_clustersumoff, sizeof(int32_t));
newcg->cg_clusteroff = newcg->cg_clustersumoff +
Index: sbin/fsck_ffs/setup.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/setup.c,v
retrieving revision 1.52
diff -u -r1.52 setup.c
--- sbin/fsck_ffs/setup.c 2001/12/19 10:05:20 1.52
+++ sbin/fsck_ffs/setup.c 2002/06/20 22:40:05
@@ -51,6 +51,7 @@
#include <sys/file.h>
#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/dir.h>
#include <ufs/ufs/ufs_bswap.h>
#include <ufs/ffs/fs.h>
#include <ufs/ffs/ffs_extern.h>
@@ -71,7 +72,9 @@
static void badsb __P((int, char *));
static int calcsb __P((const char *, int, struct fs *));
static struct disklabel *getdisklabel __P((const char *, int));
+static struct partition *getdisklabelpart __P((const char *, struct disklabel *));
static int readsb __P((int));
+static int readappleufs __P((void));
/*
* Read in a superblock finding an alternate if necessary.
@@ -431,6 +434,26 @@
usedsoftdep = 1;
else
usedsoftdep = 0;
+
+ {
+ struct partition *pp = 0;
+ if (!forceimage)
+ pp = getdisklabelpart(dev,lp);
+ if (pp && (pp->p_fstype == FS_APPLEUFS)) {
+ isappleufs = 1;
+ }
+ }
+ if (readappleufs()) {
+ isappleufs = 1;
+ }
+
+ dirblksiz = DIRBLKSIZ;
+ if (isappleufs)
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
+
+ if (debug)
+ printf("isappleufs = %d, dirblksiz = %d\n", isappleufs, dirblksiz);
+
return (1);
badsblabel:
@@ -439,6 +462,107 @@
return (0);
}
+static int
+readappleufs()
+{
+ ufs_daddr_t label = APPLEUFS_LABEL_OFFSET / dev_bsize;
+ struct appleufslabel *appleufs;
+ int i;
+
+ /* @@@ deal with APPLEUFS_LABEL_OFFSET not being block aligned (CD's?) */
+ /* @@@ also, we should use getblk here instead of bread */
+ if (bread(fsreadfd, (char *)appleufsblk.b_un.b_fs, label, (long)APPLEUFS_LABEL_SIZE) != 0)
+ return 0;
+ appleufsblk.b_bno = label;
+ appleufsblk.b_size = APPLEUFS_LABEL_SIZE;
+
+ appleufs = appleufsblk.b_un.b_appleufs;
+
+ if (ntohl(appleufs->ul_magic) != APPLEUFS_LABEL_MAGIC) {
+ if (!isappleufs) {
+ return 0;
+ } else {
+ pfatal("MISSING APPLEUFS VOLUME LABEL\n");
+ if (reply("FIX") == 0) {
+ return 1;
+ }
+ ffs_appleufs_set(appleufs,NULL,-1);
+ appleufsdirty();
+ }
+ }
+
+ if (ntohl(appleufs->ul_version) != APPLEUFS_LABEL_VERSION) {
+ pwarn("INCORRECT APPLE UFS VERSION NUMBER (%d should be %d)",
+ ntohl(appleufs->ul_version),APPLEUFS_LABEL_VERSION);
+ if (preen) {
+ printf(" (CORRECTED)\n");
+ }
+ if (preen || reply("CORRECT")) {
+ appleufs->ul_version = htonl(APPLEUFS_LABEL_VERSION);
+ appleufsdirty();
+ }
+ }
+
+ if (ntohs(appleufs->ul_namelen) > APPLEUFS_MAX_LABEL_NAME) {
+ pwarn("APPLE UFS LABEL NAME TOO LONG");
+ if (preen) {
+ printf(" (TRUNCATED)\n");
+ }
+ if (preen || reply("TRUNCATE")) {
+ appleufs->ul_namelen = htons(APPLEUFS_MAX_LABEL_NAME);
+ appleufsdirty();
+ }
+ }
+
+ if (ntohs(appleufs->ul_namelen) == 0) {
+ pwarn("MISSING APPLE UFS LABEL NAME");
+ if (preen) {
+ printf(" (FIXED)\n");
+ }
+ if (preen || reply("FIX")) {
+ ffs_appleufs_set(appleufs,NULL,-1);
+ appleufsdirty();
+ }
+ }
+
+ /* Scan name for first illegal character */
+ for (i=0;i<ntohs(appleufs->ul_namelen);i++) {
+ if ((appleufs->ul_name[i] == '\0') ||
+ (appleufs->ul_name[i] == ':') ||
+ (appleufs->ul_name[i] == '/')) {
+ pwarn("APPLE UFS LABEL NAME CONTAINS ILLEGAL CHARACTER");
+ if (preen) {
+ printf(" (TRUNCATED)\n");
+ }
+ if (preen || reply("TRUNCATE")) {
+ appleufs->ul_namelen = i+1;
+ appleufsdirty();
+ }
+ break;
+ }
+ }
+
+ /* Check the checksum last, because if anything else was wrong,
+ * then the checksum gets reset anyway.
+ */
+ appleufs->ul_checksum = 0;
+ appleufs->ul_checksum = ffs_appleufs_cksum(appleufs);
+ if (appleufsblk.b_un.b_appleufs->ul_checksum != appleufs->ul_checksum) {
+ pwarn("INVALID APPLE UFS CHECKSUM (%#04x should be %#04x)",
+ appleufsblk.b_un.b_appleufs->ul_checksum, appleufs->ul_checksum);
+ if (preen) {
+ printf(" (CORRECTED)\n");
+ }
+ if (preen || reply("CORRECT")) {
+ appleufsdirty();
+ } else {
+ /* put the incorrect checksum back in place */
+ appleufs->ul_checksum = appleufsblk.b_un.b_appleufs->ul_checksum;
+ }
+ }
+ return 1;
+}
+
/*
* Read in the super block and its summary info.
*/
@@ -652,20 +776,15 @@
{
struct disklabel *lp;
struct partition *pp;
- char *cp;
int i;
- cp = strchr(dev, '\0') - 1;
- if ((cp == (char *)-1 || (*cp < 'a' || *cp > 'p')) && !isdigit(*cp)) {
+ lp = getdisklabel(dev, devfd);
+ pp = getdisklabelpart(dev,lp);
+ if (pp == 0) {
pfatal("%s: CANNOT FIGURE OUT FILE SYSTEM PARTITION\n", dev);
return (0);
}
- lp = getdisklabel(dev, devfd);
- if (isdigit(*cp))
- pp = &lp->d_partitions[0];
- else
- pp = &lp->d_partitions[*cp - 'a'];
- if (pp->p_fstype != FS_BSDFFS) {
+ if ((pp->p_fstype != FS_BSDFFS) && (pp->p_fstype != FS_APPLEUFS)) {
pfatal("%s: NOT LABELED AS A BSD FILE SYSTEM (%s)\n",
dev, pp->p_fstype < FSMAXTYPES ?
fstypenames[pp->p_fstype] : "unknown");
@@ -716,3 +835,21 @@
}
return (&lab);
}
+
+static struct partition *
+getdisklabelpart(dev, lp)
+ const char *dev;
+ struct disklabel *lp;
+{
+ char *cp;
+
+ cp = strchr(dev, '\0') - 1;
+ if ((cp == (char *)-1 || (*cp < 'a' || *cp > 'p')) && !isdigit(*cp)) {
+ return 0;
+ }
+ if (isdigit(*cp))
+ return &lp->d_partitions[0];
+ else
+ return &lp->d_partitions[*cp - 'a'];
+}
+
Index: sbin/fsck_ffs/utilities.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsck_ffs/utilities.c,v
retrieving revision 1.33
diff -u -r1.33 utilities.c
--- sbin/fsck_ffs/utilities.c 2002/05/06 03:17:43 1.33
+++ sbin/fsck_ffs/utilities.c 2002/06/20 22:40:05
@@ -144,6 +144,11 @@
errx(EEXIT, "cannot allocate buffer pool");
cgblk.b_un.b_buf = bufp;
initbarea(&cgblk);
+ bufp = malloc((unsigned int)APPLEUFS_LABEL_SIZE);
+ if (bufp == 0)
+ errx(EEXIT, "cannot allocate buffer pool");
+ appleufsblk.b_un.b_buf = bufp;
+ initbarea(&appleufsblk);
bufhead.b_next = bufhead.b_prev = &bufhead;
bufcnt = MAXBUFSPACE / sblock->fs_bsize;
if (bufcnt < MINBUFS)
@@ -279,6 +284,8 @@
sbdirty();
flush(fswritefd, &sblk);
}
+ flush(fswritefd, &appleufsblk);
+ free(appleufsblk.b_un.b_buf);
flush(fswritefd, &cgblk);
free(cgblk.b_un.b_buf);
for (bp = bufhead.b_prev; bp && bp != &bufhead; bp = nbp) {
Index: sbin/fsdb/Makefile
===================================================================
RCS file: /cvsroot/basesrc/sbin/fsdb/Makefile,v
retrieving revision 1.12
diff -u -r1.12 Makefile
--- sbin/fsdb/Makefile 1999/01/15 13:32:06 1.12
+++ sbin/fsdb/Makefile 2002/06/20 22:40:05
@@ -6,7 +6,7 @@
SRCS= fsdb.c fsdbutil.c
SRCS+= dir.c inode.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
pass5.c setup.c utilities.c
-SRCS+= ffs_bswap.c ffs_subr.c ffs_tables.c
+SRCS+= ffs_bswap.c ffs_subr.c ffs_tables.c ffs_appleufs.c
SRCS+= fsutil.c
FSCK= ${.CURDIR}/../fsck
Index: sbin/mbrlabel/mbrlabel.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/mbrlabel/mbrlabel.c,v
retrieving revision 1.20
diff -u -r1.20 mbrlabel.c
--- sbin/mbrlabel/mbrlabel.c 2002/05/21 01:39:56 1.20
+++ sbin/mbrlabel/mbrlabel.c 2002/06/20 22:40:05
@@ -106,6 +106,7 @@
{ MBR_PTYPE_LNXSWAP, FS_SWAP },
{ MBR_PTYPE_NETBSD, FS_BSDFFS },
{ MBR_PTYPE_NTFS, FS_NTFS },
+ { MBR_PTYPE_APPLEUFS, FS_APPLEUFS },
{ 0, 0 }
};
@@ -223,6 +224,7 @@
fstypenames[npe.p_fstype], unused + 'a');
switch (npe.p_fstype) {
case FS_BSDFFS:
+ case FS_APPLEUFS:
npe.p_size = 16384; /* XXX */
npe.p_fsize = 1024;
npe.p_frag = 8;
Index: sbin/newfs/Makefile
===================================================================
RCS file: /cvsroot/basesrc/sbin/newfs/Makefile,v
retrieving revision 1.22
diff -u -r1.22 Makefile
--- sbin/newfs/Makefile 2002/01/08 20:54:49 1.22
+++ sbin/newfs/Makefile 2002/06/20 22:40:05
@@ -2,7 +2,7 @@
# @(#)Makefile 8.2 (Berkeley) 3/27/94
PROG= newfs
-SRCS= dkcksum.c getmntopts.c newfs.c mkfs.c ffs_bswap.c
+SRCS= dkcksum.c getmntopts.c newfs.c mkfs.c ffs_bswap.c ffs_appleufs.c
MAN= newfs.8 mount_mfs.8
WARNS= 2
Index: sbin/newfs/extern.h
===================================================================
RCS file: /cvsroot/basesrc/sbin/newfs/extern.h,v
retrieving revision 1.7
diff -u -r1.7 extern.h
--- sbin/newfs/extern.h 2002/01/07 12:00:09 1.7
+++ sbin/newfs/extern.h 2002/06/20 22:40:05
@@ -63,3 +63,5 @@
extern u_long memleft; /* virtual memory available */
extern caddr_t membase; /* start address of memory based filesystem */
extern int needswap; /* Filesystem not in native byte order */
+extern int isappleufs; /* Filesystem is Apple UFS */
+extern char *appleufs_volname; /* Apple UFS volume name */
Index: sbin/newfs/mkfs.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/newfs/mkfs.c,v
retrieving revision 1.64
diff -u -r1.64 mkfs.c
--- sbin/newfs/mkfs.c 2002/04/10 17:28:13 1.64
+++ sbin/newfs/mkfs.c 2002/06/20 22:40:05
@@ -164,6 +164,12 @@
printf("preposterous size %d\n", fssize), exit(13);
wtfs(fssize - 1, sectorsize, (char *)&sblock);
+ if (isappleufs) {
+ struct appleufslabel appleufs;
+ ffs_appleufs_set(&appleufs,appleufs_volname,utime);
+ wtfs(APPLEUFS_LABEL_OFFSET/sectorsize,APPLEUFS_LABEL_SIZE,&appleufs);
+ }
+
/*
* collect and verify the sector and track info
*/
@@ -658,7 +664,10 @@
* Update information about this partion in pack
* label, to that it may be updated on disk.
*/
- pp->p_fstype = FS_BSDFFS;
+ if (isappleufs)
+ pp->p_fstype = FS_APPLEUFS;
+ else
+ pp->p_fstype = FS_BSDFFS;
pp->p_fsize = sblock.fs_fsize;
pp->p_frag = sblock.fs_frag;
pp->p_cpg = sblock.fs_cpg;
@@ -712,6 +721,13 @@
} else {
acg.cg_clustersumoff = acg.cg_freeoff +
howmany(sblock.fs_fpg, NBBY) - sizeof(int32_t);
+ if (isappleufs) {
+ /* Apple PR2216969 gives rationale for this change.
+ * I believe they were mistaken, but we need to
+ * duplicate it for compatibility. -- dbj@netbsd.org
+ */
+ acg.cg_clustersumoff += sizeof(int32_t);
+ }
acg.cg_clustersumoff =
roundup(acg.cg_clustersumoff, sizeof(int32_t));
acg.cg_clusteroff = acg.cg_clustersumoff +
@@ -868,6 +884,9 @@
{
#ifdef LOSTDIR
int i;
+ int dirblksiz = DIRBLKSIZ;
+ if (isappleufs)
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
#endif
/*
@@ -884,12 +903,12 @@
*/
if (Oflag) {
(void)makedir((struct direct *)olost_found_dir, 2);
- for (i = DIRBLKSIZ; i < sblock.fs_bsize; i += DIRBLKSIZ)
+ for (i = dirblksiz; i < sblock.fs_bsize; i += dirblksiz)
copy_dir((struct direct*)&olost_found_dir[2],
(struct direct*)&buf[i]);
} else {
(void)makedir(lost_found_dir, 2);
- for (i = DIRBLKSIZ; i < sblock.fs_bsize; i += DIRBLKSIZ)
+ for (i = dirblksiz; i < sblock.fs_bsize; i += dirblksiz)
copy_dir(&lost_found_dir[2], (struct direct*)&buf[i]);
}
node.di_mode = IFDIR | UMASK;
@@ -937,8 +956,11 @@
{
char *cp;
int i, spcleft;
+ int dirblksiz = DIRBLKSIZ;
+ if (isappleufs)
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
- spcleft = DIRBLKSIZ;
+ spcleft = dirblksiz;
for (cp = buf, i = 0; i < entries - 1; i++) {
protodir[i].d_reclen = DIRSIZ(Oflag, &protodir[i], 0);
copy_dir(&protodir[i], (struct direct*)cp);
@@ -947,7 +969,7 @@
}
protodir[i].d_reclen = spcleft;
copy_dir(&protodir[i], (struct direct*)cp);
- return (DIRBLKSIZ);
+ return (dirblksiz);
}
/*
Index: sbin/newfs/newfs.8
===================================================================
RCS file: /cvsroot/basesrc/sbin/newfs/newfs.8,v
retrieving revision 1.42
diff -u -r1.42 newfs.8
--- sbin/newfs/newfs.8 2002/04/06 05:57:17 1.42
+++ sbin/newfs/newfs.8 2002/06/20 22:40:05
@@ -64,6 +64,7 @@
.Op Fl s Ar size
.Op Fl t Ar ntracks
.Op Fl u Ar nsectors
+.Op Fl v Ar volname
.Op Fl x Ar sectors
.Ar special
.Sh DESCRIPTION
@@ -108,7 +109,9 @@
No attempts to use or update the disk label will be made.
.It Fl I
Do not require that the file system type listed in the disk label is
-.Ql 4.2BSD .
+.Ql 4.2BSD
+or
+.Ql Apple UFS .
.It Fl N
Causes the file system parameters to be printed out
without really creating the file system.
@@ -254,6 +257,9 @@
sector size (as specified by
.Fl S Ar secsize )
after suffix interpretation.
+.It Fl v Ar volname
+This specifies that a Apple UFS filesystem should be created
+with the given volume name.
.El
.Pp
The following options override the standard sizes for the disk geometry.
@@ -330,7 +336,9 @@
command to succeed,
the disk label should first be updated such that the fstype field for the
partition is set to
-.Ql 4.2BSD ,
+.Ql 4.2BSD
+or
+.Ql Apple UFS ,
unless
.Fl F
or
Index: sbin/newfs/newfs.c
===================================================================
RCS file: /cvsroot/basesrc/sbin/newfs/newfs.c,v
retrieving revision 1.58
diff -u -r1.58 newfs.c
--- sbin/newfs/newfs.c 2002/02/20 04:04:39 1.58
+++ sbin/newfs/newfs.c 2002/06/20 22:40:06
@@ -205,6 +205,8 @@
char *disktype;
int unlabeled;
#endif
+char *appleufs_volname = 0; /* Apple UFS volume name */
+int isappleufs = 0;
char device[MAXPATHLEN];
@@ -248,7 +250,7 @@
opstring = mfs ?
"NT:a:b:c:d:e:f:g:h:i:m:o:p:s:u:" :
- "B:FINOS:T:Za:b:c:d:e:f:g:h:i:k:l:m:n:o:p:r:s:t:u:x:";
+ "B:FINOS:T:Za:b:c:d:e:f:g:h:i:k:l:m:n:o:p:r:s:t:u:v:x:";
while ((ch = getopt(argc, argv, opstring)) != -1)
switch (ch) {
case 'B':
@@ -422,6 +424,14 @@
optarg, 1, INT_MAX);
}
break;
+ case 'v':
+ appleufs_volname = optarg;
+ if (strchr(appleufs_volname, ':') || strchr(appleufs_volname, '/'))
+ errx(1,"Apple UFS volume name cannot contain ':' or '/'");
+ if (appleufs_volname[0] == '\0')
+ errx(1,"Apple UFS volume name cannot be zero length");
+ isappleufs = 1;
+ break;
case 'x':
cylspares = strsuftoi("spare sectors per cylinder",
optarg, 0, INT_MAX);
@@ -558,8 +568,15 @@
pp = &lp->d_partitions[*cp - 'a'];
if (pp->p_size == 0)
errx(1, "`%c' partition is unavailable", *cp);
- if (!Iflag && pp->p_fstype != FS_BSDFFS)
- errx(1, "`%c' partition type is not `4.2BSD'", *cp);
+ if (pp->p_fstype == FS_APPLEUFS)
+ isappleufs = 1;
+ if (isappleufs) {
+ if (!Iflag && (pp->p_fstype != FS_APPLEUFS))
+ errx(1, "`%c' partition type is not `Apple UFS'", *cp);
+ } else {
+ if (!Iflag && (pp->p_fstype != FS_BSDFFS))
+ errx(1, "`%c' partition type is not `4.2BSD'", *cp);
+ }
} /* !Fflag && !mfs */
if (fssize == 0)
@@ -918,6 +935,7 @@
{ NEWFS, "-t ntracks\ttracks/cylinder" },
{ NEWFS, "-u nsectors\tsectors/track" },
{ MFS_MOUNT, "-u username\tuser name of mount point" },
+ { NEWFS, "-v volname\tApple UFS volume name" },
{ NEWFS, "-x cylspares\tspare sectors per cylinder" },
{ 0, NULL }
};
Index: sys/arch/i386/i386/disksubr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/i386/i386/disksubr.c,v
retrieving revision 1.45
diff -u -r1.45 disksubr.c
--- sys/arch/i386/i386/disksubr.c 2002/02/19 17:09:44 1.45
+++ sys/arch/i386/i386/disksubr.c 2002/06/20 22:40:33
@@ -208,6 +208,11 @@
if (dp->mbrp_typ == MBR_PTYPE_NTFS)
pp->p_fstype = FS_NTFS;
+#ifdef APPLE_UFS
+ if (dp->mbrp_typ == MBR_PTYPE_APPLEUFS)
+ pp->p_fstype = FS_APPLEUFS;
+#endif
+
/* is this ours? */
if (dp == ourdp) {
/* need sector address for SCSI/IDE,
Index: sys/arch/macppc/include/disklabel.h
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/macppc/include/disklabel.h,v
retrieving revision 1.8
diff -u -r1.8 disklabel.h
--- sys/arch/macppc/include/disklabel.h 2002/03/23 01:29:35 1.8
+++ sys/arch/macppc/include/disklabel.h 2002/06/20 22:40:37
@@ -178,6 +178,7 @@
#define PART_TYPE_FWB_COMPONENT "FWB DRIVER COMPONENTS"
#define PART_TYPE_FREE "APPLE_FREE"
#define PART_TYPE_MAC "APPLE_HFS"
+#define PART_TYPE_APPLEUFS "APPLE_UFS"
#define PART_TYPE_NETBSD "NETBSD"
#define PART_TYPE_NBSD_PPCBOOT "NETBSD/MACPPC"
#define PART_TYPE_NBSD_68KBOOT "NETBSD/MAC68K"
Index: sys/arch/macppc/macppc/disksubr.c
===================================================================
RCS file: /cvsroot/syssrc/sys/arch/macppc/macppc/disksubr.c,v
retrieving revision 1.20
diff -u -r1.20 disksubr.c
--- sys/arch/macppc/macppc/disksubr.c 2002/03/27 20:23:11 1.20
+++ sys/arch/macppc/macppc/disksubr.c 2002/06/20 22:40:37
@@ -126,6 +126,7 @@
#define SWAP_PART 3
#define HFS_PART 4
#define SCRATCH_PART 5
+#define APPLEUFS_PART 6
int fat_types[] = { MBR_PTYPE_FAT12, MBR_PTYPE_FAT16S,
MBR_PTYPE_FAT16B, MBR_PTYPE_FAT32,
@@ -226,6 +227,9 @@
type = SCRATCH_PART;
} else if (strcmp(PART_TYPE_MAC, typestr) == 0)
type = HFS_PART;
+ else if (strcmp(PART_TYPE_APPLEUFS, typestr) == 0) {
+ type = APPLEUFS_PART;
+ }
else
type = SCRATCH_PART; /* no known type */
@@ -378,6 +382,9 @@
break;
case SCRATCH_PART:
setpartition(part + i, pp, FS_OTHER);
+ break;
+ case APPLEUFS_PART:
+ setpartition(part + i, pp, FS_APPLEUFS);
break;
default:
slot = 0;
Index: sys/sys/disklabel.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/disklabel.h,v
retrieving revision 1.70
diff -u -r1.70 disklabel.h
--- sys/sys/disklabel.h 2002/03/27 19:07:32 1.70
+++ sys/sys/disklabel.h 2002/06/20 22:41:08
@@ -323,8 +323,9 @@
#define FS_NTFS 18 /* Windows/NT file system */
#define FS_RAID 19 /* RAIDframe component */
#define FS_CCD 20 /* concatenated disk component */
+#define FS_APPLEUFS 21 /* Apple UFS */
-/* Adjust the FSMAXTYPES def below if you add something after CCD */
+/* Adjust the FSMAXTYPES def below if you add something after APPLEUFS */
#ifdef FSTYPENAMES
static const char *const fstypenames[] = {
@@ -349,11 +350,12 @@
"NTFS",
"RAID",
"ccd",
+ "Apple UFS",
NULL
};
#define FSMAXTYPES (sizeof(fstypenames) / sizeof(fstypenames[0]) - 1)
#else
-#define FSMAXTYPES (FS_CCD + 1)
+#define FSMAXTYPES (FS_APPLEUFS + 1)
#endif
#ifdef FSCKNAMES
@@ -380,6 +382,7 @@
NULL, /* Windows/NT */
NULL, /* RAID Component */
NULL, /* concatenated disk component */
+ "ffs", /* Apple UFS */
NULL /* NULL */
};
#define FSMAXNAMES (sizeof(fscknames) / sizeof(fscknames[0]) - 1)
@@ -410,6 +413,7 @@
"ntfs", /* Windows/NT */
NULL, /* RAID Component */
NULL, /* concatenated disk component */
+ "ffs", /* Apple UFS */
NULL /* NULL */
};
#define FSMAXMOUNTNAMES (sizeof(mountnames) / sizeof(mountnames[0]) - 1)
Index: sys/sys/disklabel_mbr.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/disklabel_mbr.h,v
retrieving revision 1.7
diff -u -r1.7 disklabel_mbr.h
--- sys/sys/disklabel_mbr.h 2002/03/02 07:04:31 1.7
+++ sys/sys/disklabel_mbr.h 2002/06/20 22:41:08
@@ -82,6 +82,7 @@
#define MBR_PTYPE_EXT_LNX 0x85 /* Linux extended partition */
#define MBR_PTYPE_NTFSVOL 0x87 /* NTFS volume set or HPFS mirrored */
#define MBR_PTYPE_PREP 0x41 /* PReP */
+#define MBR_PTYPE_APPLEUFS 0xa8 /* Apple UFS */
/* Isolate the relevant bits to get sector and cylinder. */
#define MBR_PSECT(s) ((s) & 0x3f)
Index: sys/ufs/files.ufs
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/files.ufs,v
retrieving revision 1.1
diff -u -r1.1 files.ufs
--- sys/ufs/files.ufs 2002/04/16 23:14:10 1.1
+++ sys/ufs/files.ufs 2002/06/20 22:41:08
@@ -5,7 +5,7 @@
deffs fs_mfs.h MFS # XXX
deffs fs_lfs.h LFS # XXX
-defflag opt_ffs.h FFS_EI
+defflag opt_ffs.h FFS_EI APPLE_UFS
file ufs/ext2fs/ext2fs_alloc.c ext2fs
file ufs/ext2fs/ext2fs_balloc.c ext2fs
@@ -29,6 +29,7 @@
file ufs/ffs/ffs_tables.c ffs | mfs
file ufs/ffs/ffs_vfsops.c ffs | mfs
file ufs/ffs/ffs_vnops.c ffs | mfs
+file ufs/ffs/ffs_appleufs.c ffs & apple_ufs
file ufs/lfs/lfs_alloc.c lfs
file ufs/lfs/lfs_balloc.c lfs
Index: sys/ufs/ffs/ffs_appleufs.c
===================================================================
RCS file: ffs_appleufs.c
diff -N ffs_appleufs.c
--- /dev/null Fri Jun 21 01:55:31 2002
+++ ffs_appleufs.c Fri Jun 21 01:41:08 2002
@@ -0,0 +1,155 @@
+/* $NetBSD: $ */
+/*
+ * Copyright (c) 2002 Darrin B. Jewell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Darrin B. Jewell
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: $");
+
+#include <sys/param.h>
+#include <sys/time.h>
+#if defined(_KERNEL)
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#endif
+
+#include <ufs/ufs/dinode.h>
+#include <ufs/ufs/ufs_bswap.h>
+#include <ufs/ffs/fs.h>
+#include <ufs/ffs/ffs_extern.h>
+
+#if !defined(_KERNEL) && !defined(STANDALONE)
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#define KASSERT(x) assert(x)
+#endif
+
+/*
+ * this is the same calculation as in_cksum
+ */
+u_int16_t
+ffs_appleufs_cksum(appleufs)
+ const struct appleufslabel *appleufs;
+{
+ const u_int16_t *p = (const u_int16_t *)appleufs;
+ int len = sizeof(struct appleufslabel);
+ long res = 0;
+ while (len > 1) {
+ res += *p++;
+ len -= 2;
+ }
+#if 0 /* sizeof(struct appleufslabel) is guaranteed to be even */
+ if (len == 1)
+ res += htons(*(u_char *)p<<8);
+#endif
+ res = (res >> 16) + (res & 0xffff);
+ res += (res >> 16);
+ return (~res);
+}
+
+/* copies o to n, validating and byteswapping along the way
+ * returns 0 if ok, EINVAL if not valid
+ */
+int
+ffs_appleufs_validate(name,o,n)
+ const char *name;
+ const struct appleufslabel *o;
+ struct appleufslabel *n;
+{
+ struct appleufslabel tmp;
+ if (!n) n = &tmp;
+
+ if (o->ul_magic != ntohl(APPLEUFS_LABEL_MAGIC)) {
+ return EINVAL;
+ }
+ *n = *o;
+ n->ul_checksum = 0;
+ n->ul_checksum = ffs_appleufs_cksum(n);
+ if (n->ul_checksum != o->ul_checksum) {
+#if defined(DIAGNOSTIC) || !defined(_KERNEL)
+ printf("%s: invalid APPLE UFS checksum. found 0x%x, expecting 0x%x",
+ name,o->ul_checksum,n->ul_checksum);
+#endif
+ return EINVAL;
+ }
+ n->ul_magic = ntohl(o->ul_magic);
+ n->ul_version = ntohl(o->ul_version);
+ n->ul_time = ntohl(o->ul_time);
+ n->ul_namelen = ntohs(o->ul_namelen);
+
+ if (n->ul_namelen > APPLEUFS_MAX_LABEL_NAME) {
+#if defined(DIAGNOSTIC) || !defined(_KERNEL)
+ printf("%s: APPLE UFS label name too long, truncated.\n",
+ name);
+#endif
+ n->ul_namelen = APPLEUFS_MAX_LABEL_NAME;
+ }
+ /* if len is max, will set ul_reserved[0] */
+ n->ul_name[n->ul_namelen] = '\0';
+#ifdef DEBUG
+ printf("%s: found APPLE UFS label v%d: \"%s\"\n",
+ name,n->ul_version,n->ul_name);
+#endif
+
+ return 0;
+}
+
+void
+ffs_appleufs_set(appleufs,name,t)
+ struct appleufslabel *appleufs;
+ const char *name;
+ time_t t;
+{
+ size_t namelen;
+ if (!name) name = "untitled";
+ if (t == ((time_t)-1)) {
+#if defined(_KERNEL)
+ t = time.tv_sec;
+#elif defined(STANDALONE)
+ t = 0;
+#else
+ (void)time(&t);
+#endif
+ }
+ namelen = strlen(name);
+ if (namelen > APPLEUFS_MAX_LABEL_NAME)
+ namelen = APPLEUFS_MAX_LABEL_NAME;
+ memset(appleufs, 0, sizeof(*appleufs));
+ appleufs->ul_magic = htonl(APPLEUFS_LABEL_MAGIC);
+ appleufs->ul_version = htonl(APPLEUFS_LABEL_VERSION);
+ appleufs->ul_time = htonl((u_int32_t)t);
+ appleufs->ul_namelen = htons(namelen);
+ strncpy(appleufs->ul_name,name,namelen);
+ appleufs->ul_checksum = ffs_appleufs_cksum(appleufs);
+}
Index: sys/ufs/ffs/ffs_extern.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ffs/ffs_extern.h,v
retrieving revision 1.22
diff -u -r1.22 ffs_extern.h
--- sys/ufs/ffs/ffs_extern.h 2002/05/05 17:00:06 1.22
+++ sys/ufs/ffs/ffs_extern.h 2002/06/20 22:41:08
@@ -134,6 +134,12 @@
int ffs_sbupdate __P((struct ufsmount *, int));
int ffs_cgupdate __P((struct ufsmount *, int));
+/* ffs_appleufs.c */
+u_int16_t ffs_appleufs_cksum __P((const struct appleufslabel *));
+int ffs_appleufs_validate __P((const char*,const struct appleufslabel *,struct appleufslabel *));
+void ffs_appleufs_set __P((struct appleufslabel *, const char *, time_t));
+
+
/* ffs_vnops.c */
int ffs_read __P((void *));
int ffs_write __P((void *));
Index: sys/ufs/ffs/ffs_vfsops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ffs/ffs_vfsops.c,v
retrieving revision 1.98.4.1
diff -u -r1.98.4.1 ffs_vfsops.c
--- sys/ufs/ffs/ffs_vfsops.c 2002/06/10 16:46:17 1.98.4.1
+++ sys/ufs/ffs/ffs_vfsops.c 2002/06/20 22:41:09
@@ -498,7 +498,42 @@
bp->b_flags |= B_INVAL;
brelse(bp);
free(newfs, M_UFSMNT);
+
+#ifdef APPLE_UFS
+ /* Recheck for apple UFS filesystem */
+ VFSTOUFS(mountp)->um_flags &= ~UFS_ISAPPLEUFS;
+ /* First check to see if this is tagged as an Apple UFS filesystem
+ * in the disklabel
+ */
+ if ((VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) == 0) &&
+ (dpart.part->p_fstype == FS_APPLEUFS)) {
+ VFSTOUFS(mountp)->um_flags |= UFS_ISAPPLEUFS;
+
+ } else {
+ /* Manually look for an apple ufs label, and if a valid one
+ * is found, then treat it like an Apple UFS filesystem anyway
+ */
+ error = bread(devvp, (ufs_daddr_t)(APPLEUFS_LABEL_OFFSET / size),
+ APPLEUFS_LABEL_SIZE, cred, &bp);
+ if (error) {
+ brelse(bp);
+ return (error);
+ }
+ error = ffs_appleufs_validate(fs->fs_fsmnt,
+ (struct appleufslabel *)bp->b_data,NULL);
+ if (error == 0) {
+ VFSTOUFS(mountp)->um_flags |= UFS_ISAPPLEUFS;
+ }
+ brelse(bp);
+ bp = NULL;
+ }
+#endif
+
mountp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
+ if (UFS_MPISAPPLEUFS(mountp)) {
+ /* see comment about NeXT below */
+ mountp->mnt_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN;
+ }
ffs_oldfscompat(fs);
/* An old fsck may have zeroed these fields, so recheck them. */
if (fs->fs_avgfilesize <= 0)
@@ -511,6 +546,7 @@
}
ffs_statfs(mountp, &mountp->mnt_stat, p);
+
/*
* Step 3: re-read summary information from disk.
*/
@@ -714,6 +750,32 @@
brelse(bp);
bp = NULL;
+#ifdef APPLE_UFS
+ /* First check to see if this is tagged as an Apple UFS filesystem
+ * in the disklabel
+ */
+ if ((VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) == 0) &&
+ (dpart.part->p_fstype == FS_APPLEUFS)) {
+ ump->um_flags |= UFS_ISAPPLEUFS;
+
+ } else {
+ /* Manually look for an apple ufs label, and if a valid one
+ * is found, then treat it like an Apple UFS filesystem anyway
+ */
+ error = bread(devvp, (ufs_daddr_t)(APPLEUFS_LABEL_OFFSET / size),
+ APPLEUFS_LABEL_SIZE, cred, &bp);
+ if (error)
+ goto out;
+ error = ffs_appleufs_validate(fs->fs_fsmnt,
+ (struct appleufslabel *)bp->b_data,NULL);
+ if (error == 0) {
+ ump->um_flags |= UFS_ISAPPLEUFS;
+ }
+ brelse(bp);
+ bp = NULL;
+ }
+#endif
+
/*
* verify that we can access the last block in the fs
* if we're mounting read/write.
@@ -784,6 +846,14 @@
mp->mnt_stat.f_fsid.val[0] = (long)dev;
mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_FFS);
mp->mnt_maxsymlinklen = fs->fs_maxsymlinklen;
+ if (UFS_MPISAPPLEUFS(mp)) {
+ /* NeXT used to keep short symlinks in the inode even
+ * when using FS_42INODEFMT. In that case fs->fs_maxsymlinklen
+ * is probably -1, but we still need to be able to identify
+ * short symlinks.
+ */
+ mp->mnt_maxsymlinklen = APPLEUFS_MAXSYMLINKLEN;
+ }
mp->mnt_fs_bshift = fs->fs_bshift;
mp->mnt_dev_bshift = DEV_BSHIFT; /* XXX */
mp->mnt_flag |= MNT_LOCAL;
Index: sys/ufs/ffs/fs.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ffs/fs.h,v
retrieving revision 1.25
diff -u -r1.25 fs.h
--- sys/ufs/ffs/fs.h 2002/04/10 14:31:07 1.25
+++ sys/ufs/ffs/fs.h 2002/06/20 22:41:09
@@ -549,4 +549,26 @@
*/
#define NINDIR(fs) ((fs)->fs_nindir)
+/*
+ * Apple UFS Label:
+ * We check for this to decide to use APPLEUFS_DIRBLKSIZ
+ */
+#define APPLEUFS_LABEL_MAGIC 0x4c41424c /* LABL */
+#define APPLEUFS_LABEL_SIZE 1024
+#define APPLEUFS_LABEL_OFFSET (BBSIZE - APPLEUFS_LABEL_SIZE) /* located at 7k */
+#define APPLEUFS_LABEL_VERSION 1
+#define APPLEUFS_MAX_LABEL_NAME 512
+
+struct appleufslabel {
+ u_int32_t ul_magic;
+ u_int16_t ul_checksum;
+ u_int32_t ul_version;
+ u_int32_t ul_time;
+ u_int16_t ul_namelen;
+ u_char ul_name[APPLEUFS_MAX_LABEL_NAME];
+ u_char ul_reserved[32];
+ u_char ul_unused[460];
+};
+
+
#endif /* !_UFS_FFS_FS_H_ */
Index: sys/ufs/ufs/dinode.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/dinode.h,v
retrieving revision 1.13
diff -u -r1.13 dinode.h
--- sys/ufs/ufs/dinode.h 2001/07/27 01:24:54 1.13
+++ sys/ufs/ufs/dinode.h 2002/06/20 22:41:09
@@ -110,6 +110,12 @@
#define di_shortlink di_db
#define MAXSYMLINKLEN ((NDADDR + NIADDR) * sizeof(ufs_daddr_t))
+/* NeXT used to keep short symlinks in the inode even when using
+ * FS_42INODEFMT. In that case fs->fs_maxsymlinklen is probably -1,
+ * but short symlinks were stored in inodes shorter than this:
+ */
+#define APPLEUFS_MAXSYMLINKLEN 60
+
/* File permissions. */
#define IEXEC 0000100 /* Executable. */
#define IWRITE 0000200 /* Writeable. */
Index: sys/ufs/ufs/dir.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/dir.h,v
retrieving revision 1.13
diff -u -r1.13 dir.h
--- sys/ufs/ufs/dir.h 2002/02/06 15:44:49 1.13
+++ sys/ufs/ufs/dir.h 2002/06/20 22:41:09
@@ -80,6 +80,7 @@
#define DIRBLKSIZ DEV_BSIZE
#undef MAXNAMLEN
#define MAXNAMLEN 255
+#define APPLEUFS_DIRBLKSIZ 1024
struct direct {
u_int32_t d_ino; /* inode number of entry */
Index: sys/ufs/ufs/ufs_lookup.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/ufs_lookup.c,v
retrieving revision 1.39
diff -u -r1.39 ufs_lookup.c
--- sys/ufs/ufs/ufs_lookup.c 2002/05/12 23:06:30 1.39
+++ sys/ufs/ufs/ufs_lookup.c 2002/06/20 22:41:10
@@ -135,6 +135,10 @@
int flags;
int nameiop = cnp->cn_nameiop;
const int needswap = UFS_MPNEEDSWAP(ap->a_dvp->v_mount);
+ int dirblksiz = DIRBLKSIZ;
+ if (UFS_MPISAPPLEUFS(ap->a_dvp->v_mount)) {
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
+ }
cnp->cn_flags &= ~PDIRUNLOCK;
flags = cnp->cn_flags;
@@ -209,7 +213,7 @@
nchstats.ncs_2passes++;
}
prevoff = dp->i_offset;
- endsearch = roundup(dp->i_ffs_size, DIRBLKSIZ);
+ endsearch = roundup(dp->i_ffs_size, dirblksiz);
enduseful = 0;
searchloop:
@@ -231,7 +235,7 @@
* boundary, have to start looking for free space again.
*/
if (slotstatus == NONE &&
- (entryoffsetinblock & (DIRBLKSIZ - 1)) == 0) {
+ (entryoffsetinblock & (dirblksiz - 1)) == 0) {
slotoffset = -1;
slotfreespace = 0;
}
@@ -248,7 +252,7 @@
int i;
ufs_dirbad(dp, dp->i_offset, "mangled entry");
- i = DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1));
+ i = dirblksiz - (entryoffsetinblock & (dirblksiz - 1));
dp->i_offset += i;
entryoffsetinblock += i;
continue;
@@ -390,12 +394,12 @@
* dp->i_offset + dp->i_count.
*/
if (slotstatus == NONE) {
- dp->i_offset = roundup(dp->i_ffs_size, DIRBLKSIZ);
+ dp->i_offset = roundup(dp->i_ffs_size, dirblksiz);
dp->i_count = 0;
enduseful = dp->i_offset;
} else if (nameiop == DELETE) {
dp->i_offset = slotoffset;
- if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0)
+ if ((dp->i_offset & (dirblksiz - 1)) == 0)
dp->i_count = 0;
else
dp->i_count = dp->i_offset - prevoff;
@@ -405,7 +409,7 @@
if (enduseful < slotoffset + slotsize)
enduseful = slotoffset + slotsize;
}
- dp->i_endoff = roundup(enduseful, DIRBLKSIZ);
+ dp->i_endoff = roundup(enduseful, dirblksiz);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
/*
* We return with the directory locked, so that
@@ -456,7 +460,7 @@
* in the cache as to where the entry was found.
*/
if ((flags & ISLASTCN) && nameiop == LOOKUP)
- dp->i_diroff = dp->i_offset &~ (DIRBLKSIZ - 1);
+ dp->i_diroff = dp->i_offset &~ (dirblksiz - 1);
/*
* If deleting, and at end of pathname, return
@@ -478,7 +482,7 @@
* is a previous entry in this block) in dp->i_count.
* Save directory inode pointer in ndp->ni_dvp for dirremove().
*/
- if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0)
+ if ((dp->i_offset & (dirblksiz - 1)) == 0)
dp->i_count = 0;
else
dp->i_count = dp->i_offset - prevoff;
@@ -638,6 +642,10 @@
int i;
int namlen;
const int needswap = UFS_MPNEEDSWAP(dp->v_mount);
+ int dirblksiz = DIRBLKSIZ;
+ if (UFS_MPISAPPLEUFS(dp->v_mount)) {
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
+ }
#if (BYTE_ORDER == LITTLE_ENDIAN)
if (dp->v_mount->mnt_maxsymlinklen > 0 || needswap != 0)
@@ -652,16 +660,16 @@
#endif
if ((ufs_rw16(ep->d_reclen, needswap) & 0x3) != 0 ||
ufs_rw16(ep->d_reclen, needswap) >
- DIRBLKSIZ - (entryoffsetinblock & (DIRBLKSIZ - 1)) ||
+ dirblksiz - (entryoffsetinblock & (dirblksiz - 1)) ||
ufs_rw16(ep->d_reclen, needswap) <
DIRSIZ(FSFMT(dp), ep, needswap) ||
namlen > MAXNAMLEN) {
/*return (1); */
printf("First bad, reclen=%x, DIRSIZ=%lu, namlen=%d, flags=%x "
- "entryoffsetinblock=%d\n",
+ "entryoffsetinblock=%d, dirblksiz = %d\n",
ufs_rw16(ep->d_reclen, needswap),
(u_long)DIRSIZ(FSFMT(dp), ep, needswap),
- namlen, dp->v_mount->mnt_flag, entryoffsetinblock);
+ namlen, dp->v_mount->mnt_flag, entryoffsetinblock,dirblksiz);
goto bad;
}
if (ep->d_ino == 0)
@@ -732,6 +740,10 @@
char *dirbuf;
struct timespec ts;
const int needswap = UFS_MPNEEDSWAP(dvp->v_mount);
+ int dirblksiz = DIRBLKSIZ;
+ if (UFS_MPISAPPLEUFS(dvp->v_mount)) {
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
+ }
error = 0;
cr = cnp->cn_cred;
@@ -747,21 +759,21 @@
* be on a directory block boundary and we will write the
* new entry into a fresh block.
*/
- if (dp->i_offset & (DIRBLKSIZ - 1))
+ if (dp->i_offset & (dirblksiz - 1))
panic("ufs_direnter: newblk");
flags = B_CLRBUF;
if (!DOINGSOFTDEP(dvp))
flags |= B_SYNC;
- if ((error = VOP_BALLOC(dvp, (off_t)dp->i_offset, DIRBLKSIZ,
+ if ((error = VOP_BALLOC(dvp, (off_t)dp->i_offset, dirblksiz,
cr, flags, &bp)) != 0) {
if (DOINGSOFTDEP(dvp) && newdirbp != NULL)
bdwrite(newdirbp);
return (error);
}
- dp->i_ffs_size = dp->i_offset + DIRBLKSIZ;
+ dp->i_ffs_size = dp->i_offset + dirblksiz;
dp->i_flag |= IN_CHANGE | IN_UPDATE;
uvm_vnp_setsize(dvp, dp->i_ffs_size);
- dirp->d_reclen = ufs_rw16(DIRBLKSIZ, needswap);
+ dirp->d_reclen = ufs_rw16(dirblksiz, needswap);
dirp->d_ino = ufs_rw32(dirp->d_ino, needswap);
if (dvp->v_mount->mnt_maxsymlinklen <= 0) {
#if (BYTE_ORDER == LITTLE_ENDIAN)
@@ -785,11 +797,11 @@
* block does not have to ensure that the block is
* written before the inode.
*/
- blkoff += DIRBLKSIZ;
+ blkoff += dirblksiz;
while (blkoff < bp->b_bcount) {
((struct direct *)
- (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ;
- blkoff += DIRBLKSIZ;
+ (bp->b_data + blkoff))->d_reclen = dirblksiz;
+ blkoff += dirblksiz;
}
if (softdep_setup_directory_add(bp, dp, dp->i_offset,
ufs_rw32(dirp->d_ino, needswap), newdirbp, 1) == 0) {
Index: sys/ufs/ufs/ufs_vnops.c
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/ufs_vnops.c,v
retrieving revision 1.86
diff -u -r1.86 ufs_vnops.c
--- sys/ufs/ufs/ufs_vnops.c 2002/05/14 17:37:52 1.86
+++ sys/ufs/ufs/ufs_vnops.c 2002/06/20 22:41:10
@@ -1178,6 +1178,10 @@
struct dirtemplate dirtemplate;
struct direct newdir;
int error, dmode, blkoff;
+ int dirblksiz = DIRBLKSIZ;
+ if (UFS_MPISAPPLEUFS(ap->a_dvp->v_mount)) {
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
+ }
dvp = ap->a_dvp;
vap = ap->a_vap;
@@ -1240,6 +1244,7 @@
* Initialize directory with "." and ".." from static template.
*/
dirtemplate = mastertemplate;
+ dirtemplate.dotdot_reclen = dirblksiz - dirtemplate.dot_reclen;
dirtemplate.dot_ino = ufs_rw32(ip->i_number,
UFS_MPNEEDSWAP(dvp->v_mount));
dirtemplate.dotdot_ino = ufs_rw32(dp->i_number,
@@ -1261,10 +1266,10 @@
} else
dirtemplate.dot_type = dirtemplate.dotdot_type = 0;
}
- if ((error = VOP_BALLOC(tvp, (off_t)0, DIRBLKSIZ, cnp->cn_cred,
+ if ((error = VOP_BALLOC(tvp, (off_t)0, dirblksiz, cnp->cn_cred,
B_CLRBUF, &bp)) != 0)
goto bad;
- ip->i_ffs_size = DIRBLKSIZ;
+ ip->i_ffs_size = dirblksiz;
ip->i_flag |= IN_CHANGE | IN_UPDATE;
uvm_vnp_setsize(tvp, ip->i_ffs_size);
memcpy((caddr_t)bp->b_data, (caddr_t)&dirtemplate, sizeof dirtemplate);
@@ -1275,11 +1280,11 @@
* block does not have to ensure that the block is
* written before the inode.
*/
- blkoff = DIRBLKSIZ;
+ blkoff = dirblksiz;
while (blkoff < bp->b_bcount) {
((struct direct *)
- (bp->b_data + blkoff))->d_reclen = DIRBLKSIZ;
- blkoff += DIRBLKSIZ;
+ (bp->b_data + blkoff))->d_reclen = dirblksiz;
+ blkoff += dirblksiz;
}
}
/*
@@ -1491,12 +1496,16 @@
int error;
size_t count, lost;
off_t off;
+ int dirblksiz = DIRBLKSIZ;
+ if (UFS_MPISAPPLEUFS(ap->a_vp->v_mount)) {
+ dirblksiz = APPLEUFS_DIRBLKSIZ;
+ }
uio = ap->a_uio;
off = uio->uio_offset;
count = uio->uio_resid;
/* Make sure we don't return partial entries. */
- count -= (uio->uio_offset + count) & (DIRBLKSIZ -1);
+ count -= (uio->uio_offset + count) & (dirblksiz -1);
if (count <= 0)
return (EINVAL);
lost = uio->uio_resid - count;
Index: sys/ufs/ufs/ufsmount.h
===================================================================
RCS file: /cvsroot/syssrc/sys/ufs/ufs/ufsmount.h,v
retrieving revision 1.8
diff -u -r1.8 ufsmount.h
--- sys/ufs/ufs/ufsmount.h 2000/11/27 08:40:02 1.8
+++ sys/ufs/ufs/ufsmount.h 2002/06/20 22:41:10
@@ -54,6 +54,11 @@
};
#ifdef _KERNEL
+
+#if defined(_KERNEL_OPT)
+#include "opt_ffs.h"
+#endif
+
struct buf;
struct inode;
struct nameidata;
@@ -94,6 +99,7 @@
/* UFS-specific flags */
#define UFS_NEEDSWAP 0x01 /* filesystem metadata need byte-swapping */
+#define UFS_ISAPPLEUFS 0x02 /* filesystem is Apple UFS */
/*
* Flags describing the state of quotas.
@@ -103,6 +109,12 @@
/* Convert mount ptr to ufsmount ptr. */
#define VFSTOUFS(mp) ((struct ufsmount *)((mp)->mnt_data))
+
+#ifdef APPLE_UFS
+#define UFS_MPISAPPLEUFS(mp) (VFSTOUFS(mp)->um_flags & UFS_ISAPPLEUFS)
+#else
+#define UFS_MPISAPPLEUFS(mp) (0)
+#endif
/*
* Macros to access file system parameters in the ufsmount structure.
Index: usr.bin/file/magdir/filesystems
===================================================================
RCS file: /cvsroot/basesrc/usr.bin/file/magdir/filesystems,v
retrieving revision 1.11
diff -u -r1.11 filesystems
--- usr.bin/file/magdir/filesystems 2002/05/18 07:00:49 1.11
+++ usr.bin/file/magdir/filesystems 2002/06/20 22:41:14
@@ -89,6 +89,10 @@
>8320 lelong 1 SPACE optimization
9564 belong 0x00011954 Unix Fast File system (big-endian),
+>7168 long 0x4c41424c Apple UFS Volume
+>>7186 string x named %s,
+>>7176 belong x volume label version %d,
+>>7180 bedate x created on %s,
>8404 string x last mounted on %s,
#>9504 bedate x last checked at %s,
>8224 bedate x last written at %s,
>Release-Note:
>Audit-Trail:
>Unformatted: