Restore backward compatibility of UFS2 with previous NetBSD releases by

disabling support in UFS2 for extended attributes (including ACLs).
Add a new variant of UFS2 called "UFS2ea" that does support extended attributes.
Add new	fsck_ffs operations "-c	ea" and	"-c no-ea" to convert file systems
from UFS2 to UFS2ea and	vice-versa (both of which delete all existing extended
attributes in the process).
This commit is contained in:
chs 2022-11-17 06:40:38 +00:00
parent 77dab346ef
commit 87ba0e2a31
54 changed files with 908 additions and 151 deletions

View File

@ -1,4 +1,4 @@
$NetBSD: UPDATING,v 1.334 2022/11/12 02:20:15 mrg Exp $
$NetBSD: UPDATING,v 1.335 2022/11/17 06:40:38 chs Exp $
This file (UPDATING) is intended to be a brief reference to recent
changes that might cause problems in the build process, and a guide for
@ -19,6 +19,33 @@ See also: BUILDING, build.sh, Makefile.
Recent changes:
^^^^^^^^^^^^^^^
20221116:
The addition to NetBSD's version of UFS2 of support for extended
attributes broke backward compatibility with previous releases
of NetBSD, so UFS2 has been restored to being compatible with
previous NetBSD releases by disabling extended attributes.
(Note that ACLs are implemented as extended attributes, so
this changes disables ACLs as well.)
Support for UFS2 with extended attributes is now available in a new
UFS variant called UFS2ea. If you have created extended attributes
in an original UFS2 file system then "fsck -p" will now fail due to
the unexpected presence of extended attributes and "fsck -y" will
remove all extended attributes. If you wish to preserve extended
attributes rather than delete them, there is a utility to convert
a UFS2 file system to UFS2ea and leave extended attributes in place,
but this should be used with caution since it will preserve any
extended attributes that have been corrupted by the backward
incompatibility too.
If you wish to use a UFS2ea file system as your root file system,
then you will need to update your boot loader to a version that
supports UFS2ea.
For more information, see:
https://wiki.netbsd.org/features/UFS2ea
20221111:
The new libdrm import worsened the conflict issues for the
kdump/ktruss ioctl, and i915 now conflicts with base, and has

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1230 2022/11/10 06:13:58 blymn Exp $
# $NetBSD: mi,v 1.1231 2022/11/17 06:40:38 chs Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -4354,6 +4354,7 @@
./usr/tests/sbin/fsck_ffs/Kyuafile tests-sbin-tests compattestfile,atf,kyua
./usr/tests/sbin/fsck_ffs/t_check_quotas tests-sbin-tests compattestfile,atf
./usr/tests/sbin/fsck_ffs/t_enable_quotas tests-sbin-tests compattestfile,atf
./usr/tests/sbin/fsck_ffs/t_extattr tests-sbin-tests compattestfile,atf
./usr/tests/sbin/gpt tests-sbin-tests compattestfile,atf
./usr/tests/sbin/gpt/Atffile tests-sbin-tests compattestfile,atf
./usr/tests/sbin/gpt/Kyuafile tests-sbin-tests compattestfile,atf,kyua

View File

@ -1,4 +1,4 @@
/* $NetBSD: badsect.c,v 1.34 2016/09/05 01:09:57 sevan Exp $ */
/* $NetBSD: badsect.c,v 1.35 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1981, 1983, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1981, 1983, 1993\
#if 0
static char sccsid[] = "@(#)badsect.c 8.2 (Berkeley) 5/4/95";
#else
__RCSID("$NetBSD: badsect.c,v 1.34 2016/09/05 01:09:57 sevan Exp $");
__RCSID("$NetBSD: badsect.c,v 1.35 2022/11/17 06:40:38 chs Exp $");
#endif
#endif /* not lint */
@ -151,11 +151,13 @@ main(int argc, char *argv[])
rdfs(sblock_try[i], SBLOCKSIZE, fs);
switch (fs->fs_magic) {
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC:
break;
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC_SWAPPED:

View File

@ -1,4 +1,4 @@
/* $NetBSD: cgdconfig.c,v 1.60 2022/09/13 10:14:32 riastradh Exp $ */
/* $NetBSD: cgdconfig.c,v 1.61 2022/11/17 06:40:38 chs Exp $ */
/*-
* Copyright (c) 2002, 2003 The NetBSD Foundation, Inc.
@ -33,7 +33,7 @@
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 2002, 2003\
The NetBSD Foundation, Inc. All rights reserved.");
__RCSID("$NetBSD: cgdconfig.c,v 1.60 2022/09/13 10:14:32 riastradh Exp $");
__RCSID("$NetBSD: cgdconfig.c,v 1.61 2022/11/17 06:40:38 chs Exp $");
#endif
#ifdef HAVE_ARGON2
@ -1207,8 +1207,10 @@ verify_ffs(int fd)
switch (u.fs.fs_magic) {
case FS_UFS1_MAGIC:
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
case FS_UFS1_MAGIC_SWAPPED:
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
return 0;
default:
continue;

View File

@ -1,4 +1,4 @@
/* $NetBSD: clri.c,v 1.24 2015/08/30 05:23:17 mlelstv Exp $ */
/* $NetBSD: clri.c,v 1.25 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1990, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1990, 1993\
#if 0
static char sccsid[] = "@(#)clri.c 8.3 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: clri.c,v 1.24 2015/08/30 05:23:17 mlelstv Exp $");
__RCSID("$NetBSD: clri.c,v 1.25 2022/11/17 06:40:38 chs Exp $");
#endif
#endif /* not lint */
@ -107,11 +107,13 @@ main(int argc, char *argv[])
sbp = (struct fs *)sblock;
switch(sbp->fs_magic) {
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
is_ufs2 = 1;
/*FALLTHROUGH*/
case FS_UFS1_MAGIC:
break;
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
is_ufs2 = 1;
/*FALLTHROUGH*/
case FS_UFS1_MAGIC_SWAPPED:

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_inode.c,v 1.23 2019/03/01 16:42:11 christos Exp $ */
/* $NetBSD: ffs_inode.c,v 1.24 2022/11/17 06:40:38 chs Exp $ */
/*-
* Copyright (c) 1980, 1991, 1993, 1994
@ -36,7 +36,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1991, 1993, 1994\
#endif /* not lint */
#ifndef lint
__RCSID("$NetBSD: ffs_inode.c,v 1.23 2019/03/01 16:42:11 christos Exp $");
__RCSID("$NetBSD: ffs_inode.c,v 1.24 2022/11/17 06:40:38 chs Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -83,11 +83,17 @@ fs_read_sblock(char *superblock)
rawread(sblock_try[i], (char *)superblock, MAXBSIZE);
switch(sblock->fs_magic) {
case FS_UFS2EA_MAGIC:
sblock->fs_magic = FS_UFS2_MAGIC;
/*FALLTHROUGH*/
case FS_UFS2_MAGIC:
is_ufs2 = 1;
/*FALLTHROUGH*/
case FS_UFS1_MAGIC:
break;
case FS_UFS2EA_MAGIC_SWAPPED:
sblock->fs_magic = FS_UFS2_MAGIC_SWAPPED;
/*FALLTHROUGH*/
case FS_UFS2_MAGIC_SWAPPED:
is_ufs2 = 1;
/*FALLTHROUGH*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.27 2011/06/09 19:57:52 christos Exp $ */
/* $NetBSD: extern.h,v 1.28 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1994 James A. Jegers
@ -42,6 +42,7 @@ void clri(struct inodesc *, const char *, int);
int cmpsblks(const struct fs *, struct fs *);
int cmpsblks42(const struct fs *, struct fs *);
int cmpsblks44(const struct fs *, struct fs *);
void cvt_magic(struct fs *);
union dinode * getnextinode(ino_t);
void direrror(ino_t, const char *);
int dirscan(struct inodesc *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsck.h,v 1.55 2020/04/18 12:54:38 jdolecek Exp $ */
/* $NetBSD: fsck.h,v 1.56 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -166,6 +166,7 @@ extern struct fs *sblocksave;
sb_oldfscompat_write(sblk.b_un.b_fs, sblocksave); \
if (needswap) \
ffs_sb_swap(sblk.b_un.b_fs, sblk.b_un.b_fs); \
cvt_magic(sblk.b_un.b_fs); \
sblk.b_dirty = 1; \
} while (0)
#define cgdirty() do {copyback_cg(&cgblk); cgblk.b_dirty = 1;} while (0)
@ -280,12 +281,15 @@ extern int zflag; /* zero unused directory space */
extern int cvtlevel; /* convert to newer file system format */
extern int doinglevel1; /* converting to new cylinder group format */
extern int doinglevel2; /* converting to new inode format */
extern int doing2ea; /* converting UFS2 to UFS2ea */
extern int doing2noea; /* converting UFS2ea to UFS2 */
extern int newinofmt; /* filesystem has new inode format */
extern char usedsoftdep; /* just fix soft dependency inconsistencies */
extern int preen; /* just fix normal inconsistencies */
extern int quiet; /* Don't print anything if clean */
extern int forceimage; /* file system is an image file */
extern int is_ufs2; /* we're dealing with an UFS2 filesystem */
extern int is_ufs2ea; /* is the variant that supports exattrs */
extern int markclean; /* mark file system clean when done */
extern char havesb; /* superblock has been read */
extern char skipclean; /* skip clean file systems if preening */

View File

@ -1,4 +1,4 @@
.\" $NetBSD: fsck_ffs.8,v 1.51 2019/05/05 14:59:06 christos Exp $
.\" $NetBSD: fsck_ffs.8,v 1.52 2022/11/17 06:40:38 chs Exp $
.\"
.\" Copyright (c) 1980, 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@ -205,7 +205,23 @@ option to
.Xr newfs 8 .
.El
.Pp
Note that FFSv2 file systems are always level 4.
Note that FFSv2 file systems always have the features of FFSv1 level 4.
.Pp
FFSv2 file systems have separate conversion options:
.Bl -tag -width 3n -offset indent
.It ea
Convert the file system to the format which supports extended attributes
(and access control lists).
After this conversion is performed, the file system will no longer be
recognized at all by releases prior to
.Nx 10.0 .
.It no-ea
Convert the file system to the format which does not support extended attributes
(or access control lists).
This will remove any existing extended attributes, and the file system
will become recognizable to releases prior to
.Nx 10.0 .
.El
.Pp
In interactive mode,
.Nm
@ -227,6 +243,7 @@ in the second line)
and the file system level
.Dq ( fslevel
in the sixth line).
.Pp
.It Fl d
Print debugging output.
.It Fl F

View File

@ -1,4 +1,4 @@
/* $NetBSD: main.c,v 1.89 2020/04/06 09:54:24 martin Exp $ */
/* $NetBSD: main.c,v 1.90 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1986, 1993\
#if 0
static char sccsid[] = "@(#)main.c 8.6 (Berkeley) 5/14/95";
#else
__RCSID("$NetBSD: main.c,v 1.89 2020/04/06 09:54:24 martin Exp $");
__RCSID("$NetBSD: main.c,v 1.90 2022/11/17 06:40:38 chs Exp $");
#endif
#endif /* not lint */
@ -102,11 +102,14 @@ int zflag;
int cvtlevel;
int doinglevel1;
int doinglevel2;
int doing2ea;
int doing2noea;
int newinofmt;
char usedsoftdep;
int preen;
int forceimage;
int is_ufs2;
int is_ufs2ea;
int markclean;
char havesb;
char skipclean;
@ -194,6 +197,14 @@ main(int argc, char *argv[])
case 'c':
skipclean = 0;
if (strcmp(optarg, "ea") == 0) {
doing2ea = 1;
break;
}
if (strcmp(optarg, "no-ea") == 0) {
doing2noea = 1;
break;
}
cvtlevel = argtoi('c', "conversion level", optarg, 10);
if (cvtlevel > 4) {
cvtlevel = 4;
@ -201,7 +212,7 @@ main(int argc, char *argv[])
cvtlevel);
}
break;
case 'd':
debug++;
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass1.c,v 1.59 2020/04/19 19:37:06 christos Exp $ */
/* $NetBSD: pass1.c,v 1.60 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)pass1.c 8.6 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: pass1.c,v 1.59 2020/04/19 19:37:06 christos Exp $");
__RCSID("$NetBSD: pass1.c,v 1.60 2022/11/17 06:40:38 chs Exp $");
#endif
#endif /* not lint */
@ -423,7 +423,23 @@ checkinode(ino_t inumber, struct inodesc *idesc)
else
idesc->id_type = ADDR;
(void)ckinode(dp, idesc);
if (is_ufs2 && iswap32(dp->dp2.di_extsize) > 0) {
if (is_ufs2 && (!is_ufs2ea || doing2noea) &&
(iswap32(dp->dp2.di_extsize) != 0 ||
iswap64(dp->dp2.di_extb[0]) != 0 ||
iswap64(dp->dp2.di_extb[1]) != 0)) {
pfatal("NON-ZERO EXTATTR FIELDS");
if (!reply("CLEAR EXTATTR FIELDS AND SET PERMS TO 0")) {
markclean = 0;
return;
}
dp = ginode(inumber);
dp->dp2.di_extsize = iswap32(0);
dp->dp2.di_extb[0] = iswap64(0);
dp->dp2.di_extb[1] = iswap64(0);
dp->dp2.di_mode &= ~07777;
inodirty();
}
if (is_ufs2ea && iswap32(dp->dp2.di_extsize) > 0) {
int ret, offset;
idesc->id_type = ADDR;
ndb = howmany(iswap32(dp->dp2.di_extsize), sblock->fs_bsize);

View File

@ -1,4 +1,4 @@
/* $NetBSD: pass5.c,v 1.54 2013/06/23 22:03:34 dholland Exp $ */
/* $NetBSD: pass5.c,v 1.55 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)pass5.c 8.9 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: pass5.c,v 1.54 2013/06/23 22:03:34 dholland Exp $");
__RCSID("$NetBSD: pass5.c,v 1.55 2022/11/17 06:40:38 chs Exp $");
#endif
#endif /* not lint */
@ -223,11 +223,13 @@ pass5(void)
* write back the superblock to the spare at this
* cylinder group.
*/
if ((cvtlevel && sblk.b_dirty) || doswap) {
if ((cvtlevel && sblk.b_dirty) || doswap || doing2ea || doing2noea) {
bwrite(fswritefd, sblk.b_un.b_buf,
FFS_FSBTODB(sblock, cgsblock(sblock, c)),
sblock->fs_sbsize);
} else {
int alt_ufs2ea = 0;
/*
* Read in the current alternate superblock,
* and compare it to the master. If it's
@ -242,10 +244,15 @@ pass5(void)
sblock->fs_sbsize);
if (needswap)
ffs_sb_swap(asblk.b_un.b_fs, altsblock);
if (altsblock->fs_magic == FS_UFS2EA_MAGIC) {
altsblock->fs_magic = FS_UFS2_MAGIC;
alt_ufs2ea = 1;
}
}
sb_oldfscompat_write(sblock, sblocksave);
if ((asblk.b_errs || cmpsblks(sblock, altsblock)) &&
dofix(&idesc[3],
if ((asblk.b_errs || cmpsblks(sblock, altsblock) ||
is_ufs2ea != alt_ufs2ea) &&
dofix(&idesc[3],
"ALTERNATE SUPERBLK(S) ARE INCORRECT")) {
bwrite(fswritefd, sblk.b_un.b_buf,
FFS_FSBTODB(sblock, cgsblock(sblock, c)),

View File

@ -1,4 +1,4 @@
/* $NetBSD: setup.c,v 1.103 2020/04/17 09:42:27 jdolecek Exp $ */
/* $NetBSD: setup.c,v 1.104 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)setup.c 8.10 (Berkeley) 5/9/95";
#else
__RCSID("$NetBSD: setup.c,v 1.103 2020/04/17 09:42:27 jdolecek Exp $");
__RCSID("$NetBSD: setup.c,v 1.104 2022/11/17 06:40:38 chs Exp $");
#endif
#endif /* not lint */
@ -718,7 +718,8 @@ detect_byteorder(struct fs *fs, int sblockoff)
fs->fs_magic == FS_UFS1_MAGIC_SWAPPED))
/* Likely to be the first alternate of a fs with 64k blocks */
return -1;
if (fs->fs_magic == FS_UFS1_MAGIC || fs->fs_magic == FS_UFS2_MAGIC) {
if (fs->fs_magic == FS_UFS1_MAGIC || fs->fs_magic == FS_UFS2_MAGIC ||
fs->fs_magic == FS_UFS2EA_MAGIC) {
#ifndef NO_FFS_EI
if (endian == 0 || BYTE_ORDER == endian) {
needswap = 0;
@ -732,7 +733,8 @@ detect_byteorder(struct fs *fs, int sblockoff)
}
#ifndef NO_FFS_EI
else if (fs->fs_magic == FS_UFS1_MAGIC_SWAPPED ||
fs->fs_magic == FS_UFS2_MAGIC_SWAPPED) {
fs->fs_magic == FS_UFS2_MAGIC_SWAPPED ||
fs->fs_magic == FS_UFS2EA_MAGIC_SWAPPED) {
if (endian == 0 || BYTE_ORDER != endian) {
needswap = 1;
doswap = do_blkswap = do_dirswap = 0;
@ -746,6 +748,29 @@ detect_byteorder(struct fs *fs, int sblockoff)
return -1;
}
/* Update on-disk fs->fs_magic if we are converting */
void
cvt_magic(struct fs *fs)
{
if (is_ufs2ea || doing2ea) {
if (fs->fs_magic == FS_UFS2_MAGIC) {
fs->fs_magic = FS_UFS2EA_MAGIC;
}
if (fs->fs_magic == FS_UFS2_MAGIC_SWAPPED) {
fs->fs_magic = FS_UFS2EA_MAGIC_SWAPPED;
}
}
if (doing2noea) {
if (fs->fs_magic == FS_UFS2EA_MAGIC) {
fs->fs_magic = FS_UFS2_MAGIC;
}
if (fs->fs_magic == FS_UFS2EA_MAGIC_SWAPPED) {
fs->fs_magic = FS_UFS2_MAGIC_SWAPPED;
}
}
}
/*
* Possible superblock locations ordered from most to least likely.
*/
@ -811,9 +836,15 @@ readsb(int listerr)
memmove(sblock, sblk.b_un.b_fs, SBLOCKSIZE);
if (needswap)
ffs_sb_swap(sblk.b_un.b_fs, sblock);
if (sblock->fs_magic == FS_UFS2EA_MAGIC) {
is_ufs2ea = 1;
sblock->fs_magic = FS_UFS2_MAGIC;
}
is_ufs2 = sblock->fs_magic == FS_UFS2_MAGIC;
/* change on-disk magic if asked */
cvt_magic(fs);
/*
* run a few consistency checks of the super block
*/
@ -845,6 +876,11 @@ readsb(int listerr)
memmove(altsblock, asblk.b_un.b_fs, sblock->fs_sbsize);
if (needswap)
ffs_sb_swap(asblk.b_un.b_fs, altsblock);
if (altsblock->fs_magic == FS_UFS2EA_MAGIC) {
altsblock->fs_magic = FS_UFS2_MAGIC;
}
/* change on-disk magic if asked */
cvt_magic(asblk.b_un.b_fs);
if (cmpsblks(sblock, altsblock)) {
if (debug) {
uint32_t *nlp, *olp, *endlp;
@ -873,7 +909,7 @@ out:
sb_oldfscompat_read(sblock, &sblocksave);
/* Now we know the SB is valid, we can write it back if needed */
if (doswap) {
if (doswap || doing2ea || doing2noea) {
sbdirty();
dirty(&asblk);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: utilities.c,v 1.66 2020/04/17 09:42:27 jdolecek Exp $ */
/* $NetBSD: utilities.c,v 1.67 2022/11/17 06:40:38 chs Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)utilities.c 8.6 (Berkeley) 5/19/95";
#else
__RCSID("$NetBSD: utilities.c,v 1.66 2020/04/17 09:42:27 jdolecek Exp $");
__RCSID("$NetBSD: utilities.c,v 1.67 2022/11/17 06:40:38 chs Exp $");
#endif
#endif /* not lint */
@ -324,6 +324,18 @@ ckfini(int noint)
"\n***** FILE SYSTEM MARKED CLEAN *****\n");
}
}
if (doing2ea) {
printf("ENABLING EXTATTR SUPPORT\n");
is_ufs2ea = 1;
sbdirty();
flush(fswritefd, &sblk);
}
if (doing2noea) {
printf("DISABLING EXTATTR SUPPORT\n");
is_ufs2ea = 0;
sbdirty();
flush(fswritefd, &sblk);
}
if (debug)
printf("cache missed %ld of %ld (%d%%)\n", diskreads,
totalreads, (int)(diskreads * 100 / totalreads));

View File

@ -1,4 +1,4 @@
.\" $NetBSD: fsdb.8,v 1.27 2021/05/29 16:51:25 christos Exp $
.\" $NetBSD: fsdb.8,v 1.28 2022/11/17 06:40:38 chs Exp $
.\"
.\" Copyright (c) 1996, 2017 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -35,7 +35,7 @@
.Nd FFS debugging/editing tool
.Sh SYNOPSIS
.Nm
.Op Fl dFn
.Op Fl dFnN
.Fl f Ar fsname
.Sh DESCRIPTION
.Nm
@ -74,6 +74,12 @@ The
.Fl n
option disables writing to the device, preventing any changes from being made
to the filesystem.
.Pp
The
.Fl N
option causes the superblock not to be marked dirty when
.Nm
exits.
.Sh COMMANDS
Besides the built-in
.Xr editline 3

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsdb.c,v 1.52 2021/05/29 16:51:25 christos Exp $ */
/* $NetBSD: fsdb.c,v 1.53 2022/11/17 06:40:38 chs Exp $ */
/*-
* Copyright (c) 1996, 2017 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fsdb.c,v 1.52 2021/05/29 16:51:25 christos Exp $");
__RCSID("$NetBSD: fsdb.c,v 1.53 2022/11/17 06:40:38 chs Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -51,6 +51,7 @@ __RCSID("$NetBSD: fsdb.c,v 1.52 2021/05/29 16:51:25 christos Exp $");
#include <time.h>
#include <unistd.h>
#include <err.h>
#include <stdbool.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ufs/dir.h>
@ -91,13 +92,17 @@ int bflag;
int debug;
int zflag;
int cvtlevel;
int eaflag;
int doinglevel1;
int doinglevel2;
int doing2ea;
int doing2noea;
int newinofmt;
char usedsoftdep;
int preen;
int forceimage;
int is_ufs2;
int is_ufs2ea;
int markclean;
char havesb;
char skipclean;
@ -137,6 +142,7 @@ static int scannames(struct inodesc *);
static int dolookup(char *);
static int chinumfunc(struct inodesc *);
static int chnamefunc(struct inodesc *);
static int chreclenfunc(struct inodesc *);
static int dotime(char *, int64_t *, int32_t *);
static void print_blks32(int32_t *buf, int size, uint64_t *blknum, struct wrinfo *wrp);
static void print_blks64(int64_t *buf, int size, uint64_t *blknum, struct wrinfo *wrp);
@ -160,7 +166,7 @@ ino_t curinum;
static void
usage(void)
{
errx(1, "usage: %s [-dFn] -f <fsname>", getprogname());
errx(1, "usage: %s [-dFfNn] <fsname>", getprogname());
}
/*
* We suck in lots of fsck code, and just pick & choose the stuff we want.
@ -173,11 +179,12 @@ main(int argc, char *argv[])
{
int ch, rval;
char *fsys = NULL;
bool makedirty = true;
forceimage = 0;
debug = 0;
isappleufs = 0;
while ((ch = getopt(argc, argv, "dFf:n")) != -1) {
while ((ch = getopt(argc, argv, "dFf:Nn")) != -1) {
switch (ch) {
case 'd':
debug++;
@ -188,6 +195,9 @@ main(int argc, char *argv[])
case 'f':
fsys = optarg;
break;
case 'N':
makedirty = false;
break;
case 'n':
nflag++;
break;
@ -195,6 +205,10 @@ main(int argc, char *argv[])
usage();
}
}
argc -= optind;
argv += optind;
if (fsys == NULL)
fsys = argv[0];
if (fsys == NULL)
usage();
endian = 0;
@ -205,6 +219,10 @@ main(int argc, char *argv[])
rval = cmdloop();
if (nflag)
exit(rval);
if (!makedirty) {
ckfini(1);
exit(rval);
}
sblock->fs_clean = 0; /* mark it dirty */
sbdirty();
markclean = 0;
@ -245,6 +263,15 @@ CMDFUNC(chatime); /* Change atime */
CMDFUNC(chbirthtime); /* Change birthtime */
CMDFUNC(chinum); /* Change inode # of dirent */
CMDFUNC(chname); /* Change dirname of dirent */
CMDFUNC(chreclen); /* Change reclen of dirent */
CMDFUNC(chextsize); /* Change extsize */
CMDFUNC(chblocks); /* Change blocks */
CMDFUNC(chdb); /* Change direct block pointer */
CMDFUNC(chib); /* Change indirect block pointer */
CMDFUNC(chextb); /* Change extattr block pointer */
CMDFUNC(chfreelink); /* Change freelink pointer */
CMDFUNC(iptrs); /* print raw block pointers for active inode */
CMDFUNC(saveea); /* Save extattrs */
static struct cmdtable cmds[] = {
{"help", "Print out help", 1, 1, helpfn},
@ -261,13 +288,14 @@ static struct cmdtable cmds[] = {
{"linkcount", "Set link count to COUNT", 2, 2, linkcount},
{"ls", "List current inode as directory", 1, 1, ls},
{"blks", "List current inode's data blocks", 1, 1, blks},
{"saveblks", "Save current inode's data blocks", 2, 2, blks},
{"saveblks", "Save current inode's data blocks to FILE", 2, 2, blks},
{"findblk", "Find inode owning disk block(s)", 2, 33, findblk},
{"rm", "Remove NAME from current inode directory", 2, 2, rm},
{"del", "Remove NAME from current inode directory", 2, 2, rm},
{"ln", "Hardlink INO into current inode directory as NAME", 3, 3, ln},
{"chinum", "Change dir entry number INDEX to INUM", 3, 3, chinum},
{"chname", "Change dir entry number INDEX to NAME", 3, 3, chname},
{"chreclen", "Change dir entry number INDEX to RECLEN", 3, 3, chreclen},
{"chtype", "Change type of current inode to TYPE", 2, 2, newtype},
{"chmod", "Change mode of current inode to MODE", 2, 2, chmode},
{"chown", "Change owner of current inode to OWNER", 2, 2, chowner},
@ -276,11 +304,19 @@ static struct cmdtable cmds[] = {
{"chflags", "Change flags of current inode to FLAGS", 2, 2, chaflags},
{"chgen", "Change generation number of current inode to GEN", 2, 2,
chgen},
{ "chextsize", "Change extsize of current inode to EXTSIZE", 2, 2, chextsize },
{ "chblocks", "Change blocks of current inode to BLOCKS", 2, 2, chblocks },
{ "chdb", "Change db pointer N of current inode to BLKNO", 3, 3, chdb },
{ "chib", "Change ib pointer N of current inode to BLKNO", 3, 3, chib },
{ "chextb", "Change extb pointer N of current inode to BLKNO", 3, 3, chextb },
{ "chfreelink", "Change freelink of current inode to FREELINK", 2, 2, chfreelink },
{ "iptrs", "Print raw block pointers of current inode", 1, 1, iptrs },
{"mtime", "Change mtime of current inode to MTIME", 2, 2, chmtime},
{"ctime", "Change ctime of current inode to CTIME", 2, 2, chctime},
{"atime", "Change atime of current inode to ATIME", 2, 2, chatime},
{"birthtime", "Change atime of current inode to BIRTHTIME", 2, 2,
chbirthtime},
{"saveea", "Save current inode's extattr blocks to FILE", 2, 2, saveea},
{"quit", "Exit", 1, 1, quit},
{"q", "Exit", 1, 1, quit},
{"exit", "Exit", 1, 1, quit},
@ -491,6 +527,7 @@ static const char *typename[] = {
"whiteout",
};
static int diroff;
static int slot;
static int
@ -498,10 +535,11 @@ scannames(struct inodesc *idesc)
{
struct direct *dirp = idesc->id_dirp;
printf("slot %d ino %d reclen %d: %s, `%.*s'\n",
slot++, iswap32(dirp->d_ino), iswap16(dirp->d_reclen),
typename[dirp->d_type],
printf("slot %d off %d ino %d reclen %d: %s, `%.*s'\n",
slot++, diroff, iswap32(dirp->d_ino), iswap16(dirp->d_reclen),
typename[dirp->d_type],
dirp->d_namlen, dirp->d_name);
diroff += dirp->d_reclen;
return (KEEPON);
}
@ -511,6 +549,7 @@ CMDFUNC(ls)
checkactivedir(); /* let it go on anyway */
slot = 0;
diroff = 0;
idesc.id_number = curinum;
idesc.id_func = scannames;
idesc.id_type = DATA;
@ -524,16 +563,18 @@ CMDFUNC(ls)
CMDFUNC(blks)
{
uint64_t blkno = 0;
int i, type;
int i;
struct wrinfo wrinfo, *wrp = NULL;
bool saveblks;
if (strcmp(argv[0], "saveblks") == 0) {
saveblks = strcmp(argv[0], "saveblks") == 0;
if (saveblks) {
wrinfo.fd = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0644);
if (wrinfo.fd == -1) {
warn("unable to create file %s", argv[1]);
return 0;
}
wrinfo.size = DIP(curinode, size);
wrinfo.size = iswap64(DIP(curinode, size));
wrinfo.written_size = 0;
wrp = &wrinfo;
}
@ -541,12 +582,6 @@ CMDFUNC(blks)
warnx("no current inode");
return 0;
}
type = iswap16(DIP(curinode, mode)) & IFMT;
if (type != IFDIR && type != IFREG) {
warnx("inode %llu not a file or directory",
(unsigned long long)curinum);
return 0;
}
if (is_ufs2) {
printf("I=%llu %lld blocks\n", (unsigned long long)curinum,
(long long)(iswap64(curinode->dp2.di_blocks)));
@ -564,6 +599,11 @@ CMDFUNC(blks)
for (i = 0; i < UFS_NIADDR; i++)
print_indirblks64(iswap64(curinode->dp2.di_ib[i]), i,
&blkno, wrp);
printf("Extattr blocks:\n");
blkno = 0;
if (saveblks)
wrinfo.size += iswap32(curinode->dp2.di_extsize);
print_blks64(curinode->dp2.di_extb, UFS_NXADDR, &blkno, wrp);
} else {
for (i = 0; i < UFS_NIADDR; i++)
print_indirblks32(iswap32(curinode->dp1.di_ib[i]), i,
@ -827,7 +867,7 @@ static int
writefileblk(struct wrinfo *wrp, uint64_t blk)
{
char buf[MAXBSIZE];
long long size;
long long size, rsize;
size = wrp->size - wrp->written_size;
if (size > sblock->fs_bsize)
@ -837,7 +877,8 @@ writefileblk(struct wrinfo *wrp, uint64_t blk)
return -1;
}
if (bread(fsreadfd, buf, FFS_FSBTODB(sblock, blk), size) != 0)
rsize = roundup(size, DEV_BSIZE);
if (bread(fsreadfd, buf, FFS_FSBTODB(sblock, blk), rsize) != 0)
return -1;
if (write(wrp->fd, buf, size) != size)
return -1;
@ -1154,6 +1195,53 @@ CMDFUNC(chname)
}
}
static int
chreclenfunc(struct inodesc *idesc)
{
struct direct *dirp = idesc->id_dirp;
if (slotcount++ == desired) {
dirp->d_reclen = iswap16(idesc->id_parent);
return STOP | ALTERED | FOUND;
}
return KEEPON;
}
CMDFUNC(chreclen)
{
char *cp;
uint32_t reclen;
struct inodesc idesc;
slotcount = 0;
if (!checkactivedir())
return 1;
desired = strtoul(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0') {
printf("invalid slot number `%s'\n", argv[1]);
return 1;
}
reclen = strtoul(argv[2], &cp, 0);
if (reclen >= UINT16_MAX) {
printf("invalid reclen `%s'\n", argv[2]);
return 1;
}
idesc.id_number = curinum;
idesc.id_func = chreclenfunc;
idesc.id_fix = IGNORE;
idesc.id_type = DATA;
idesc.id_parent = reclen; /* XXX convenient hiding place */
if (ckinode(curinode, &idesc) & FOUND)
return 0;
else {
warnx("no %sth slot in current directory", argv[1]);
return 1;
}
}
static struct typemap {
const char *typename;
int typebits;
@ -1162,6 +1250,9 @@ static struct typemap {
{ "dir", IFDIR },
{ "socket", IFSOCK },
{ "fifo", IFIFO },
{"link", IFLNK},
{"chr", IFCHR},
{"blk", IFBLK},
};
CMDFUNC(newtype)
@ -1217,13 +1308,13 @@ CMDFUNC(chmode)
CMDFUNC(chlen)
{
long len;
off_t len;
char *cp;
if (!checkactive())
return 1;
len = strtol(argv[1], &cp, 0);
len = strtoull(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0' || len < 0) {
warnx("bad length '%s'", argv[1]);
return 1;
@ -1281,6 +1372,160 @@ CMDFUNC(chgen)
return 0;
}
CMDFUNC(chextsize)
{
uint32_t extsize;
char *cp;
if (!is_ufs2)
return 1;
if (!checkactive())
return 1;
extsize = strtol(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0') {
warnx("bad extsize `%s'", argv[1]);
return 1;
}
curinode->dp2.di_extsize = extsize;
inodirty();
printactive();
return 0;
}
CMDFUNC(chblocks)
{
uint64_t blocks;
char *cp;
if (!checkactive())
return 1;
blocks = strtoll(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0') {
warnx("bad blocks `%s'", argv[1]);
return 1;
}
DIP_SET(curinode, blocks, blocks);
inodirty();
printactive();
return 0;
}
CMDFUNC(chdb)
{
unsigned int idx;
daddr_t bno;
char *cp;
if (!checkactive())
return 1;
idx = strtoull(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0') {
warnx("bad pointer idx `%s'", argv[1]);
return 1;
}
bno = strtoll(argv[2], &cp, 0);
if (cp == argv[2] || *cp != '\0') {
warnx("bad block number `%s'", argv[2]);
return 1;
}
if (idx >= UFS_NDADDR) {
warnx("pointer index %d is out of range", idx);
return 1;
}
DIP_SET(curinode, db[idx], bno);
inodirty();
printactive();
return 0;
}
CMDFUNC(chib)
{
unsigned int idx;
daddr_t bno;
char *cp;
if (!checkactive())
return 1;
idx = strtoull(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0') {
warnx("bad pointer idx `%s'", argv[1]);
return 1;
}
bno = strtoll(argv[2], &cp, 0);
if (cp == argv[2] || *cp != '\0') {
warnx("bad block number `%s'", argv[2]);
return 1;
}
if (idx >= UFS_NIADDR) {
warnx("pointer index %d is out of range", idx);
return 1;
}
DIP_SET(curinode, ib[idx], bno);
inodirty();
printactive();
return 0;
}
CMDFUNC(chextb)
{
unsigned int idx;
daddr_t bno;
char *cp;
if (!checkactive())
return 1;
idx = strtoull(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0') {
warnx("bad pointer idx `%s'", argv[1]);
return 1;
}
bno = strtoll(argv[2], &cp, 0);
if (cp == argv[2] || *cp != '\0') {
warnx("bad block number `%s'", argv[2]);
return 1;
}
if (idx >= UFS_NXADDR) {
warnx("pointer index %d is out of range", idx);
return 1;
}
curinode->dp2.di_extb[idx] = bno;
inodirty();
printactive();
return 0;
}
CMDFUNC(chfreelink)
{
#if 0
ino_t freelink;
char *cp;
if (!checkactive())
return 1;
freelink = strtoll(argv[1], &cp, 0);
if (cp == argv[1] || *cp != '\0') {
warnx("bad freelink `%s'", argv[1]);
return 1;
}
DIP_SET(curinode, freelink, freelink);
inodirty();
printactive();
#endif
return 0;
}
CMDFUNC(linkcount)
{
int lcnt;
@ -1418,6 +1663,8 @@ CMDFUNC(chmtime)
int64_t rsec;
int32_t nsec;
if (!checkactive())
return 1;
if (dotime(argv[1], &rsec, &nsec))
return 1;
DIP_SET(curinode, mtime, rsec);
@ -1432,6 +1679,8 @@ CMDFUNC(chatime)
int64_t rsec;
int32_t nsec;
if (!checkactive())
return 1;
if (dotime(argv[1], &rsec, &nsec))
return 1;
DIP_SET(curinode, atime, rsec);
@ -1446,6 +1695,8 @@ CMDFUNC(chctime)
int64_t rsec;
int32_t nsec;
if (!checkactive())
return 1;
if (dotime(argv[1], &rsec, &nsec))
return 1;
DIP_SET(curinode, ctime, rsec);
@ -1464,6 +1715,8 @@ CMDFUNC(chbirthtime)
warnx("birthtime can only be set in ufs2");
return 1;
}
if (!checkactive())
return 1;
if (dotime(argv[1], &rsec, &nsec))
return 1;
@ -1473,3 +1726,43 @@ CMDFUNC(chbirthtime)
printactive();
return 0;
}
CMDFUNC(iptrs)
{
int i;
if (!checkactive())
return 1;
for (i = 0; i < UFS_NDADDR; i++)
printf("di_db %d %ju\n", i, DIP(curinode, db[i]));
for (i = 0; i < UFS_NIADDR; i++)
printf("di_ib %d %ju\n", i, DIP(curinode, ib[i]));
if (is_ufs2)
for (i = 0; i < UFS_NXADDR; i++)
printf("di_extb %d %ju\n", i, curinode->dp2.di_extb[i]);
return 0;
}
CMDFUNC(saveea)
{
struct wrinfo wrinfo;
uint64_t blkno = 0;
if (!is_ufs2) {
warnx("dumping extattrs is only supported for ufs2");
return 1;
}
if (!checkactive())
return 1;
wrinfo.fd = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0644);
if (wrinfo.fd == -1) {
warn("unable to create file %s", argv[1]);
return 0;
}
wrinfo.size = iswap32(curinode->dp2.di_extsize);
wrinfo.written_size = 0;
print_blks64(curinode->dp2.di_extb, UFS_NXADDR, &blkno, &wrinfo);
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsdbutil.c,v 1.23 2021/05/29 16:51:25 christos Exp $ */
/* $NetBSD: fsdbutil.c,v 1.24 2022/11/17 06:40:38 chs Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fsdbutil.c,v 1.23 2021/05/29 16:51:25 christos Exp $");
__RCSID("$NetBSD: fsdbutil.c,v 1.24 2022/11/17 06:40:38 chs Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -95,11 +95,13 @@ printstat(const char *cp, ino_t inum, union dinode *dp)
time_t t;
char *p;
uint64_t size, blocks;
uint32_t extsize;
uint16_t mode;
uint32_t rdev;
uint32_t uid, gid;
size = iswap64(DIP(dp, size));
extsize = is_ufs2 ? iswap32(dp->dp2.di_extsize) : 0;
blocks = is_ufs2 ? iswap64(DIP(dp, blocks)) : iswap32(DIP(dp, blocks));
mode = iswap16(DIP(dp, mode));
rdev = iswap32(DIP(dp, rdev));
@ -139,8 +141,8 @@ printstat(const char *cp, ino_t inum, union dinode *dp)
puts("fifo");
break;
}
printf("I=%llu MODE=%o SIZE=%llu", (unsigned long long)inum, mode,
(unsigned long long)size);
printf("I=%llu MODE=%o SIZE=%llu EXTSIZE=%u", (unsigned long long)inum,
mode, (unsigned long long)size, extsize);
t = is_ufs2 ? iswap64(dp->dp2.di_mtime) : iswap32(dp->dp1.di_mtime);
p = ctime(&t);
printf("\n\t MTIME=%15.15s %4.4s [%d nsec]", &p[4], &p[20],

View File

@ -1,4 +1,4 @@
/* $NetBSD: fsirand.c,v 1.32 2013/10/19 01:09:58 christos Exp $ */
/* $NetBSD: fsirand.c,v 1.33 2022/11/17 06:40:39 chs Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: fsirand.c,v 1.32 2013/10/19 01:09:58 christos Exp $");
__RCSID("$NetBSD: fsirand.c,v 1.33 2022/11/17 06:40:39 chs Exp $");
#endif /* lint */
#include <sys/param.h>
@ -95,11 +95,13 @@ getsblock(int fd, const char *name, struct fs *fs)
switch(fs->fs_magic) {
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC:
break;
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC_SWAPPED:

View File

@ -1,4 +1,4 @@
/* $NetBSD: extern.h,v 1.19 2020/04/18 12:54:38 jdolecek Exp $ */
/* $NetBSD: extern.h,v 1.20 2022/11/17 06:40:39 chs Exp $ */
/*
* Copyright (c) 1997 Christos Zoulas. All rights reserved.
@ -31,6 +31,7 @@ void mkfs(const char *, int, int, mode_t, uid_t, gid_t);
extern int mfs; /* run as the memory based filesystem */
extern int Nflag; /* run mkfs without writing file system */
extern int Oflag; /* format as an 4.3BSD file system */
extern int eaflag; /* use UFS2ea fs_magic */
extern int verbosity; /* amount of printf() output */
extern int64_t fssize; /* file system size */
extern int sectorsize; /* bytes/sector */

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs.c,v 1.131 2022/01/01 10:32:28 msaitoh Exp $ */
/* $NetBSD: mkfs.c,v 1.132 2022/11/17 06:40:39 chs Exp $ */
/*
* Copyright (c) 1980, 1989, 1993
@ -73,7 +73,7 @@
#if 0
static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
#else
__RCSID("$NetBSD: mkfs.c,v 1.131 2022/01/01 10:32:28 msaitoh Exp $");
__RCSID("$NetBSD: mkfs.c,v 1.132 2022/11/17 06:40:39 chs Exp $");
#endif
#endif /* not lint */
@ -745,6 +745,8 @@ mkfs(const char *fsys, int fi, int fo,
memset(iobuf + sizeof(sblock), 0, i - sizeof(sblock));
if (needswap)
ffs_sb_swap(&sblock, (struct fs *)iobuf);
if (eaflag)
((struct fs *)iobuf)->fs_magic = FS_UFS2EA_MAGIC;
if ((sblock.fs_old_flags & FS_FLAGS_UPDATED) == 0)
memset(iobuf + offsetof(struct fs, fs_old_postbl_start),
0xff, 256);

View File

@ -1,4 +1,4 @@
.\" $NetBSD: newfs.8,v 1.85 2019/04/13 19:29:27 maya Exp $
.\" $NetBSD: newfs.8,v 1.86 2022/11/17 06:40:39 chs Exp $
.\"
.\" Copyright (c) 1983, 1987, 1991, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
@ -229,9 +229,10 @@ or
This is the default.
.It 2
FFSv2; enhanced Fast File System, suited for more than 1 Terabyte capacity.
.\" Supports access control lists.
This is also known as
.Sq UFS2 .
.It 2ea
FFSv2 plus support for extended attributes and access control lists.
.El
See
.Xr fsck_ffs 8

View File

@ -1,4 +1,4 @@
/* $NetBSD: newfs.c,v 1.117 2022/04/16 18:15:20 andvar Exp $ */
/* $NetBSD: newfs.c,v 1.118 2022/11/17 06:40:39 chs Exp $ */
/*
* Copyright (c) 1983, 1989, 1993, 1994
@ -78,7 +78,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1989, 1993, 1994\
#if 0
static char sccsid[] = "@(#)newfs.c 8.13 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: newfs.c,v 1.117 2022/04/16 18:15:20 andvar Exp $");
__RCSID("$NetBSD: newfs.c,v 1.118 2022/11/17 06:40:39 chs Exp $");
#endif
#endif /* not lint */
@ -207,6 +207,7 @@ int mfs; /* run as the memory based filesystem */
int Gflag; /* allow garbage parameters (for testing) */
int Nflag; /* run without writing file system */
int Oflag = 1; /* format as an 4.3BSD file system */
int eaflag; /* use UFS2ea fs_magic */
int verbosity; /* amount of printf() output */
#define DEFAULT_VERBOSITY 3 /* 4 is traditional behavior */
int64_t fssize; /* file system size */
@ -315,6 +316,10 @@ main(int argc, char *argv[])
verbosity = DEFAULT_VERBOSITY;
break;
case 'O':
if (strcmp(optarg, "2ea") == 0) {
eaflag = 1;
optarg[1] = 0;
}
Oflag = strsuftoi64("format", optarg, 0, 2, NULL);
break;
case 'S':
@ -862,7 +867,7 @@ struct help_strings {
{ NEWFS, "-I \t\tdo not check that the file system type is '4.2BSD'" },
{ BOTH, "-N \t\tdo not create file system, just print out "
"parameters" },
{ NEWFS, "-O N\t\tfilesystem format: 0 => 4.3BSD, 1 => FFSv1, 2 => FFSv2" },
{ NEWFS, "-O N\t\tfilesystem format: 0 => 4.3BSD, 1 => FFSv1, 2 => FFSv2, 2ea => FFSv2 with extattrs" },
{ NEWFS, "-S secsize\tsector size" },
#ifdef COMPAT
{ NEWFS, "-T disktype\tdisk type" },

View File

@ -1,4 +1,4 @@
/* $NetBSD: resize_ffs.c,v 1.56 2022/04/08 10:17:53 andvar Exp $ */
/* $NetBSD: resize_ffs.c,v 1.57 2022/11/17 06:40:39 chs Exp $ */
/* From sources sent on February 17, 2003 */
/*-
* As its sole author, I explicitly place this code in the public
@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: resize_ffs.c,v 1.56 2022/04/08 10:17:53 andvar Exp $");
__RCSID("$NetBSD: resize_ffs.c,v 1.57 2022/11/17 06:40:39 chs Exp $");
#include <sys/disk.h>
#include <sys/disklabel.h>
@ -2227,12 +2227,14 @@ main(int argc, char **argv)
readat(where / DEV_BSIZE, oldsb, SBLOCKSIZE);
switch (oldsb->fs_magic) {
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC:
needswap = 0;
break;
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC_SWAPPED:

View File

@ -1,4 +1,4 @@
/* $NetBSD: scan_ffs.c,v 1.35 2022/01/20 14:45:14 christos Exp $ */
/* $NetBSD: scan_ffs.c,v 1.36 2022/11/17 06:40:39 chs Exp $ */
/*
* Copyright (c) 2005-2007 Juan Romero Pardines
@ -33,7 +33,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: scan_ffs.c,v 1.35 2022/01/20 14:45:14 christos Exp $");
__RCSID("$NetBSD: scan_ffs.c,v 1.36 2022/11/17 06:40:39 chs Exp $");
#endif /* not lint */
#include <sys/types.h>
@ -128,7 +128,9 @@ ffs_checkver(struct sblockinfo *sbi)
sbi->ffs->fs_size = sbi->ffs->fs_old_size;
return FSTYPE_FFSV1;
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
return FSTYPE_FFSV2;
default:
return FSTYPE_NONE;

View File

@ -1,4 +1,4 @@
/* $NetBSD: tunefs.c,v 1.55 2021/09/18 03:05:20 christos Exp $ */
/* $NetBSD: tunefs.c,v 1.56 2022/11/17 06:40:39 chs Exp $ */
/*
* Copyright (c) 1983, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\
#if 0
static char sccsid[] = "@(#)tunefs.c 8.3 (Berkeley) 5/3/95";
#else
__RCSID("$NetBSD: tunefs.c,v 1.55 2021/09/18 03:05:20 christos Exp $");
__RCSID("$NetBSD: tunefs.c,v 1.56 2022/11/17 06:40:39 chs Exp $");
#endif
#endif /* not lint */
@ -81,6 +81,7 @@ int fi;
long dev_bsize = 512;
int needswap = 0;
int is_ufs2 = 0;
int extattr = 0;
off_t sblockloc;
int userquota = 0;
int groupquota = 0;
@ -361,7 +362,9 @@ main(int argc, char *argv[])
if (aflag) {
name = "ACLs";
if (strcmp(avalue, "enable") == 0) {
if (sblock.fs_flags & FS_NFS4ACLS) {
if (is_ufs2 && !extattr) {
warnx("%s not supported by this fs", name);
} else if (sblock.fs_flags & FS_NFS4ACLS) {
warnx("%s remains unchanged as enabled", name);
} else if (sblock.fs_flags & FS_POSIX1EACLS) {
warnx("%s and POSIX.1e ACLs are mutually "
@ -384,7 +387,9 @@ main(int argc, char *argv[])
if (pflag) {
name = "POSIX1e ACLs";
if (strcmp(pvalue, "enable") == 0) {
if (sblock.fs_flags & FS_POSIX1EACLS) {
if (is_ufs2 && !extattr) {
warnx("%s not supported by this fs", name);
} else if (sblock.fs_flags & FS_POSIX1EACLS) {
warnx("%s remains unchanged as enabled", name);
} else if (sblock.fs_flags & FS_NFS4ACLS) {
warnx("%s and ACLs are mutually "
@ -657,11 +662,17 @@ getsb(struct fs *fs, const char *file)
errx(5, "cannot find filesystem superblock");
bread(sblock_try[i] / dev_bsize, (char *)fs, SBLOCKSIZE, file);
switch(fs->fs_magic) {
case FS_UFS2EA_MAGIC:
extattr = 1;
/*FALLTHROUGH*/
case FS_UFS2_MAGIC:
is_ufs2 = 1;
/*FALLTHROUGH*/
case FS_UFS1_MAGIC:
break;
case FS_UFS2EA_MAGIC_SWAPPED:
extattr = 1;
/*FALLTHROUGH*/
case FS_UFS2_MAGIC_SWAPPED:
is_ufs2 = 1;
/*FALLTHROUGH*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: readufs_ffs.c,v 1.1 2014/02/24 07:23:43 skrll Exp $ */
/* $NetBSD: readufs_ffs.c,v 1.2 2022/11/17 06:40:39 chs Exp $ */
/* from Id: readufs_ffs.c,v 1.8 2004/06/12 04:26:39 itohy Exp */
/*
@ -66,7 +66,7 @@ try_ffs(void)
break;
#endif
#ifdef USE_UFS2
if (magic == FS_UFS2_MAGIC) {
if (magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_MAGIC) {
#ifdef USE_UFS1
fsi.ufstype = UFSTYPE_UFS2;
#endif
@ -81,7 +81,8 @@ try_ffs(void)
*/
fsi_ffs.magic = magic;
#ifdef DEBUG_WITH_STDIO
printf("FFS: detected UFS%d format\n", (magic == FS_UFS2_MAGIC) + 1);
printf("FFS: detected UFS%d format\n",
(magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_MAGIC) + 1);
#endif
/* This partition looks like an FFS. */

View File

@ -1,4 +1,4 @@
\ $NetBSD: bootblk.fth,v 1.16 2021/07/24 21:31:36 andvar Exp $
\ $NetBSD: bootblk.fth,v 1.17 2022/11/17 06:40:39 chs Exp $
\
\ IEEE 1275 Open Firmware Boot Block
\
@ -624,6 +624,7 @@ create cur-blockno -1 l, -1 l, \ Current disk block.
fs_magic l@ case
fs1_magic_value of init-ffs-v1 true endof
fs2_magic_value of init-ffs-v2 true endof
fs2ea_magic_value of init-ffs-v2 true endof
false swap \ Return false
endcase
;
@ -890,7 +891,7 @@ create cur-blockno -1 l, -1 l, \ Current disk block.
: do-boot ( bootfile -- )
." NetBSD IEEE 1275 Multi-FS Bootblock" cr
." Version $NetBSD: bootblk.fth,v 1.16 2021/07/24 21:31:36 andvar Exp $" cr
." Version $NetBSD: bootblk.fth,v 1.17 2022/11/17 06:40:39 chs Exp $" cr
boot-path load-file ( -- load-base )
dup 0<> if " init-program " evaluate then
;

View File

@ -1,4 +1,4 @@
# $NetBSD: genfth.cf,v 1.9 2013/06/10 10:26:22 hannken Exp $
# $NetBSD: genfth.cf,v 1.10 2022/11/17 06:40:39 chs Exp $
#
# Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -158,6 +158,7 @@ member d_name
define fs1_magic_value FS_UFS1_MAGIC
define fs2_magic_value FS_UFS2_MAGIC
define fs2ea_magic_value FS_UFS2EA_MAGIC
define fs_42postblfmt FS_42POSTBLFMT
define fs_44inodefmt FS_44INODEFMT
define ndaddr UFS_NDADDR

View File

@ -1,4 +1,4 @@
/* $NetBSD: readufs_ffs.c,v 1.14 2013/06/23 02:06:05 dholland Exp $ */
/* $NetBSD: readufs_ffs.c,v 1.15 2022/11/17 06:40:39 chs Exp $ */
/* from Id: readufs_ffs.c,v 1.6 2003/04/08 09:19:32 itohy Exp */
/*
@ -69,7 +69,7 @@ try_ffs(void)
}
#endif
#ifdef USE_UFS2
if (magic == FS_UFS2_MAGIC) {
if (magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_MAGIC) {
#ifdef USE_UFS1
fsi.ufstype = UFSTYPE_UFS2;
#endif
@ -84,7 +84,8 @@ try_ffs(void)
*/
fsi_ffs.magic = magic;
#ifdef DEBUG_WITH_STDIO
printf("FFS: detected UFS%d format\n", (magic == FS_UFS2_MAGIC) + 1);
printf("FFS: detected UFS%d format\n",
(magic == FS_UFS2_MAGIC || magic == FS_UFS2EA_MAGIC) + 1);
#endif
/* This partition looks like an FFS. */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffsv1.c,v 1.9 2022/04/24 06:52:59 mlelstv Exp $ */
/* $NetBSD: ffsv1.c,v 1.10 2022/11/17 06:40:39 chs Exp $ */
#define LIBSA_FFSv1
@ -17,9 +17,4 @@
#define ufs_indp_swap bswap32
#define indp_t int32_t
#define FS_MAGIC FS_UFS1_MAGIC
/* #define FSMOD "wapbl/ufs/ffs" */
#define FSMOD NULL
#include "ufs.c"

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffsv2.c,v 1.9 2022/04/24 06:52:59 mlelstv Exp $ */
/* $NetBSD: ffsv2.c,v 1.10 2022/11/17 06:40:39 chs Exp $ */
#define LIBSA_FFSv2
@ -17,9 +17,4 @@
#define ufs_indp_swap bswap64
#define indp_t int64_t
#define FS_MAGIC FS_UFS2_MAGIC
/* #define FSMOD "wapbl/ufs/ffs" */
#define FSMOD NULL
#include "ufs.c"

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfsv1.c,v 1.15 2021/05/27 06:54:44 mrg Exp $ */
/* $NetBSD: lfsv1.c,v 1.16 2022/11/17 06:40:39 chs Exp $ */
#define LIBSA_LFS
#define REQUIRED_LFS_VERSION 1
@ -25,8 +25,6 @@
#define dblksize(a, b, c) lfs_dblksize((a), (b), (c))
#define FSBTODB(fs, daddr) (daddr) /* LFSv1 uses sectors for addresses */
#define FS_MAGIC LFS_MAGIC
#define FSMOD "lfs"
#include "lib/libsa/ufs.c"

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfsv2.c,v 1.15 2021/05/27 06:54:44 mrg Exp $ */
/* $NetBSD: lfsv2.c,v 1.16 2022/11/17 06:40:40 chs Exp $ */
#define LIBSA_LFS
#define REQUIRED_LFS_VERSION 2
@ -29,8 +29,6 @@
#define dblksize(a, b, c) lfs_dblksize((a), (b), (c))
#define FSBTODB(a, b) LFS_FSBTODB((a), (b))
#define FS_MAGIC LFS_MAGIC
#define FSMOD "lfs"
#include "lib/libsa/ufs.c"

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs.c,v 1.86 2022/04/29 07:42:07 rin Exp $ */
/* $NetBSD: ufs.c,v 1.87 2022/11/17 06:40:40 chs Exp $ */
/*-
* Copyright (c) 1993
@ -156,9 +156,6 @@ typedef uint32_t ino32_t;
#ifndef FSBTODB
#define FSBTODB(fs, indp) FFS_FSBTODB(fs, indp)
#endif
#ifndef FS_MAGIC
#define FS_MAGIC FS_UFS1_MAGIC
#endif
#ifndef UFS_NINDIR
#define UFS_NINDIR FFS_NINDIR
#endif
@ -214,17 +211,54 @@ static int search_directory(const char *, int, struct open_file *, ino32_t *);
static void ffs_oldfscompat(FS *);
#endif
#ifdef LIBSA_FFSv1
static __inline__ bool
ffs_is_magic(FS *fs)
{
return fs->fs_magic == FS_MAGIC;
return fs->fs_magic == FS_UFS1_MAGIC;
}
static __inline__ bool
ffs_is_magic_swapped(FS *fs)
{
return fs->fs_magic == bswap32(FS_UFS1_MAGIC);
}
#endif
#ifdef LIBSA_FFSv2
static __inline__ bool
ffs_is_magic(FS *fs)
{
return fs->fs_magic == FS_UFS2_MAGIC || fs->fs_magic == FS_UFS2EA_MAGIC;
}
static __inline__ bool
ffs_is_magic_swapped(FS *fs)
{
return fs->fs_magic == bswap32(FS_UFS2_MAGIC) ||
fs->fs_magic == bswap32(FS_UFS2EA_MAGIC);
}
#endif
#ifdef LIBSA_LFS
static __inline__ bool
ffs_is_magic(FS *fs)
{
return fs->fs_magic == LFS_MAGIC;
}
static __inline__ bool
ffs_is_magic_swapped(FS *fs)
{
return fs->fs_magic == bswap32(LFS_MAGIC);
}
#endif
static __inline__ void
ffs_fix_magic_swapped(struct file *fp, FS *fs)
{
#ifdef LIBSA_FFS_EI
fp->f_swapped = fs->fs_magic == bswap32(FS_MAGIC);
fp->f_swapped = ffs_is_magic_swapped(fs);
if (fp->f_swapped)
{
ffs_sb_swap(fs, fs);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_balloc.c,v 1.65 2020/09/05 16:30:13 riastradh Exp $ */
/* $NetBSD: ffs_balloc.c,v 1.66 2022/11/17 06:40:40 chs Exp $ */
/*
* Copyright (c) 2002 Networks Associates Technology, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c,v 1.65 2020/09/05 16:30:13 riastradh Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_balloc.c,v 1.66 2022/11/17 06:40:40 chs Exp $");
#if defined(_KERNEL_OPT)
#include "opt_quota.h"
@ -543,6 +543,8 @@ ffs_balloc_ufs2(struct vnode *vp, off_t off, int size, kauth_cred_t cred,
const int needswap = UFS_FSNEEDSWAP(fs);
UVMHIST_FUNC("ffs_balloc"); UVMHIST_CALLED(ubchist);
KASSERT((ump->um_flags & UFS_EA) != 0 || (flags & IO_EXT) == 0);
lbn = ffs_lblkno(fs, off);
size = ffs_blkoff(fs, off) + size;
if (size > fs->fs_bsize)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_extattr.c,v 1.8 2021/12/14 11:06:50 chs Exp $ */
/* $NetBSD: ffs_extattr.c,v 1.9 2022/11/17 06:40:40 chs Exp $ */
/*-
* SPDX-License-Identifier: (BSD-2-Clause-FreeBSD AND BSD-3-Clause)
@ -66,7 +66,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_extattr.c,v 1.8 2021/12/14 11:06:50 chs Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_extattr.c,v 1.9 2022/11/17 06:40:40 chs Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -464,6 +464,9 @@ ffs_open_ea(struct vnode *vp, kauth_cred_t cred)
int error;
ip = VTOI(vp);
if ((ip->i_ump->um_flags & UFS_EA) == 0) {
return EOPNOTSUPP;
}
ffs_lock_ea(vp);
if (ip->i_ea_area != NULL) {
@ -497,6 +500,7 @@ ffs_close_ea(struct vnode *vp, int commit, kauth_cred_t cred)
struct ufs2_dinode *dp;
ip = VTOI(vp);
KASSERT((ip->i_ump->um_flags & UFS_EA) != 0);
if (commit)
KASSERT(VOP_ISLOCKED(vp) == LK_EXCLUSIVE);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vfsops.c,v 1.377 2022/11/10 10:53:29 hannken Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.378 2022/11/17 06:40:40 chs Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.377 2022/11/10 10:53:29 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.378 2022/11/17 06:40:40 chs Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -845,6 +845,15 @@ ffs_reload(struct mount *mp, kauth_cred_t cred, struct lwp *l)
brelse(bp, 0);
/* Allow converting from UFS2 to UFS2EA but not vice versa. */
if (newfs->fs_magic == FS_UFS2EA_MAGIC) {
ump->um_flags |= UFS_EA;
newfs->fs_magic = FS_UFS2_MAGIC;
} else {
if ((ump->um_flags & UFS_EA) != 0)
return EINVAL;
}
if ((newfs->fs_magic != FS_UFS1_MAGIC) &&
(newfs->fs_magic != FS_UFS2_MAGIC)) {
kmem_free(newfs, fs_sbsize);
@ -1217,6 +1226,13 @@ ffs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
* size to read the superblock. Once read, we swap the whole
* superblock structure.
*/
if (fs->fs_magic == FS_UFS2EA_MAGIC) {
ump->um_flags |= UFS_EA;
fs->fs_magic = FS_UFS2_MAGIC;
} else if (fs->fs_magic == FS_UFS2EA_MAGIC_SWAPPED) {
ump->um_flags |= UFS_EA;
fs->fs_magic = FS_UFS2_MAGIC_SWAPPED;
}
if (fs->fs_magic == FS_UFS1_MAGIC) {
fs_sbsize = fs->fs_sbsize;
fstype = UFS1;
@ -2375,6 +2391,11 @@ ffs_sbupdate(struct ufsmount *mp, int waitfor)
memcpy(bp->b_data, fs, fs->fs_sbsize);
ffs_oldfscompat_write((struct fs *)bp->b_data, mp);
if (mp->um_flags & UFS_EA) {
struct fs *bfs = (struct fs *)bp->b_data;
KASSERT(bfs->fs_magic == FS_UFS2_MAGIC);
bfs->fs_magic = FS_UFS2EA_MAGIC;
}
#ifdef FFS_EI
if (mp->um_flags & UFS_NEEDSWAP)
ffs_sb_swap((struct fs *)bp->b_data, (struct fs *)bp->b_data);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fs.h,v 1.69 2021/09/18 03:05:20 christos Exp $ */
/* $NetBSD: fs.h,v 1.70 2022/11/17 06:40:40 chs Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -398,8 +398,10 @@ struct fs {
*/
#define FS_UFS1_MAGIC 0x011954 /* UFS1 fast file system magic number */
#define FS_UFS2_MAGIC 0x19540119 /* UFS2 fast file system magic number */
#define FS_UFS2EA_MAGIC 0x19012038 /* UFS2 with extattrs */
#define FS_UFS1_MAGIC_SWAPPED 0x54190100
#define FS_UFS2_MAGIC_SWAPPED 0x19015419
#define FS_UFS2EA_MAGIC_SWAPPED 0x38200119
#define FS_OKAY 0x7c269d38 /* superblock checksum */
#define FS_42INODEFMT -1 /* 4.2BSD inode format */
#define FS_44INODEFMT 2 /* 4.4BSD inode format */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_bmap.c,v 1.53 2020/04/20 03:57:02 christos Exp $ */
/* $NetBSD: ufs_bmap.c,v 1.54 2022/11/17 06:40:40 chs Exp $ */
/*
* Copyright (c) 1989, 1991, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ufs_bmap.c,v 1.53 2020/04/20 03:57:02 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: ufs_bmap.c,v 1.54 2022/11/17 06:40:40 chs Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -191,7 +191,7 @@ ufs_bmaparray(struct vnode *vp, daddr_t bn, daddr_t *bnp, struct indir *ap,
}
return (0);
} else if (bn < 0 && bn >= -UFS_NXADDR) {
KASSERT(ump->um_fstype == UFS2);
KASSERT(ump->um_fstype == UFS2 && (ump->um_flags & UFS_EA) != 0);
daddr = ufs_rw64(ip->i_ffs2_extb[-1 - bn], UFS_MPNEEDSWAP(ump));
*bnp = blkptrtodb(ump, daddr);
if (*bnp == 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufsmount.h,v 1.43 2015/03/27 17:27:56 riastradh Exp $ */
/* $NetBSD: ufsmount.h,v 1.44 2022/11/17 06:40:40 chs Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -163,6 +163,7 @@ struct ufs_ops {
#define UFS_ISAPPLEUFS 0x02 /* filesystem is Apple UFS */
#define UFS_QUOTA 0x04 /* filesystem has QUOTA (v1) */
#define UFS_QUOTA2 0x08 /* filesystem has QUOTA2 */
#define UFS_EA 0x10 /* UFS2 with extattrs */
/*
* Filesystem types

View File

@ -1,4 +1,4 @@
/* $NetBSD: t_extattr.c,v 1.2 2020/04/12 23:52:20 christos Exp $ */
/* $NetBSD: t_extattr.c,v 1.3 2022/11/17 06:40:40 chs Exp $ */
/*-
* Copyright (c) 2020 The NetBSD Foundation, Inc.
@ -29,7 +29,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: t_extattr.c,v 1.2 2020/04/12 23:52:20 christos Exp $");
__RCSID("$NetBSD: t_extattr.c,v 1.3 2022/11/17 06:40:40 chs Exp $");
#include <sys/types.h>
#include <sys/mount.h>
@ -78,8 +78,8 @@ check_list(const char *buf, ssize_t nr)
}
}
// Make it ffsv2
const char *newfs = "newfs -O 2 -F -s 10000 " IMGNAME;
// Make it ffsv2 with extattrs
const char *newfs = "newfs -O 2ea -F -s 10000 " IMGNAME;
#define FAKEBLK "/dev/formula1"
static void

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.2 2011/03/06 17:08:41 bouyer Exp $
# $NetBSD: Makefile,v 1.3 2022/11/17 06:40:40 chs Exp $
.include <bsd.own.mk>
@ -9,4 +9,6 @@ TESTS_SH+= ${name}
TESTS_SH_SRC_${name}= quotas_common.sh ${name}.sh
.endfor
TESTS_SH+= t_extattr
.include <bsd.test.mk>

View File

@ -0,0 +1,197 @@
# $NetBSD: t_extattr.sh,v 1.1 2022/11/17 06:40:40 chs Exp $
#
# Copyright (c) 2021 The NetBSD Foundation, Inc.
# 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.
#
# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
# ``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 FOUNDATION OR CONTRIBUTORS
# 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.
#
VND=vnd0
BDEV=/dev/${VND}a
CDEV=/dev/r${VND}a
IMG=fsimage
MNT=mnt
atf_test_case fsck_extattr_enable cleanup
atf_test_case fsck_extattr_enable_corrupted cleanup
atf_test_case fsck_extattr_disable cleanup
cleanup()
{
echo in cleanup
umount -f ${MNT} > /dev/null 2>&1 || true
vnconfig -u ${VND} > /dev/null 2>&1 || true
}
fsck_extattr_enable_head()
{
atf_set "descr" "Checks fsck_ffs enabling extattrs"
}
fsck_extattr_enable_body()
{
atf_check mkdir -p ${MNT}
atf_check -o ignore newfs -O2 -s 4m -F ${IMG}
atf_check vnconfig ${VND} ${IMG}
# Verify that extattrs are disabled.
atf_check -o ignore -e 'match:POSIX1e ACLs not supported by this fs' \
tunefs -p enable ${CDEV}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check touch ${MNT}/file
atf_check -s exit:1 -e ignore setextattr user name1 value1 ${MNT}/file
atf_check umount ${MNT}
# Enable extattrs.
atf_check -o 'match:ENABLING EXTATTR SUPPORT' \
fsck_ffs -c ea ${CDEV}
# Verify that extattrs are now enabled.
atf_check -o 'match:POSIX1e ACLs set' -e ignore \
tunefs -p enable ${CDEV}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check touch ${MNT}/file
atf_check setextattr user testname testvalue ${MNT}/file
atf_check -o 'match:testvalue' getextattr user testname ${MNT}/file
atf_check umount ${MNT}
atf_check vnconfig -u ${VND}
}
fsck_extattr_enable_cleanup()
{
cleanup
}
fsck_extattr_enable_corrupted_head()
{
atf_set "descr" "Checks fsck_ffs enabling extattrs with corruption"
}
fsck_extattr_enable_corrupted_body()
{
atf_check mkdir -p ${MNT}
# Create an fs with extattrs enabled and set an extattr on the test file.
atf_check -o ignore newfs -O2ea -b 8k -f 1k -s 4m -F ${IMG}
atf_check vnconfig ${VND} ${IMG}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check touch ${MNT}/file
atf_check setextattr user testname testvalue ${MNT}/file
atf_check -o 'match:testvalue' getextattr user testname ${MNT}/file
atf_check umount ${MNT}
# Find the location and size of the extattr block.
extb0=$(printf 'cd file\niptrs\n' | fsdb -n $CDEV | grep 'di_extb 0' |
awk '{print $3}')
extsize=$(printf 'cd file\n' | fsdb -n $CDEV | grep EXTSIZE | tail -1 |
awk '{print $4}' | sed 's,.*=,,')
atf_check [ $extb0 != 0 ]
atf_check [ $extsize != 0 ]
# Recreate the fs with extattrs disabled and set the extattr block
# size/location of the new test file to the same values as the old
# test file. This simulates extattrs having been created in a
# UFS2-non-ea file system before UFS2ea was invented.
atf_check -o ignore newfs -O2 -b 8k -f 1k -s 4m -F ${IMG}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check touch ${MNT}/file
atf_check umount ${MNT}
printf "cd file\nchextb 0 $extb0\n" | fsdb -N $CDEV
printf "cd file\nchextsize $extsize\n" | fsdb -N $CDEV
# Convert to enable extattrs.
atf_check -o 'match:CLEAR EXTATTR FIELDS' \
-o 'match:ENABLING EXTATTR SUPPORT' \
fsck_ffs -y -c ea ${CDEV}
# Verify that the test file does not have the extattr.
atf_check -o ignore fsck -n ${CDEV}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check -s exit:1 -e 'match:Attribute not found' \
getextattr user testname ${MNT}/file
atf_check umount ${MNT}
atf_check vnconfig -u ${VND}
}
fsck_extattr_enable_corrupted_cleanup()
{
cleanup
}
fsck_extattr_disable_head()
{
atf_set "descr" "Checks fsck_ffs disabling extattrs"
}
fsck_extattr_disable_body()
{
atf_check mkdir -p ${MNT}
# Create an fs with extattrs enabled and set an extattr on the test file.
atf_check -o ignore newfs -O2ea -b 8k -f 1k -s 4m -F ${IMG}
atf_check vnconfig ${VND} ${IMG}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check touch ${MNT}/file
atf_check setextattr user testname testvalue ${MNT}/file
atf_check -o 'match:testvalue' getextattr user testname ${MNT}/file
atf_check umount ${MNT}
# Convert to disable extattrs.
atf_check -o 'match:CLEAR EXTATTR FIELDS' \
-o 'match:DISABLING EXTATTR SUPPORT' \
fsck_ffs -y -c no-ea ${CDEV}
# Verify that the test file does not have the test extattr.
atf_check -o ignore fsck -n ${CDEV}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check -s exit:1 -e 'match:getextattr: mnt/file: failed: Operation not supported' \
getextattr user testname ${MNT}/file
atf_check umount ${MNT}
# Convert to enable extattrs again.
atf_check -o 'match:ENABLING EXTATTR SUPPORT' \
fsck_ffs -y -c ea ${CDEV}
# Verify that the test extattr is still gone.
atf_check -o ignore fsck -n ${CDEV}
atf_check mount -t ffs ${BDEV} ${MNT}
atf_check -s exit:1 -e 'match:Attribute not found' \
getextattr user testname ${MNT}/file
atf_check umount ${MNT}
atf_check vnconfig -u ${VND}
}
fsck_extattr_disable_cleanup()
{
cleanup
}
atf_init_test_cases()
{
atf_add_test_case fsck_extattr_enable
atf_add_test_case fsck_extattr_enable_corrupted
atf_add_test_case fsck_extattr_disable
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: dumpfs.c,v 1.65 2021/09/18 03:05:20 christos Exp $ */
/* $NetBSD: dumpfs.c,v 1.66 2022/11/17 06:40:40 chs Exp $ */
/*
* Copyright (c) 1983, 1992, 1993
@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1992, 1993\
#if 0
static char sccsid[] = "@(#)dumpfs.c 8.5 (Berkeley) 4/29/95";
#else
__RCSID("$NetBSD: dumpfs.c,v 1.65 2021/09/18 03:05:20 christos Exp $");
__RCSID("$NetBSD: dumpfs.c,v 1.66 2022/11/17 06:40:40 chs Exp $");
#endif
#endif /* not lint */
@ -192,11 +192,13 @@ dumpfs(const char *name)
if (read(fd, &afs, SBLOCKSIZE) != SBLOCKSIZE)
continue;
switch(afs.fs_magic) {
case FS_UFS2EA_MAGIC:
case FS_UFS2_MAGIC:
is_ufs2 = 1;
break;
case FS_UFS1_MAGIC:
break;
case FS_UFS2EA_MAGIC_SWAPPED:
case FS_UFS2_MAGIC_SWAPPED:
is_ufs2 = 1;
needswap = 1;
@ -294,7 +296,8 @@ print_superblock(struct fs *fs, uint16_t *opostbl,
time_t t;
int32_t fsflags;
printf("format\tFFSv%d\n", is_ufs2+1);
printf("format\tFFSv%d%s\n", is_ufs2+1,
fs->fs_magic == FS_UFS2EA_MAGIC ? "ea" : "");
#if BYTE_ORDER == LITTLE_ENDIAN
if (needswap)
#else

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs.c,v 1.1 2018/01/09 03:31:15 christos Exp $ */
/* $NetBSD: ufs.c,v 1.2 2022/11/17 06:40:40 chs Exp $ */
/*-
* Copyright (c) 2017 The NetBSD Foundation, Inc.
@ -36,7 +36,7 @@
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__RCSID("$NetBSD: ufs.c,v 1.1 2018/01/09 03:31:15 christos Exp $");
__RCSID("$NetBSD: ufs.c,v 1.2 2022/11/17 06:40:40 chs Exp $");
#include <sys/types.h>
#include <stdint.h>
@ -67,6 +67,12 @@ fstyp_ufs(FILE *fp, char *label, size_t labelsize)
fs = (struct fs *)read_buf(fp, superblock, SBLOCKSIZE);
if (fs == NULL)
continue;
if (fs->fs_magic == FS_UFS2EA_MAGIC)
fs->fs_magic = FS_UFS2_MAGIC;
else if (fs->fs_magic == FS_UFS2EA_MAGIC_SWAPPED)
fs->fs_magic = FS_UFS2_MAGIC_SWAPPED;
/*
* Check for magic. We also need to check if file system size
* is equal to providers size, because sysinstall(8) used to

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs.c,v 1.32 2013/06/23 02:06:06 dholland Exp $ */
/* $NetBSD: ffs.c,v 1.33 2022/11/17 06:40:40 chs Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if !defined(__lint)
__RCSID("$NetBSD: ffs.c,v 1.32 2013/06/23 02:06:06 dholland Exp $");
__RCSID("$NetBSD: ffs.c,v 1.33 2022/11/17 06:40:40 chs Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -502,6 +502,7 @@ ffs_match_common(ib_params *params, off_t offset)
continue;
switch (fs->fs_magic) {
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC:
@ -512,6 +513,7 @@ ffs_match_common(ib_params *params, off_t offset)
break;
#ifndef FFS_NO_SWAP
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
is_ufs2 = 1;
/* FALLTHROUGH */
case FS_UFS1_MAGIC_SWAPPED:

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs.c,v 1.72 2022/04/09 10:05:35 riastradh Exp $ */
/* $NetBSD: ffs.c,v 1.73 2022/11/17 06:40:41 chs Exp $ */
/*
* Copyright (c) 2001 Wasabi Systems, Inc.
@ -71,7 +71,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: ffs.c,v 1.72 2022/04/09 10:05:35 riastradh Exp $");
__RCSID("$NetBSD: ffs.c,v 1.73 2022/11/17 06:40:41 chs Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -180,6 +180,8 @@ ffs_prep_opts(fsinfo_t *fsopts)
0, 0, "Optimization (time|space)" },
{ 'l', "label", ffs_opts->label, OPT_STRARRAY,
1, sizeof(ffs_opts->label), "UFS label" },
{ 'e', "extattr", &ffs_opts->extattr, OPT_INT32,
0, 1, "extattr support" },
{ .name = NULL }
};
@ -194,6 +196,7 @@ ffs_prep_opts(fsinfo_t *fsopts)
ffs_opts->avgfilesize= -1;
ffs_opts->avgfpdir= -1;
ffs_opts->version = 1;
ffs_opts->extattr = 1;
fsopts->fs_specific = ffs_opts;
fsopts->fs_options = copy_opts(ffs_options);

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs.h,v 1.2 2011/10/09 21:33:43 christos Exp $ */
/* $NetBSD: ffs.h,v 1.3 2022/11/17 06:40:41 chs Exp $ */
/*
* Copyright (c) 2001-2003 Wasabi Systems, Inc.
@ -60,6 +60,7 @@ typedef struct {
int avgfilesize; /* expected average file size */
int avgfpdir; /* expected # of files per directory */
int version; /* filesystem version (1 = FFS, 2 = UFS2) */
int extattr; /* use UFS2ea magic */
int maxbsize; /* maximum extent size */
int maxblkspercg; /* max # of blocks per cylinder group */
/* XXX: support `old' file systems ? */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_balloc.c,v 1.21 2015/03/29 05:52:59 agc Exp $ */
/* $NetBSD: ffs_balloc.c,v 1.22 2022/11/17 06:40:41 chs Exp $ */
/* From NetBSD: ffs_balloc.c,v 1.25 2001/08/08 08:36:36 lukem Exp */
/*
@ -38,7 +38,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(__lint)
__RCSID("$NetBSD: ffs_balloc.c,v 1.21 2015/03/29 05:52:59 agc Exp $");
__RCSID("$NetBSD: ffs_balloc.c,v 1.22 2022/11/17 06:40:41 chs Exp $");
#endif /* !__lint */
#include <sys/param.h>
@ -74,7 +74,8 @@ static int ffs_balloc_ufs2(struct inode *, off_t, int, struct buf **);
int
ffs_balloc(struct inode *ip, off_t offset, int bufsize, struct buf **bpp)
{
if (ip->i_fs->fs_magic == FS_UFS2_MAGIC)
if (ip->i_fs->fs_magic == FS_UFS2_MAGIC ||
ip->i_fs->fs_magic == FS_UFS2EA_MAGIC)
return ffs_balloc_ufs2(ip, offset, bufsize, bpp);
else
return ffs_balloc_ufs1(ip, offset, bufsize, bpp);

View File

@ -1,4 +1,4 @@
/* $NetBSD: mkfs.c,v 1.40 2022/04/02 19:16:49 mlelstv Exp $ */
/* $NetBSD: mkfs.c,v 1.41 2022/11/17 06:40:41 chs Exp $ */
/*
* Copyright (c) 2002 Networks Associates Technology, Inc.
@ -48,7 +48,7 @@
static char sccsid[] = "@(#)mkfs.c 8.11 (Berkeley) 5/3/95";
#else
#ifdef __RCSID
__RCSID("$NetBSD: mkfs.c,v 1.40 2022/04/02 19:16:49 mlelstv Exp $");
__RCSID("$NetBSD: mkfs.c,v 1.41 2022/11/17 06:40:41 chs Exp $");
#endif
#endif
#endif /* not lint */
@ -109,6 +109,7 @@ union {
#define writebuf wb.pad
static int Oflag; /* format as an 4.3BSD file system */
static int extattr; /* use UFS2ea magic */
static int64_t fssize; /* file system size */
static int sectorsize; /* bytes/sector */
static int fsize; /* fragment size */
@ -148,6 +149,7 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp)
ffs_opt_t *ffs_opts = fsopts->fs_specific;
Oflag = ffs_opts->version;
extattr = ffs_opts->extattr;
fssize = fsopts->size / fsopts->sectorsize;
sectorsize = fsopts->sectorsize;
fsize = ffs_opts->fsize;
@ -296,7 +298,10 @@ ffs_mkfs(const char *fsys, const fsinfo_t *fsopts, time_t tstamp)
sblock.fs_old_postblformat = 1;
sblock.fs_old_nrpos = 1;
} else {
sblock.fs_magic = FS_UFS2_MAGIC;
if (extattr)
sblock.fs_magic = FS_UFS2EA_MAGIC;
else
sblock.fs_magic = FS_UFS2_MAGIC;
#if 0 /* XXX makefs is used for small filesystems. */
sblock.fs_sblockloc = SBLOCK_UFS2;
#else

View File

@ -1,4 +1,4 @@
.\" $NetBSD: makefs.8,v 1.70 2022/04/06 13:39:06 wiz Exp $
.\" $NetBSD: makefs.8,v 1.71 2022/11/17 06:40:41 chs Exp $
.\"
.\" Copyright (c) 2001-2003 Wasabi Systems, Inc.
.\" All rights reserved.
@ -304,6 +304,8 @@ Expected number of files per directory.
Block size.
.It Sy density
Bytes per inode.
.It Sy extattr
UFS2 with extended attributes.
.It Sy extent
Maximum extent size.
.It Sy fsize

View File

@ -1,4 +1,4 @@
/* $NetBSD: quot.c,v 1.34 2016/07/28 08:24:58 martin Exp $ */
/* $NetBSD: quot.c,v 1.35 2022/11/17 06:40:41 chs Exp $ */
/*
* Copyright (C) 1991, 1994 Wolfgang Solfrank.
@ -33,7 +33,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: quot.c,v 1.34 2016/07/28 08:24:58 martin Exp $");
__RCSID("$NetBSD: quot.c,v 1.35 2022/11/17 06:40:41 chs Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -569,10 +569,12 @@ quot(const char *name, const char *mp)
fs = (struct fs *)superblock;
if (fs->fs_magic != FS_UFS1_MAGIC &&
fs->fs_magic != FS_UFS2_MAGIC)
fs->fs_magic != FS_UFS2_MAGIC &&
fs->fs_magic != FS_UFS2EA_MAGIC)
continue;
if (fs->fs_magic == FS_UFS2_MAGIC
|| fs->fs_magic == FS_UFS2EA_MAGIC
|| fs->fs_old_flags & FS_FLAGS_UPDATED) {
/* Not the main superblock */
if (fs->fs_sblockloc != sbloc)

View File

@ -1,4 +1,4 @@
/* $NetBSD: quotacheck.c,v 1.49 2015/06/16 23:04:14 christos Exp $ */
/* $NetBSD: quotacheck.c,v 1.50 2022/11/17 06:40:41 chs Exp $ */
/*
* Copyright (c) 1980, 1990, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1980, 1990, 1993\
#if 0
static char sccsid[] = "@(#)quotacheck.c 8.6 (Berkeley) 4/28/95";
#else
__RCSID("$NetBSD: quotacheck.c,v 1.49 2015/06/16 23:04:14 christos Exp $");
__RCSID("$NetBSD: quotacheck.c,v 1.50 2022/11/17 06:40:41 chs Exp $");
#endif
#endif /* not lint */
@ -367,6 +367,9 @@ chkquota(const char *type, const char *fsname, const char *mntpt, void *v,
bread(sblock_try[i], (char *)&sblock, SBLOCKSIZE);
switch (sblock.fs_magic) {
#ifdef HAVE_UFSv2
case FS_UFS2EA_MAGIC:
sblock.fs_magic = FS_UFS2_MAGIC;
/*FALLTHROUGH*/
case FS_UFS2_MAGIC:
is_ufs2 = 1;
/*FALLTHROUGH*/
@ -374,6 +377,9 @@ chkquota(const char *type, const char *fsname, const char *mntpt, void *v,
case FS_UFS1_MAGIC:
break;
#ifdef HAVE_UFSv2
case FS_UFS2EA_MAGIC_SWAPPED:
sblock.fs_magic = FS_UFS2_MAGIC_SWAPPED;
/*FALLTHROUGH*/
case FS_UFS2_MAGIC_SWAPPED:
is_ufs2 = 1;
/*FALLTHROUGH*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: label.c,v 1.41 2022/06/21 15:46:10 martin Exp $ */
/* $NetBSD: label.c,v 1.42 2022/11/17 06:40:41 chs Exp $ */
/*
* Copyright 1997 Jonathan Stone
@ -36,7 +36,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: label.c,v 1.41 2022/06/21 15:46:10 martin Exp $");
__RCSID("$NetBSD: label.c,v 1.42 2022/11/17 06:40:41 chs Exp $");
#endif
#include <sys/types.h>
@ -2023,7 +2023,9 @@ get_last_mounted(int fd, daddr_t partstart, uint *fs_type, uint *fs_sub_type,
*fs_sub_type = 1;
continue;
case FS_UFS2_MAGIC:
case FS_UFS2EA_MAGIC:
case FS_UFS2_MAGIC_SWAPPED:
case FS_UFS2EA_MAGIC_SWAPPED:
/* Check we have the main superblock */
if (SB->fs_sblockloc == *sbp) {
mnt = (const char *)SB->fs_fsmnt;