Update from 4.4-Lite, with local changes.
This commit is contained in:
parent
175ecf65e1
commit
ccfa3742b5
@ -1,5 +1,5 @@
|
||||
# from: @(#)Makefile 5.16 (Berkeley) 7/15/92
|
||||
# $Id: Makefile,v 1.13 1993/12/22 10:24:34 cgd Exp $
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.14 1994/06/08 18:57:30 mycroft Exp $
|
||||
|
||||
# dump.h header file
|
||||
# itime.c reads /etc/dumpdates
|
||||
|
@ -1,4 +1,5 @@
|
||||
.\" Copyright (c) 1980, 1991 Regents of the University of California.
|
||||
.\" Copyright (c) 1980, 1991, 1993
|
||||
.\" Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
@ -29,10 +30,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)dump.8 6.10 (Berkeley) 6/20/92
|
||||
.\" $Id: dump.8,v 1.8 1994/01/28 20:07:07 jtc Exp $
|
||||
.\" from: @(#)dump.8 8.1 (Berkeley) 6/16/93
|
||||
.\" $Id: dump.8,v 1.9 1994/06/08 18:57:31 mycroft Exp $
|
||||
.\"
|
||||
.Dd June 20, 1992
|
||||
.Dd June 16, 1993
|
||||
.Dt DUMP 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
@ -40,7 +41,7 @@
|
||||
.Nd filesystem backup
|
||||
.Sh SYNOPSIS
|
||||
.Nm dump
|
||||
.Op Cm 0123456789fusTdWn Op Ar argument ...
|
||||
.Op Cm 0123456789BbhfusTdWn Op Ar argument ...
|
||||
.Op Ar filesystem
|
||||
.Sh DESCRIPTION
|
||||
.Nm Dump
|
||||
@ -70,14 +71,33 @@ The following options are supported by
|
||||
.It Cm 0\-9
|
||||
Dump levels.
|
||||
A level 0, full backup,
|
||||
guarantees the entire file system is copied.
|
||||
guarantees the entire file system is copied
|
||||
(but see also the
|
||||
.Cm h
|
||||
option below).
|
||||
A level number above 0,
|
||||
incremental backup,
|
||||
tells dump to
|
||||
copy all files new or modified since the
|
||||
last dump of the same or lower level. The default
|
||||
level is 9.
|
||||
.It Cm f Op Ar file
|
||||
.It Cm B Ar records
|
||||
The number of dump records per volume.
|
||||
This option overrides the calculation of tape size
|
||||
based on length and density.
|
||||
.It Cm b Ar blocksize
|
||||
The number of kilobytes per dump record.
|
||||
.It Cm h Ar level
|
||||
Honor the user
|
||||
.Dq nodump
|
||||
flag
|
||||
.Dp Dv UF_NODUMP
|
||||
only for dumps at or above the given
|
||||
.Ar level .
|
||||
The default honor level is 1,
|
||||
so that incremental backups omit such files
|
||||
but full backups retain them.
|
||||
.It Cm f Ar file
|
||||
Write the backup to
|
||||
.Ar file ;
|
||||
.Ar file
|
||||
@ -98,6 +118,8 @@ the last file name will used for all remaining volumes after prompting
|
||||
for media changes.
|
||||
If the name of the file is of the form
|
||||
.Dq host:file ,
|
||||
or
|
||||
.Dq user@host:file ,
|
||||
.Nm dump
|
||||
writes to the named file on the remote host using
|
||||
.Xr rmt 8 .
|
||||
@ -121,9 +143,6 @@ If this amount is exceeded,
|
||||
prompts for a new tape.
|
||||
It is recommended to be a bit conservative on this option.
|
||||
The default tape length is 2300 feet.
|
||||
.It Cm B Ar blocks
|
||||
Set the size of the dump file to the specified number of 1024-byte blocks,
|
||||
superseding the tape size and density.
|
||||
.It Cm u
|
||||
Update the file
|
||||
.Pa /etc/dumpdates
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -30,8 +30,8 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)dump.h 5.21 (Berkeley) 7/16/92
|
||||
* $Id: dump.h,v 1.6 1993/12/22 10:24:39 cgd Exp $
|
||||
* from: @(#)dump.h 8.1 (Berkeley) 6/5/93
|
||||
* $Id: dump.h,v 1.7 1994/06/08 18:57:33 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define MAXINOPB (MAXBSIZE / sizeof(struct dinode))
|
||||
@ -74,6 +74,7 @@ long tapesize; /* estimated tape size, blocks */
|
||||
long tsize; /* tape size in 0.1" units */
|
||||
long asize; /* number of 0.1" units written on current tape */
|
||||
int etapes; /* estimated number of tapes */
|
||||
int nonodump; /* if set, do not honor UF_NODUMP user flags */
|
||||
|
||||
int notify; /* notify operator flag */
|
||||
int blockswritten; /* number of blocks written on current tape */
|
||||
@ -85,6 +86,10 @@ long dev_bsize; /* block size of underlying disk device */
|
||||
int dev_bshift; /* log2(dev_bsize) */
|
||||
int tp_bshift; /* log2(TP_BSIZE) */
|
||||
|
||||
#ifndef __P
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
/* operator interface functions */
|
||||
void broadcast __P((char *message));
|
||||
void lastdump __P((int arg)); /* int should be char */
|
||||
@ -113,18 +118,25 @@ void writeheader __P((ino_t ino));
|
||||
int alloctape __P((void));
|
||||
void close_rewind __P((void));
|
||||
void dumpblock __P((daddr_t blkno, int size));
|
||||
void flushtape __P((void));
|
||||
void startnewtape __P((int top));
|
||||
void trewind __P((void));
|
||||
void writerec __P((char *dp, int isspcl));
|
||||
|
||||
void Exit __P((int status));
|
||||
__dead void Exit __P((int status));
|
||||
void dumpabort __P((int signo));
|
||||
void getfstab __P((void));
|
||||
|
||||
char *rawname __P((char *cp));
|
||||
struct dinode *getino __P((ino_t inum));
|
||||
|
||||
/* rdump routines */
|
||||
#ifdef RDUMP
|
||||
void rmtclose __P((void));
|
||||
int rmthost __P((char *host));
|
||||
int rmtopen __P((char *tape, int mode));
|
||||
int rmtwrite __P((char *buf, int count));
|
||||
#endif /* RDUMP */
|
||||
|
||||
void interrupt __P((int signo)); /* in case operator bangs on console */
|
||||
|
||||
/*
|
||||
@ -171,14 +183,21 @@ void sig __P((int signo));
|
||||
/*
|
||||
* Compatibility with old systems.
|
||||
*/
|
||||
#ifndef __STDC__
|
||||
#ifdef COMPAT
|
||||
#include <sys/file.h>
|
||||
#define _PATH_FSTAB "/etc/fstab"
|
||||
extern char *index(), *strdup();
|
||||
extern char *index(), *rindex(), *strdup();
|
||||
extern char *ctime();
|
||||
extern int read(), write();
|
||||
extern int errno;
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_UTMP
|
||||
#define _PATH_UTMP "/etc/utmp"
|
||||
#endif
|
||||
#ifndef _PATH_FSTAB
|
||||
#define _PATH_FSTAB "/etc/fstab"
|
||||
#endif
|
||||
|
||||
#ifdef sunos
|
||||
extern char *calloc();
|
||||
extern char *malloc();
|
||||
@ -188,7 +207,7 @@ extern char *strncpy();
|
||||
extern char *strcat();
|
||||
extern time_t time();
|
||||
extern void endgrent();
|
||||
extern void exit();
|
||||
extern __dead void exit();
|
||||
extern off_t lseek();
|
||||
extern char *strerror();
|
||||
extern const char *strerror();
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,65 +32,69 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)dumprmt.c 5.15 (Berkeley) 6/18/92"; */
|
||||
static char *rcsid = "$Id: dumprmt.c,v 1.5 1993/12/22 10:24:42 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)dumprmt.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: dumprmt.c,v 1.6 1994/06/08 18:57:34 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef sunos
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/mtio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/mtio.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#ifdef sunos
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/inode.h>
|
||||
#else
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#endif
|
||||
#include <ufs/dinode.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <netdb.h>
|
||||
#include <protocols/dumprestore.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <netdb.h>
|
||||
#include <pwd.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "pathnames.h"
|
||||
#include "dump.h"
|
||||
|
||||
#define TS_CLOSED 0
|
||||
#define TS_OPEN 1
|
||||
|
||||
static int rmtstate = TS_CLOSED;
|
||||
int rmtape;
|
||||
void rmtgetconn();
|
||||
void rmtconnaborted();
|
||||
int rmtreply();
|
||||
int rmtgetb();
|
||||
void rmtgets();
|
||||
int rmtcall();
|
||||
char *rmtpeer;
|
||||
static int rmtape;
|
||||
static char *rmtpeer;
|
||||
|
||||
extern int ntrec; /* blocking factor on tape */
|
||||
extern void msg();
|
||||
static int okname __P((char *));
|
||||
static int rmtcall __P((char *, char *));
|
||||
static void rmtconnaborted __P((/* int, int */));
|
||||
static int rmtgetb __P((void));
|
||||
static void rmtgetconn __P((void));
|
||||
static void rmtgets __P((char *, int));
|
||||
static int rmtreply __P((char *));
|
||||
|
||||
extern void exit();
|
||||
extern int ntrec; /* blocking factor on tape */
|
||||
|
||||
int
|
||||
rmthost(host)
|
||||
char *host;
|
||||
{
|
||||
|
||||
rmtpeer = host;
|
||||
rmtpeer = malloc(strlen(host) + 1);
|
||||
if (rmtpeer)
|
||||
strcpy(rmtpeer, host);
|
||||
else
|
||||
rmtpeer = host;
|
||||
signal(SIGPIPE, rmtconnaborted);
|
||||
rmtgetconn();
|
||||
if (rmtape < 0)
|
||||
@ -98,39 +102,86 @@ rmthost(host)
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
rmtconnaborted()
|
||||
{
|
||||
|
||||
(void) fprintf(stderr, "rdump: Lost connection to remote host.\n");
|
||||
(void) exit(1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
rmtgetconn()
|
||||
{
|
||||
static struct servent *sp = 0;
|
||||
struct passwd *pw;
|
||||
char *name = "root";
|
||||
register char *cp;
|
||||
static struct servent *sp = NULL;
|
||||
static struct passwd *pwd = NULL;
|
||||
#ifdef notdef
|
||||
static int on = 1;
|
||||
#endif
|
||||
char *tuser;
|
||||
int size;
|
||||
int maxseg;
|
||||
|
||||
if (sp == 0) {
|
||||
if (sp == NULL) {
|
||||
sp = getservbyname("shell", "tcp");
|
||||
if (sp == 0) {
|
||||
if (sp == NULL) {
|
||||
(void) fprintf(stderr,
|
||||
"rdump: shell/tcp: unknown service\n");
|
||||
(void) exit(1);
|
||||
exit(1);
|
||||
}
|
||||
pwd = getpwuid(getuid());
|
||||
if (pwd == NULL) {
|
||||
(void) fprintf(stderr, "rdump: who are you?\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
pw = getpwuid(getuid());
|
||||
if (pw && pw->pw_name)
|
||||
name = pw->pw_name;
|
||||
rmtape = rcmd(&rmtpeer, (u_short)sp->s_port, name, name, _PATH_RMT,
|
||||
(int *)0);
|
||||
if ((cp = index(rmtpeer, '@')) != NULL) {
|
||||
tuser = rmtpeer;
|
||||
*cp = '\0';
|
||||
if (!okname(tuser))
|
||||
exit(1);
|
||||
rmtpeer = ++cp;
|
||||
} else
|
||||
tuser = pwd->pw_name;
|
||||
rmtape = rcmd(&rmtpeer, (u_short)sp->s_port, pwd->pw_name, tuser,
|
||||
_PATH_RMT, (int *)0);
|
||||
size = ntrec * TP_BSIZE;
|
||||
if (size > 60 * 1024) /* XXX */
|
||||
size = 60 * 1024;
|
||||
/* Leave some space for rmt request/response protocol */
|
||||
size += 2 * 1024;
|
||||
while (size > TP_BSIZE &&
|
||||
setsockopt(rmtape, SOL_SOCKET, SO_SNDBUF, &size, sizeof (size)) < 0)
|
||||
size -= TP_BSIZE;
|
||||
size -= TP_BSIZE;
|
||||
(void)setsockopt(rmtape, SOL_SOCKET, SO_RCVBUF, &size, sizeof (size));
|
||||
maxseg = 1024;
|
||||
if (setsockopt(rmtape, IPPROTO_TCP, TCP_MAXSEG,
|
||||
&maxseg, sizeof (maxseg)) < 0)
|
||||
perror("TCP_MAXSEG setsockopt");
|
||||
|
||||
#ifdef notdef
|
||||
if (setsockopt(rmtape, IPPROTO_TCP, TCP_NODELAY, &on, sizeof (on)) < 0)
|
||||
perror("TCP_NODELAY setsockopt");
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
okname(cp0)
|
||||
char *cp0;
|
||||
{
|
||||
register char *cp;
|
||||
register int c;
|
||||
|
||||
for (cp = cp0; *cp; cp++) {
|
||||
c = *cp;
|
||||
if (!isascii(c) || !(isalnum(c) || c == '_' || c == '-')) {
|
||||
(void) fprintf(stderr, "rdump: invalid user name %s\n",
|
||||
cp0);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
@ -237,7 +288,7 @@ rmtstatus()
|
||||
register char *cp;
|
||||
|
||||
if (rmtstate != TS_OPEN)
|
||||
return (0);
|
||||
return (NULL);
|
||||
rmtcall("status", "S\n");
|
||||
for (i = 0, cp = (char *)&mts; i < sizeof(mts); i++)
|
||||
*cp++ = rmtgetb();
|
||||
@ -256,7 +307,7 @@ rmtioctl(cmd, count)
|
||||
return (rmtcall("ioctl", buf));
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
rmtcall(cmd, buf)
|
||||
char *cmd, *buf;
|
||||
{
|
||||
@ -266,16 +317,17 @@ rmtcall(cmd, buf)
|
||||
return (rmtreply(cmd));
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
rmtreply(cmd)
|
||||
char *cmd;
|
||||
{
|
||||
register char *cp;
|
||||
char code[30], emsg[BUFSIZ];
|
||||
|
||||
rmtgets(code, sizeof (code));
|
||||
if (*code == 'E' || *code == 'F') {
|
||||
rmtgets(emsg, sizeof (emsg));
|
||||
msg("%s: %s\n", cmd, emsg, code + 1);
|
||||
msg("%s: %s", cmd, emsg);
|
||||
if (*code == 'F') {
|
||||
rmtstate = TS_CLOSED;
|
||||
return (-1);
|
||||
@ -283,7 +335,12 @@ rmtreply(cmd)
|
||||
return (-1);
|
||||
}
|
||||
if (*code != 'A') {
|
||||
msg("Protocol to remote tape server botched (code %s?).\n",
|
||||
/* Kill trailing newline */
|
||||
cp = code + strlen(code);
|
||||
if (cp > code && *--cp == '\n')
|
||||
*cp = '\0';
|
||||
|
||||
msg("Protocol to remote tape server botched (code \"%s\").\n",
|
||||
code);
|
||||
rmtconnaborted();
|
||||
}
|
||||
@ -300,21 +357,25 @@ rmtgetb()
|
||||
return (c);
|
||||
}
|
||||
|
||||
/* Get a line (guaranteed to have a trailing newline). */
|
||||
void
|
||||
rmtgets(cp, len)
|
||||
char *cp;
|
||||
rmtgets(line, len)
|
||||
char *line;
|
||||
int len;
|
||||
{
|
||||
register char *cp = line;
|
||||
|
||||
while (len > 1) {
|
||||
*cp = rmtgetb();
|
||||
if (*cp == '\n') {
|
||||
cp[1] = 0;
|
||||
cp[1] = '\0';
|
||||
return;
|
||||
}
|
||||
cp++;
|
||||
len--;
|
||||
}
|
||||
msg("Protocol to remote tape server botched (in rmtgets).\n");
|
||||
*cp = '\0';
|
||||
msg("Protocol to remote tape server botched.\n");
|
||||
msg("(rmtgets got \"%s\").\n", line);
|
||||
rmtconnaborted();
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,31 +32,33 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)itime.c 5.15 (Berkeley) 6/18/92"; */
|
||||
static char *rcsid = "$Id: itime.c,v 1.1 1993/12/22 10:24:44 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)itime.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: itime.c,v 1.2 1994/06/08 18:57:35 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef sunos
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ufs/fs.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef sunos
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/fsdir.h>
|
||||
#include <ufs/inode.h>
|
||||
#include <ufs/fs.h>
|
||||
#else
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#endif
|
||||
#include <ufs/dinode.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <protocols/dumprestore.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "dump.h"
|
||||
|
||||
struct dumpdates **ddatev = 0;
|
||||
@ -64,11 +66,10 @@ int nddates = 0;
|
||||
int ddates_in = 0;
|
||||
struct dumptime *dthead = 0;
|
||||
|
||||
void readdumptimes();
|
||||
int getrecord();
|
||||
int makedumpdate();
|
||||
|
||||
static void dumprecout();
|
||||
static void dumprecout __P((FILE *, struct dumpdates *));
|
||||
static int getrecord __P((FILE *, struct dumpdates *));
|
||||
static int makedumpdate __P((struct dumpdates *, char *));
|
||||
static void readdumptimes __P((FILE *));
|
||||
|
||||
void
|
||||
initdumptimes()
|
||||
@ -102,7 +103,7 @@ initdumptimes()
|
||||
(void) fclose(df);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
readdumptimes(df)
|
||||
FILE *df;
|
||||
{
|
||||
@ -233,7 +234,8 @@ dumprecout(file, what)
|
||||
}
|
||||
|
||||
int recno;
|
||||
int
|
||||
|
||||
static int
|
||||
getrecord(df, ddatep)
|
||||
FILE *df;
|
||||
struct dumpdates *ddatep;
|
||||
@ -255,12 +257,12 @@ getrecord(df, ddatep)
|
||||
return(0);
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
makedumpdate(ddp, tbuf)
|
||||
struct dumpdates *ddp;
|
||||
char *tbuf;
|
||||
{
|
||||
char un_buf[32];
|
||||
char un_buf[128];
|
||||
|
||||
(void) sscanf(tbuf, DUMPINFMT, ddp->dd_name, &ddp->dd_level, un_buf);
|
||||
ddp->dd_ddate = unctime(un_buf);
|
||||
|
356
sbin/dump/main.c
356
sbin/dump/main.c
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1991, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,45 +32,49 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1980, 1991 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1980, 1991, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)main.c 5.24 (Berkeley) 7/16/92"; */
|
||||
static char *rcsid = "$Id: main.c,v 1.2 1994/03/28 01:50:05 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)main.c 8.4 (Berkeley) 4/15/94";*/
|
||||
static char *rcsid = "$Id: main.c,v 1.3 1994/06/08 18:57:36 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef sunos
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ufs/fs.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#ifdef sunos
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/inode.h>
|
||||
#include <ufs/fs.h>
|
||||
#else
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#endif
|
||||
#include <ufs/dinode.h>
|
||||
|
||||
#include <protocols/dumprestore.h>
|
||||
#include <signal.h>
|
||||
#ifdef __STDC__
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <fstab.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "dump.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
#ifndef SBOFF
|
||||
#define SBOFF (SBLOCK * DEV_BSIZE)
|
||||
#endif
|
||||
|
||||
int notify = 0; /* notify operator flag */
|
||||
int blockswritten = 0; /* number of blocks written on current tape */
|
||||
int tapeno = 0; /* current tape number */
|
||||
@ -80,10 +84,11 @@ int cartridge = 0; /* Assume non-cartridge tape */
|
||||
long dev_bsize = 1; /* recalculated below */
|
||||
long blocksperfile; /* output blocks per file */
|
||||
char *host = NULL; /* remote host (if any) */
|
||||
#ifdef RDUMP
|
||||
int rmthost();
|
||||
#endif
|
||||
|
||||
static long numarg __P((int, char *, long, long, int *, char ***));
|
||||
static __dead void missingarg __P((int, char *));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
@ -94,12 +99,11 @@ main(argc, argv)
|
||||
register struct fstab *dt;
|
||||
register char *map;
|
||||
register char *cp;
|
||||
int i, anydirskipped, bflag = 0, Tflag = 0;
|
||||
float fetapes;
|
||||
int i, anydirskipped, bflag = 0, Tflag = 0, honorlevel = 1;
|
||||
ino_t maxino;
|
||||
|
||||
spcl.c_date = 0;
|
||||
(void) time((time_t *) &(spcl.c_date));
|
||||
(void)time((time_t *)&spcl.c_date);
|
||||
|
||||
tsize = 0; /* Default later, based on 'c' option for cart tapes */
|
||||
tape = _PATH_DEFTAPE;
|
||||
@ -114,147 +118,108 @@ main(argc, argv)
|
||||
}
|
||||
argv++;
|
||||
argc -= 2;
|
||||
for (cp = *argv++; *cp; cp++) {
|
||||
for (cp = *argv++; cp != NULL && *cp != '\0'; cp++) {
|
||||
switch (*cp) {
|
||||
case '-':
|
||||
continue;
|
||||
break;
|
||||
|
||||
case 'w':
|
||||
lastdump('w'); /* tell us only what has to be done */
|
||||
(void) exit(0);
|
||||
exit(0);
|
||||
|
||||
case 'W': /* what to do */
|
||||
lastdump('W'); /* tell us state of what is done */
|
||||
(void) exit(0); /* do nothing else */
|
||||
exit(0); /* do nothing else */
|
||||
|
||||
case 'f': /* output file */
|
||||
if (argc < 1)
|
||||
break;
|
||||
missingarg('f', "output file");
|
||||
tape = *argv++;
|
||||
argc--;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case 'd': /* density, in bits per inch */
|
||||
if (argc < 1)
|
||||
break;
|
||||
density = atoi(*argv) / 10;
|
||||
if (density < 1) {
|
||||
(void) fprintf(stderr, "bad density \"%s\"\n",
|
||||
*argv);
|
||||
Exit(X_ABORT);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
density = numarg('d', "density",
|
||||
10L, 327670L, &argc, &argv) / 10;
|
||||
if (density >= 625 && !bflag)
|
||||
ntrec = HIGHDENSITYTREC;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case 's': /* tape size, feet */
|
||||
if (argc < 1)
|
||||
break;
|
||||
tsize = atol(*argv);
|
||||
if (tsize < 1) {
|
||||
(void) fprintf(stderr, "bad size \"%s\"\n",
|
||||
*argv);
|
||||
Exit(X_ABORT);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
tsize *= 12 * 10;
|
||||
continue;
|
||||
tsize = numarg('s', "size",
|
||||
1L, 0L, &argc, &argv) * 12 * 10;
|
||||
break;
|
||||
|
||||
case 'T': /* time of last dump */
|
||||
if (argc < 1)
|
||||
break;
|
||||
missingarg('T', "time of last dump");
|
||||
spcl.c_ddate = unctime(*argv);
|
||||
if (spcl.c_ddate < 0) {
|
||||
(void) fprintf(stderr, "bad time \"%s\"\n",
|
||||
(void)fprintf(stderr, "bad time \"%s\"\n",
|
||||
*argv);
|
||||
Exit(X_ABORT);
|
||||
exit(X_ABORT);
|
||||
}
|
||||
Tflag++;
|
||||
Tflag = 1;
|
||||
lastlevel = '?';
|
||||
argc--;
|
||||
argv++;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case 'b': /* blocks per tape write */
|
||||
if (argc < 1)
|
||||
break;
|
||||
bflag++;
|
||||
ntrec = atoi(*argv);
|
||||
if (ntrec < 1) {
|
||||
(void) fprintf(stderr, "%s \"%s\"\n",
|
||||
"bad number of blocks per write ", *argv);
|
||||
Exit(X_ABORT);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
continue;
|
||||
ntrec = numarg('b', "number of blocks per write",
|
||||
1L, 1000L, &argc, &argv);
|
||||
break;
|
||||
|
||||
case 'B': /* blocks per output file */
|
||||
if (argc < 1)
|
||||
break;
|
||||
blocksperfile = atol(*argv);
|
||||
if (blocksperfile < 1) {
|
||||
(void) fprintf(stderr, "%s \"%s\"\n",
|
||||
"bad number of blocks per file ", *argv);
|
||||
Exit(X_ABORT);
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
continue;
|
||||
blocksperfile = numarg('B', "number of blocks per file",
|
||||
1L, 0L, &argc, &argv);
|
||||
break;
|
||||
|
||||
case 'c': /* Tape is cart. not 9-track */
|
||||
cartridge++;
|
||||
continue;
|
||||
cartridge = 1;
|
||||
break;
|
||||
|
||||
case '0': /* dump level */
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
case '8':
|
||||
case '9':
|
||||
/* dump level */
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
level = *cp;
|
||||
continue;
|
||||
break;
|
||||
|
||||
case 'u': /* update /etc/dumpdates */
|
||||
uflag++;
|
||||
continue;
|
||||
uflag = 1;
|
||||
break;
|
||||
|
||||
case 'n': /* notify operators */
|
||||
notify++;
|
||||
continue;
|
||||
notify = 1;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
honorlevel = numarg('h', "honor level",
|
||||
0L, 10L, &argc, &argv);
|
||||
break;
|
||||
|
||||
default:
|
||||
(void) fprintf(stderr, "bad key '%c'\n", *cp);
|
||||
Exit(X_ABORT);
|
||||
(void)fprintf(stderr, "bad key '%c'\n", *cp);
|
||||
exit(X_ABORT);
|
||||
}
|
||||
(void) fprintf(stderr, "missing argument to '%c'\n", *cp);
|
||||
Exit(X_ABORT);
|
||||
}
|
||||
if (argc < 1) {
|
||||
(void) fprintf(stderr, "Must specify disk or filesystem\n");
|
||||
Exit(X_ABORT);
|
||||
} else {
|
||||
disk = *argv++;
|
||||
argc--;
|
||||
(void)fprintf(stderr, "Must specify disk or filesystem\n");
|
||||
exit(X_ABORT);
|
||||
}
|
||||
disk = *argv++;
|
||||
argc--;
|
||||
if (argc >= 1) {
|
||||
(void) fprintf(stderr, "Unknown arguments to dump:");
|
||||
(void)fprintf(stderr, "Unknown arguments to dump:");
|
||||
while (argc--)
|
||||
(void) fprintf(stderr, " %s", *argv++);
|
||||
(void) fprintf(stderr, "\n");
|
||||
Exit(X_ABORT);
|
||||
(void)fprintf(stderr, " %s", *argv++);
|
||||
(void)fprintf(stderr, "\n");
|
||||
exit(X_ABORT);
|
||||
}
|
||||
if (Tflag && uflag) {
|
||||
(void) fprintf(stderr,
|
||||
(void)fprintf(stderr,
|
||||
"You cannot use the T and u flags together.\n");
|
||||
Exit(X_ABORT);
|
||||
exit(X_ABORT);
|
||||
}
|
||||
if (strcmp(tape, "-") == 0) {
|
||||
pipeout++;
|
||||
@ -282,16 +247,16 @@ main(argc, argv)
|
||||
if (index(tape, ':')) {
|
||||
host = tape;
|
||||
tape = index(host, ':');
|
||||
*tape++ = 0;
|
||||
*tape++ = '\0';
|
||||
#ifdef RDUMP
|
||||
if (rmthost(host) == 0)
|
||||
(void) exit(X_ABORT);
|
||||
exit(X_ABORT);
|
||||
#else
|
||||
(void) fprintf(stderr, "remote dump not enabled\n");
|
||||
(void) exit(X_ABORT);
|
||||
(void)fprintf(stderr, "remote dump not enabled\n");
|
||||
exit(X_ABORT);
|
||||
#endif
|
||||
}
|
||||
(void) setuid(getuid()); /* rmthost() is the only reason to be setuid */
|
||||
(void)setuid(getuid()); /* rmthost() is the only reason to be setuid */
|
||||
|
||||
if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
|
||||
signal(SIGHUP, sig);
|
||||
@ -317,17 +282,17 @@ main(argc, argv)
|
||||
* the file system name with or without the leading '/'.
|
||||
*/
|
||||
dt = fstabsearch(disk);
|
||||
if (dt != 0) {
|
||||
if (dt != NULL) {
|
||||
disk = rawname(dt->fs_spec);
|
||||
(void) strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
|
||||
(void) strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
|
||||
(void)strncpy(spcl.c_dev, dt->fs_spec, NAMELEN);
|
||||
(void)strncpy(spcl.c_filesys, dt->fs_file, NAMELEN);
|
||||
} else {
|
||||
(void) strncpy(spcl.c_dev, disk, NAMELEN);
|
||||
(void) strncpy(spcl.c_filesys, "an unlisted file system",
|
||||
(void)strncpy(spcl.c_dev, disk, NAMELEN);
|
||||
(void)strncpy(spcl.c_filesys, "an unlisted file system",
|
||||
NAMELEN);
|
||||
}
|
||||
(void) strcpy(spcl.c_label, "none");
|
||||
(void) gethostname(spcl.c_host, NAMELEN);
|
||||
(void)strcpy(spcl.c_label, "none");
|
||||
(void)gethostname(spcl.c_host, NAMELEN);
|
||||
spcl.c_level = level - '0';
|
||||
spcl.c_type = TS_TAPE;
|
||||
if (!Tflag)
|
||||
@ -338,7 +303,7 @@ main(argc, argv)
|
||||
msg("Date of last level %c dump: %s", lastlevel,
|
||||
spcl.c_ddate == 0 ? "the epoch\n" : ctime(&spcl.c_ddate));
|
||||
msg("Dumping %s ", disk);
|
||||
if (dt != 0)
|
||||
if (dt != NULL)
|
||||
msgtail("(%s) ", dt->fs_file);
|
||||
if (host)
|
||||
msgtail("to %s on host %s\n", tape, host);
|
||||
@ -347,7 +312,7 @@ main(argc, argv)
|
||||
|
||||
if ((diskfd = open(disk, O_RDONLY)) < 0) {
|
||||
msg("Cannot open %s\n", disk);
|
||||
Exit(X_ABORT);
|
||||
exit(X_ABORT);
|
||||
}
|
||||
sync();
|
||||
sblock = (struct fs *)sblock_buf;
|
||||
@ -361,18 +326,19 @@ main(argc, argv)
|
||||
tp_bshift = ffs(TP_BSIZE) - 1;
|
||||
if (TP_BSIZE != (1 << tp_bshift))
|
||||
quit("TP_BSIZE (%d) is not a power of 2", TP_BSIZE);
|
||||
#ifdef BSD44
|
||||
#ifdef FS_44INODEFMT
|
||||
if (sblock->fs_inodefmt >= FS_44INODEFMT)
|
||||
spcl.c_flags |= DR_NEWINODEFMT;
|
||||
#endif
|
||||
maxino = sblock->fs_ipg * sblock->fs_ncg - 1;
|
||||
mapsize = roundup(howmany(sblock->fs_ipg * sblock->fs_ncg, NBBY),
|
||||
TP_BSIZE);
|
||||
maxino = sblock->fs_ipg * sblock->fs_ncg;
|
||||
mapsize = roundup(howmany(maxino, NBBY), TP_BSIZE);
|
||||
usedinomap = (char *)calloc((unsigned) mapsize, sizeof(char));
|
||||
dumpdirmap = (char *)calloc((unsigned) mapsize, sizeof(char));
|
||||
dumpinomap = (char *)calloc((unsigned) mapsize, sizeof(char));
|
||||
tapesize = 3 * (howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
|
||||
|
||||
nonodump = spcl.c_level < honorlevel;
|
||||
|
||||
msg("mapping (Pass I) [regular files]\n");
|
||||
anydirskipped = mapfiles(maxino, &tapesize);
|
||||
|
||||
@ -381,11 +347,14 @@ main(argc, argv)
|
||||
anydirskipped = mapdirs(maxino, &tapesize);
|
||||
}
|
||||
|
||||
if (pipeout)
|
||||
if (pipeout) {
|
||||
tapesize += 10; /* 10 trailer blocks */
|
||||
else {
|
||||
msg("estimated %ld tape blocks.\n", tapesize);
|
||||
} else {
|
||||
double fetapes;
|
||||
|
||||
if (blocksperfile)
|
||||
fetapes = (float) tapesize / blocksperfile;
|
||||
fetapes = (double) tapesize / blocksperfile;
|
||||
else if (cartridge) {
|
||||
/* Estimate number of tapes, assuming streaming stops at
|
||||
the end of each block written, and not in mid-block.
|
||||
@ -420,30 +389,27 @@ main(argc, argv)
|
||||
tapesize += (etapes - 1) *
|
||||
(howmany(mapsize * sizeof(char), TP_BSIZE) + 1);
|
||||
tapesize += etapes + 10; /* headers + 10 trailer blks */
|
||||
}
|
||||
if (pipeout)
|
||||
msg("estimated %ld tape blocks.\n", tapesize);
|
||||
else
|
||||
msg("estimated %ld tape blocks on %3.2f tape(s).\n",
|
||||
tapesize, fetapes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate tape buffer
|
||||
* Allocate tape buffer.
|
||||
*/
|
||||
if (!alloctape())
|
||||
quit("can't allocate tape buffers - try a smaller blocking factor.\n");
|
||||
|
||||
startnewtape(1);
|
||||
(void) time((time_t *)&(tstart_writing));
|
||||
dumpmap(usedinomap, TS_CLRI, maxino);
|
||||
(void)time((time_t *)&(tstart_writing));
|
||||
dumpmap(usedinomap, TS_CLRI, maxino - 1);
|
||||
|
||||
msg("dumping (Pass III) [directories]\n");
|
||||
for (map = dumpdirmap, ino = 0; ino < maxino; ) {
|
||||
if ((ino % NBBY) == 0)
|
||||
dirty = 0; /* XXX just to get gcc to shut up */
|
||||
for (map = dumpdirmap, ino = 1; ino < maxino; ino++) {
|
||||
if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */
|
||||
dirty = *map++;
|
||||
else
|
||||
dirty >>= 1;
|
||||
ino++;
|
||||
if ((dirty & 1) == 0)
|
||||
continue;
|
||||
/*
|
||||
@ -452,30 +418,32 @@ main(argc, argv)
|
||||
dp = getino(ino);
|
||||
if ((dp->di_mode & IFMT) != IFDIR)
|
||||
continue;
|
||||
(void) dumpino(dp, ino);
|
||||
(void)dumpino(dp, ino);
|
||||
}
|
||||
|
||||
msg("dumping (Pass IV) [regular files]\n");
|
||||
for (map = dumpinomap, ino = 0; ino < maxino; ) {
|
||||
if ((ino % NBBY) == 0)
|
||||
for (map = dumpinomap, ino = 1; ino < maxino; ino++) {
|
||||
int mode;
|
||||
|
||||
if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */
|
||||
dirty = *map++;
|
||||
else
|
||||
dirty >>= 1;
|
||||
ino++;
|
||||
if ((dirty & 1) == 0)
|
||||
continue;
|
||||
/*
|
||||
* Skip inodes deleted and reallocated as directories.
|
||||
*/
|
||||
dp = getino(ino);
|
||||
if ((dp->di_mode & IFMT) == IFDIR)
|
||||
mode = dp->di_mode & IFMT;
|
||||
if (mode == IFDIR)
|
||||
continue;
|
||||
(void) dumpino(dp, ino);
|
||||
(void)dumpino(dp, ino);
|
||||
}
|
||||
|
||||
spcl.c_type = TS_END;
|
||||
for (i = 0; i < ntrec; i++)
|
||||
writeheader(maxino);
|
||||
writeheader(maxino - 1);
|
||||
if (pipeout)
|
||||
msg("DUMP: %ld tape blocks\n",spcl.c_tapea);
|
||||
else
|
||||
@ -489,6 +457,50 @@ main(argc, argv)
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Pick up a numeric argument. It must be nonnegative and in the given
|
||||
* range (except that a vmax of 0 means unlimited).
|
||||
*/
|
||||
static long
|
||||
numarg(letter, meaning, vmin, vmax, pargc, pargv)
|
||||
int letter;
|
||||
char *meaning;
|
||||
long vmin, vmax;
|
||||
int *pargc;
|
||||
char ***pargv;
|
||||
{
|
||||
register char *p;
|
||||
long val;
|
||||
char *str;
|
||||
|
||||
if (--*pargc < 0)
|
||||
missingarg(letter, meaning);
|
||||
str = *(*pargv)++;
|
||||
for (p = str; *p; p++)
|
||||
if (!isdigit(*p))
|
||||
goto bad;
|
||||
val = atol(str);
|
||||
if (val < vmin || (vmax && val > vmax))
|
||||
goto bad;
|
||||
return (val);
|
||||
|
||||
bad:
|
||||
(void)fprintf(stderr, "bad '%c' (%s) value \"%s\"\n",
|
||||
letter, meaning, str);
|
||||
exit(X_ABORT);
|
||||
}
|
||||
|
||||
static __dead void
|
||||
missingarg(letter, meaning)
|
||||
int letter;
|
||||
char *meaning;
|
||||
{
|
||||
|
||||
(void)fprintf(stderr, "The '%c' flag (%s) requires an argument\n",
|
||||
letter, meaning);
|
||||
exit(X_ABORT);
|
||||
}
|
||||
|
||||
void
|
||||
sig(signo)
|
||||
int signo;
|
||||
@ -503,15 +515,15 @@ sig(signo)
|
||||
if (pipeout)
|
||||
quit("Signal on pipe: cannot recover\n");
|
||||
msg("Rewriting attempted as response to unknown signal.\n");
|
||||
(void) fflush(stderr);
|
||||
(void) fflush(stdout);
|
||||
(void)fflush(stderr);
|
||||
(void)fflush(stdout);
|
||||
close_rewind();
|
||||
(void) exit(X_REWRITE);
|
||||
exit(X_REWRITE);
|
||||
/* NOTREACHED */
|
||||
case SIGSEGV:
|
||||
msg("SIGSEGV: ABORTING!\n");
|
||||
(void) signal(SIGSEGV, SIG_DFL);
|
||||
(void) kill(0, SIGSEGV);
|
||||
(void)signal(SIGSEGV, SIG_DFL);
|
||||
(void)kill(0, SIGSEGV);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
@ -521,31 +533,29 @@ rawname(cp)
|
||||
char *cp;
|
||||
{
|
||||
static char rawbuf[MAXPATHLEN];
|
||||
char *rindex();
|
||||
char *dp = rindex(cp, '/');
|
||||
|
||||
if (dp == 0)
|
||||
return (0);
|
||||
*dp = 0;
|
||||
(void) strcpy(rawbuf, cp);
|
||||
if (dp == NULL)
|
||||
return (NULL);
|
||||
*dp = '\0';
|
||||
(void)strcpy(rawbuf, cp);
|
||||
*dp = '/';
|
||||
(void) strcat(rawbuf, "/r");
|
||||
(void) strcat(rawbuf, dp+1);
|
||||
(void)strcat(rawbuf, "/r");
|
||||
(void)strcat(rawbuf, dp + 1);
|
||||
return (rawbuf);
|
||||
}
|
||||
|
||||
#ifdef sunos
|
||||
char *
|
||||
const char *
|
||||
strerror(errnum)
|
||||
int errnum;
|
||||
{
|
||||
extern int sys_nerr;
|
||||
extern char *sys_errlist[];
|
||||
extern const char *const sys_errlist[];
|
||||
|
||||
if (errnum < sys_nerr) {
|
||||
return(sys_errlist[errnum]);
|
||||
} else {
|
||||
return("bogus errno in strerror");
|
||||
}
|
||||
if (errnum < sys_nerr)
|
||||
return (sys_errlist[errnum]);
|
||||
else
|
||||
return ("bogus errno in strerror");
|
||||
}
|
||||
#endif
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1988 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,42 +32,39 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)optr.c 5.14 (Berkeley) 7/16/92"; */
|
||||
static char *rcsid = "$Id: optr.c,v 1.1 1993/12/22 10:24:50 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)optr.c 8.2 (Berkeley) 1/6/94";*/
|
||||
static char *rcsid = "$Id: optr.c,v 1.2 1994/06/08 18:57:37 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef sunos
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/wait.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fstab.h>
|
||||
#include <grp.h>
|
||||
#include <utmp.h>
|
||||
#include <tzfile.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#endif
|
||||
#include <tzfile.h>
|
||||
#ifdef __STDC__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
#ifndef __STDC__
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
#include "dump.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
static void alarmcatch();
|
||||
static void sendmes();
|
||||
void alarmcatch __P((/* int, int */));
|
||||
int datesort __P((const void *, const void *));
|
||||
static void sendmes __P((char *, char *));
|
||||
|
||||
/*
|
||||
* Query the operator; This previously-fascist piece of code
|
||||
@ -80,8 +77,8 @@ static void sendmes();
|
||||
* Every 2 minutes we reprint the message, alerting others
|
||||
* that dump needs attention.
|
||||
*/
|
||||
int timeout;
|
||||
char *attnmessage; /* attention message */
|
||||
static int timeout;
|
||||
static char *attnmessage; /* attention message */
|
||||
|
||||
int
|
||||
query(question)
|
||||
@ -131,7 +128,7 @@ char lastmsg[100];
|
||||
* Alert the console operator, and enable the alarm clock to
|
||||
* sleep for 2 minutes in case nobody comes to satisfy dump
|
||||
*/
|
||||
static void
|
||||
void
|
||||
alarmcatch()
|
||||
{
|
||||
if (notify == 0) {
|
||||
@ -190,7 +187,6 @@ set_operators()
|
||||
}
|
||||
}
|
||||
|
||||
struct tm *localtime();
|
||||
struct tm *localclock;
|
||||
|
||||
/*
|
||||
@ -428,7 +424,7 @@ getfstab()
|
||||
_PATH_FSTAB, strerror(errno));
|
||||
return;
|
||||
}
|
||||
while (fs = getfsent()) {
|
||||
while ((fs = getfsent()) != NULL) {
|
||||
if (strcmp(fs->fs_type, FSTAB_RW) &&
|
||||
strcmp(fs->fs_type, FSTAB_RO) &&
|
||||
strcmp(fs->fs_type, FSTAB_RQ))
|
||||
@ -460,7 +456,7 @@ fstabsearch(key)
|
||||
{
|
||||
register struct pfstab *pf;
|
||||
register struct fstab *fs;
|
||||
char *rn, *rawname();
|
||||
char *rn;
|
||||
|
||||
for (pf = table; pf != NULL; pf = pf->pf_next) {
|
||||
fs = pf->pf_fstab;
|
||||
@ -493,7 +489,7 @@ lastdump(arg)
|
||||
register struct fstab *dt;
|
||||
register struct dumpdates *dtwalk;
|
||||
char *lastname, *date;
|
||||
int dumpme, datesort();
|
||||
int dumpme;
|
||||
time_t tnow;
|
||||
|
||||
(void) time(&tnow);
|
||||
@ -530,7 +526,7 @@ lastdump(arg)
|
||||
|
||||
int
|
||||
datesort(a1, a2)
|
||||
void *a1, *a2;
|
||||
const void *a1, *a2;
|
||||
{
|
||||
struct dumpdates *d1 = *(struct dumpdates **)a1;
|
||||
struct dumpdates *d2 = *(struct dumpdates **)a2;
|
||||
@ -541,4 +537,3 @@ datesort(a1, a2)
|
||||
return (d2->dd_ddate - d1->dd_ddate);
|
||||
return (diff);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -30,8 +30,8 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pathnames.h 5.6 (Berkeley) 2/28/91
|
||||
* $Id: pathnames.h,v 1.5 1993/12/22 10:24:53 cgd Exp $
|
||||
* from: @(#)pathnames.h 8.1 (Berkeley) 6/5/93
|
||||
* $Id: pathnames.h,v 1.6 1994/06/08 18:57:38 mycroft Exp $
|
||||
*/
|
||||
|
||||
#include <paths.h>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,34 +32,39 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)tape.c 5.25 (Berkeley) 7/16/92"; */
|
||||
static char *rcsid = "$Id: tape.c,v 1.2 1994/03/09 01:14:43 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)tape.c 8.2 (Berkeley) 3/17/94";*/
|
||||
static char *rcsid = "$Id: tape.c,v 1.3 1994/06/08 18:57:40 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef sunos
|
||||
#include <sys/param.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ufs/fs.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/wait.h>
|
||||
#include <ufs/fs.h>
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/wait.h>
|
||||
#ifdef sunos
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/inode.h>
|
||||
#else
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#endif
|
||||
|
||||
#include <protocols/dumprestore.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#else
|
||||
int write(), read();
|
||||
#endif
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include "dump.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
@ -72,13 +77,13 @@ extern int ntrec; /* blocking factor on tape */
|
||||
extern int cartridge;
|
||||
extern char *host;
|
||||
char *nexttape;
|
||||
#ifdef RDUMP
|
||||
int rmtopen(), rmtwrite();
|
||||
void rmtclose();
|
||||
#endif
|
||||
void rollforward();
|
||||
int atomic();
|
||||
void doslave(), enslave(), flushtape(), killall();
|
||||
|
||||
static int atomic __P((int (*)(), int, char *, int));
|
||||
static void doslave __P((int, int));
|
||||
static void enslave __P((void));
|
||||
static void flushtape __P((void));
|
||||
static void killall __P((void));
|
||||
static void rollforward __P((void));
|
||||
|
||||
/*
|
||||
* Concurrent dump mods (Caltech) - disk block reading and tape writing
|
||||
@ -229,14 +234,11 @@ sigpipe(signo)
|
||||
quit("Broken pipe\n");
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
flushtape()
|
||||
{
|
||||
int i, blks, got;
|
||||
long lastfirstrec;
|
||||
#ifndef __STDC__
|
||||
int write(), read();
|
||||
#endif
|
||||
|
||||
int siz = (char *)nextblock - (char *)slp->req;
|
||||
|
||||
@ -403,6 +405,7 @@ rollforward()
|
||||
* For each request in the current slave, copy it to tslp.
|
||||
*/
|
||||
|
||||
prev = NULL;
|
||||
for (p = slp->req; p->count > 0; p += p->count) {
|
||||
*q = *p;
|
||||
if (p->dblk == 0)
|
||||
@ -410,6 +413,8 @@ rollforward()
|
||||
prev = q;
|
||||
q += q->count;
|
||||
}
|
||||
if (prev == NULL)
|
||||
quit("rollforward: protocol botch");
|
||||
if (prev->dblk != 0)
|
||||
prev->count -= 1;
|
||||
else
|
||||
@ -502,7 +507,6 @@ startnewtape(top)
|
||||
char *p;
|
||||
#ifdef sunos
|
||||
void (*interrupt_save)();
|
||||
char *index();
|
||||
#else
|
||||
sig_t interrupt_save;
|
||||
#endif
|
||||
@ -510,7 +514,7 @@ startnewtape(top)
|
||||
interrupt_save = signal(SIGINT, SIG_IGN);
|
||||
parentpid = getpid();
|
||||
|
||||
restore_check_point:
|
||||
restore_check_point:
|
||||
(void)signal(SIGINT, interrupt_save);
|
||||
/*
|
||||
* All signals are inherited...
|
||||
@ -531,7 +535,7 @@ startnewtape(top)
|
||||
#ifdef TDEBUG
|
||||
msg("Tape: %d; parent process: %d child process %d\n",
|
||||
tapeno+1, parentpid, childpid);
|
||||
#endif TDEBUG
|
||||
#endif /* TDEBUG */
|
||||
while ((waitpid = wait(&status)) != childpid)
|
||||
msg("Parent %d waiting for child %d has another child %d return\n",
|
||||
parentpid, childpid, waitpid);
|
||||
@ -556,7 +560,7 @@ startnewtape(top)
|
||||
childpid, status);
|
||||
break;
|
||||
}
|
||||
#endif TDEBUG
|
||||
#endif /* TDEBUG */
|
||||
switch(status) {
|
||||
case X_FINOK:
|
||||
Exit(X_FINOK);
|
||||
@ -574,7 +578,7 @@ startnewtape(top)
|
||||
sleep(4); /* allow time for parent's message to get out */
|
||||
msg("Child on Tape %d has parent %d, my pid = %d\n",
|
||||
tapeno+1, parentpid, getpid());
|
||||
#endif TDEBUG
|
||||
#endif /* TDEBUG */
|
||||
/*
|
||||
* If we have a name like "/dev/rmt0,/dev/rmt1",
|
||||
* use the name before the comma first, and save
|
||||
@ -584,7 +588,7 @@ startnewtape(top)
|
||||
if (nexttape || index(tape, ',')) {
|
||||
if (nexttape && *nexttape)
|
||||
tape = nexttape;
|
||||
if (p = index(tape, ',')) {
|
||||
if ((p = index(tape, ',')) != NULL) {
|
||||
*p = '\0';
|
||||
nexttape = p + 1;
|
||||
} else
|
||||
@ -645,15 +649,15 @@ dumpabort(signo)
|
||||
Exit(X_ABORT);
|
||||
}
|
||||
|
||||
void
|
||||
__dead void
|
||||
Exit(status)
|
||||
int status;
|
||||
{
|
||||
|
||||
#ifdef TDEBUG
|
||||
msg("pid = %d exits with status %d\n", getpid(), status);
|
||||
#endif TDEBUG
|
||||
(void) exit(status);
|
||||
#endif /* TDEBUG */
|
||||
exit(status);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -730,16 +734,13 @@ killall()
|
||||
* file, allowing the following process to lock it and proceed. We
|
||||
* get the lock back for the next cycle by swapping descriptors.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
doslave(cmd, slave_number)
|
||||
register int cmd;
|
||||
int slave_number;
|
||||
{
|
||||
register int nread;
|
||||
int nextslave, size, wrote, eot_count;
|
||||
#ifndef __STDC__
|
||||
int read();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Need our own seek pointer.
|
||||
@ -845,10 +846,11 @@ doslave(cmd, slave_number)
|
||||
* or a write may not write all we ask if we get a signal,
|
||||
* loop until the count is satisfied (or error).
|
||||
*/
|
||||
int
|
||||
static int
|
||||
atomic(func, fd, buf, count)
|
||||
int (*func)(), fd, count;
|
||||
int (*func)(), fd;
|
||||
char *buf;
|
||||
int count;
|
||||
{
|
||||
int got, need = count;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980, 1988, 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1988, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,34 +32,49 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)traverse.c 5.21 (Berkeley) 7/19/92"; */
|
||||
static char *rcsid = "$Id: traverse.c,v 1.3 1994/04/25 18:22:50 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)traverse.c 8.2 (Berkeley) 9/23/93";*/
|
||||
static char *rcsid = "$Id: traverse.c,v 1.4 1994/06/08 18:57:42 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifdef sunos
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <sys/param.h>
|
||||
#include <ufs/fs.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <ufs/fs.h>
|
||||
#endif
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <ufs/dir.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <protocols/dumprestore.h>
|
||||
#ifdef __STDC__
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#ifdef sunos
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/fsdir.h>
|
||||
#include <ufs/inode.h>
|
||||
#else
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#endif
|
||||
|
||||
#include <protocols/dumprestore.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#ifdef __STDC__
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "dump.h"
|
||||
|
||||
void dmpindir();
|
||||
#define HASDUMPEDFILE 0x1
|
||||
#define HASSUBDIRS 0x2
|
||||
|
||||
#ifdef FS_44INODEFMT
|
||||
typedef quad_t fsizeT;
|
||||
#else
|
||||
typedef long fsizeT;
|
||||
#endif
|
||||
|
||||
static int dirindir __P((ino_t ino, daddr_t blkno, int level, long *size));
|
||||
static void dmpindir __P((ino_t ino, daddr_t blk, int level, fsizeT *size));
|
||||
static int searchdir __P((ino_t ino, daddr_t blkno, long size, long filesize));
|
||||
|
||||
/*
|
||||
* This is an estimation of the number of TP_BSIZE blocks in the file.
|
||||
* It estimates the number of blocks in files with holes by assuming
|
||||
@ -100,6 +115,24 @@ blockest(dp)
|
||||
return (blkest + 1);
|
||||
}
|
||||
|
||||
/* Auxiliary macro to pick up files changed since previous dump. */
|
||||
#ifdef FS_44INODEFMT
|
||||
#define CHANGEDSINCE(dp, t) \
|
||||
((dp)->di_mtime.ts_sec >= (t) || (dp)->di_ctime.ts_sec >= (t))
|
||||
#else
|
||||
#define CHANGEDSINCE(dp, t) \
|
||||
((dp)->di_mtime >= (t) || (dp)->di_ctime >= (t))
|
||||
#endif
|
||||
|
||||
/* The WANTTODUMP macro decides whether a file should be dumped. */
|
||||
#ifdef UF_NODUMP
|
||||
#define WANTTODUMP(dp) \
|
||||
(CHANGEDSINCE(dp, spcl.c_ddate) && \
|
||||
(nonodump || ((dp)->di_flags & UF_NODUMP) != UF_NODUMP))
|
||||
#else
|
||||
#define WANTTODUMP(dp) CHANGEDSINCE(dp, spcl.c_ddate)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Dump pass 1.
|
||||
*
|
||||
@ -107,6 +140,7 @@ blockest(dp)
|
||||
* that have been modified since the previous dump time. Also, find all
|
||||
* the directories in the filesystem.
|
||||
*/
|
||||
int
|
||||
mapfiles(maxino, tapesize)
|
||||
ino_t maxino;
|
||||
long *tapesize;
|
||||
@ -123,20 +157,12 @@ mapfiles(maxino, tapesize)
|
||||
SETINO(ino, usedinomap);
|
||||
if (mode == IFDIR)
|
||||
SETINO(ino, dumpdirmap);
|
||||
if ((dp->di_mtime.ts_sec >= spcl.c_ddate ||
|
||||
dp->di_ctime.ts_sec >= spcl.c_ddate)
|
||||
#ifdef BSD44
|
||||
# ifndef sunos
|
||||
&& (dp->di_flags & NODUMP) != NODUMP
|
||||
# endif /* sunos */
|
||||
#endif /* BSD44 */
|
||||
) {
|
||||
if (WANTTODUMP(dp)) {
|
||||
SETINO(ino, dumpinomap);
|
||||
if (mode != IFREG && mode != IFDIR && mode != IFLNK) {
|
||||
if (mode != IFREG && mode != IFDIR && mode != IFLNK)
|
||||
*tapesize += 1;
|
||||
continue;
|
||||
}
|
||||
*tapesize += blockest(dp);
|
||||
else
|
||||
*tapesize += blockest(dp);
|
||||
continue;
|
||||
}
|
||||
if (mode == IFDIR)
|
||||
@ -162,6 +188,7 @@ mapfiles(maxino, tapesize)
|
||||
* its parent may now qualify for the same treatment on this or a later
|
||||
* pass using this algorithm.
|
||||
*/
|
||||
int
|
||||
mapdirs(maxino, tapesize)
|
||||
ino_t maxino;
|
||||
long *tapesize;
|
||||
@ -173,12 +200,12 @@ mapdirs(maxino, tapesize)
|
||||
long filesize;
|
||||
int ret, change = 0;
|
||||
|
||||
for (map = dumpdirmap, ino = 0; ino < maxino; ) {
|
||||
if ((ino % NBBY) == 0)
|
||||
isdir = 0; /* XXX just to get gcc to shut up */
|
||||
for (map = dumpdirmap, ino = 1; ino < maxino; ino++) {
|
||||
if (((ino - 1) % NBBY) == 0) /* map is offset by 1 */
|
||||
isdir = *map++;
|
||||
else
|
||||
isdir >>= 1;
|
||||
ino++;
|
||||
if ((isdir & 1) == 0 || TSTINO(ino, dumpinomap))
|
||||
continue;
|
||||
dp = getino(ino);
|
||||
@ -219,6 +246,7 @@ mapdirs(maxino, tapesize)
|
||||
* as directories. Quit as soon as any entry is found that will
|
||||
* require the directory to be dumped.
|
||||
*/
|
||||
static int
|
||||
dirindir(ino, blkno, ind_level, filesize)
|
||||
ino_t ino;
|
||||
daddr_t blkno;
|
||||
@ -257,6 +285,7 @@ dirindir(ino, blkno, ind_level, filesize)
|
||||
* any of the entries are on the dump list and to see if the directory
|
||||
* contains any subdirectories.
|
||||
*/
|
||||
static int
|
||||
searchdir(ino, blkno, size, filesize)
|
||||
ino_t ino;
|
||||
daddr_t blkno;
|
||||
@ -310,7 +339,7 @@ dumpino(dp, ino)
|
||||
ino_t ino;
|
||||
{
|
||||
int ind_level, cnt;
|
||||
long size;
|
||||
fsizeT size;
|
||||
char buf[TP_BSIZE];
|
||||
|
||||
if (newtape) {
|
||||
@ -321,22 +350,22 @@ dumpino(dp, ino)
|
||||
spcl.c_dinode = *dp;
|
||||
spcl.c_type = TS_INODE;
|
||||
spcl.c_count = 0;
|
||||
switch (dp->di_mode & S_IFMT) {
|
||||
|
||||
switch (IFTODT(dp->di_mode)) {
|
||||
|
||||
case DT_UNKNOWN:
|
||||
case 0:
|
||||
/*
|
||||
* Freed inode.
|
||||
*/
|
||||
return;
|
||||
|
||||
case DT_LNK:
|
||||
#ifdef BSD44
|
||||
case S_IFLNK:
|
||||
/*
|
||||
* Check for short symbolic link.
|
||||
*/
|
||||
#ifdef FS_44INODEFMT
|
||||
if (dp->di_size > 0 &&
|
||||
dp->di_size < sblock->fs_maxsymlinklen) {
|
||||
(dp->di_size < sblock->fs_maxsymlinklen ||
|
||||
(sblock->fs_maxsymlinklen == 0 && OLDFASTLINK(dp)))) {
|
||||
spcl.c_addr[0] = 1;
|
||||
spcl.c_count = 1;
|
||||
writeheader(ino);
|
||||
@ -346,31 +375,19 @@ dumpino(dp, ino)
|
||||
writerec(buf, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef NetBSD
|
||||
if (DFASTLINK(*dp)) {
|
||||
spcl.c_addr[0] = 1;
|
||||
spcl.c_count = 1;
|
||||
writeheader(ino);
|
||||
bcopy((caddr_t)dp->di_symlink, buf,
|
||||
(u_long)dp->di_size);
|
||||
buf[dp->di_size] = '\0';
|
||||
writerec(buf, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* fall through */
|
||||
|
||||
case DT_DIR:
|
||||
case DT_REG:
|
||||
case S_IFDIR:
|
||||
case S_IFREG:
|
||||
if (dp->di_size > 0)
|
||||
break;
|
||||
/* fall through */
|
||||
|
||||
case DT_FIFO:
|
||||
case DT_SOCK:
|
||||
case DT_CHR:
|
||||
case DT_BLK:
|
||||
case S_IFIFO:
|
||||
case S_IFSOCK:
|
||||
case S_IFCHR:
|
||||
case S_IFBLK:
|
||||
writeheader(ino);
|
||||
return;
|
||||
|
||||
@ -378,7 +395,6 @@ dumpino(dp, ino)
|
||||
msg("Warning: undefined file type 0%o\n", dp->di_mode & IFMT);
|
||||
return;
|
||||
}
|
||||
|
||||
if (dp->di_size > NDADDR * sblock->fs_bsize)
|
||||
cnt = NDADDR * sblock->fs_frag;
|
||||
else
|
||||
@ -396,12 +412,12 @@ dumpino(dp, ino)
|
||||
/*
|
||||
* Read indirect blocks, and pass the data blocks to be dumped.
|
||||
*/
|
||||
void
|
||||
static void
|
||||
dmpindir(ino, blk, ind_level, size)
|
||||
ino_t ino;
|
||||
daddr_t blk;
|
||||
int ind_level;
|
||||
long *size;
|
||||
fsizeT *size;
|
||||
{
|
||||
int i, cnt;
|
||||
daddr_t idblk[MAXNINDIR];
|
||||
@ -518,7 +534,7 @@ getino(inum)
|
||||
curino = inum;
|
||||
if (inum >= minino && inum < maxino)
|
||||
return (&inoblock[inum - minino]);
|
||||
bread(fsbtodb(sblock, itod(sblock, inum)), (char *)inoblock,
|
||||
bread(fsbtodb(sblock, ino_to_fsba(sblock, inum)), (char *)inoblock,
|
||||
(int)sblock->fs_bsize);
|
||||
minino = inum - (inum % INOPB(sblock));
|
||||
maxino = minino + INOPB(sblock);
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*-
|
||||
* Copyright (c) 1980 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,18 +32,23 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/* from: static char sccsid[] = "@(#)unctime.c 5.5 (Berkeley) 6/18/92"; */
|
||||
static char *rcsid = "$Id: unctime.c,v 1.6 1993/12/24 01:16:59 jtc Exp $";
|
||||
/*static char sccsid[] = "from: @(#)unctime.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: unctime.c,v 1.7 1994/06/08 18:57:43 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#ifdef __STDC__
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifndef __P
|
||||
#include <sys/cdefs.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert a ctime(3) format string into a system format date.
|
||||
* Return the date thus calculated.
|
||||
@ -62,19 +67,19 @@ static char *rcsid = "$Id: unctime.c,v 1.6 1993/12/24 01:16:59 jtc Exp $";
|
||||
#define E_SECOND 17
|
||||
#define E_YEAR 20
|
||||
|
||||
static int lookup();
|
||||
static int lookup __P((char *));
|
||||
|
||||
|
||||
time_t
|
||||
unctime(str)
|
||||
char *str;
|
||||
{
|
||||
struct tm then;
|
||||
char dbuf[30];
|
||||
char dbuf[26];
|
||||
|
||||
if (strlen(str) != 25)
|
||||
str[25] = 0;
|
||||
(void) strcpy(dbuf, str);
|
||||
dbuf[E_MONTH+3] = 0;
|
||||
(void) strncpy(dbuf, str, sizeof(dbuf) - 1);
|
||||
dbuf[sizeof(dbuf) - 1] = '\0';
|
||||
dbuf[E_MONTH+3] = '\0';
|
||||
if ((then.tm_mon = lookup(&dbuf[E_MONTH])) < 0)
|
||||
return (-1);
|
||||
then.tm_mday = atoi(&dbuf[E_DAY]);
|
||||
@ -95,7 +100,7 @@ lookup(str)
|
||||
{
|
||||
register char *cp, *cp2;
|
||||
|
||||
for (cp = months, cp2 = str; *cp != 0; cp += 3)
|
||||
for (cp = months, cp2 = str; *cp != '\0'; cp += 3)
|
||||
if (strncmp(cp, cp2, 3) == 0)
|
||||
return((cp-months) / 3);
|
||||
return(-1);
|
||||
|
@ -1,5 +1,5 @@
|
||||
# from: @(#)Makefile 5.3 (Berkeley) 5/11/90
|
||||
# $Id: Makefile,v 1.4 1993/08/01 05:38:06 mycroft Exp $
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.5 1994/06/08 18:58:21 mycroft Exp $
|
||||
|
||||
PROG= dumpfs
|
||||
MAN8= dumpfs.0
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 1983, 1991 Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -29,10 +29,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)dumpfs.8 6.2 (Berkeley) 3/16/91
|
||||
.\" $Id: dumpfs.8,v 1.4 1993/08/01 07:39:20 mycroft Exp $
|
||||
.\" from: @(#)dumpfs.8 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: dumpfs.8,v 1.5 1994/06/08 18:58:22 mycroft Exp $
|
||||
.\"
|
||||
.Dd March 16, 1991
|
||||
.Dd June 5, 1993
|
||||
.Dt DUMPFS 8
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1983 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1983, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,27 +32,29 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1983, 1992, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)dumpfs.c 5.10 (Berkeley) 6/1/90";*/
|
||||
static char rcsid[] = "$Id: dumpfs.c,v 1.5 1994/04/25 18:23:19 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)dumpfs.c 8.2 (Berkeley) 2/2/94";*/
|
||||
static char *rcsid = "$Id: dumpfs.c,v 1.6 1994/06/08 18:58:23 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <fstab.h>
|
||||
|
||||
/*
|
||||
* dumpfs
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
union {
|
||||
struct fs fs;
|
||||
@ -68,46 +70,60 @@ union {
|
||||
|
||||
long dev_bsize = 1;
|
||||
|
||||
int dumpfs __P((char *));
|
||||
int dumpcg __P((char *, int, int));
|
||||
void pbits __P((void *, int));
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register struct fstab *fs;
|
||||
int ch, eval;
|
||||
|
||||
argc--, argv++;
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: dumpfs fs ...\n");
|
||||
exit(1);
|
||||
}
|
||||
for (; argc > 0; argv++, argc--) {
|
||||
fs = getfsfile(*argv);
|
||||
if (fs == 0)
|
||||
dumpfs(*argv);
|
||||
while ((ch = getopt(argc, argv, "")) != EOF)
|
||||
switch(ch) {
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
for (eval = 0; *argv; ++argv)
|
||||
if ((fs = getfsfile(*argv)) == NULL)
|
||||
eval |= dumpfs(*argv);
|
||||
else
|
||||
dumpfs(fs->fs_spec);
|
||||
}
|
||||
eval |= dumpfs(fs->fs_spec);
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
int
|
||||
dumpfs(name)
|
||||
char *name;
|
||||
{
|
||||
int c, i, j, k, size;
|
||||
int fd, c, i, j, k, size;
|
||||
|
||||
if ((fd = open(name, O_RDONLY, 0)) < 0)
|
||||
goto err;
|
||||
if (lseek(fd, (off_t)SBOFF, SEEK_SET) == (off_t)-1)
|
||||
goto err;
|
||||
if (read(fd, &afs, SBSIZE) != SBSIZE)
|
||||
goto err;
|
||||
|
||||
close(0);
|
||||
if (open(name, 0) != 0) {
|
||||
perror(name);
|
||||
return;
|
||||
}
|
||||
lseek(0, SBOFF, 0);
|
||||
if (read(0, &afs, SBSIZE) != SBSIZE) {
|
||||
perror(name);
|
||||
return;
|
||||
}
|
||||
if (afs.fs_postblformat == FS_42POSTBLFMT)
|
||||
afs.fs_nrpos = 8;
|
||||
dev_bsize = afs.fs_fsize / fsbtodb(&afs, 1);
|
||||
printf("magic\t%x\tformat\t%s\ttime\t%s", afs.fs_magic,
|
||||
afs.fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic",
|
||||
printf("magic\t%x\ttime\t%s", afs.fs_magic,
|
||||
ctime(&afs.fs_time));
|
||||
printf("cylgrp\t%s\tinodes\t%s\n",
|
||||
afs.fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic",
|
||||
afs.fs_inodefmt < FS_44INODEFMT ? "4.2/4.3BSD" : "4.4BSD");
|
||||
printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n",
|
||||
afs.fs_cstotal.cs_nbfree, afs.fs_cstotal.cs_ndir,
|
||||
afs.fs_cstotal.cs_nifree, afs.fs_cstotal.cs_nffree);
|
||||
@ -128,8 +144,9 @@ dumpfs(name)
|
||||
afs.fs_rotdelay, afs.fs_headswitch, afs.fs_trkseek, afs.fs_rps);
|
||||
printf("ntrak\t%d\tnsect\t%d\tnpsect\t%d\tspc\t%d\n",
|
||||
afs.fs_ntrak, afs.fs_nsect, afs.fs_npsect, afs.fs_spc);
|
||||
printf("trackskew %d\tinterleave %d\n",
|
||||
afs.fs_trackskew, afs.fs_interleave);
|
||||
printf("symlinklen %d\ttrackskew %d\tinterleave %d\tcontigsumsize %d\n",
|
||||
afs.fs_maxsymlinklen, afs.fs_trackskew, afs.fs_interleave,
|
||||
afs.fs_contigsumsize);
|
||||
printf("nindir\t%d\tinopb\t%d\tnspf\t%d\n",
|
||||
afs.fs_nindir, afs.fs_inopb, afs.fs_nspf);
|
||||
printf("sblkno\t%d\tcblkno\t%d\tiblkno\t%d\tdblkno\t%d\n",
|
||||
@ -165,13 +182,13 @@ dumpfs(name)
|
||||
for (i = 0, j = 0; i < afs.fs_cssize; i += afs.fs_bsize, j++) {
|
||||
size = afs.fs_cssize - i < afs.fs_bsize ?
|
||||
afs.fs_cssize - i : afs.fs_bsize;
|
||||
afs.fs_csp[j] = (struct csum *)calloc(1, size);
|
||||
lseek(0, fsbtodb(&afs, (afs.fs_csaddr + j * afs.fs_frag)) *
|
||||
dev_bsize, 0);
|
||||
if (read(0, afs.fs_csp[j], size) != size) {
|
||||
perror(name);
|
||||
return;
|
||||
}
|
||||
afs.fs_csp[j] = calloc(1, size);
|
||||
if (lseek(fd,
|
||||
(off_t)(fsbtodb(&afs, (afs.fs_csaddr + j * afs.fs_frag)) *
|
||||
dev_bsize), SEEK_SET) == (off_t)-1)
|
||||
goto err;
|
||||
if (read(fd, afs.fs_csp[j], size) != size)
|
||||
goto err;
|
||||
}
|
||||
for (i = 0; i < afs.fs_ncg; i++) {
|
||||
struct csum *cs = &afs.fs_cs(&afs, i);
|
||||
@ -189,27 +206,37 @@ dumpfs(name)
|
||||
}
|
||||
printf("\n");
|
||||
for (i = 0; i < afs.fs_ncg; i++)
|
||||
dumpcg(name, i);
|
||||
close(0);
|
||||
if (dumpcg(name, fd, i))
|
||||
goto err;
|
||||
(void)close(fd);
|
||||
return (0);
|
||||
|
||||
err: if (fd != -1)
|
||||
(void)close(fd);
|
||||
(void)fprintf(stderr, "dumpfs: %s: %s\n", name, strerror(errno));
|
||||
return (1);
|
||||
};
|
||||
|
||||
dumpcg(name, c)
|
||||
int
|
||||
dumpcg(name, fd, c)
|
||||
char *name;
|
||||
int c;
|
||||
int fd, c;
|
||||
{
|
||||
int i,j;
|
||||
off_t cur;
|
||||
int i, j;
|
||||
|
||||
printf("\ncg %d:\n", c);
|
||||
lseek(0, fsbtodb(&afs, cgtod(&afs, c)) * dev_bsize, 0);
|
||||
i = lseek(0, 0, 1);
|
||||
if (read(0, (char *)&acg, afs.fs_bsize) != afs.fs_bsize) {
|
||||
printf("dumpfs: %s: error reading cg\n", name);
|
||||
return;
|
||||
if ((cur = lseek(fd, (off_t)(fsbtodb(&afs, cgtod(&afs, c)) * dev_bsize),
|
||||
SEEK_SET)) == (off_t)-1)
|
||||
return (1);
|
||||
if (read(fd, &acg, afs.fs_bsize) != afs.fs_bsize) {
|
||||
(void)fprintf(stderr, "dumpfs: %s: error reading cg\n", name);
|
||||
return (1);
|
||||
}
|
||||
printf("magic\t%x\ttell\t%x\ttime\t%s",
|
||||
printf("magic\t%x\ttell\t%qx\ttime\t%s",
|
||||
afs.fs_postblformat == FS_42POSTBLFMT ?
|
||||
((struct ocg *)&acg)->cg_magic : acg.cg_magic,
|
||||
i, ctime(&acg.cg_time));
|
||||
cur, ctime(&acg.cg_time));
|
||||
printf("cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n",
|
||||
acg.cg_cgx, acg.cg_ncyl, acg.cg_niblk, acg.cg_ndblk);
|
||||
printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n",
|
||||
@ -221,7 +248,23 @@ dumpcg(name, c)
|
||||
printf("\t%d", acg.cg_frsum[i]);
|
||||
j += i * acg.cg_frsum[i];
|
||||
}
|
||||
printf("\nsum of frsum: %d\niused:\t", j);
|
||||
printf("\nsum of frsum: %d", j);
|
||||
if (afs.fs_contigsumsize > 0) {
|
||||
for (i = 1; i < afs.fs_contigsumsize; i++) {
|
||||
if ((i - 1) % 8 == 0)
|
||||
printf("\nclusters %d-%d:", i,
|
||||
afs.fs_contigsumsize - 1 < i + 7 ?
|
||||
afs.fs_contigsumsize - 1 : i + 7);
|
||||
printf("\t%d", cg_clustersum(&acg)[i]);
|
||||
}
|
||||
printf("\nclusters size %d and over: %d\n",
|
||||
afs.fs_contigsumsize,
|
||||
cg_clustersum(&acg)[afs.fs_contigsumsize]);
|
||||
printf("clusters free:\t");
|
||||
pbits(cg_clustersfree(&acg), acg.cg_nclusterblks);
|
||||
} else
|
||||
printf("\n");
|
||||
printf("iused:\t");
|
||||
pbits(cg_inosused(&acg), afs.fs_ipg);
|
||||
printf("free:\t");
|
||||
pbits(cg_blksfree(&acg), afs.fs_fpg);
|
||||
@ -238,26 +281,36 @@ dumpcg(name, c)
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return (0);
|
||||
};
|
||||
|
||||
pbits(cp, max)
|
||||
register char *cp;
|
||||
void
|
||||
pbits(vp, max)
|
||||
register void *vp;
|
||||
int max;
|
||||
{
|
||||
register int i;
|
||||
int count = 0, j;
|
||||
register char *p;
|
||||
int count, j;
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
if (isset(cp, i)) {
|
||||
for (count = i = 0, p = vp; i < max; i++)
|
||||
if (isset(p, i)) {
|
||||
if (count)
|
||||
printf(",%s", count % 6 ? " " : "\n\t");
|
||||
count++;
|
||||
printf("%d", i);
|
||||
j = i;
|
||||
while ((i+1)<max && isset(cp, i+1))
|
||||
while ((i+1)<max && isset(p, i+1))
|
||||
i++;
|
||||
if (i != j)
|
||||
printf("-%d", i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: dumpfs filesys | device\n");
|
||||
exit(1);
|
||||
}
|
||||
|
10
sbin/dumplfs/Makefile
Normal file
10
sbin/dumplfs/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/18/93
|
||||
# $Id: Makefile,v 1.1 1994/06/08 18:58:47 mycroft Exp $
|
||||
|
||||
PROG= dumplfs
|
||||
CFLAGS+=-I/sys/ufs/lfs
|
||||
SRCS= dumplfs.c lfs_cksum.c misc.c
|
||||
.PATH: /sys/ufs/lfs
|
||||
MAN8= dumplfs.0
|
||||
|
||||
.include <bsd.prog.mk>
|
60
sbin/dumplfs/dumplfs.8
Normal file
60
sbin/dumplfs/dumplfs.8
Normal file
@ -0,0 +1,60 @@
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)dumplfs.8 8.1 (Berkeley) 6/18/93
|
||||
.\" $Id: dumplfs.8,v 1.1 1994/06/08 18:58:48 mycroft Exp $
|
||||
.\"
|
||||
.Dd June 18, 1993
|
||||
.Dt DUMPLFS 8
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
.Nm dumplfs
|
||||
.Nd dump file system information
|
||||
.Sh SYNOPSIS
|
||||
.Nm dumplfs
|
||||
.Op Ar filesys No \&| Ar device
|
||||
.Sh DESCRIPTION
|
||||
.Nm Dumplfs
|
||||
prints out the file system layout information for the
|
||||
LFS file system or special device specified.
|
||||
The listing is very long and detailed.
|
||||
This command is useful mostly for finding out certain file system
|
||||
information such as the file system block size.
|
||||
.Sh SEE ALSO
|
||||
.Xr fs 5 ,
|
||||
.Xr disktab 5 ,
|
||||
.Xr disklabel 8 ,
|
||||
.Xr newlfs 8 ,
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm dumplfs
|
||||
command appeared in
|
||||
.Bx 4.4 .
|
613
sbin/dumplfs/dumplfs.c
Normal file
613
sbin/dumplfs/dumplfs.c
Normal file
@ -0,0 +1,613 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1991, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)dumplfs.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: dumplfs.c,v 1.1 1994/06/08 18:58:50 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/lfs/lfs.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <fstab.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "extern.h"
|
||||
|
||||
static void addseg __P((char *));
|
||||
static void dump_cleaner_info __P((struct lfs *, void *));
|
||||
static void dump_dinode __P((struct dinode *));
|
||||
static void dump_ifile __P((int, struct lfs *, int));
|
||||
static int dump_ipage_ifile __P((int, IFILE *, int));
|
||||
static int dump_ipage_segusage __P((struct lfs *, int, IFILE *, int));
|
||||
static void dump_segment __P((int, int, daddr_t, struct lfs *, int));
|
||||
static int dump_sum __P((int, struct lfs *, SEGSUM *, int, daddr_t));
|
||||
static void dump_super __P((struct lfs *));
|
||||
static void usage __P((void));
|
||||
|
||||
typedef struct seglist SEGLIST;
|
||||
struct seglist {
|
||||
SEGLIST *next;
|
||||
int num;
|
||||
};
|
||||
SEGLIST *seglist;
|
||||
|
||||
int daddr_shift;
|
||||
char *special;
|
||||
|
||||
/* Segment Usage formats */
|
||||
#define print_suheader \
|
||||
(void)printf("segnum\tflags\tnbytes\tninos\tnsums\tlastmod\n")
|
||||
|
||||
#define print_suentry(i, sp) \
|
||||
(void)printf("%d\t%c%c%c\t%d\t%d\t%d\t%s", i, \
|
||||
(((sp)->su_flags & SEGUSE_ACTIVE) ? 'A' : ' '), \
|
||||
(((sp)->su_flags & SEGUSE_DIRTY) ? 'D' : 'C'), \
|
||||
(((sp)->su_flags & SEGUSE_SUPERBLOCK) ? 'S' : ' '), \
|
||||
(sp)->su_nbytes, (sp)->su_ninos, (sp)->su_nsums, \
|
||||
ctime((time_t *)&(sp)->su_lastmod))
|
||||
|
||||
/* Ifile formats */
|
||||
#define print_iheader \
|
||||
(void)printf("inum\tstatus\tversion\tdaddr\t\tfreeptr\n")
|
||||
#define print_ientry(i, ip) \
|
||||
if (ip->if_daddr == LFS_UNUSED_DADDR) \
|
||||
(void)printf("%d\tFREE\t%d\t \t\t%d\n", \
|
||||
i, ip->if_version, ip->if_nextfree); \
|
||||
else \
|
||||
(void)printf("%d\tINUSE\t%d\t%8X \n", \
|
||||
i, ip->if_version, ip->if_daddr)
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
struct lfs lfs_sb1, lfs_sb2, *lfs_master;
|
||||
daddr_t seg_addr;
|
||||
int ch, do_allsb, do_ientries, fd, segnum;
|
||||
|
||||
do_allsb = 0;
|
||||
do_ientries = 0;
|
||||
while ((ch = getopt(argc, argv, "ais:")) != EOF)
|
||||
switch(ch) {
|
||||
case 'a': /* Dump all superblocks */
|
||||
do_allsb = 1;
|
||||
break;
|
||||
case 'i': /* Dump ifile entries */
|
||||
do_ientries = 1;
|
||||
break;
|
||||
case 's': /* Dump out these segments */
|
||||
addseg(optarg);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1)
|
||||
usage();
|
||||
|
||||
special = argv[0];
|
||||
if ((fd = open(special, O_RDONLY, 0)) < 0)
|
||||
err("%s: %s", special, strerror(errno));
|
||||
|
||||
/* Read the first superblock */
|
||||
get(fd, LFS_LABELPAD, &lfs_sb1, sizeof(struct lfs));
|
||||
daddr_shift = lfs_sb1.lfs_bshift - lfs_sb1.lfs_fsbtodb;
|
||||
|
||||
/*
|
||||
* Read the second superblock and figure out which check point is
|
||||
* most up to date.
|
||||
*/
|
||||
get(fd,
|
||||
lfs_sb1.lfs_sboffs[1] << daddr_shift, &lfs_sb2, sizeof(struct lfs));
|
||||
|
||||
lfs_master = &lfs_sb1;
|
||||
if (lfs_sb1.lfs_tstamp < lfs_sb2.lfs_tstamp)
|
||||
lfs_master = &lfs_sb2;
|
||||
|
||||
(void)printf("Master Superblock:\n");
|
||||
dump_super(lfs_master);
|
||||
|
||||
dump_ifile(fd, lfs_master, do_ientries);
|
||||
|
||||
if (seglist != NULL)
|
||||
for (; seglist != NULL; seglist = seglist->next) {
|
||||
seg_addr = lfs_master->lfs_sboffs[0] + seglist->num *
|
||||
(lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb);
|
||||
dump_segment(fd,
|
||||
seglist->num, seg_addr, lfs_master, do_allsb);
|
||||
}
|
||||
else
|
||||
for (segnum = 0, seg_addr = lfs_master->lfs_sboffs[0];
|
||||
segnum < lfs_master->lfs_nseg; segnum++, seg_addr +=
|
||||
lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb)
|
||||
dump_segment(fd,
|
||||
segnum, seg_addr, lfs_master, do_allsb);
|
||||
|
||||
(void)close(fd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are reading all the blocks of an inode and dumping out the ifile table.
|
||||
* This code could be tighter, but this is a first pass at getting the stuff
|
||||
* printed out rather than making this code incredibly efficient.
|
||||
*/
|
||||
static void
|
||||
dump_ifile(fd, lfsp, do_ientries)
|
||||
int fd;
|
||||
struct lfs *lfsp;
|
||||
int do_ientries;
|
||||
{
|
||||
IFILE *ipage;
|
||||
struct dinode *dip, *dpage;
|
||||
daddr_t addr, *addrp, *dindir, *iaddrp, *indir;
|
||||
int block_limit, i, inum, j, nblocks, nsupb, psize;
|
||||
|
||||
psize = lfsp->lfs_bsize;
|
||||
addr = lfsp->lfs_idaddr;
|
||||
|
||||
if (!(dpage = malloc(psize)))
|
||||
err("%s", strerror(errno));
|
||||
get(fd, addr << daddr_shift, dpage, psize);
|
||||
|
||||
for (dip = dpage + INOPB(lfsp) - 1; dip >= dpage; --dip)
|
||||
if (dip->di_inumber == LFS_IFILE_INUM)
|
||||
break;
|
||||
|
||||
if (dip < dpage)
|
||||
err("unable to locate ifile inode");
|
||||
|
||||
(void)printf("\nIFILE inode\n");
|
||||
dump_dinode(dip);
|
||||
|
||||
(void)printf("\nIFILE contents\n");
|
||||
nblocks = dip->di_size >> lfsp->lfs_bshift;
|
||||
block_limit = MIN(nblocks, NDADDR);
|
||||
|
||||
/* Get the direct block */
|
||||
if ((ipage = malloc(psize)) == NULL)
|
||||
err("%s", strerror(errno));
|
||||
for (inum = 0, addrp = dip->di_db, i = 0; i < block_limit;
|
||||
i++, addrp++) {
|
||||
get(fd, *addrp << daddr_shift, ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
print_suheader;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i < (lfsp->lfs_segtabsz + lfsp->lfs_cleansz)) {
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
if (!inum)
|
||||
if(!do_ientries)
|
||||
goto e0;
|
||||
else
|
||||
print_iheader;
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb);
|
||||
|
||||
}
|
||||
|
||||
if (nblocks <= NDADDR)
|
||||
goto e0;
|
||||
|
||||
/* Dump out blocks off of single indirect block */
|
||||
if (!(indir = malloc(psize)))
|
||||
err("%s", strerror(errno));
|
||||
get(fd, dip->di_ib[0] << daddr_shift, indir, psize);
|
||||
block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
|
||||
for (addrp = indir; i < block_limit; i++, addrp++) {
|
||||
if (*addrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, *addrp << daddr_shift,ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
continue;
|
||||
} else
|
||||
i -= lfsp->lfs_cleansz;
|
||||
|
||||
if (i < lfsp->lfs_segtabsz) {
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
if (!inum)
|
||||
if(!do_ientries)
|
||||
goto e1;
|
||||
else
|
||||
print_iheader;
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb);
|
||||
}
|
||||
|
||||
if (nblocks <= lfsp->lfs_nindir * lfsp->lfs_ifpb)
|
||||
goto e1;
|
||||
|
||||
/* Get the double indirect block */
|
||||
if (!(dindir = malloc(psize)))
|
||||
err("%s", strerror(errno));
|
||||
get(fd, dip->di_ib[1] << daddr_shift, dindir, psize);
|
||||
for (iaddrp = dindir, j = 0; j < lfsp->lfs_nindir; j++, iaddrp++) {
|
||||
if (*iaddrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, *iaddrp << daddr_shift, indir, psize);
|
||||
block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
|
||||
for (addrp = indir; i < block_limit; i++, addrp++) {
|
||||
if (*addrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, *addrp << daddr_shift, ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
continue;
|
||||
} else
|
||||
i -= lfsp->lfs_cleansz;
|
||||
|
||||
if (i < lfsp->lfs_segtabsz) {
|
||||
inum = dump_ipage_segusage(lfsp,
|
||||
inum, ipage, lfsp->lfs_sepb);
|
||||
if (!inum)
|
||||
if(!do_ientries)
|
||||
goto e2;
|
||||
else
|
||||
print_iheader;
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum,
|
||||
ipage, lfsp->lfs_ifpb);
|
||||
}
|
||||
}
|
||||
e2: free(dindir);
|
||||
e1: free(indir);
|
||||
e0: free(dpage);
|
||||
free(ipage);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_ipage_ifile(i, pp, tot)
|
||||
int i;
|
||||
IFILE *pp;
|
||||
int tot;
|
||||
{
|
||||
IFILE *ip;
|
||||
int cnt, max;
|
||||
|
||||
max = i + tot;
|
||||
|
||||
for (ip = pp, cnt = i; cnt < max; cnt++, ip++)
|
||||
print_ientry(cnt, ip);
|
||||
return (max);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_ipage_segusage(lfsp, i, pp, tot)
|
||||
struct lfs *lfsp;
|
||||
int i;
|
||||
IFILE *pp;
|
||||
int tot;
|
||||
{
|
||||
SEGUSE *sp;
|
||||
int cnt, max;
|
||||
|
||||
max = i + tot;
|
||||
for (sp = (SEGUSE *)pp, cnt = i;
|
||||
cnt < lfsp->lfs_nseg && cnt < max; cnt++, sp++)
|
||||
print_suentry(cnt, sp);
|
||||
if (max >= lfsp->lfs_nseg)
|
||||
return (0);
|
||||
else
|
||||
return (max);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dinode(dip)
|
||||
struct dinode *dip;
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)printf("%s%d\t%s%d\t%s%d\t%s%d\t%s%d\n",
|
||||
"mode ", dip->di_mode,
|
||||
"nlink ", dip->di_nlink,
|
||||
"uid ", dip->di_uid,
|
||||
"gid ", dip->di_gid,
|
||||
"size ", dip->di_size);
|
||||
(void)printf("%s%s%s%s%s%s",
|
||||
"atime ", ctime(&dip->di_atime.ts_sec),
|
||||
"mtime ", ctime(&dip->di_mtime.ts_sec),
|
||||
"ctime ", ctime(&dip->di_ctime.ts_sec));
|
||||
(void)printf("inum %d\n", dip->di_inumber);
|
||||
(void)printf("Direct Addresses\n");
|
||||
for (i = 0; i < NDADDR; i++) {
|
||||
(void)printf("\t0x%X", dip->di_db[i]);
|
||||
if ((i % 6) == 5)
|
||||
(void)printf("\n");
|
||||
}
|
||||
for (i = 0; i < NIADDR; i++)
|
||||
(void)printf("\t0x%X", dip->di_ib[i]);
|
||||
(void)printf("\n");
|
||||
}
|
||||
|
||||
static int
|
||||
dump_sum(fd, lfsp, sp, segnum, addr)
|
||||
struct lfs *lfsp;
|
||||
SEGSUM *sp;
|
||||
int fd, segnum;
|
||||
daddr_t addr;
|
||||
{
|
||||
FINFO *fp;
|
||||
long *dp;
|
||||
int i, j;
|
||||
int ck;
|
||||
int numblocks;
|
||||
struct dinode *inop;
|
||||
|
||||
if (sp->ss_sumsum != (ck = cksum(&sp->ss_datasum,
|
||||
LFS_SUMMARY_SIZE - sizeof(sp->ss_sumsum)))) {
|
||||
(void)printf("dumplfs: %s %d address 0x%lx\n",
|
||||
"corrupt summary block; segment", segnum, addr);
|
||||
return(0);
|
||||
}
|
||||
|
||||
(void)printf("Segment Summary Info at 0x%lx\n", addr);
|
||||
(void)printf(" %s0x%X\t%s%d\t%s%d\n %s0x%X\t%s0x%X",
|
||||
"next ", sp->ss_next,
|
||||
"nfinfo ", sp->ss_nfinfo,
|
||||
"ninos ", sp->ss_ninos,
|
||||
"sumsum ", sp->ss_sumsum,
|
||||
"datasum ", sp->ss_datasum );
|
||||
(void)printf("\tcreate %s", ctime((time_t *)&sp->ss_create));
|
||||
|
||||
numblocks = (sp->ss_ninos + INOPB(lfsp) - 1) / INOPB(lfsp);
|
||||
|
||||
/* Dump out inode disk addresses */
|
||||
dp = (daddr_t *)sp;
|
||||
dp += LFS_SUMMARY_SIZE / sizeof(daddr_t);
|
||||
inop = malloc(1 << lfsp->lfs_bshift);
|
||||
printf(" Inode addresses:");
|
||||
for (dp--, i = 0; i < sp->ss_ninos; dp--) {
|
||||
printf("\t0x%X {", *dp);
|
||||
get(fd, *dp << (lfsp->lfs_bshift - lfsp->lfs_fsbtodb), inop,
|
||||
(1 << lfsp->lfs_bshift));
|
||||
for (j = 0; i < sp->ss_ninos && j < INOPB(lfsp); j++, i++) {
|
||||
if (j > 0)
|
||||
(void)printf(", ");
|
||||
(void)printf("%d", inop[j].di_inumber);
|
||||
}
|
||||
(void)printf("}");
|
||||
if (((i/INOPB(lfsp)) % 4) == 3)
|
||||
(void)printf("\n");
|
||||
}
|
||||
free(inop);
|
||||
|
||||
printf("\n");
|
||||
for (fp = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo; i++) {
|
||||
numblocks += fp->fi_nblocks;
|
||||
(void)printf(" FINFO for inode: %d version %d nblocks %d\n",
|
||||
fp->fi_ino, fp->fi_version, fp->fi_nblocks);
|
||||
dp = &(fp->fi_blocks[0]);
|
||||
for (j = 0; j < fp->fi_nblocks; j++, dp++) {
|
||||
(void)printf("\t%d", *dp);
|
||||
if ((j % 8) == 7)
|
||||
(void)printf("\n");
|
||||
}
|
||||
if ((j % 8) != 0)
|
||||
(void)printf("\n");
|
||||
fp = (FINFO *)dp;
|
||||
}
|
||||
return (numblocks);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_segment(fd, segnum, addr, lfsp, dump_sb)
|
||||
int fd, segnum;
|
||||
daddr_t addr;
|
||||
struct lfs *lfsp;
|
||||
int dump_sb;
|
||||
{
|
||||
struct lfs lfs_sb, *sbp;
|
||||
SEGSUM *sump;
|
||||
char sumblock[LFS_SUMMARY_SIZE];
|
||||
int did_one, nblocks, sb;
|
||||
off_t sum_offset, super_off;
|
||||
|
||||
(void)printf("\nSEGMENT %d (Disk Address 0x%X)\n",
|
||||
addr >> (lfsp->lfs_segshift - daddr_shift), addr);
|
||||
sum_offset = (addr << (lfsp->lfs_bshift - lfsp->lfs_fsbtodb));
|
||||
|
||||
sb = 0;
|
||||
did_one = 0;
|
||||
do {
|
||||
get(fd, sum_offset, sumblock, LFS_SUMMARY_SIZE);
|
||||
sump = (SEGSUM *)sumblock;
|
||||
if (sump->ss_sumsum != cksum (&sump->ss_datasum,
|
||||
LFS_SUMMARY_SIZE - sizeof(sump->ss_sumsum))) {
|
||||
sbp = (struct lfs *)sump;
|
||||
if (sb = (sbp->lfs_magic == LFS_MAGIC)) {
|
||||
super_off = sum_offset;
|
||||
sum_offset += LFS_SBPAD;
|
||||
} else if (did_one)
|
||||
break;
|
||||
else {
|
||||
printf("Segment at 0x%X corrupt\n", addr);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
nblocks = dump_sum(fd, lfsp, sump, segnum, sum_offset >>
|
||||
(lfsp->lfs_bshift - lfsp->lfs_fsbtodb));
|
||||
if (nblocks)
|
||||
sum_offset += LFS_SUMMARY_SIZE +
|
||||
(nblocks << lfsp->lfs_bshift);
|
||||
else
|
||||
sum_offset = 0;
|
||||
did_one = 1;
|
||||
}
|
||||
} while (sum_offset);
|
||||
|
||||
if (dump_sb && sb) {
|
||||
get(fd, super_off, &lfs_sb, sizeof(struct lfs));
|
||||
dump_super(&lfs_sb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_super(lfsp)
|
||||
struct lfs *lfsp;
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)printf("%s0x%X\t%s0x%X\t%s%d\t%s%d\n",
|
||||
"magic ", lfsp->lfs_magic,
|
||||
"version ", lfsp->lfs_version,
|
||||
"size ", lfsp->lfs_size,
|
||||
"ssize ", lfsp->lfs_ssize);
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"dsize ", lfsp->lfs_dsize,
|
||||
"bsize ", lfsp->lfs_bsize,
|
||||
"fsize ", lfsp->lfs_fsize,
|
||||
"frag ", lfsp->lfs_frag);
|
||||
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"minfree ", lfsp->lfs_minfree,
|
||||
"inopb ", lfsp->lfs_inopb,
|
||||
"ifpb ", lfsp->lfs_ifpb,
|
||||
"nindir ", lfsp->lfs_nindir);
|
||||
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"nseg ", lfsp->lfs_nseg,
|
||||
"nspf ", lfsp->lfs_nspf,
|
||||
"cleansz ", lfsp->lfs_cleansz,
|
||||
"segtabsz ", lfsp->lfs_segtabsz);
|
||||
|
||||
(void)printf("%s0x%X\t%s%d\t%s0x%X\t%s%d\n",
|
||||
"segmask ", lfsp->lfs_segmask,
|
||||
"segshift ", lfsp->lfs_segshift,
|
||||
"bmask ", lfsp->lfs_bmask,
|
||||
"bshift ", lfsp->lfs_bshift);
|
||||
|
||||
(void)printf("%s0x%X\t\t%s%d\t%s0x%X\t%s%d\n",
|
||||
"ffmask ", lfsp->lfs_ffmask,
|
||||
"ffshift ", lfsp->lfs_ffshift,
|
||||
"fbmask ", lfsp->lfs_fbmask,
|
||||
"fbshift ", lfsp->lfs_fbshift);
|
||||
|
||||
(void)printf("%s%d\t%s%d\t%s0x%X\t%s0x%qx\n",
|
||||
"sushift ", lfsp->lfs_sushift,
|
||||
"fsbtodb ", lfsp->lfs_fsbtodb,
|
||||
"cksum ", lfsp->lfs_cksum,
|
||||
"maxfilesize ", lfsp->lfs_maxfilesize);
|
||||
|
||||
(void)printf("Superblock disk addresses:\t");
|
||||
for (i = 0; i < LFS_MAXNUMSB; i++) {
|
||||
(void)printf(" 0x%X", lfsp->lfs_sboffs[i]);
|
||||
if ( i == (LFS_MAXNUMSB >> 1))
|
||||
(void)printf("\n\t\t\t\t");
|
||||
}
|
||||
(void)printf("\n");
|
||||
|
||||
(void)printf("Checkpoint Info\n");
|
||||
(void)printf("%s%d\t%s0x%X\t%s%d\n",
|
||||
"free ", lfsp->lfs_free,
|
||||
"idaddr ", lfsp->lfs_idaddr,
|
||||
"ifile ", lfsp->lfs_ifile);
|
||||
(void)printf("%s%d\t%s%d\t%s%d\n",
|
||||
"bfree ", lfsp->lfs_bfree,
|
||||
"avail ", lfsp->lfs_avail,
|
||||
"uinodes ", lfsp->lfs_uinodes);
|
||||
(void)printf("%s%d\t%s0x%X\t%s0x%X\n%s0x%X\t%s0x%X\t",
|
||||
"nfiles ", lfsp->lfs_nfiles,
|
||||
"lastseg ", lfsp->lfs_lastseg,
|
||||
"nextseg ", lfsp->lfs_nextseg,
|
||||
"curseg ", lfsp->lfs_curseg,
|
||||
"offset ", lfsp->lfs_offset);
|
||||
(void)printf("tstamp %s", ctime((time_t *)&lfsp->lfs_tstamp));
|
||||
(void)printf("\nIn-Memory Information\n");
|
||||
(void)printf("%s%d\t%s0x%X\t%s%d%s%d\t%s%d\n",
|
||||
"seglock ", lfsp->lfs_seglock,
|
||||
"iocount ", lfsp->lfs_iocount,
|
||||
"writer ", lfsp->lfs_writer,
|
||||
"dirops ", lfsp->lfs_dirops,
|
||||
"doifile ", lfsp->lfs_doifile);
|
||||
(void)printf("%s%d\t%s%d\t%s0x%X\t%s%d\n",
|
||||
"nactive ", lfsp->lfs_nactive,
|
||||
"fmod ", lfsp->lfs_fmod,
|
||||
"clean ", lfsp->lfs_clean,
|
||||
"ronly ", lfsp->lfs_ronly);
|
||||
}
|
||||
|
||||
static void
|
||||
addseg(arg)
|
||||
char *arg;
|
||||
{
|
||||
SEGLIST *p;
|
||||
|
||||
if ((p = malloc(sizeof(SEGLIST))) == NULL)
|
||||
err("%s", strerror(errno));
|
||||
p->next = seglist;
|
||||
p->num = atoi(arg);
|
||||
seglist = p;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_cleaner_info(lfsp, ipage)
|
||||
struct lfs *lfsp;
|
||||
void *ipage;
|
||||
{
|
||||
CLEANERINFO *cip;
|
||||
|
||||
cip = (CLEANERINFO *)ipage;
|
||||
(void)printf("segments clean\t%d\tsegments dirty\t%d\n\n",
|
||||
cip->clean, cip->dirty);
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: dumplfs [-ai] [-s segnum] file\n");
|
||||
exit(1);
|
||||
}
|
40
sbin/dumplfs/extern.h
Normal file
40
sbin/dumplfs/extern.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* from: @(#)extern.h 8.1 (Berkeley) 6/5/93
|
||||
* $Id: extern.h,v 1.1 1994/06/08 18:58:51 mycroft Exp $
|
||||
*/
|
||||
|
||||
void err __P((const char *, ...));
|
||||
void get __P((int, off_t, void *, size_t));
|
||||
|
||||
extern char *special;
|
91
sbin/dumplfs/misc.c
Normal file
91
sbin/dumplfs/misc.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)misc.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: misc.c,v 1.1 1994/06/08 18:58:52 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "extern.h"
|
||||
|
||||
void
|
||||
get(fd, off, p, len)
|
||||
int fd;
|
||||
off_t off;
|
||||
void *p;
|
||||
size_t len;
|
||||
{
|
||||
int rbytes;
|
||||
|
||||
if (lseek(fd, off, SEEK_SET) < 0)
|
||||
err("%s: %s", special, strerror(errno));
|
||||
if ((rbytes = read(fd, p, len)) < 0)
|
||||
err("%s: %s", special, strerror(errno));
|
||||
if (rbytes != len)
|
||||
err("%s: short read (%d, not %d)", special, rbytes, len);
|
||||
}
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
err(const char *fmt, ...)
|
||||
#else
|
||||
err(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void)fprintf(stderr, "dumplfs: ");
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
@ -1,10 +1,10 @@
|
||||
# from: @(#)Makefile 5.15 (Berkeley) 6/29/90
|
||||
# $Id: Makefile,v 1.5 1993/08/01 05:37:50 mycroft Exp $
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.6 1994/06/08 19:00:18 mycroft Exp $
|
||||
|
||||
PROG= fsck
|
||||
MAN8= fsck.0
|
||||
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
|
||||
pass5.c preen.c setup.c utilities.c ufs_subr.c ufs_tables.c
|
||||
.PATH: ${.CURDIR}/../../sys/ufs
|
||||
pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
|
||||
.PATH: ${.CURDIR}/../../sys/ufs/ffs
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
151
sbin/fsck/SMM.doc/0.t
Normal file
151
sbin/fsck/SMM.doc/0.t
Normal file
@ -0,0 +1,151 @@
|
||||
.\" Copyright (c) 1986, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)0.t 8.1 (Berkeley) 6/8/93
|
||||
.\" $Id: 0.t,v 1.1 1994/06/08 19:00:49 mycroft Exp $
|
||||
.\"
|
||||
.if n .ND
|
||||
.TL
|
||||
Fsck \- The UNIX\(dg File System Check Program
|
||||
.EH 'SMM:3-%''The \s-2UNIX\s+2 File System Check Program'
|
||||
.OH 'The \s-2UNIX\s+2 File System Check Program''SMM:3-%'
|
||||
.AU
|
||||
Marshall Kirk McKusick
|
||||
.AI
|
||||
Computer Systems Research Group
|
||||
Computer Science Division
|
||||
Department of Electrical Engineering and Computer Science
|
||||
University of California, Berkeley
|
||||
Berkeley, CA 94720
|
||||
.AU
|
||||
T. J. Kowalski
|
||||
.AI
|
||||
Bell Laboratories
|
||||
Murray Hill, New Jersey 07974
|
||||
.AB
|
||||
.FS
|
||||
\(dgUNIX is a trademark of Bell Laboratories.
|
||||
.FE
|
||||
.FS
|
||||
This work was done under grants from
|
||||
the National Science Foundation under grant MCS80-05144,
|
||||
and the Defense Advance Research Projects Agency (DoD) under
|
||||
Arpa Order No. 4031 monitored by Naval Electronic System Command under
|
||||
Contract No. N00039-82-C-0235.
|
||||
.FE
|
||||
This document reflects the use of
|
||||
.I fsck
|
||||
with the 4.2BSD and 4.3BSD file system organization. This
|
||||
is a revision of the
|
||||
original paper written by
|
||||
T. J. Kowalski.
|
||||
.PP
|
||||
File System Check Program (\fIfsck\fR)
|
||||
is an interactive file system check and repair program.
|
||||
.I Fsck
|
||||
uses the redundant structural information in the
|
||||
UNIX file system to perform several consistency checks.
|
||||
If an inconsistency is detected, it is reported
|
||||
to the operator, who may elect to fix or ignore
|
||||
each inconsistency.
|
||||
These inconsistencies result from the permanent interruption
|
||||
of the file system updates, which are performed every
|
||||
time a file is modified.
|
||||
Unless there has been a hardware failure,
|
||||
.I fsck
|
||||
is able to repair corrupted file systems
|
||||
using procedures based upon the order in which UNIX honors
|
||||
these file system update requests.
|
||||
.PP
|
||||
The purpose of this document is to describe the normal updating
|
||||
of the file system,
|
||||
to discuss the possible causes of file system corruption,
|
||||
and to present the corrective actions implemented
|
||||
by
|
||||
.I fsck.
|
||||
Both the program and the interaction between the
|
||||
program and the operator are described.
|
||||
.sp 2
|
||||
.LP
|
||||
Revised July 16, 1985
|
||||
.AE
|
||||
.LP
|
||||
.bp
|
||||
.ce
|
||||
.B "TABLE OF CONTENTS"
|
||||
.LP
|
||||
.sp 1
|
||||
.nf
|
||||
.B "1. Introduction"
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B "2. Overview of the file system
|
||||
2.1. Superblock
|
||||
2.2. Summary Information
|
||||
2.3. Cylinder groups
|
||||
2.4. Fragments
|
||||
2.5. Updates to the file system
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B "3. Fixing corrupted file systems
|
||||
3.1. Detecting and correcting corruption
|
||||
3.2. Super block checking
|
||||
3.3. Free block checking
|
||||
3.4. Checking the inode state
|
||||
3.5. Inode links
|
||||
3.6. Inode data size
|
||||
3.7. Checking the data associated with an inode
|
||||
3.8. File system connectivity
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B Acknowledgements
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B References
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B "4. Appendix A
|
||||
4.1. Conventions
|
||||
4.2. Initialization
|
||||
4.3. Phase 1 - Check Blocks and Sizes
|
||||
4.4. Phase 1b - Rescan for more Dups
|
||||
4.5. Phase 2 - Check Pathnames
|
||||
4.6. Phase 3 - Check Connectivity
|
||||
4.7. Phase 4 - Check Reference Counts
|
||||
4.8. Phase 5 - Check Cyl groups
|
||||
4.9. Cleanup
|
||||
.ds RH Introduction
|
||||
.bp
|
84
sbin/fsck/SMM.doc/1.t
Normal file
84
sbin/fsck/SMM.doc/1.t
Normal file
@ -0,0 +1,84 @@
|
||||
.\" Copyright (c) 1982, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)1.t 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: 1.t,v 1.1 1994/06/08 19:01:21 mycroft Exp $
|
||||
.\"
|
||||
.ds RH Introduction
|
||||
.NH
|
||||
Introduction
|
||||
.PP
|
||||
This document reflects the use of
|
||||
.I fsck
|
||||
with the 4.2BSD and 4.3BSD file system organization. This
|
||||
is a revision of the
|
||||
original paper written by
|
||||
T. J. Kowalski.
|
||||
.PP
|
||||
When a UNIX
|
||||
operating system is brought up, a consistency
|
||||
check of the file systems should always be performed.
|
||||
This precautionary measure helps to insure
|
||||
a reliable environment for file storage on disk.
|
||||
If an inconsistency is discovered,
|
||||
corrective action must be taken.
|
||||
.I Fsck
|
||||
runs in two modes.
|
||||
Normally it is run non-interactively by the system after
|
||||
a normal boot.
|
||||
When running in this mode,
|
||||
it will only make changes to the file system that are known
|
||||
to always be correct.
|
||||
If an unexpected inconsistency is found
|
||||
.I fsck
|
||||
will exit with a non-zero exit status,
|
||||
leaving the system running single-user.
|
||||
Typically the operator then runs
|
||||
.I fsck
|
||||
interactively.
|
||||
When running in this mode,
|
||||
each problem is listed followed by a suggested corrective action.
|
||||
The operator must decide whether or not the suggested correction
|
||||
should be made.
|
||||
.PP
|
||||
The purpose of this memo is to dispel the
|
||||
mystique surrounding
|
||||
file system inconsistencies.
|
||||
It first describes the updating of the file system
|
||||
(the calm before the storm) and
|
||||
then describes file system corruption (the storm).
|
||||
Finally,
|
||||
the set of deterministic corrective actions
|
||||
used by
|
||||
.I fsck
|
||||
(the Coast Guard
|
||||
to the rescue) is presented.
|
||||
.ds RH Overview of the File System
|
266
sbin/fsck/SMM.doc/2.t
Normal file
266
sbin/fsck/SMM.doc/2.t
Normal file
@ -0,0 +1,266 @@
|
||||
.\" Copyright (c) 1982, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)2.t 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: 2.t,v 1.1 1994/06/08 19:01:22 mycroft Exp $
|
||||
.\"
|
||||
.ds RH Overview of the file system
|
||||
.NH
|
||||
Overview of the file system
|
||||
.PP
|
||||
The file system is discussed in detail in [Mckusick84];
|
||||
this section gives a brief overview.
|
||||
.NH 2
|
||||
Superblock
|
||||
.PP
|
||||
A file system is described by its
|
||||
.I "super-block" .
|
||||
The super-block is built when the file system is created (\c
|
||||
.I newfs (8))
|
||||
and never changes.
|
||||
The super-block
|
||||
contains the basic parameters of the file system,
|
||||
such as the number of data blocks it contains
|
||||
and a count of the maximum number of files.
|
||||
Because the super-block contains critical data,
|
||||
.I newfs
|
||||
replicates it to protect against catastrophic loss.
|
||||
The
|
||||
.I "default super block"
|
||||
always resides at a fixed offset from the beginning
|
||||
of the file system's disk partition.
|
||||
The
|
||||
.I "redundant super blocks"
|
||||
are not referenced unless a head crash
|
||||
or other hard disk error causes the default super-block
|
||||
to be unusable.
|
||||
The redundant blocks are sprinkled throughout the disk partition.
|
||||
.PP
|
||||
Within the file system are files.
|
||||
Certain files are distinguished as directories and contain collections
|
||||
of pointers to files that may themselves be directories.
|
||||
Every file has a descriptor associated with it called an
|
||||
.I "inode".
|
||||
The inode contains information describing ownership of the file,
|
||||
time stamps indicating modification and access times for the file,
|
||||
and an array of indices pointing to the data blocks for the file.
|
||||
In this section,
|
||||
we assume that the first 12 blocks
|
||||
of the file are directly referenced by values stored
|
||||
in the inode structure itself\(dg.
|
||||
.FS
|
||||
\(dgThe actual number may vary from system to system, but is usually in
|
||||
the range 5-13.
|
||||
.FE
|
||||
The inode structure may also contain references to indirect blocks
|
||||
containing further data block indices.
|
||||
In a file system with a 4096 byte block size, a singly indirect
|
||||
block contains 1024 further block addresses,
|
||||
a doubly indirect block contains 1024 addresses of further single indirect
|
||||
blocks,
|
||||
and a triply indirect block contains 1024 addresses of further doubly indirect
|
||||
blocks (the triple indirect block is never needed in practice).
|
||||
.PP
|
||||
In order to create files with up to
|
||||
2\(ua32 bytes,
|
||||
using only two levels of indirection,
|
||||
the minimum size of a file system block is 4096 bytes.
|
||||
The size of file system blocks can be any power of two
|
||||
greater than or equal to 4096.
|
||||
The block size of the file system is maintained in the super-block,
|
||||
so it is possible for file systems of different block sizes
|
||||
to be accessible simultaneously on the same system.
|
||||
The block size must be decided when
|
||||
.I newfs
|
||||
creates the file system;
|
||||
the block size cannot be subsequently
|
||||
changed without rebuilding the file system.
|
||||
.NH 2
|
||||
Summary information
|
||||
.PP
|
||||
Associated with the super block is non replicated
|
||||
.I "summary information" .
|
||||
The summary information changes
|
||||
as the file system is modified.
|
||||
The summary information contains
|
||||
the number of blocks, fragments, inodes and directories in the file system.
|
||||
.NH 2
|
||||
Cylinder groups
|
||||
.PP
|
||||
The file system partitions the disk into one or more areas called
|
||||
.I "cylinder groups".
|
||||
A cylinder group is comprised of one or more consecutive
|
||||
cylinders on a disk.
|
||||
Each cylinder group includes inode slots for files, a
|
||||
.I "block map"
|
||||
describing available blocks in the cylinder group,
|
||||
and summary information describing the usage of data blocks
|
||||
within the cylinder group.
|
||||
A fixed number of inodes is allocated for each cylinder group
|
||||
when the file system is created.
|
||||
The current policy is to allocate one inode for each 2048
|
||||
bytes of disk space;
|
||||
this is expected to be far more inodes than will ever be needed.
|
||||
.PP
|
||||
All the cylinder group bookkeeping information could be
|
||||
placed at the beginning of each cylinder group.
|
||||
However if this approach were used,
|
||||
all the redundant information would be on the top platter.
|
||||
A single hardware failure that destroyed the top platter
|
||||
could cause the loss of all copies of the redundant super-blocks.
|
||||
Thus the cylinder group bookkeeping information
|
||||
begins at a floating offset from the beginning of the cylinder group.
|
||||
The offset for
|
||||
the
|
||||
.I "i+1" st
|
||||
cylinder group is about one track further
|
||||
from the beginning of the cylinder group
|
||||
than it was for the
|
||||
.I "i" th
|
||||
cylinder group.
|
||||
In this way,
|
||||
the redundant
|
||||
information spirals down into the pack;
|
||||
any single track, cylinder,
|
||||
or platter can be lost without losing all copies of the super-blocks.
|
||||
Except for the first cylinder group,
|
||||
the space between the beginning of the cylinder group
|
||||
and the beginning of the cylinder group information stores data.
|
||||
.NH 2
|
||||
Fragments
|
||||
.PP
|
||||
To avoid waste in storing small files,
|
||||
the file system space allocator divides a single
|
||||
file system block into one or more
|
||||
.I "fragments".
|
||||
The fragmentation of the file system is specified
|
||||
when the file system is created;
|
||||
each file system block can be optionally broken into
|
||||
2, 4, or 8 addressable fragments.
|
||||
The lower bound on the size of these fragments is constrained
|
||||
by the disk sector size;
|
||||
typically 512 bytes is the lower bound on fragment size.
|
||||
The block map associated with each cylinder group
|
||||
records the space availability at the fragment level.
|
||||
Aligned fragments are examined
|
||||
to determine block availability.
|
||||
.PP
|
||||
On a file system with a block size of 4096 bytes
|
||||
and a fragment size of 1024 bytes,
|
||||
a file is represented by zero or more 4096 byte blocks of data,
|
||||
and possibly a single fragmented block.
|
||||
If a file system block must be fragmented to obtain
|
||||
space for a small amount of data,
|
||||
the remainder of the block is made available for allocation
|
||||
to other files.
|
||||
For example,
|
||||
consider an 11000 byte file stored on
|
||||
a 4096/1024 byte file system.
|
||||
This file uses two full size blocks and a 3072 byte fragment.
|
||||
If no fragments with at least 3072 bytes
|
||||
are available when the file is created,
|
||||
a full size block is split yielding the necessary 3072 byte
|
||||
fragment and an unused 1024 byte fragment.
|
||||
This remaining fragment can be allocated to another file, as needed.
|
||||
.NH 2
|
||||
Updates to the file system
|
||||
.PP
|
||||
Every working day hundreds of files
|
||||
are created, modified, and removed.
|
||||
Every time a file is modified,
|
||||
the operating system performs a
|
||||
series of file system updates.
|
||||
These updates, when written on disk, yield a consistent file system.
|
||||
The file system stages
|
||||
all modifications of critical information;
|
||||
modification can
|
||||
either be completed or cleanly backed out after a crash.
|
||||
Knowing the information that is first written to the file system,
|
||||
deterministic procedures can be developed to
|
||||
repair a corrupted file system.
|
||||
To understand this process,
|
||||
the order that the update
|
||||
requests were being honored must first be understood.
|
||||
.PP
|
||||
When a user program does an operation to change the file system,
|
||||
such as a
|
||||
.I write ,
|
||||
the data to be written is copied into an internal
|
||||
.I "in-core"
|
||||
buffer in the kernel.
|
||||
Normally, the disk update is handled asynchronously;
|
||||
the user process is allowed to proceed even though
|
||||
the data has not yet been written to the disk.
|
||||
The data,
|
||||
along with the inode information reflecting the change,
|
||||
is eventually written out to disk.
|
||||
The real disk write may not happen until long after the
|
||||
.I write
|
||||
system call has returned.
|
||||
Thus at any given time, the file system,
|
||||
as it resides on the disk,
|
||||
lags the state of the file system represented by the in-core information.
|
||||
.PP
|
||||
The disk information is updated to reflect the in-core information
|
||||
when the buffer is required for another use,
|
||||
when a
|
||||
.I sync (2)
|
||||
is done (at 30 second intervals) by
|
||||
.I "/etc/update" "(8),"
|
||||
or by manual operator intervention with the
|
||||
.I sync (8)
|
||||
command.
|
||||
If the system is halted without writing out the in-core information,
|
||||
the file system on the disk will be in an inconsistent state.
|
||||
.PP
|
||||
If all updates are done asynchronously, several serious
|
||||
inconsistencies can arise.
|
||||
One inconsistency is that a block may be claimed by two inodes.
|
||||
Such an inconsistency can occur when the system is halted before
|
||||
the pointer to the block in the old inode has been cleared
|
||||
in the copy of the old inode on the disk,
|
||||
and after the pointer to the block in the new inode has been written out
|
||||
to the copy of the new inode on the disk.
|
||||
Here,
|
||||
there is no deterministic method for deciding
|
||||
which inode should really claim the block.
|
||||
A similar problem can arise with a multiply claimed inode.
|
||||
.PP
|
||||
The problem with asynchronous inode updates
|
||||
can be avoided by doing all inode deallocations synchronously.
|
||||
Consequently,
|
||||
inodes and indirect blocks are written to the disk synchronously
|
||||
(\fIi.e.\fP the process blocks until the information is
|
||||
really written to disk)
|
||||
when they are being deallocated.
|
||||
Similarly inodes are kept consistent by synchronously
|
||||
deleting, adding, or changing directory entries.
|
||||
.ds RH Fixing corrupted file systems
|
440
sbin/fsck/SMM.doc/3.t
Normal file
440
sbin/fsck/SMM.doc/3.t
Normal file
@ -0,0 +1,440 @@
|
||||
.\" Copyright (c) 1982, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)3.t 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: 3.t,v 1.1 1994/06/08 19:01:23 mycroft Exp $
|
||||
.\"
|
||||
.ds RH Fixing corrupted file systems
|
||||
.NH
|
||||
Fixing corrupted file systems
|
||||
.PP
|
||||
A file system
|
||||
can become corrupted in several ways.
|
||||
The most common of these ways are
|
||||
improper shutdown procedures
|
||||
and hardware failures.
|
||||
.PP
|
||||
File systems may become corrupted during an
|
||||
.I "unclean halt" .
|
||||
This happens when proper shutdown
|
||||
procedures are not observed,
|
||||
physically write-protecting a mounted file system,
|
||||
or a mounted file system is taken off-line.
|
||||
The most common operator procedural failure is forgetting to
|
||||
.I sync
|
||||
the system before halting the CPU.
|
||||
.PP
|
||||
File systems may become further corrupted if proper startup
|
||||
procedures are not observed, e.g.,
|
||||
not checking a file system for inconsistencies,
|
||||
and not repairing inconsistencies.
|
||||
Allowing a corrupted file system to be used (and, thus, to be modified
|
||||
further) can be disastrous.
|
||||
.PP
|
||||
Any piece of hardware can fail at any time.
|
||||
Failures
|
||||
can be as subtle as a bad block
|
||||
on a disk pack, or as blatant as a non-functional disk-controller.
|
||||
.NH 2
|
||||
Detecting and correcting corruption
|
||||
.PP
|
||||
Normally
|
||||
.I fsck
|
||||
is run non-interactively.
|
||||
In this mode it will only fix
|
||||
corruptions that are expected to occur from an unclean halt.
|
||||
These actions are a proper subset of the actions that
|
||||
.I fsck
|
||||
will take when it is running interactively.
|
||||
Throughout this paper we assume that
|
||||
.I fsck
|
||||
is being run interactively,
|
||||
and all possible errors can be encountered.
|
||||
When an inconsistency is discovered in this mode,
|
||||
.I fsck
|
||||
reports the inconsistency for the operator to
|
||||
chose a corrective action.
|
||||
.PP
|
||||
A quiescent\(dd
|
||||
.FS
|
||||
\(dd I.e., unmounted and not being written on.
|
||||
.FE
|
||||
file system may be checked for structural integrity
|
||||
by performing consistency checks on the
|
||||
redundant data intrinsic to a file system.
|
||||
The redundant data is either read from
|
||||
the file system,
|
||||
or computed from other known values.
|
||||
The file system
|
||||
.B must
|
||||
be in a quiescent state when
|
||||
.I fsck
|
||||
is run,
|
||||
since
|
||||
.I fsck
|
||||
is a multi-pass program.
|
||||
.PP
|
||||
In the following sections,
|
||||
we discuss methods to discover inconsistencies
|
||||
and possible corrective actions
|
||||
for the cylinder group blocks, the inodes, the indirect blocks, and
|
||||
the data blocks containing directory entries.
|
||||
.NH 2
|
||||
Super-block checking
|
||||
.PP
|
||||
The most commonly corrupted item in a file system
|
||||
is the summary information
|
||||
associated with the super-block.
|
||||
The summary information is prone to corruption
|
||||
because it is modified with every change to the file
|
||||
system's blocks or inodes,
|
||||
and is usually corrupted
|
||||
after an unclean halt.
|
||||
.PP
|
||||
The super-block is checked for inconsistencies
|
||||
involving file-system size, number of inodes,
|
||||
free-block count, and the free-inode count.
|
||||
The file-system size must be larger than the
|
||||
number of blocks used by the super-block
|
||||
and the number of blocks used by the list of inodes.
|
||||
The file-system size and layout information
|
||||
are the most critical pieces of information for
|
||||
.I fsck .
|
||||
While there is no way to actually check these sizes,
|
||||
since they are statically determined by
|
||||
.I newfs ,
|
||||
.I fsck
|
||||
can check that these sizes are within reasonable bounds.
|
||||
All other file system checks require that these sizes be correct.
|
||||
If
|
||||
.I fsck
|
||||
detects corruption in the static parameters of the default super-block,
|
||||
.I fsck
|
||||
requests the operator to specify the location of an alternate super-block.
|
||||
.NH 2
|
||||
Free block checking
|
||||
.PP
|
||||
.I Fsck
|
||||
checks that all the blocks
|
||||
marked as free in the cylinder group block maps
|
||||
are not claimed by any files.
|
||||
When all the blocks have been initially accounted for,
|
||||
.I fsck
|
||||
checks that
|
||||
the number of free blocks
|
||||
plus the number of blocks claimed by the inodes
|
||||
equals the total number of blocks in the file system.
|
||||
.PP
|
||||
If anything is wrong with the block allocation maps,
|
||||
.I fsck
|
||||
will rebuild them,
|
||||
based on the list it has computed of allocated blocks.
|
||||
.PP
|
||||
The summary information associated with the super-block
|
||||
counts the total number of free blocks within the file system.
|
||||
.I Fsck
|
||||
compares this count to the
|
||||
number of free blocks it found within the file system.
|
||||
If the two counts do not agree, then
|
||||
.I fsck
|
||||
replaces the incorrect count in the summary information
|
||||
by the actual free-block count.
|
||||
.PP
|
||||
The summary information
|
||||
counts the total number of free inodes within the file system.
|
||||
.I Fsck
|
||||
compares this count to the number
|
||||
of free inodes it found within the file system.
|
||||
If the two counts do not agree, then
|
||||
.I fsck
|
||||
replaces the incorrect count in the
|
||||
summary information by the actual free-inode count.
|
||||
.NH 2
|
||||
Checking the inode state
|
||||
.PP
|
||||
An individual inode is not as likely to be corrupted as
|
||||
the allocation information.
|
||||
However, because of the great number of active inodes,
|
||||
a few of the inodes are usually corrupted.
|
||||
.PP
|
||||
The list of inodes in the file system
|
||||
is checked sequentially starting with inode 2
|
||||
(inode 0 marks unused inodes;
|
||||
inode 1 is saved for future generations)
|
||||
and progressing through the last inode in the file system.
|
||||
The state of each inode is checked for
|
||||
inconsistencies involving format and type,
|
||||
link count,
|
||||
duplicate blocks,
|
||||
bad blocks,
|
||||
and inode size.
|
||||
.PP
|
||||
Each inode contains a mode word.
|
||||
This mode word describes the type and state of the inode.
|
||||
Inodes must be one of six types:
|
||||
regular inode, directory inode, symbolic link inode,
|
||||
special block inode, special character inode, or socket inode.
|
||||
Inodes may be found in one of three allocation states:
|
||||
unallocated, allocated, and neither unallocated nor allocated.
|
||||
This last state suggests an incorrectly formated inode.
|
||||
An inode can get in this state if
|
||||
bad data is written into the inode list.
|
||||
The only possible corrective action is for
|
||||
.I fsck
|
||||
is to clear the inode.
|
||||
.NH 2
|
||||
Inode links
|
||||
.PP
|
||||
Each inode counts the
|
||||
total number of directory entries
|
||||
linked to the inode.
|
||||
.I Fsck
|
||||
verifies the link count of each inode
|
||||
by starting at the root of the file system,
|
||||
and descending through the directory structure.
|
||||
The actual link count for each inode
|
||||
is calculated during the descent.
|
||||
.PP
|
||||
If the stored link count is non-zero and the actual
|
||||
link count is zero,
|
||||
then no directory entry appears for the inode.
|
||||
If this happens,
|
||||
.I fsck
|
||||
will place the disconnected file in the
|
||||
.I lost+found
|
||||
directory.
|
||||
If the stored and actual link counts are non-zero and unequal,
|
||||
a directory entry may have been added or removed without the inode being
|
||||
updated.
|
||||
If this happens,
|
||||
.I fsck
|
||||
replaces the incorrect stored link count by the actual link count.
|
||||
.PP
|
||||
Each inode contains a list,
|
||||
or pointers to
|
||||
lists (indirect blocks),
|
||||
of all the blocks claimed by the inode.
|
||||
Since indirect blocks are owned by an inode,
|
||||
inconsistencies in indirect blocks directly
|
||||
affect the inode that owns it.
|
||||
.PP
|
||||
.I Fsck
|
||||
compares each block number claimed by an inode
|
||||
against a list of already allocated blocks.
|
||||
If another inode already claims a block number,
|
||||
then the block number is added to a list of
|
||||
.I "duplicate blocks" .
|
||||
Otherwise, the list of allocated blocks
|
||||
is updated to include the block number.
|
||||
.PP
|
||||
If there are any duplicate blocks,
|
||||
.I fsck
|
||||
will perform a partial second
|
||||
pass over the inode list
|
||||
to find the inode of the duplicated block.
|
||||
The second pass is needed,
|
||||
since without examining the files associated with
|
||||
these inodes for correct content,
|
||||
not enough information is available
|
||||
to determine which inode is corrupted and should be cleared.
|
||||
If this condition does arise
|
||||
(only hardware failure will cause it),
|
||||
then the inode with the earliest
|
||||
modify time is usually incorrect,
|
||||
and should be cleared.
|
||||
If this happens,
|
||||
.I fsck
|
||||
prompts the operator to clear both inodes.
|
||||
The operator must decide which one should be kept
|
||||
and which one should be cleared.
|
||||
.PP
|
||||
.I Fsck
|
||||
checks the range of each block number claimed by an inode.
|
||||
If the block number is
|
||||
lower than the first data block in the file system,
|
||||
or greater than the last data block,
|
||||
then the block number is a
|
||||
.I "bad block number" .
|
||||
Many bad blocks in an inode are usually caused by
|
||||
an indirect block that was not written to the file system,
|
||||
a condition which can only occur if there has been a hardware failure.
|
||||
If an inode contains bad block numbers,
|
||||
.I fsck
|
||||
prompts the operator to clear it.
|
||||
.NH 2
|
||||
Inode data size
|
||||
.PP
|
||||
Each inode contains a count of the number of data blocks
|
||||
that it contains.
|
||||
The number of actual data blocks
|
||||
is the sum of the allocated data blocks
|
||||
and the indirect blocks.
|
||||
.I Fsck
|
||||
computes the actual number of data blocks
|
||||
and compares that block count against
|
||||
the actual number of blocks the inode claims.
|
||||
If an inode contains an incorrect count
|
||||
.I fsck
|
||||
prompts the operator to fix it.
|
||||
.PP
|
||||
Each inode contains a thirty-two bit size field.
|
||||
The size is the number of data bytes
|
||||
in the file associated with the inode.
|
||||
The consistency of the byte size field is roughly checked
|
||||
by computing from the size field the maximum number of blocks
|
||||
that should be associated with the inode,
|
||||
and comparing that expected block count against
|
||||
the actual number of blocks the inode claims.
|
||||
.NH 2
|
||||
Checking the data associated with an inode
|
||||
.PP
|
||||
An inode can directly or indirectly
|
||||
reference three kinds of data blocks.
|
||||
All referenced blocks must be the same kind.
|
||||
The three types of data blocks are:
|
||||
plain data blocks, symbolic link data blocks, and directory data blocks.
|
||||
Plain data blocks
|
||||
contain the information stored in a file;
|
||||
symbolic link data blocks
|
||||
contain the path name stored in a link.
|
||||
Directory data blocks contain directory entries.
|
||||
.I Fsck
|
||||
can only check the validity of directory data blocks.
|
||||
.PP
|
||||
Each directory data block is checked for
|
||||
several types of inconsistencies.
|
||||
These inconsistencies include
|
||||
directory inode numbers pointing to unallocated inodes,
|
||||
directory inode numbers that are greater than
|
||||
the number of inodes in the file system,
|
||||
incorrect directory inode numbers for ``\fB.\fP'' and ``\fB..\fP'',
|
||||
and directories that are not attached to the file system.
|
||||
If the inode number in a directory data block
|
||||
references an unallocated inode,
|
||||
then
|
||||
.I fsck
|
||||
will remove that directory entry.
|
||||
Again,
|
||||
this condition can only arise when there has been a hardware failure.
|
||||
.PP
|
||||
If a directory entry inode number references
|
||||
outside the inode list, then
|
||||
.I fsck
|
||||
will remove that directory entry.
|
||||
This condition occurs if bad data is written into a directory data block.
|
||||
.PP
|
||||
The directory inode number entry for ``\fB.\fP''
|
||||
must be the first entry in the directory data block.
|
||||
The inode number for ``\fB.\fP''
|
||||
must reference itself;
|
||||
e.g., it must equal the inode number
|
||||
for the directory data block.
|
||||
The directory inode number entry
|
||||
for ``\fB..\fP'' must be
|
||||
the second entry in the directory data block.
|
||||
Its value must equal the inode number for the
|
||||
parent of the directory entry
|
||||
(or the inode number of the directory
|
||||
data block if the directory is the
|
||||
root directory).
|
||||
If the directory inode numbers are
|
||||
incorrect,
|
||||
.I fsck
|
||||
will replace them with the correct values.
|
||||
If there are multiple hard links to a directory,
|
||||
the first one encountered is considered the real parent
|
||||
to which ``\fB..\fP'' should point;
|
||||
\fIfsck\fP recommends deletion for the subsequently discovered names.
|
||||
.NH 2
|
||||
File system connectivity
|
||||
.PP
|
||||
.I Fsck
|
||||
checks the general connectivity of the file system.
|
||||
If directories are not linked into the file system, then
|
||||
.I fsck
|
||||
links the directory back into the file system in the
|
||||
.I lost+found
|
||||
directory.
|
||||
This condition only occurs when there has been a hardware failure.
|
||||
.ds RH "References"
|
||||
.SH
|
||||
\s+2Acknowledgements\s0
|
||||
.PP
|
||||
I thank Bill Joy, Sam Leffler, Robert Elz and Dennis Ritchie
|
||||
for their suggestions and help in implementing the new file system.
|
||||
Thanks also to Robert Henry for his editorial input to
|
||||
get this document together.
|
||||
Finally we thank our sponsors,
|
||||
the National Science Foundation under grant MCS80-05144,
|
||||
and the Defense Advance Research Projects Agency (DoD) under
|
||||
Arpa Order No. 4031 monitored by Naval Electronic System Command under
|
||||
Contract No. N00039-82-C-0235. (Kirk McKusick, July 1983)
|
||||
.PP
|
||||
I would like to thank Larry A. Wehr for advice that lead
|
||||
to the first version of
|
||||
.I fsck
|
||||
and Rick B. Brandt for adapting
|
||||
.I fsck
|
||||
to
|
||||
UNIX/TS. (T. Kowalski, July 1979)
|
||||
.sp 2
|
||||
.SH
|
||||
\s+2References\s0
|
||||
.LP
|
||||
.IP [Dolotta78] 20
|
||||
Dolotta, T. A., and Olsson, S. B. eds.,
|
||||
.I "UNIX User's Manual, Edition 1.1\^" ,
|
||||
January 1978.
|
||||
.IP [Joy83] 20
|
||||
Joy, W., Cooper, E., Fabry, R., Leffler, S., McKusick, M., and Mosher, D.
|
||||
4.2BSD System Manual,
|
||||
.I "University of California at Berkeley" ,
|
||||
.I "Computer Systems Research Group Technical Report"
|
||||
#4, 1982.
|
||||
.IP [McKusick84] 20
|
||||
McKusick, M., Joy, W., Leffler, S., and Fabry, R.
|
||||
A Fast File System for UNIX,
|
||||
\fIACM Transactions on Computer Systems 2\fP, 3.
|
||||
pp. 181-197, August 1984.
|
||||
.IP [Ritchie78] 20
|
||||
Ritchie, D. M., and Thompson, K.,
|
||||
The UNIX Time-Sharing System,
|
||||
.I "The Bell System Technical Journal"
|
||||
.B 57 ,
|
||||
6 (July-August 1978, Part 2), pp. 1905-29.
|
||||
.IP [Thompson78] 20
|
||||
Thompson, K.,
|
||||
UNIX Implementation,
|
||||
.I "The Bell System Technical Journal\^"
|
||||
.B 57 ,
|
||||
6 (July-August 1978, Part 2), pp. 1931-46.
|
||||
.ds RH Appendix A \- Fsck Error Conditions
|
||||
.bp
|
1425
sbin/fsck/SMM.doc/4.t
Normal file
1425
sbin/fsck/SMM.doc/4.t
Normal file
File diff suppressed because it is too large
Load Diff
8
sbin/fsck/SMM.doc/Makefile
Normal file
8
sbin/fsck/SMM.doc/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/8/93
|
||||
# $Id: Makefile,v 1.1 1994/06/08 19:01:26 mycroft Exp $
|
||||
|
||||
DIR= smm/03.fsck
|
||||
SRCS= 0.t 1.t 2.t 3.t 4.t
|
||||
MACROS= -ms
|
||||
|
||||
.include <bsd.doc.mk>
|
130
sbin/fsck/dir.c
130
sbin/fsck/dir.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,18 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)dir.c 5.19 (Berkeley) 7/26/91";*/
|
||||
static char rcsid[] = "$Id: dir.c,v 1.6 1994/04/25 18:28:20 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)dir.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: dir.c,v 1.7 1994/06/08 19:00:19 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#define KERNEL
|
||||
#include <ufs/dir.h>
|
||||
#undef KERNEL
|
||||
#include <stddef.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
@ -51,7 +48,14 @@ static char rcsid[] = "$Id: dir.c,v 1.6 1994/04/25 18:28:20 cgd Exp $";
|
||||
char *lfname = "lost+found";
|
||||
int lfmode = 01777;
|
||||
struct dirtemplate emptydir = { 0, DIRBLKSIZ };
|
||||
struct dirtemplate dirhead = { 0, 12, 1, ".", 0, DIRBLKSIZ - 12, 2, ".." };
|
||||
struct dirtemplate dirhead = {
|
||||
0, 12, DT_DIR, 1, ".",
|
||||
0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
|
||||
};
|
||||
struct odirtemplate odirhead = {
|
||||
0, 12, 1, ".",
|
||||
0, DIRBLKSIZ - 12, 2, ".."
|
||||
};
|
||||
|
||||
struct direct *fsck_readdir();
|
||||
struct bufarea *getdirblk();
|
||||
@ -107,8 +111,29 @@ dirscan(idesc)
|
||||
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
||||
dsize = dp->d_reclen;
|
||||
bcopy((char *)dp, dbuf, (size_t)dsize);
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
if (!newinofmt) {
|
||||
struct direct *tdp = (struct direct *)dbuf;
|
||||
u_char tmp;
|
||||
|
||||
tmp = tdp->d_namlen;
|
||||
tdp->d_namlen = tdp->d_type;
|
||||
tdp->d_type = tmp;
|
||||
}
|
||||
# endif
|
||||
idesc->id_dirp = (struct direct *)dbuf;
|
||||
if ((n = (*idesc->id_func)(idesc)) & ALTERED) {
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
if (!newinofmt && !doinglevel2) {
|
||||
struct direct *tdp;
|
||||
u_char tmp;
|
||||
|
||||
tdp = (struct direct *)dbuf;
|
||||
tmp = tdp->d_namlen;
|
||||
tdp->d_namlen = tdp->d_type;
|
||||
tdp->d_type = tmp;
|
||||
}
|
||||
# endif
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
bcopy(dbuf, bp->b_un.b_buf + idesc->id_loc - dsize,
|
||||
(size_t)dsize);
|
||||
@ -130,39 +155,34 @@ fsck_readdir(idesc)
|
||||
{
|
||||
register struct direct *dp, *ndp;
|
||||
register struct bufarea *bp;
|
||||
long blksiz, new_id_filesize;
|
||||
int fix, new_id_loc, new_reclen, orig_id_loc, size;
|
||||
long size, blksiz, fix, dploc;
|
||||
|
||||
blksiz = idesc->id_numfrags * sblock.fs_fsize;
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
orig_id_loc = idesc->id_loc;
|
||||
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))
|
||||
goto dpok;
|
||||
/*
|
||||
* See below about recursion.
|
||||
*/
|
||||
new_id_loc = idesc->id_loc + DIRBLKSIZ;
|
||||
new_id_filesize = idesc->id_filesize - DIRBLKSIZ;
|
||||
fix = dofix(idesc, "DIRECTORY CORRUPTED");
|
||||
idesc->id_loc = new_id_loc;
|
||||
idesc->id_filesize = new_id_filesize;
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
dp = (struct direct *)(bp->b_un.b_buf + orig_id_loc);
|
||||
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
|
||||
dp->d_reclen = DIRBLKSIZ;
|
||||
dp->d_ino = 0;
|
||||
dp->d_type = 0;
|
||||
dp->d_namlen = 0;
|
||||
dp->d_name[0] = '\0';
|
||||
if (fix)
|
||||
dirty(bp);
|
||||
idesc->id_loc += DIRBLKSIZ;
|
||||
idesc->id_filesize -= DIRBLKSIZ;
|
||||
return (dp);
|
||||
}
|
||||
dpok:
|
||||
if (idesc->id_filesize <= 0 || idesc->id_loc >= blksiz)
|
||||
return NULL;
|
||||
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
|
||||
dploc = idesc->id_loc;
|
||||
dp = (struct direct *)(bp->b_un.b_buf + dploc);
|
||||
idesc->id_loc += dp->d_reclen;
|
||||
idesc->id_filesize -= dp->d_reclen;
|
||||
if ((idesc->id_loc % DIRBLKSIZ) == 0)
|
||||
@ -171,23 +191,12 @@ dpok:
|
||||
if (idesc->id_loc < blksiz && idesc->id_filesize > 0 &&
|
||||
dircheck(idesc, ndp) == 0) {
|
||||
size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
||||
/*
|
||||
* dofix() may recurse here. Don't let it cause multiple
|
||||
* fixups.
|
||||
*/
|
||||
new_id_loc = idesc->id_loc + size;
|
||||
new_id_filesize = idesc->id_filesize - size;
|
||||
new_reclen = dp->d_reclen + size;
|
||||
idesc->id_loc += size;
|
||||
idesc->id_filesize -= size;
|
||||
fix = dofix(idesc, "DIRECTORY CORRUPTED");
|
||||
idesc->id_loc = new_id_loc;
|
||||
idesc->id_filesize = new_id_filesize;
|
||||
/*
|
||||
* dofix() calls fsck_readdir() and getdirblk() discards
|
||||
* the lock on bp so bp may now be invalid.
|
||||
*/
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
dp = (struct direct *)(bp->b_un.b_buf + orig_id_loc);
|
||||
dp->d_reclen = new_reclen;
|
||||
dp = (struct direct *)(bp->b_un.b_buf + dploc);
|
||||
dp->d_reclen += size;
|
||||
if (fix)
|
||||
dirty(bp);
|
||||
}
|
||||
@ -204,22 +213,34 @@ dircheck(idesc, dp)
|
||||
{
|
||||
register int size;
|
||||
register char *cp;
|
||||
u_char namlen, type;
|
||||
int spaceleft;
|
||||
|
||||
size = DIRSIZ(!newinofmt, dp);
|
||||
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
||||
if (spaceleft < offsetof(struct direct, d_name))
|
||||
return (0); /* dp is bad; don't use it */
|
||||
size = DIRSIZ(dp);
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
if (!newinofmt) {
|
||||
type = dp->d_namlen;
|
||||
namlen = dp->d_type;
|
||||
} else {
|
||||
namlen = dp->d_namlen;
|
||||
type = dp->d_type;
|
||||
}
|
||||
# else
|
||||
namlen = dp->d_namlen;
|
||||
type = dp->d_type;
|
||||
# endif
|
||||
if (dp->d_ino < maxino &&
|
||||
dp->d_reclen != 0 &&
|
||||
dp->d_reclen <= spaceleft &&
|
||||
(dp->d_reclen & 0x3) == 0 &&
|
||||
dp->d_reclen >= size &&
|
||||
idesc->id_filesize >= size &&
|
||||
dp->d_namlen <= MAXNAMLEN) {
|
||||
namlen <= MAXNAMLEN &&
|
||||
type <= 15) {
|
||||
if (dp->d_ino == 0)
|
||||
return (1);
|
||||
for (cp = dp->d_name, size = 0; size < dp->d_namlen; size++)
|
||||
for (cp = dp->d_name, size = 0; size < namlen; size++)
|
||||
if (*cp == 0 || (*cp++ == '/'))
|
||||
return (0);
|
||||
if (*cp == 0)
|
||||
@ -297,9 +318,9 @@ mkentry(idesc)
|
||||
int newlen, oldlen;
|
||||
|
||||
newent.d_namlen = strlen(idesc->id_name);
|
||||
newlen = DIRSIZ(&newent);
|
||||
newlen = DIRSIZ(0, &newent);
|
||||
if (dirp->d_ino != 0)
|
||||
oldlen = DIRSIZ(dirp);
|
||||
oldlen = DIRSIZ(0, dirp);
|
||||
else
|
||||
oldlen = 0;
|
||||
if (dirp->d_reclen - oldlen < newlen)
|
||||
@ -308,6 +329,10 @@ mkentry(idesc)
|
||||
dirp->d_reclen = oldlen;
|
||||
dirp = (struct direct *)(((char *)dirp) + oldlen);
|
||||
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
||||
if (newinofmt)
|
||||
dirp->d_type = typemap[idesc->id_parent];
|
||||
else
|
||||
dirp->d_type = 0;
|
||||
dirp->d_reclen = newent.d_reclen;
|
||||
dirp->d_namlen = newent.d_namlen;
|
||||
bcopy(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
||||
@ -322,6 +347,10 @@ chgino(idesc)
|
||||
if (bcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
|
||||
return (KEEPON);
|
||||
dirp->d_ino = idesc->id_parent;
|
||||
if (newinofmt)
|
||||
dirp->d_type = typemap[idesc->id_parent];
|
||||
else
|
||||
dirp->d_type = 0;
|
||||
return (ALTERED|STOP);
|
||||
}
|
||||
|
||||
@ -551,17 +580,22 @@ allocdir(parent, request, mode)
|
||||
char *cp;
|
||||
struct dinode *dp;
|
||||
register struct bufarea *bp;
|
||||
struct dirtemplate *dirp;
|
||||
|
||||
ino = allocino(request, IFDIR|mode);
|
||||
dirhead.dot_ino = ino;
|
||||
dirhead.dotdot_ino = parent;
|
||||
if (newinofmt)
|
||||
dirp = &dirhead;
|
||||
else
|
||||
dirp = (struct dirtemplate *)&odirhead;
|
||||
dirp->dot_ino = ino;
|
||||
dirp->dotdot_ino = parent;
|
||||
dp = ginode(ino);
|
||||
bp = getdirblk(dp->di_db[0], sblock.fs_fsize);
|
||||
if (bp->b_errs) {
|
||||
freeino(ino);
|
||||
return (0);
|
||||
}
|
||||
bcopy((char *)&dirhead, bp->b_un.b_buf, sizeof dirhead);
|
||||
bcopy((char *)dirp, bp->b_un.b_buf, sizeof(struct dirtemplate));
|
||||
for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
|
||||
cp < &bp->b_un.b_buf[sblock.fs_fsize];
|
||||
cp += DIRBLKSIZ)
|
||||
|
148
sbin/fsck/fsck.8
148
sbin/fsck/fsck.8
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 1980, 1989 Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1980, 1989, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -29,33 +29,32 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)fsck.8 6.9 (Berkeley) 4/20/91
|
||||
.\" $Id: fsck.8,v 1.6 1994/04/13 10:12:33 deraadt Exp $
|
||||
.\" from: @(#)fsck.8 8.2 (Berkeley) 12/11/93
|
||||
.\" $Id: fsck.8,v 1.7 1994/06/08 19:00:20 mycroft Exp $
|
||||
.\"
|
||||
.Dd April 20, 1991
|
||||
.Dd December 11, 1993
|
||||
.Dt FSCK 8
|
||||
.Os BSD 4.2
|
||||
.de us
|
||||
\\$1\l'|0\(ul'
|
||||
..
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm fsck
|
||||
.Nd file system consistency check and interactive repair
|
||||
.Nm fsck
|
||||
.Nd filesystem consistency check and interactive repair
|
||||
.Sh SYNOPSIS
|
||||
.Nm fsck
|
||||
.Fl p
|
||||
.Op Fl m Ar mode
|
||||
.Nm fsck
|
||||
.Op Fl b Ar block#
|
||||
.Op Fl c
|
||||
.Op Fl c Ar level
|
||||
.Op Fl l Ar maxparallel
|
||||
.Op Fl y
|
||||
.Op Fl n
|
||||
.Op Fl m Ar mode
|
||||
.Op Ar filesystem ...
|
||||
.Op Ar filesystem
|
||||
.Ar ...
|
||||
.Sh DESCRIPTION
|
||||
The first form of
|
||||
.Nm fsck
|
||||
preens a standard set of filesystems or the specified file systems.
|
||||
preens a standard set of filesystems or the specified filesystems.
|
||||
It is normally used in the script
|
||||
.Pa /etc/rc
|
||||
during automatic reboot.
|
||||
@ -63,12 +62,8 @@ Here
|
||||
.Nm fsck
|
||||
reads the table
|
||||
.Pa /etc/fstab
|
||||
to determine which file systems to check.
|
||||
Only partitions in fstab that are mounted
|
||||
.Dq rw ,
|
||||
.Dq rq
|
||||
or
|
||||
.Dq ro
|
||||
to determine which filesystems to check.
|
||||
Only partitions in fstab that are mounted ``rw,'' ``rq'' or ``ro''
|
||||
and that have non-zero pass number are checked.
|
||||
Filesystems with pass number 1 (normally just the root filesystem)
|
||||
are checked one at a time.
|
||||
@ -78,10 +73,10 @@ The disk drive containing each filesystem is inferred from the longest prefix
|
||||
of the device name that ends in a digit; the remaining characters are assumed
|
||||
to be the partition designator.
|
||||
.Pp
|
||||
The system takes care that only a restricted class of innocuous
|
||||
The kernel takes care that only a restricted class of innocuous filesystem
|
||||
inconsistencies can happen unless hardware or software failures intervene.
|
||||
These are limited to the following:
|
||||
.Bl -item -offset indent
|
||||
.Bl -item -compact
|
||||
.It
|
||||
Unreferenced inodes
|
||||
.It
|
||||
@ -101,27 +96,29 @@ with the
|
||||
option will correct; if it encounters other inconsistencies, it exits
|
||||
with an abnormal return status and an automatic reboot will then fail.
|
||||
For each corrected inconsistency one or more lines will be printed
|
||||
identifying the file system on which the correction will take place,
|
||||
and the nature of the correction. After successfully correcting a file
|
||||
system,
|
||||
identifying the filesystem on which the correction will take place,
|
||||
and the nature of the correction. After successfully correcting a filesystem,
|
||||
.Nm fsck
|
||||
will print the number of files on that file system,
|
||||
will print the number of files on that filesystem,
|
||||
the number of used and free blocks,
|
||||
and the percentage of fragmentation.
|
||||
.Pp
|
||||
If sent a QUIT signal,
|
||||
If sent a
|
||||
.Dv QUIT
|
||||
signal,
|
||||
.Nm fsck
|
||||
will finish the file system checks, then exit with an abnormal
|
||||
will finish the filesystem checks, then exit with an abnormal
|
||||
return status that causes an automatic reboot to fail.
|
||||
This is useful when to finish the file system checks during an automatic reboot,
|
||||
This is useful when you want to finish the filesystem checks during an
|
||||
automatic reboot,
|
||||
but do not want the machine to come up multiuser after the checks complete.
|
||||
.Pp
|
||||
Without the
|
||||
.Fl p
|
||||
option,
|
||||
.Nm fsck
|
||||
audits and interactively repairs inconsistent conditions for file systems.
|
||||
If the file system is inconsistent the operator is prompted for concurrence
|
||||
audits and interactively repairs inconsistent conditions for filesystems.
|
||||
If the filesystem is inconsistent the operator is prompted for concurrence
|
||||
before each correction is attempted.
|
||||
It should be noted that some of the corrective actions which are not
|
||||
correctable under the
|
||||
@ -130,11 +127,11 @@ option will result in some loss of data.
|
||||
The amount and severity of data lost may be determined from the diagnostic
|
||||
output.
|
||||
The default action for each consistency correction
|
||||
is to wait for the operator to respond
|
||||
.Ic yes
|
||||
is to wait for the operator to respond
|
||||
.Li yes
|
||||
or
|
||||
.Ic no .
|
||||
If the operator does not have write permission on the file system
|
||||
.Li no .
|
||||
If the operator does not have write permission on the filesystem
|
||||
.Nm fsck
|
||||
will default to a
|
||||
.Fl n
|
||||
@ -143,19 +140,17 @@ action.
|
||||
.Nm Fsck
|
||||
has more consistency checks than
|
||||
its predecessors
|
||||
.Nm check ,
|
||||
.Nm dcheck ,
|
||||
.Nm fcheck ,
|
||||
.Em check , dcheck , fcheck ,
|
||||
and
|
||||
.Nm icheck
|
||||
.Em icheck
|
||||
combined.
|
||||
.Pp
|
||||
The following flags are interpreted by
|
||||
.Nm fsck.
|
||||
.Nm fsck .
|
||||
.Bl -tag -width indent
|
||||
.It Fl b
|
||||
Use the block specified immediately after the flag as
|
||||
the super block for the file system. Block 32 is usually
|
||||
the super block for the filesystem. Block 32 is usually
|
||||
an alternate super block.
|
||||
.It Fl l
|
||||
Limit the number of parallel checks to the number specified in the following
|
||||
@ -165,8 +160,9 @@ If a smaller limit is given, the disks are checked round-robin, one filesystem
|
||||
at a time.
|
||||
.It Fl m
|
||||
Use the mode specified in octal immediately after the flag as the
|
||||
permission bits to use when creating the lost+found directory
|
||||
rather than the default 1777.
|
||||
permission bits to use when creating the
|
||||
.Pa lost+found
|
||||
directory rather than the default 1777.
|
||||
In particular, systems that do not wish to have lost files accessible
|
||||
by all users on the system should use a more restrictive
|
||||
set of permissions such as 700.
|
||||
@ -178,50 +174,60 @@ to continue after essentially unlimited trouble has been encountered.
|
||||
.It Fl n
|
||||
Assume a no response to all questions asked by
|
||||
.Nm fsck
|
||||
except for
|
||||
.Dq CONTINUE? ,
|
||||
which is assumed to be affirmative; do not open the file system for writing.
|
||||
except for
|
||||
.Ql CONTINUE? ,
|
||||
which is assumed to be affirmative;
|
||||
do not open the filesystem for writing.
|
||||
.It Fl c
|
||||
If the file system is in the old (static table) format,
|
||||
convert it to the new (dynamic table) format.
|
||||
If the file system is in the new format,
|
||||
convert it to the old format provided the old format
|
||||
can support the filesystem configuration.
|
||||
Convert the filesystem to the specified level.
|
||||
Note that the level of a filesystem can only be raised.
|
||||
.Bl -tag -width indent
|
||||
There are currently three levels defined:
|
||||
.It 0
|
||||
The filesystem is in the old (static table) format.
|
||||
.It 1
|
||||
The filesystem is in the new (dynamic table) format.
|
||||
.It 2
|
||||
The filesystem supports 32-bit uid's and gid's,
|
||||
short symbolic links are stored in the inode,
|
||||
and directories have an added field showing the file type.
|
||||
.El
|
||||
.Pp
|
||||
In interactive mode,
|
||||
.Nm fsck
|
||||
will list the direction the conversion is to be made
|
||||
will list the conversion to be made
|
||||
and ask whether the conversion should be done.
|
||||
If a negative answer is given,
|
||||
no further operations are done on the filesystem.
|
||||
In preen mode,
|
||||
the direction of the conversion is listed and done if
|
||||
the conversion is listed and done if
|
||||
possible without user interaction.
|
||||
Conversion in preen mode is best used when all the file systems
|
||||
Conversion in preen mode is best used when all the filesystems
|
||||
are being converted at once.
|
||||
The format of a file system can be determined from the
|
||||
The format of a filesystem can be determined from the
|
||||
first line of output from
|
||||
.Xr dumpfs 8 .
|
||||
.El
|
||||
.Pp
|
||||
If no filesystems are given to
|
||||
.Nm fsck
|
||||
then a default list of file systems is read from
|
||||
then a default list of filesystems is read from
|
||||
the file
|
||||
.Pa /etc/fstab .
|
||||
.Pp
|
||||
.Bl -enum -indent indent -compact
|
||||
Inconsistencies checked are as follows:
|
||||
.Bl -enum -width indent -compact
|
||||
.It
|
||||
Blocks claimed by more than one inode or the free map.
|
||||
.It
|
||||
Blocks claimed by an inode outside the range of the file system.
|
||||
Blocks claimed by an inode outside the range of the filesystem.
|
||||
.It
|
||||
Incorrect link counts.
|
||||
.It
|
||||
Size checks:
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
Directory size not of proper format.
|
||||
.Bl -item -indent indent -compact
|
||||
.It
|
||||
Directory size not a multiple of DIRBLKSIZ.
|
||||
.It
|
||||
Partially truncated file.
|
||||
.El
|
||||
@ -231,8 +237,8 @@ Bad inode format.
|
||||
Blocks not accounted for anywhere.
|
||||
.It
|
||||
Directory checks:
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
.Bl -item -indent indent -compact
|
||||
.It
|
||||
File pointing to unallocated inode.
|
||||
.It
|
||||
Inode number out of range.
|
||||
@ -242,15 +248,15 @@ or having the wrong inode number.
|
||||
.El
|
||||
.It
|
||||
Super Block checks:
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
More blocks for inodes than there are in the file system.
|
||||
.El
|
||||
.Bl -item -indent indent -compact
|
||||
.It
|
||||
More blocks for inodes than there are in the filesystem.
|
||||
.It
|
||||
Bad free block map format.
|
||||
.It
|
||||
Total free block and/or free inode count incorrect.
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
Orphaned files and directories (allocated but unreferenced) are,
|
||||
with the operator's concurrence, reconnected by
|
||||
@ -266,15 +272,17 @@ If there is insufficient space its size is increased.
|
||||
Because of inconsistencies between the block device and the buffer cache,
|
||||
the raw device should always be used.
|
||||
.Sh FILES
|
||||
.Bl -tag -width indent-two -compact
|
||||
.Bl -tag -width /etc/fstab -compact
|
||||
.It Pa /etc/fstab
|
||||
contains default list of file systems to check.
|
||||
contains default list of filesystems to check.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
The diagnostics produced by
|
||||
.Nm fsck
|
||||
are fully enumerated and explained in Appendix A of
|
||||
``Fsck \- The UNIX File System Check Program'' (SMM:5).
|
||||
.Rs
|
||||
.%T "Fsck \- The UNIX File System Check Program"
|
||||
.Re
|
||||
.Sh SEE ALSO
|
||||
.Xr fstab 5 ,
|
||||
.Xr fs 5 ,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -30,8 +30,8 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fsck.h 5.17 (Berkeley) 7/27/90
|
||||
* $Id: fsck.h,v 1.5 1994/05/02 10:18:21 pk Exp $
|
||||
* from: @(#)fsck.h 8.1 (Berkeley) 6/5/93
|
||||
* $Id: fsck.h,v 1.6 1994/06/08 19:00:21 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define MAXDUP 10 /* limit on dup blks (per inode) */
|
||||
@ -78,6 +78,7 @@ struct bufarea sblk; /* file system superblock */
|
||||
struct bufarea cgblk; /* cylinder group blocks */
|
||||
struct bufarea *pdirbp; /* current directory contents */
|
||||
struct bufarea *pbp; /* current inode block */
|
||||
struct bufarea *getdatablk();
|
||||
|
||||
#define dirty(bp) (bp)->b_dirty = 1
|
||||
#define initbarea(bp) \
|
||||
@ -99,7 +100,7 @@ struct inodesc {
|
||||
ino_t id_parent; /* for DATA nodes, their parent */
|
||||
daddr_t id_blkno; /* current block number being examined */
|
||||
int id_numfrags; /* number of frags contained in block */
|
||||
long id_filesize; /* for DATA nodes, the size of the directory */
|
||||
quad_t id_filesize; /* for DATA nodes, the size of the directory */
|
||||
int id_loc; /* for DATA nodes, current location in dir */
|
||||
int id_entryno; /* for DATA nodes, current entry number */
|
||||
struct direct *id_dirp; /* for DATA nodes, ptr to current entry */
|
||||
@ -161,14 +162,17 @@ struct inoinfo {
|
||||
} **inphead, **inpsort;
|
||||
long numdirs, listmax, inplast;
|
||||
|
||||
char *devname; /* name of device being checked */
|
||||
char *cdevname; /* name of device being checked */
|
||||
long dev_bsize; /* computed value of DEV_BSIZE */
|
||||
long secsize; /* actual disk sector size */
|
||||
char nflag; /* assume a no response */
|
||||
char yflag; /* assume a yes response */
|
||||
int bflag; /* location of alternate super block */
|
||||
int debug; /* output debugging info */
|
||||
int cvtflag; /* convert to old file system format */
|
||||
int cvtlevel; /* convert to newer file system format */
|
||||
int doinglevel1; /* converting to new cylinder group format */
|
||||
int doinglevel2; /* converting to new inode format */
|
||||
int newinofmt; /* filesystem has new inode format */
|
||||
char preen; /* just fix normal inconsistencies */
|
||||
char hotroot; /* checking root device */
|
||||
char havesb; /* superblock has been read */
|
||||
@ -181,6 +185,7 @@ char *blockmap; /* ptr to primary blk allocation map */
|
||||
ino_t maxino; /* number of inodes in file system */
|
||||
ino_t lastino; /* last inode in use */
|
||||
char *statemap; /* ptr to inode state table */
|
||||
char *typemap; /* ptr to inode type table */
|
||||
short *lncntp; /* ptr to link count table */
|
||||
|
||||
ino_t lfdir; /* lost & found directory inode number */
|
||||
@ -203,32 +208,9 @@ struct dinode zino;
|
||||
#define ALTERED 0x08
|
||||
#define FOUND 0x10
|
||||
|
||||
int ckinode __P((struct dinode *, struct inodesc *));
|
||||
int iblock __P((struct inodesc *, long, u_long));
|
||||
int chkrange __P((daddr_t, int));
|
||||
struct dinode *ginode __P((ino_t));
|
||||
struct dinode *getnextinode __P((ino_t));
|
||||
void cacheino __P((struct dinode *, ino_t));
|
||||
struct inoinfo *getinoinfo __P((ino_t));
|
||||
void resetinodebuf __P((void));
|
||||
void freeinodebuf __P((void));
|
||||
void inocleanup __P((void));
|
||||
void inodirty __P((void));
|
||||
void clri __P((struct inodesc *, char *, int));
|
||||
int findname __P((struct inodesc *));
|
||||
int findino __P((struct inodesc *));
|
||||
void pinode __P((ino_t));
|
||||
void blkerror __P((ino_t, char *, daddr_t));
|
||||
ino_t allocino __P((ino_t, int));
|
||||
void freeino __P((ino_t));
|
||||
|
||||
int ftypeok __P((struct dinode *));
|
||||
struct bufarea *getdatablk __P((daddr_t, long));
|
||||
void getblk __P((struct bufarea *, daddr_t, long));
|
||||
void flush __P((int, struct bufarea *));
|
||||
int bread __P((int, char *, daddr_t, long));
|
||||
int bwrite __P((int, char *, daddr_t, long));
|
||||
int allocblk __P((long));
|
||||
void freeblk __P((daddr_t, long));
|
||||
void getpathname __P((char *, ino_t, ino_t));
|
||||
|
||||
time_t time();
|
||||
struct dinode *ginode();
|
||||
struct inoinfo *getinoinfo();
|
||||
void getblk();
|
||||
ino_t allocino();
|
||||
int findino();
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,15 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)inode.c 5.18 (Berkeley) 3/19/91";*/
|
||||
static char rcsid[] = "$Id: inode.c,v 1.8 1994/05/02 10:18:23 pk Exp $";
|
||||
/*static char sccsid[] = "from: @(#)inode.c 8.4 (Berkeley) 4/18/94";*/
|
||||
static char *rcsid = "$Id: inode.c,v 1.9 1994/06/08 19:00:23 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/dir.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#ifndef SMALL
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@ -50,7 +50,6 @@ static char rcsid[] = "$Id: inode.c,v 1.8 1994/05/02 10:18:23 pk Exp $";
|
||||
|
||||
static ino_t startinum;
|
||||
|
||||
int
|
||||
ckinode(dp, idesc)
|
||||
struct dinode *dp;
|
||||
register struct inodesc *idesc;
|
||||
@ -58,13 +57,17 @@ ckinode(dp, idesc)
|
||||
register daddr_t *ap;
|
||||
long ret, n, ndb, offset;
|
||||
struct dinode dino;
|
||||
quad_t remsize, sizepb;
|
||||
mode_t mode;
|
||||
|
||||
if (idesc->id_fix != IGNORE)
|
||||
idesc->id_fix = DONTKNOW;
|
||||
idesc->id_entryno = 0;
|
||||
idesc->id_filesize = dp->di_size;
|
||||
if ((dp->di_mode & IFMT) == IFBLK || (dp->di_mode & IFMT) == IFCHR ||
|
||||
DFASTLINK(*dp))
|
||||
mode = dp->di_mode & IFMT;
|
||||
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
||||
(dp->di_size < sblock.fs_maxsymlinklen ||
|
||||
(sblock.fs_maxsymlinklen == 0 && OLDFASTLINK(dp)))))
|
||||
return (KEEPON);
|
||||
dino = *dp;
|
||||
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
||||
@ -85,28 +88,31 @@ ckinode(dp, idesc)
|
||||
return (ret);
|
||||
}
|
||||
idesc->id_numfrags = sblock.fs_frag;
|
||||
remsize = dino.di_size - sblock.fs_bsize * NDADDR;
|
||||
sizepb = sblock.fs_bsize;
|
||||
for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
|
||||
if (*ap) {
|
||||
idesc->id_blkno = *ap;
|
||||
ret = iblock(idesc, n,
|
||||
dino.di_size - sblock.fs_bsize * NDADDR);
|
||||
ret = iblock(idesc, n, remsize);
|
||||
if (ret & STOP)
|
||||
return (ret);
|
||||
}
|
||||
sizepb *= NINDIR(&sblock);
|
||||
remsize -= sizepb;
|
||||
}
|
||||
return (KEEPON);
|
||||
}
|
||||
|
||||
int
|
||||
iblock(idesc, ilevel, isize)
|
||||
struct inodesc *idesc;
|
||||
register long ilevel;
|
||||
u_long isize;
|
||||
long ilevel;
|
||||
quad_t isize;
|
||||
{
|
||||
register daddr_t *ap;
|
||||
register daddr_t *aplim;
|
||||
int i, n, (*func)(), nif, sizepb;
|
||||
register struct bufarea *bp;
|
||||
int i, n, (*func)(), nif;
|
||||
quad_t sizepb;
|
||||
char buf[BUFSIZ];
|
||||
extern int dirscan(), pass1check();
|
||||
|
||||
@ -122,7 +128,7 @@ iblock(idesc, ilevel, isize)
|
||||
ilevel--;
|
||||
for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
|
||||
sizepb *= NINDIR(&sblock);
|
||||
nif = isize / sizepb + 1;
|
||||
nif = howmany(isize , sizepb);
|
||||
if (nif > NINDIR(&sblock))
|
||||
nif = NINDIR(&sblock);
|
||||
if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
|
||||
@ -140,18 +146,19 @@ iblock(idesc, ilevel, isize)
|
||||
flush(fswritefd, bp);
|
||||
}
|
||||
aplim = &bp->b_un.b_indir[nif];
|
||||
for (ap = bp->b_un.b_indir, i = 1; ap < aplim; ap++, i++) {
|
||||
for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
|
||||
if (*ap) {
|
||||
idesc->id_blkno = *ap;
|
||||
if (ilevel > 0)
|
||||
n = iblock(idesc, ilevel, isize - i * sizepb);
|
||||
else
|
||||
if (ilevel == 0)
|
||||
n = (*func)(idesc);
|
||||
else
|
||||
n = iblock(idesc, ilevel, isize);
|
||||
if (n & STOP) {
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
return (n);
|
||||
}
|
||||
}
|
||||
isize -= sizepb;
|
||||
}
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
return (KEEPON);
|
||||
@ -161,7 +168,6 @@ iblock(idesc, ilevel, isize)
|
||||
* Check that a block in a legal block number.
|
||||
* Return 0 if in range, 1 if out of range.
|
||||
*/
|
||||
int
|
||||
chkrange(blk, cnt)
|
||||
daddr_t blk;
|
||||
int cnt;
|
||||
@ -208,7 +214,7 @@ ginode(inumber)
|
||||
errexit("bad inode number %d to ginode\n", inumber);
|
||||
if (startinum == 0 ||
|
||||
inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
|
||||
iblk = itod(&sblock, inumber);
|
||||
iblk = ino_to_fsba(&sblock, inumber);
|
||||
if (pbp != 0)
|
||||
pbp->b_flags &= ~B_INUSE;
|
||||
pbp = getdatablk(iblk, sblock.fs_bsize);
|
||||
@ -237,7 +243,7 @@ getnextinode(inumber)
|
||||
errexit("bad inode number %d to nextinode\n", inumber);
|
||||
if (inumber >= lastinum) {
|
||||
readcnt++;
|
||||
dblk = fsbtodb(&sblock, itod(&sblock, lastinum));
|
||||
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
|
||||
if (readcnt % readpercg == 0) {
|
||||
size = partialsize;
|
||||
lastinum += partialcnt;
|
||||
@ -251,7 +257,6 @@ getnextinode(inumber)
|
||||
return (dp++);
|
||||
}
|
||||
|
||||
void
|
||||
resetinodebuf()
|
||||
{
|
||||
|
||||
@ -277,7 +282,6 @@ resetinodebuf()
|
||||
(void)getnextinode(nextino);
|
||||
}
|
||||
|
||||
void
|
||||
freeinodebuf()
|
||||
{
|
||||
|
||||
@ -293,7 +297,6 @@ freeinodebuf()
|
||||
*
|
||||
* Enter inodes into the cache.
|
||||
*/
|
||||
void
|
||||
cacheino(dp, inumber)
|
||||
register struct dinode *dp;
|
||||
ino_t inumber;
|
||||
@ -350,7 +353,6 @@ getinoinfo(inumber)
|
||||
/*
|
||||
* Clean up all the inode cache structure.
|
||||
*/
|
||||
void
|
||||
inocleanup()
|
||||
{
|
||||
register struct inoinfo **inpp;
|
||||
@ -363,15 +365,13 @@ inocleanup()
|
||||
free((char *)inpsort);
|
||||
inphead = inpsort = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
inodirty()
|
||||
{
|
||||
|
||||
dirty(pbp);
|
||||
}
|
||||
|
||||
void
|
||||
clri(idesc, type, flag)
|
||||
register struct inodesc *idesc;
|
||||
char *type;
|
||||
@ -396,7 +396,6 @@ clri(idesc, type, flag)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
findname(idesc)
|
||||
struct inodesc *idesc;
|
||||
{
|
||||
@ -408,7 +407,6 @@ findname(idesc)
|
||||
return (STOP|FOUND);
|
||||
}
|
||||
|
||||
int
|
||||
findino(idesc)
|
||||
struct inodesc *idesc;
|
||||
{
|
||||
@ -424,7 +422,6 @@ findino(idesc)
|
||||
return (KEEPON);
|
||||
}
|
||||
|
||||
void
|
||||
pinode(ino)
|
||||
ino_t ino;
|
||||
{
|
||||
@ -446,13 +443,12 @@ pinode(ino)
|
||||
printf("%u ", (unsigned)dp->di_uid);
|
||||
printf("MODE=%o\n", dp->di_mode);
|
||||
if (preen)
|
||||
printf("%s: ", devname);
|
||||
printf("SIZE=%lu ", dp->di_size);
|
||||
p = ctime(&dp->di_mtime);
|
||||
printf("%s: ", cdevname);
|
||||
printf("SIZE=%qu ", dp->di_size);
|
||||
p = ctime(&dp->di_mtime.ts_sec);
|
||||
printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
|
||||
}
|
||||
|
||||
void
|
||||
blkerror(ino, type, blk)
|
||||
ino_t ino;
|
||||
char *type;
|
||||
@ -520,19 +516,19 @@ allocino(request, type)
|
||||
}
|
||||
dp->di_mode = type;
|
||||
(void)time(&dp->di_atime.ts_sec);
|
||||
dp->di_atime.ts_nsec = 0;
|
||||
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
||||
dp->di_size = sblock.fs_fsize;
|
||||
dp->di_blocks = btodb(sblock.fs_fsize);
|
||||
n_files++;
|
||||
inodirty();
|
||||
if (newinofmt)
|
||||
typemap[ino] = IFTODT(type);
|
||||
return (ino);
|
||||
}
|
||||
|
||||
/*
|
||||
* deallocate an inode
|
||||
*/
|
||||
void
|
||||
freeino(ino)
|
||||
ino_t ino;
|
||||
{
|
||||
|
185
sbin/fsck/main.c
185
sbin/fsck/main.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,20 +32,21 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1980, 1986, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)main.c 5.27 (Berkeley) 8/7/90";*/
|
||||
static char rcsid[] = "$Id: main.c,v 1.12 1994/04/25 18:28:29 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)main.c 8.2 (Berkeley) 1/23/94";*/
|
||||
static char *rcsid = "$Id: main.c,v 1.13 1994/06/08 19:00:24 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <fstab.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -63,11 +64,11 @@ main(argc, argv)
|
||||
int ch;
|
||||
int ret, maxrun = 0;
|
||||
extern int docheck(), checkfilesys();
|
||||
extern char *optarg;
|
||||
extern char *optarg, *blockcheck();
|
||||
extern int optind;
|
||||
|
||||
sync();
|
||||
while ((ch = getopt(argc, argv, "cdpnNyYb:l:m:")) != EOF) {
|
||||
while ((ch = getopt(argc, argv, "dpnNyYb:c:l:m:")) != EOF) {
|
||||
switch (ch) {
|
||||
case 'p':
|
||||
preen++;
|
||||
@ -79,9 +80,9 @@ main(argc, argv)
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
cvtflag++;
|
||||
cvtlevel = argtoi('c', "conversion level", optarg, 10);
|
||||
break;
|
||||
|
||||
|
||||
case 'd':
|
||||
debug++;
|
||||
break;
|
||||
@ -121,7 +122,7 @@ main(argc, argv)
|
||||
(void)signal(SIGQUIT, catchquit);
|
||||
if (argc) {
|
||||
while (argc-- > 0)
|
||||
(void)checkfilesys(*argv++, (char *)0, 0L, 0);
|
||||
(void)checkfilesys(blockcheck(*argv++), 0, 0L, 0);
|
||||
exit(0);
|
||||
}
|
||||
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
||||
@ -170,11 +171,11 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
daddr_t n_ffree, n_bfree;
|
||||
struct dups *dp;
|
||||
struct zlncnt *zlnp;
|
||||
int clean;
|
||||
int cylno;
|
||||
|
||||
if (preen && child)
|
||||
(void)signal(SIGQUIT, voidquit);
|
||||
devname = filesys;
|
||||
cdevname = filesys;
|
||||
if (debug && preen)
|
||||
pwarn("starting\n");
|
||||
if (setup(filesys) == 0) {
|
||||
@ -182,71 +183,55 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
pfatal("CAN'T CHECK FILE SYSTEM.");
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* 1: scan inodes tallying blocks used
|
||||
*/
|
||||
if (preen == 0) {
|
||||
printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
|
||||
if (hotroot)
|
||||
printf("** Root file system\n");
|
||||
printf("** Phase 1 - Check Blocks and Sizes\n");
|
||||
}
|
||||
pass1();
|
||||
|
||||
/*
|
||||
* 0: check whether file system is already clean
|
||||
* 1b: locate first references to duplicates, if any
|
||||
*/
|
||||
clean = preen && (sblock.fs_state == FSOKAY) && sblock.fs_clean;
|
||||
|
||||
#ifdef notyet
|
||||
if (clean) {
|
||||
#else
|
||||
if (0) {
|
||||
#endif
|
||||
printf("** filesystem clean -- skipping checks\n");
|
||||
} else {
|
||||
/*
|
||||
* 1: scan inodes tallying blocks used
|
||||
*/
|
||||
if (preen == 0) {
|
||||
printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
|
||||
if (hotroot)
|
||||
printf("** Root file system\n");
|
||||
printf("** Phase 1 - Check Blocks and Sizes\n");
|
||||
}
|
||||
pass1();
|
||||
|
||||
/*
|
||||
* 1b: locate first references to duplicates, if any
|
||||
*/
|
||||
if (duplist) {
|
||||
if (preen)
|
||||
pfatal("INTERNAL ERROR: dups with -p");
|
||||
printf("** Phase 1b - Rescan For More DUPS\n");
|
||||
pass1b();
|
||||
}
|
||||
|
||||
/*
|
||||
* 2: traverse directories from root to mark all connected
|
||||
* directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 2 - Check Pathnames\n");
|
||||
pass2();
|
||||
|
||||
/*
|
||||
* 3: scan inodes looking for disconnected directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 3 - Check Connectivity\n");
|
||||
pass3();
|
||||
|
||||
/*
|
||||
* 4: scan inodes looking for disconnected files; check
|
||||
* reference counts
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 4 - Check Reference Counts\n");
|
||||
pass4();
|
||||
|
||||
/*
|
||||
* 5: check and repair resource counts in cylinder groups
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 5 - Check Cyl groups\n");
|
||||
pass5();
|
||||
if (duplist) {
|
||||
if (preen)
|
||||
pfatal("INTERNAL ERROR: dups with -p");
|
||||
printf("** Phase 1b - Rescan For More DUPS\n");
|
||||
pass1b();
|
||||
}
|
||||
|
||||
/*
|
||||
* 2: traverse directories from root to mark all connected directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 2 - Check Pathnames\n");
|
||||
pass2();
|
||||
|
||||
/*
|
||||
* 3: scan inodes looking for disconnected directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 3 - Check Connectivity\n");
|
||||
pass3();
|
||||
|
||||
/*
|
||||
* 4: scan inodes looking for disconnected files; check reference counts
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 4 - Check Reference Counts\n");
|
||||
pass4();
|
||||
|
||||
/*
|
||||
* 5: check and repair resource counts in cylinder groups
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 5 - Check Cyl groups\n");
|
||||
pass5();
|
||||
|
||||
/*
|
||||
* print out summary statistics
|
||||
*/
|
||||
@ -254,8 +239,9 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
n_bfree = sblock.fs_cstotal.cs_nbfree;
|
||||
pwarn("%ld files, %ld used, %ld free ",
|
||||
n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree);
|
||||
printf("(%ld frags, %ld blocks, %.1f%% fragmentation)\n",
|
||||
n_ffree, n_bfree, (float)(n_ffree * 100) / sblock.fs_dsize);
|
||||
printf("(%ld frags, %ld blocks, %d.%d%% fragmentation)\n",
|
||||
n_ffree, n_bfree, (n_ffree * 100) / sblock.fs_dsize,
|
||||
((n_ffree * 1000 + sblock.fs_dsize / 2) / sblock.fs_dsize) % 10);
|
||||
if (debug &&
|
||||
(n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree))
|
||||
printf("%ld files missing\n", n_files);
|
||||
@ -281,30 +267,51 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
}
|
||||
zlnhead = (struct zlncnt *)0;
|
||||
duplist = (struct dups *)0;
|
||||
muldup = (struct dups *)0;
|
||||
inocleanup();
|
||||
#ifdef notyet
|
||||
if (!clean && !nflag && fswritefd != -1) {
|
||||
sblock.fs_state = FSOKAY;
|
||||
sblock.fs_clean = FS_CLEANFREQ;
|
||||
fsmodified = 1;
|
||||
}
|
||||
#endif
|
||||
if (fsmodified) {
|
||||
(void)time(&sblock.fs_time);
|
||||
sbdirty();
|
||||
}
|
||||
if (cvtlevel && sblk.b_dirty) {
|
||||
/*
|
||||
* Write out the duplicate super blocks
|
||||
*/
|
||||
for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
|
||||
bwrite(fswritefd, (char *)&sblock,
|
||||
fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE);
|
||||
}
|
||||
ckfini();
|
||||
free(blockmap);
|
||||
free(statemap);
|
||||
free((char *)lncntp);
|
||||
if (!fsmodified)
|
||||
return (0);
|
||||
if (!preen) {
|
||||
if (!preen)
|
||||
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
||||
if (hotroot)
|
||||
printf("\n***** REBOOT NETBSD *****\n");
|
||||
}
|
||||
if (hotroot) {
|
||||
struct statfs stfs_buf;
|
||||
/*
|
||||
* We modified the root. Do a mount update on
|
||||
* it, unless it is read-write, so we can continue.
|
||||
*/
|
||||
if (statfs("/", &stfs_buf) == 0) {
|
||||
long flags = stfs_buf.f_flags;
|
||||
struct ufs_args args;
|
||||
int ret;
|
||||
|
||||
if (flags & MNT_RDONLY) {
|
||||
args.fspec = 0;
|
||||
args.export.ex_flags = 0;
|
||||
args.export.ex_root = 0;
|
||||
flags |= MNT_UPDATE | MNT_RELOAD;
|
||||
ret = mount(MOUNT_UFS, "/", flags, &args);
|
||||
if (ret == 0)
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
if (!preen)
|
||||
printf("\n***** REBOOT NOW *****\n");
|
||||
sync();
|
||||
return (4);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass1.c 5.16 (Berkeley) 3/19/91";*/
|
||||
static char rcsid[] = "$Id: pass1.c,v 1.6 1994/04/25 18:28:35 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass1.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass1.c,v 1.7 1994/06/08 19:00:25 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
@ -51,12 +52,9 @@ struct dinode *getnextinode();
|
||||
|
||||
pass1()
|
||||
{
|
||||
register int c, i, j;
|
||||
register struct dinode *dp;
|
||||
struct zlncnt *zlnp;
|
||||
int ndb, cgd;
|
||||
struct inodesc idesc;
|
||||
ino_t inumber;
|
||||
int c, i, cgd;
|
||||
struct inodesc idesc;
|
||||
|
||||
/*
|
||||
* Set file system reserved blocks in used block map.
|
||||
@ -84,123 +82,177 @@ pass1()
|
||||
for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
|
||||
if (inumber < ROOTINO)
|
||||
continue;
|
||||
dp = getnextinode(inumber);
|
||||
if ((dp->di_mode & IFMT) == 0) {
|
||||
if (bcmp((char *)dp->di_db, (char *)zino.di_db,
|
||||
NDADDR * sizeof(daddr_t)) ||
|
||||
bcmp((char *)dp->di_ib, (char *)zino.di_ib,
|
||||
NIADDR * sizeof(daddr_t)) ||
|
||||
dp->di_mode || dp->di_size) {
|
||||
pfatal("PARTIALLY ALLOCATED INODE I=%lu",
|
||||
inumber);
|
||||
if (reply("CLEAR") == 1) {
|
||||
dp = ginode(inumber);
|
||||
clearinode(dp);
|
||||
inodirty();
|
||||
}
|
||||
}
|
||||
statemap[inumber] = USTATE;
|
||||
continue;
|
||||
}
|
||||
lastino = inumber;
|
||||
/* is fast symlink? */
|
||||
if (DFASTLINK(*dp)) {
|
||||
lncntp[inumber] = dp->di_nlink;
|
||||
statemap[inumber] = FSTATE;
|
||||
n_files++;
|
||||
continue;
|
||||
}
|
||||
if (/* dp->di_size < 0 || */
|
||||
dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
|
||||
if (debug)
|
||||
printf("bad size %lu:", dp->di_size);
|
||||
goto unknown;
|
||||
}
|
||||
if (!preen && (dp->di_mode & IFMT) == IFMT &&
|
||||
reply("HOLD BAD BLOCK") == 1) {
|
||||
dp = ginode(inumber);
|
||||
dp->di_size = sblock.fs_fsize;
|
||||
dp->di_mode = IFREG|0600;
|
||||
inodirty();
|
||||
}
|
||||
ndb = howmany(dp->di_size, sblock.fs_bsize);
|
||||
if (ndb < 0) {
|
||||
if (debug)
|
||||
printf("bad size %lu ndb %d:",
|
||||
dp->di_size, ndb);
|
||||
goto unknown;
|
||||
}
|
||||
if ((dp->di_mode & IFMT) == IFBLK ||
|
||||
(dp->di_mode & IFMT) == IFCHR)
|
||||
ndb++;
|
||||
for (j = ndb; j < NDADDR; j++)
|
||||
if (dp->di_db[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad direct addr: %ld\n",
|
||||
dp->di_db[j]);
|
||||
goto unknown;
|
||||
}
|
||||
for (j = 0, ndb -= NDADDR; ndb > 0; j++)
|
||||
ndb /= NINDIR(&sblock);
|
||||
for (; j < NIADDR; j++)
|
||||
if (dp->di_ib[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad indirect addr: %ld\n",
|
||||
dp->di_ib[j]);
|
||||
goto unknown;
|
||||
}
|
||||
if (ftypeok(dp) == 0)
|
||||
goto unknown;
|
||||
n_files++;
|
||||
lncntp[inumber] = dp->di_nlink;
|
||||
if (dp->di_nlink <= 0) {
|
||||
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
||||
if (zlnp == NULL) {
|
||||
pfatal("LINK COUNT TABLE OVERFLOW");
|
||||
if (reply("CONTINUE") == 0)
|
||||
errexit("");
|
||||
} else {
|
||||
zlnp->zlncnt = inumber;
|
||||
zlnp->next = zlnhead;
|
||||
zlnhead = zlnp;
|
||||
}
|
||||
}
|
||||
if ((dp->di_mode & IFMT) == IFDIR) {
|
||||
if (dp->di_size == 0)
|
||||
statemap[inumber] = DCLEAR;
|
||||
else
|
||||
statemap[inumber] = DSTATE;
|
||||
cacheino(dp, inumber);
|
||||
} else
|
||||
statemap[inumber] = FSTATE;
|
||||
badblk = dupblk = 0;
|
||||
idesc.id_number = inumber;
|
||||
(void)ckinode(dp, &idesc);
|
||||
idesc.id_entryno *= btodb(sblock.fs_fsize);
|
||||
if (dp->di_blocks != idesc.id_entryno) {
|
||||
pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
|
||||
inumber, dp->di_blocks, idesc.id_entryno);
|
||||
if (preen)
|
||||
printf(" (CORRECTED)\n");
|
||||
else if (reply("CORRECT") == 0)
|
||||
continue;
|
||||
dp = ginode(inumber);
|
||||
dp->di_blocks = idesc.id_entryno;
|
||||
inodirty();
|
||||
}
|
||||
continue;
|
||||
unknown:
|
||||
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
||||
statemap[inumber] = FCLEAR;
|
||||
checkinode(inumber, &idesc);
|
||||
}
|
||||
}
|
||||
freeinodebuf();
|
||||
}
|
||||
|
||||
checkinode(inumber, idesc)
|
||||
ino_t inumber;
|
||||
register struct inodesc *idesc;
|
||||
{
|
||||
register struct dinode *dp;
|
||||
struct zlncnt *zlnp;
|
||||
int ndb, j;
|
||||
mode_t mode;
|
||||
char symbuf[MAXSYMLINKLEN];
|
||||
|
||||
dp = getnextinode(inumber);
|
||||
mode = dp->di_mode & IFMT;
|
||||
if (mode == 0) {
|
||||
if (bcmp((char *)dp->di_db, (char *)zino.di_db,
|
||||
NDADDR * sizeof(daddr_t)) ||
|
||||
bcmp((char *)dp->di_ib, (char *)zino.di_ib,
|
||||
NIADDR * sizeof(daddr_t)) ||
|
||||
dp->di_mode || dp->di_size) {
|
||||
pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber);
|
||||
if (reply("CLEAR") == 1) {
|
||||
statemap[inumber] = USTATE;
|
||||
dp = ginode(inumber);
|
||||
clearinode(dp);
|
||||
inodirty();
|
||||
}
|
||||
}
|
||||
statemap[inumber] = USTATE;
|
||||
return;
|
||||
}
|
||||
lastino = inumber;
|
||||
if (/* dp->di_size < 0 || */
|
||||
dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
|
||||
if (debug)
|
||||
printf("bad size %qu:", dp->di_size);
|
||||
goto unknown;
|
||||
}
|
||||
if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) {
|
||||
dp = ginode(inumber);
|
||||
dp->di_size = sblock.fs_fsize;
|
||||
dp->di_mode = IFREG|0600;
|
||||
inodirty();
|
||||
}
|
||||
ndb = howmany(dp->di_size, sblock.fs_bsize);
|
||||
if (ndb < 0) {
|
||||
if (debug)
|
||||
printf("bad size %qu ndb %d:",
|
||||
dp->di_size, ndb);
|
||||
goto unknown;
|
||||
}
|
||||
if (mode == IFBLK || mode == IFCHR)
|
||||
ndb++;
|
||||
if (mode == IFLNK) {
|
||||
/*
|
||||
* Note that the old fastlink format always had di_blocks set
|
||||
* to 0. Other than that we no longer use the `spare' field
|
||||
* (which is now the extended uid) for sanity checking, the
|
||||
* new format is the same as the old. We simply ignore the
|
||||
* conversion altogether. - mycroft, 19MAY1994
|
||||
*/
|
||||
if (doinglevel2 &&
|
||||
dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN &&
|
||||
dp->di_blocks != 0) {
|
||||
if (bread(fsreadfd, symbuf,
|
||||
fsbtodb(&sblock, dp->di_db[0]),
|
||||
(long)dp->di_size) != 0)
|
||||
errexit("cannot read symlink");
|
||||
if (debug) {
|
||||
symbuf[dp->di_size] = 0;
|
||||
printf("convert symlink %d(%s) of size %d\n",
|
||||
inumber, symbuf, (long)dp->di_size);
|
||||
}
|
||||
dp = ginode(inumber);
|
||||
bcopy(symbuf, (caddr_t)dp->di_shortlink,
|
||||
(long)dp->di_size);
|
||||
dp->di_blocks = 0;
|
||||
inodirty();
|
||||
}
|
||||
/*
|
||||
* Fake ndb value so direct/indirect block checks below
|
||||
* will detect any garbage after symlink string.
|
||||
*/
|
||||
if (dp->di_size < sblock.fs_maxsymlinklen ||
|
||||
(sblock.fs_maxsymlinklen == 0 && OLDFASTLINK(dp))) {
|
||||
ndb = howmany(dp->di_size, sizeof(daddr_t));
|
||||
if (ndb > NDADDR) {
|
||||
j = ndb - NDADDR;
|
||||
for (ndb = 1; j > 1; j--)
|
||||
ndb *= NINDIR(&sblock);
|
||||
ndb += NDADDR;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = ndb; j < NDADDR; j++)
|
||||
if (dp->di_db[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad direct addr: %ld\n", dp->di_db[j]);
|
||||
goto unknown;
|
||||
}
|
||||
for (j = 0, ndb -= NDADDR; ndb > 0; j++)
|
||||
ndb /= NINDIR(&sblock);
|
||||
for (; j < NIADDR; j++)
|
||||
if (dp->di_ib[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad indirect addr: %ld\n",
|
||||
dp->di_ib[j]);
|
||||
goto unknown;
|
||||
}
|
||||
if (ftypeok(dp) == 0)
|
||||
goto unknown;
|
||||
n_files++;
|
||||
lncntp[inumber] = dp->di_nlink;
|
||||
if (dp->di_nlink <= 0) {
|
||||
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
||||
if (zlnp == NULL) {
|
||||
pfatal("LINK COUNT TABLE OVERFLOW");
|
||||
if (reply("CONTINUE") == 0)
|
||||
errexit("");
|
||||
} else {
|
||||
zlnp->zlncnt = inumber;
|
||||
zlnp->next = zlnhead;
|
||||
zlnhead = zlnp;
|
||||
}
|
||||
}
|
||||
if (mode == IFDIR) {
|
||||
if (dp->di_size == 0)
|
||||
statemap[inumber] = DCLEAR;
|
||||
else
|
||||
statemap[inumber] = DSTATE;
|
||||
cacheino(dp, inumber);
|
||||
} else
|
||||
statemap[inumber] = FSTATE;
|
||||
typemap[inumber] = IFTODT(mode);
|
||||
if (doinglevel2 &&
|
||||
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
||||
dp = ginode(inumber);
|
||||
dp->di_uid = dp->di_ouid;
|
||||
dp->di_ouid = -1;
|
||||
dp->di_gid = dp->di_ogid;
|
||||
dp->di_ogid = -1;
|
||||
inodirty();
|
||||
}
|
||||
badblk = dupblk = 0;
|
||||
idesc->id_number = inumber;
|
||||
(void)ckinode(dp, idesc);
|
||||
idesc->id_entryno *= btodb(sblock.fs_fsize);
|
||||
if (dp->di_blocks != idesc->id_entryno) {
|
||||
pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
|
||||
inumber, dp->di_blocks, idesc->id_entryno);
|
||||
if (preen)
|
||||
printf(" (CORRECTED)\n");
|
||||
else if (reply("CORRECT") == 0)
|
||||
return;
|
||||
dp = ginode(inumber);
|
||||
dp->di_blocks = idesc->id_entryno;
|
||||
inodirty();
|
||||
}
|
||||
return;
|
||||
unknown:
|
||||
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
||||
statemap[inumber] = FCLEAR;
|
||||
if (reply("CLEAR") == 1) {
|
||||
statemap[inumber] = USTATE;
|
||||
dp = ginode(inumber);
|
||||
clearinode(dp);
|
||||
inodirty();
|
||||
}
|
||||
freeinodebuf();
|
||||
}
|
||||
|
||||
pass1check(idesc)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass1b.c 5.8 (Berkeley) 7/20/90";*/
|
||||
static char rcsid[] = "$Id: pass1b.c,v 1.5 1994/04/25 18:28:42 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass1b.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass1b.c,v 1.6 1994/06/08 19:00:26 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,17 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass2.c 5.17 (Berkeley) 12/28/90";*/
|
||||
static char rcsid[] = "$Id: pass2.c,v 1.5 1994/04/25 18:28:47 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass2.c 8.2 (Berkeley) 2/27/94";*/
|
||||
static char *rcsid = "$Id: pass2.c,v 1.6 1994/06/08 19:00:27 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#define KERNEL
|
||||
#include <ufs/dir.h>
|
||||
#undef KERNEL
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
@ -116,7 +114,6 @@ pass2()
|
||||
bzero((char *)&curino, sizeof(struct inodesc));
|
||||
curino.id_type = DATA;
|
||||
curino.id_func = pass2check;
|
||||
dino.di_mode = IFDIR;
|
||||
dp = &dino;
|
||||
inpend = &inpsort[inplast];
|
||||
for (inpp = inpsort; inpp < inpend; inpp++) {
|
||||
@ -146,6 +143,8 @@ pass2()
|
||||
dp = &dino;
|
||||
}
|
||||
}
|
||||
bzero((char *)&dino, sizeof(struct dinode));
|
||||
dino.di_mode = IFDIR;
|
||||
dp->di_size = inp->i_isize;
|
||||
bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0],
|
||||
(size_t)inp->i_numblks);
|
||||
@ -177,7 +176,7 @@ pass2()
|
||||
continue;
|
||||
}
|
||||
fileerror(inp->i_parent, inp->i_number,
|
||||
"BAD INODE NUMBER FOR '..'");
|
||||
"BAD INODE NUMBER FOR '..'");
|
||||
if (reply("FIX") == 0)
|
||||
continue;
|
||||
lncntp[inp->i_dotdot]++;
|
||||
@ -203,6 +202,13 @@ pass2check(idesc)
|
||||
char namebuf[MAXPATHLEN + 1];
|
||||
char pathbuf[MAXPATHLEN + 1];
|
||||
|
||||
/*
|
||||
* If converting, set directory entry type.
|
||||
*/
|
||||
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
||||
dirp->d_type = typemap[dirp->d_ino];
|
||||
ret |= ALTERED;
|
||||
}
|
||||
/*
|
||||
* check for "."
|
||||
*/
|
||||
@ -215,13 +221,23 @@ pass2check(idesc)
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
if (newinofmt && dirp->d_type != DT_DIR) {
|
||||
direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
|
||||
dirp->d_type = DT_DIR;
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
goto chk1;
|
||||
}
|
||||
direrror(idesc->id_number, "MISSING '.'");
|
||||
proto.d_ino = idesc->id_number;
|
||||
if (newinofmt)
|
||||
proto.d_type = DT_DIR;
|
||||
else
|
||||
proto.d_type = 0;
|
||||
proto.d_namlen = 1;
|
||||
(void)strcpy(proto.d_name, ".");
|
||||
entrysize = DIRSIZ(&proto);
|
||||
entrysize = DIRSIZ(0, &proto);
|
||||
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
|
||||
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
|
||||
dirp->d_name);
|
||||
@ -249,11 +265,15 @@ chk1:
|
||||
goto chk2;
|
||||
inp = getinoinfo(idesc->id_number);
|
||||
proto.d_ino = inp->i_parent;
|
||||
if (newinofmt)
|
||||
proto.d_type = DT_DIR;
|
||||
else
|
||||
proto.d_type = 0;
|
||||
proto.d_namlen = 2;
|
||||
(void)strcpy(proto.d_name, "..");
|
||||
entrysize = DIRSIZ(&proto);
|
||||
entrysize = DIRSIZ(0, &proto);
|
||||
if (idesc->id_entryno == 0) {
|
||||
n = DIRSIZ(dirp);
|
||||
n = DIRSIZ(0, dirp);
|
||||
if (dirp->d_reclen < n + entrysize)
|
||||
goto chk2;
|
||||
proto.d_reclen = dirp->d_reclen - n;
|
||||
@ -266,6 +286,12 @@ chk1:
|
||||
}
|
||||
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
|
||||
inp->i_dotdot = dirp->d_ino;
|
||||
if (newinofmt && dirp->d_type != DT_DIR) {
|
||||
direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
|
||||
dirp->d_type = DT_DIR;
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
goto chk2;
|
||||
}
|
||||
if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") != 0) {
|
||||
@ -332,10 +358,14 @@ again:
|
||||
case FCLEAR:
|
||||
if (idesc->id_entryno <= 2)
|
||||
break;
|
||||
if (statemap[dirp->d_ino] == DCLEAR)
|
||||
errmsg = "ZERO LENGTH DIRECTORY";
|
||||
else
|
||||
if (statemap[dirp->d_ino] == FCLEAR)
|
||||
errmsg = "DUP/BAD";
|
||||
else if (!preen)
|
||||
errmsg = "ZERO LENGTH DIRECTORY";
|
||||
else {
|
||||
n = 1;
|
||||
break;
|
||||
}
|
||||
fileerror(idesc->id_number, dirp->d_ino, errmsg);
|
||||
if ((n = reply("REMOVE")) == 1)
|
||||
break;
|
||||
@ -369,6 +399,13 @@ again:
|
||||
/* fall through */
|
||||
|
||||
case FSTATE:
|
||||
if (newinofmt && dirp->d_type != typemap[dirp->d_ino]) {
|
||||
fileerror(idesc->id_number, dirp->d_ino,
|
||||
"BAD TYPE VALUE");
|
||||
dirp->d_type = typemap[dirp->d_ino];
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
lncntp[dirp->d_ino]--;
|
||||
break;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass3.c 5.10 (Berkeley) 6/1/90";*/
|
||||
static char rcsid[] = "$Id: pass3.c,v 1.5 1994/04/25 18:28:51 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass3.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass3.c,v 1.6 1994/06/08 19:00:28 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include "fsck.h"
|
||||
|
||||
pass3()
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass4.c 5.10 (Berkeley) 7/20/90";*/
|
||||
static char rcsid[] = "$Id: pass4.c,v 1.5 1994/04/25 18:28:54 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass4.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass4.c,v 1.6 1994/06/08 19:00:29 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass5.c 5.13 (Berkeley) 7/20/90";*/
|
||||
static char rcsid[] = "$Id: pass5.c,v 1.5 1994/04/25 18:28:57 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass5.c 8.2 (Berkeley) 2/2/94";*/
|
||||
static char *rcsid = "$Id: pass5.c,v 1.6 1994/06/08 19:00:30 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
|
||||
@ -52,7 +52,6 @@ pass5()
|
||||
register daddr_t d;
|
||||
register long i, j;
|
||||
struct csum *cs;
|
||||
time_t now;
|
||||
struct csum cstotal;
|
||||
struct inodesc idesc[3];
|
||||
char buf[MAXBSIZE];
|
||||
@ -61,6 +60,45 @@ pass5()
|
||||
|
||||
bzero((char *)newcg, (size_t)fs->fs_cgsize);
|
||||
newcg->cg_niblk = fs->fs_ipg;
|
||||
if (cvtlevel > 3) {
|
||||
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
|
||||
if (preen)
|
||||
pwarn("DELETING CLUSTERING MAPS\n");
|
||||
if (preen || reply("DELETE CLUSTERING MAPS")) {
|
||||
fs->fs_contigsumsize = 0;
|
||||
doinglevel1 = 1;
|
||||
sbdirty();
|
||||
}
|
||||
}
|
||||
if (fs->fs_maxcontig > 1) {
|
||||
char *doit = 0;
|
||||
|
||||
if (fs->fs_contigsumsize < 1) {
|
||||
doit = "CREAT";
|
||||
} else if (fs->fs_contigsumsize < fs->fs_maxcontig &&
|
||||
fs->fs_contigsumsize < FS_MAXCONTIG) {
|
||||
doit = "EXPAND";
|
||||
}
|
||||
if (doit) {
|
||||
i = fs->fs_contigsumsize;
|
||||
fs->fs_contigsumsize =
|
||||
MIN(fs->fs_maxcontig, FS_MAXCONTIG);
|
||||
if (CGSIZE(fs) > fs->fs_bsize) {
|
||||
pwarn("CANNOT %s CLUSTER MAPS\n", doit);
|
||||
fs->fs_contigsumsize = i;
|
||||
} else if (preen ||
|
||||
reply("CREATE CLUSTER MAPS")) {
|
||||
if (preen)
|
||||
pwarn("%sING CLUSTER MAPS\n",
|
||||
doit);
|
||||
fs->fs_cgsize =
|
||||
fragroundup(fs, CGSIZE(fs));
|
||||
doinglevel1 = 1;
|
||||
sbdirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch ((int)fs->fs_postblformat) {
|
||||
|
||||
case FS_42POSTBLFMT:
|
||||
@ -75,16 +113,27 @@ pass5()
|
||||
|
||||
case FS_DYNAMICPOSTBLFMT:
|
||||
newcg->cg_btotoff =
|
||||
&newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
|
||||
&newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
|
||||
newcg->cg_boff =
|
||||
newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
|
||||
newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
|
||||
newcg->cg_iusedoff = newcg->cg_boff +
|
||||
fs->fs_cpg * fs->fs_nrpos * sizeof(short);
|
||||
fs->fs_cpg * fs->fs_nrpos * sizeof(short);
|
||||
newcg->cg_freeoff =
|
||||
newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
|
||||
newcg->cg_nextfreeoff = newcg->cg_freeoff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs),
|
||||
NBBY);
|
||||
newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
|
||||
if (fs->fs_contigsumsize <= 0) {
|
||||
newcg->cg_nextfreeoff = newcg->cg_freeoff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY);
|
||||
} else {
|
||||
newcg->cg_clustersumoff = newcg->cg_freeoff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) -
|
||||
sizeof(long);
|
||||
newcg->cg_clustersumoff =
|
||||
roundup(newcg->cg_clustersumoff, sizeof(long));
|
||||
newcg->cg_clusteroff = newcg->cg_clustersumoff +
|
||||
(fs->fs_contigsumsize + 1) * sizeof(long);
|
||||
newcg->cg_nextfreeoff = newcg->cg_clusteroff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
|
||||
}
|
||||
newcg->cg_magic = CG_MAGIC;
|
||||
basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
|
||||
sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
|
||||
@ -96,10 +145,12 @@ pass5()
|
||||
fs->fs_postblformat);
|
||||
}
|
||||
bzero((char *)&idesc[0], sizeof idesc);
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i = 0; i < 3; i++) {
|
||||
idesc[i].id_type = ADDR;
|
||||
if (doinglevel2)
|
||||
idesc[i].id_fix = FIX;
|
||||
}
|
||||
bzero((char *)&cstotal, sizeof(struct csum));
|
||||
(void)time(&now);
|
||||
j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
|
||||
for (i = fs->fs_size; i < j; i++)
|
||||
setbmap(i);
|
||||
@ -111,16 +162,15 @@ pass5()
|
||||
dmax = dbase + fs->fs_fpg;
|
||||
if (dmax > fs->fs_size)
|
||||
dmax = fs->fs_size;
|
||||
if (now > cg->cg_time)
|
||||
newcg->cg_time = cg->cg_time;
|
||||
else
|
||||
newcg->cg_time = now;
|
||||
newcg->cg_time = cg->cg_time;
|
||||
newcg->cg_cgx = c;
|
||||
if (c == fs->fs_ncg - 1)
|
||||
newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
|
||||
else
|
||||
newcg->cg_ncyl = fs->fs_cpg;
|
||||
newcg->cg_ndblk = dmax - dbase;
|
||||
if (fs->fs_contigsumsize > 0)
|
||||
newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag;
|
||||
newcg->cg_cs.cs_ndir = 0;
|
||||
newcg->cg_cs.cs_nffree = 0;
|
||||
newcg->cg_cs.cs_nbfree = 0;
|
||||
@ -188,10 +238,42 @@ pass5()
|
||||
j = cbtocylno(fs, i);
|
||||
cg_blktot(newcg)[j]++;
|
||||
cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
|
||||
if (fs->fs_contigsumsize > 0)
|
||||
setbit(cg_clustersfree(newcg),
|
||||
i / fs->fs_frag);
|
||||
} else if (frags > 0) {
|
||||
newcg->cg_cs.cs_nffree += frags;
|
||||
blk = blkmap(fs, cg_blksfree(newcg), i);
|
||||
fragacct(fs, blk, newcg->cg_frsum, 1);
|
||||
ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
|
||||
}
|
||||
}
|
||||
if (fs->fs_contigsumsize > 0) {
|
||||
long *sump = cg_clustersum(newcg);
|
||||
u_char *mapp = cg_clustersfree(newcg);
|
||||
int map = *mapp++;
|
||||
int bit = 1;
|
||||
int run = 0;
|
||||
|
||||
for (i = 0; i < newcg->cg_nclusterblks; i++) {
|
||||
if ((map & bit) != 0) {
|
||||
run++;
|
||||
} else if (run != 0) {
|
||||
if (run > fs->fs_contigsumsize)
|
||||
run = fs->fs_contigsumsize;
|
||||
sump[run]++;
|
||||
run = 0;
|
||||
}
|
||||
if ((i & (NBBY - 1)) != (NBBY - 1)) {
|
||||
bit <<= 1;
|
||||
} else {
|
||||
map = *mapp++;
|
||||
bit = 1;
|
||||
}
|
||||
}
|
||||
if (run != 0) {
|
||||
if (run > fs->fs_contigsumsize)
|
||||
run = fs->fs_contigsumsize;
|
||||
sump[run]++;
|
||||
}
|
||||
}
|
||||
cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
|
||||
@ -204,7 +286,7 @@ pass5()
|
||||
bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs);
|
||||
sbdirty();
|
||||
}
|
||||
if (cvtflag) {
|
||||
if (doinglevel1) {
|
||||
bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize);
|
||||
cgdirty();
|
||||
continue;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,13 +32,12 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)preen.c 5.7 (Berkeley) 3/19/91";*/
|
||||
static char rcsid[] = "$Id: preen.c,v 1.5 1994/04/25 18:29:01 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)preen.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: preen.c,v 1.6 1994/06/08 19:00:31 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fstab.h>
|
||||
#include <string.h>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,20 +32,19 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)setup.c 5.33 (Berkeley) 2/22/91";*/
|
||||
static char rcsid[] = "$Id: setup.c,v 1.9 1994/04/25 18:33:42 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)setup.c 8.2 (Berkeley) 2/21/94";*/
|
||||
static char *rcsid = "$Id: setup.c,v 1.10 1994/06/08 19:00:32 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#define DKTYPENAMES
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/mount.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -56,22 +55,7 @@ struct bufarea asblk;
|
||||
#define altsblock (*asblk.b_un.b_fs)
|
||||
#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
|
||||
|
||||
/*
|
||||
* The size of a cylinder group is calculated by CGSIZE. The maximum size
|
||||
* is limited by the fact that cylinder groups are at most one block.
|
||||
* Its size is derived from the size of the maps maintained in the
|
||||
* cylinder group and the (struct cg) size.
|
||||
*/
|
||||
#define CGSIZE(fs) \
|
||||
/* base cg */ (sizeof(struct cg) + \
|
||||
/* blktot size */ (fs)->fs_cpg * sizeof(long) + \
|
||||
/* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof(short) + \
|
||||
/* inode map */ howmany((fs)->fs_ipg, NBBY) + \
|
||||
/* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY))
|
||||
|
||||
char *index();
|
||||
struct disklabel *getdisklabel();
|
||||
char *getmntdev();
|
||||
|
||||
setup(dev)
|
||||
char *dev;
|
||||
@ -79,47 +63,17 @@ setup(dev)
|
||||
long cg, size, asked, i, j;
|
||||
long bmapsize;
|
||||
struct disklabel *lp;
|
||||
struct stat statb, statb2;
|
||||
off_t sizepb;
|
||||
struct stat statb;
|
||||
struct fs proto;
|
||||
char path2[MAXPATHLEN];
|
||||
char *dev2;
|
||||
|
||||
havesb = 0;
|
||||
fswritefd = -1;
|
||||
if (stat(dev, &statb) < 0) {
|
||||
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
||||
return (0);
|
||||
}
|
||||
switch (statb.st_mode & S_IFMT) {
|
||||
case S_IFCHR:
|
||||
break;
|
||||
case S_IFDIR:
|
||||
dev2 = getmntdev(dev);
|
||||
if (dev2 != NULL && !strncmp(dev2, "/dev/", 5)) {
|
||||
snprintf(path2, sizeof(path2), "/dev/r%s", dev2 + 5);
|
||||
if (stat(path2, &statb2) == 0 &&
|
||||
(statb2.st_mode & S_IFMT) == S_IFCHR) {
|
||||
dev = path2;
|
||||
statb = statb2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pfatal("%s is not a character device", dev);
|
||||
if (reply("CONTINUE") == 0)
|
||||
return (0);
|
||||
break;
|
||||
case S_IFBLK:
|
||||
if (!strncmp(dev, "/dev/", 5)) {
|
||||
sprintf(path2, "/dev/r%s", dev + 5);
|
||||
if (stat(path2, &statb2) == 0 &&
|
||||
(statb2.st_mode & S_IFMT) == S_IFCHR &&
|
||||
minor(statb2.st_rdev) == minor(statb.st_rdev)) {
|
||||
dev = path2;
|
||||
statb = statb2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
if ((statb.st_mode & S_IFMT) != S_IFCHR) {
|
||||
pfatal("%s is not a character device", dev);
|
||||
if (reply("CONTINUE") == 0)
|
||||
return (0);
|
||||
@ -150,14 +104,6 @@ setup(dev)
|
||||
dev_bsize = secsize = lp->d_secsize;
|
||||
else
|
||||
dev_bsize = secsize = DEV_BSIZE;
|
||||
#ifdef tahoe
|
||||
/*
|
||||
* On the tahoe, the disk label and the disk driver disagree.
|
||||
* The label knows that sectors are 512 bytes, but the disk
|
||||
* drivers will only transfer in 1024 sized pieces.
|
||||
*/
|
||||
secsize = 1024;
|
||||
#endif
|
||||
/*
|
||||
* Read in the superblock, looking for alternates if necessary
|
||||
*/
|
||||
@ -227,64 +173,55 @@ setup(dev)
|
||||
dirty(&asblk);
|
||||
}
|
||||
}
|
||||
if (cvtflag) {
|
||||
if (sblock.fs_postblformat == FS_42POSTBLFMT) {
|
||||
/*
|
||||
* Requested to convert from old format to new format
|
||||
*/
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO NEW FILE SYSTEM FORMAT\n");
|
||||
else if (!reply("CONVERT TO NEW FILE SYSTEM FORMAT"))
|
||||
return(0);
|
||||
sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT;
|
||||
sblock.fs_nrpos = 8;
|
||||
sblock.fs_postbloff =
|
||||
(char *)(&sblock.fs_opostbl[0][0]) -
|
||||
(char *)(&sblock.fs_link);
|
||||
sblock.fs_rotbloff = &sblock.fs_space[0] -
|
||||
(u_char *)(&sblock.fs_link);
|
||||
sblock.fs_cgsize =
|
||||
fragroundup(&sblock, CGSIZE(&sblock));
|
||||
/*
|
||||
* Planning now for future expansion.
|
||||
*/
|
||||
# if (BYTE_ORDER == BIG_ENDIAN)
|
||||
sblock.fs_qbmask.val[0] = 0;
|
||||
sblock.fs_qbmask.val[1] = ~sblock.fs_bmask;
|
||||
sblock.fs_qfmask.val[0] = 0;
|
||||
sblock.fs_qfmask.val[1] = ~sblock.fs_fmask;
|
||||
# endif /* BIG_ENDIAN */
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
sblock.fs_qbmask.val[0] = ~sblock.fs_bmask;
|
||||
sblock.fs_qbmask.val[1] = 0;
|
||||
sblock.fs_qfmask.val[0] = ~sblock.fs_fmask;
|
||||
sblock.fs_qfmask.val[1] = 0;
|
||||
# endif /* LITTLE_ENDIAN */
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
} else if (sblock.fs_postblformat == FS_DYNAMICPOSTBLFMT) {
|
||||
/*
|
||||
* Requested to convert from new format to old format
|
||||
*/
|
||||
if (sblock.fs_nrpos != 8 || sblock.fs_ipg > 2048 ||
|
||||
sblock.fs_cpg > 32 || sblock.fs_cpc > 16) {
|
||||
printf(
|
||||
"PARAMETERS OF CURRENT FILE SYSTEM DO NOT\n\t");
|
||||
errexit(
|
||||
"ALLOW CONVERSION TO OLD FILE SYSTEM FORMAT\n");
|
||||
}
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO OLD FILE SYSTEM FORMAT\n");
|
||||
else if (!reply("CONVERT TO OLD FILE SYSTEM FORMAT"))
|
||||
return(0);
|
||||
sblock.fs_postblformat = FS_42POSTBLFMT;
|
||||
sblock.fs_cgsize = fragroundup(&sblock,
|
||||
sizeof(struct ocg) + howmany(sblock.fs_fpg, NBBY));
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
} else {
|
||||
errexit("UNKNOWN FILE SYSTEM FORMAT\n");
|
||||
if (sblock.fs_inodefmt >= FS_44INODEFMT) {
|
||||
newinofmt = 1;
|
||||
} else {
|
||||
sblock.fs_qbmask = ~sblock.fs_bmask;
|
||||
sblock.fs_qfmask = ~sblock.fs_fmask;
|
||||
newinofmt = 0;
|
||||
}
|
||||
/*
|
||||
* Convert to new inode format.
|
||||
*/
|
||||
if (cvtlevel >= 2 && sblock.fs_inodefmt < FS_44INODEFMT) {
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO NEW INODE FORMAT\n");
|
||||
else if (!reply("CONVERT TO NEW INODE FORMAT"))
|
||||
return(0);
|
||||
doinglevel2++;
|
||||
sblock.fs_inodefmt = FS_44INODEFMT;
|
||||
sizepb = sblock.fs_bsize;
|
||||
sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1;
|
||||
for (i = 0; i < NIADDR; i++) {
|
||||
sizepb *= NINDIR(&sblock);
|
||||
sblock.fs_maxfilesize += sizepb;
|
||||
}
|
||||
sblock.fs_maxsymlinklen = MAXSYMLINKLEN;
|
||||
sblock.fs_qbmask = ~sblock.fs_bmask;
|
||||
sblock.fs_qfmask = ~sblock.fs_fmask;
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
}
|
||||
/*
|
||||
* Convert to new cylinder group format.
|
||||
*/
|
||||
if (cvtlevel >= 1 && sblock.fs_postblformat == FS_42POSTBLFMT) {
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO NEW CYLINDER GROUP FORMAT\n");
|
||||
else if (!reply("CONVERT TO NEW CYLINDER GROUP FORMAT"))
|
||||
return(0);
|
||||
doinglevel1++;
|
||||
sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT;
|
||||
sblock.fs_nrpos = 8;
|
||||
sblock.fs_postbloff =
|
||||
(char *)(&sblock.fs_opostbl[0][0]) -
|
||||
(char *)(&sblock.fs_link);
|
||||
sblock.fs_rotbloff = &sblock.fs_space[0] -
|
||||
(u_char *)(&sblock.fs_link);
|
||||
sblock.fs_cgsize =
|
||||
fragroundup(&sblock, CGSIZE(&sblock));
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
}
|
||||
if (asblk.b_dirty) {
|
||||
bcopy((char *)&sblock, (char *)&altsblock,
|
||||
@ -324,6 +261,12 @@ setup(dev)
|
||||
(unsigned)(maxino + 1));
|
||||
goto badsb;
|
||||
}
|
||||
typemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
||||
if (typemap == NULL) {
|
||||
printf("cannot alloc %u bytes for typemap\n",
|
||||
(unsigned)(maxino + 1));
|
||||
goto badsb;
|
||||
}
|
||||
lncntp = (short *)calloc((unsigned)(maxino + 1), sizeof(short));
|
||||
if (lncntp == NULL) {
|
||||
printf("cannot alloc %u bytes for lncntp\n",
|
||||
@ -384,6 +327,10 @@ readsb(listerr)
|
||||
super *= dev_bsize;
|
||||
dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
|
||||
sblk.b_bno = super / dev_bsize;
|
||||
if (bflag) {
|
||||
havesb = 1;
|
||||
return (1);
|
||||
}
|
||||
/*
|
||||
* Set all possible fields that could differ, then do check
|
||||
* of whole super block against an alternate super block.
|
||||
@ -392,10 +339,6 @@ readsb(listerr)
|
||||
getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
|
||||
if (asblk.b_errs)
|
||||
return (0);
|
||||
if (bflag) {
|
||||
havesb = 1;
|
||||
return (1);
|
||||
}
|
||||
altsblock.fs_link = sblock.fs_link;
|
||||
altsblock.fs_rlink = sblock.fs_rlink;
|
||||
altsblock.fs_time = sblock.fs_time;
|
||||
@ -403,7 +346,6 @@ readsb(listerr)
|
||||
altsblock.fs_cgrotor = sblock.fs_cgrotor;
|
||||
altsblock.fs_fmod = sblock.fs_fmod;
|
||||
altsblock.fs_clean = sblock.fs_clean;
|
||||
altsblock.fs_state = sblock.fs_state;
|
||||
altsblock.fs_ronly = sblock.fs_ronly;
|
||||
altsblock.fs_flags = sblock.fs_flags;
|
||||
altsblock.fs_maxcontig = sblock.fs_maxcontig;
|
||||
@ -424,6 +366,10 @@ readsb(listerr)
|
||||
altsblock.fs_interleave = sblock.fs_interleave;
|
||||
altsblock.fs_npsect = sblock.fs_npsect;
|
||||
altsblock.fs_nrpos = sblock.fs_nrpos;
|
||||
altsblock.fs_qbmask = sblock.fs_qbmask;
|
||||
altsblock.fs_qfmask = sblock.fs_qfmask;
|
||||
altsblock.fs_state = sblock.fs_state;
|
||||
altsblock.fs_maxfilesize = sblock.fs_maxfilesize;
|
||||
if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) {
|
||||
badsb(listerr,
|
||||
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
|
||||
@ -441,7 +387,7 @@ badsb(listerr, s)
|
||||
if (!listerr)
|
||||
return;
|
||||
if (preen)
|
||||
printf("%s: ", devname);
|
||||
printf("%s: ", cdevname);
|
||||
pfatal("BAD SUPER BLOCK: %s\n", s);
|
||||
}
|
||||
|
||||
@ -519,20 +465,3 @@ getdisklabel(s, fd)
|
||||
}
|
||||
return (&lab);
|
||||
}
|
||||
|
||||
char *
|
||||
getmntdev(name)
|
||||
char *name;
|
||||
{
|
||||
long mntsize;
|
||||
register long i;
|
||||
struct statfs *mntbuf;
|
||||
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
if (!strncmp(mntbuf[i].f_fstypename, MOUNT_UFS, MFSNAMELEN) &&
|
||||
!strcmp(mntbuf[i].f_mntonname, name))
|
||||
return (mntbuf[i].f_mntfromname);
|
||||
}
|
||||
return ((char *)0);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,15 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)utilities.c 5.30 (Berkeley) 7/26/91";*/
|
||||
static char rcsid[] = "$Id: utilities.c,v 1.8 1994/05/02 10:18:25 pk Exp $";
|
||||
/*static char sccsid[] = "from: @(#)utilities.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: utilities.c,v 1.9 1994/06/08 19:00:33 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/dir.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -49,7 +49,6 @@ static char rcsid[] = "$Id: utilities.c,v 1.8 1994/05/02 10:18:25 pk Exp $";
|
||||
|
||||
long diskreads, totalreads; /* Disk cache statistics */
|
||||
|
||||
int
|
||||
ftypeok(dp)
|
||||
struct dinode *dp;
|
||||
{
|
||||
@ -71,7 +70,6 @@ ftypeok(dp)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
reply(question)
|
||||
char *question;
|
||||
{
|
||||
@ -107,7 +105,6 @@ reply(question)
|
||||
/*
|
||||
* Malloc buffers and set up cache.
|
||||
*/
|
||||
void
|
||||
bufinit()
|
||||
{
|
||||
register struct bufarea *bp;
|
||||
@ -192,7 +189,6 @@ getblk(bp, blk, size)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flush(fd, bp)
|
||||
int fd;
|
||||
register struct bufarea *bp;
|
||||
@ -218,7 +214,6 @@ flush(fd, bp)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rwerror(mesg, blk)
|
||||
char *mesg;
|
||||
daddr_t blk;
|
||||
@ -231,12 +226,15 @@ rwerror(mesg, blk)
|
||||
errexit("Program terminated\n");
|
||||
}
|
||||
|
||||
void
|
||||
ckfini()
|
||||
{
|
||||
register struct bufarea *bp, *nbp;
|
||||
int cnt = 0;
|
||||
|
||||
if (fswritefd < 0) {
|
||||
(void)close(fsreadfd);
|
||||
return;
|
||||
}
|
||||
flush(fswritefd, &sblk);
|
||||
if (havesb && sblk.b_bno != SBOFF / dev_bsize &&
|
||||
!preen && reply("UPDATE STANDARD SUPERBLOCK")) {
|
||||
@ -271,20 +269,23 @@ bread(fd, buf, blk, size)
|
||||
{
|
||||
char *cp;
|
||||
int i, errs;
|
||||
off_t offset;
|
||||
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
offset = blk;
|
||||
offset *= dev_bsize;
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
else if (read(fd, buf, (int)size) == size)
|
||||
return (0);
|
||||
rwerror("READ", blk);
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
errs = 0;
|
||||
bzero(buf, (size_t)size);
|
||||
printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
|
||||
for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
|
||||
if (read(fd, cp, (int)secsize) != secsize) {
|
||||
(void)lseek(fd, blk * dev_bsize + i + secsize, 0);
|
||||
(void)lseek(fd, offset + i + secsize, 0);
|
||||
if (secsize != dev_bsize && dev_bsize != 1)
|
||||
printf(" %ld (%ld),",
|
||||
(blk * dev_bsize + i) / secsize,
|
||||
@ -306,22 +307,25 @@ bwrite(fd, buf, blk, size)
|
||||
{
|
||||
int i;
|
||||
char *cp;
|
||||
off_t offset;
|
||||
|
||||
if (fd < 0)
|
||||
return;
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
offset = blk;
|
||||
offset *= dev_bsize;
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
else if (write(fd, buf, (int)size) == size) {
|
||||
fsmodified = 1;
|
||||
return;
|
||||
}
|
||||
rwerror("WRITE", blk);
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
|
||||
for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
|
||||
if (write(fd, cp, (int)dev_bsize) != dev_bsize) {
|
||||
(void)lseek(fd, blk * dev_bsize + i + dev_bsize, 0);
|
||||
(void)lseek(fd, offset + i + dev_bsize, 0);
|
||||
printf(" %ld,", blk + i / dev_bsize);
|
||||
}
|
||||
printf("\n");
|
||||
@ -361,7 +365,6 @@ allocblk(frags)
|
||||
/*
|
||||
* Free a previously allocated block
|
||||
*/
|
||||
void
|
||||
freeblk(blkno, frags)
|
||||
daddr_t blkno;
|
||||
long frags;
|
||||
@ -376,7 +379,6 @@ freeblk(blkno, frags)
|
||||
/*
|
||||
* Find a pathname
|
||||
*/
|
||||
void
|
||||
getpathname(namebuf, curdir, ino)
|
||||
char *namebuf;
|
||||
ino_t curdir, ino;
|
||||
@ -387,6 +389,10 @@ getpathname(namebuf, curdir, ino)
|
||||
static int busy = 0;
|
||||
extern int findname();
|
||||
|
||||
if (curdir == ino && ino == ROOTINO) {
|
||||
(void)strcpy(namebuf, "/");
|
||||
return;
|
||||
}
|
||||
if (busy ||
|
||||
(statemap[curdir] != DSTATE && statemap[curdir] != DFOUND)) {
|
||||
(void)strcpy(namebuf, "?");
|
||||
@ -432,7 +438,8 @@ getpathname(namebuf, curdir, ino)
|
||||
void
|
||||
catch()
|
||||
{
|
||||
ckfini();
|
||||
if (!doinglevel2)
|
||||
ckfini();
|
||||
exit(12);
|
||||
}
|
||||
|
||||
@ -522,11 +529,11 @@ pfatal(s, a1, a2, a3)
|
||||
{
|
||||
|
||||
if (preen) {
|
||||
printf("%s: ", devname);
|
||||
printf("%s: ", cdevname);
|
||||
printf(s, a1, a2, a3);
|
||||
printf("\n");
|
||||
printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
|
||||
devname);
|
||||
cdevname);
|
||||
exit(8);
|
||||
}
|
||||
printf(s, a1, a2, a3);
|
||||
@ -542,7 +549,7 @@ pwarn(s, a1, a2, a3, a4, a5, a6)
|
||||
{
|
||||
|
||||
if (preen)
|
||||
printf("%s: ", devname);
|
||||
printf("%s: ", cdevname);
|
||||
printf(s, a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
# from: @(#)Makefile 5.15 (Berkeley) 6/29/90
|
||||
# $Id: Makefile,v 1.5 1993/08/01 05:37:50 mycroft Exp $
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.6 1994/06/08 19:00:18 mycroft Exp $
|
||||
|
||||
PROG= fsck
|
||||
MAN8= fsck.0
|
||||
SRCS= dir.c inode.c main.c pass1.c pass1b.c pass2.c pass3.c pass4.c \
|
||||
pass5.c preen.c setup.c utilities.c ufs_subr.c ufs_tables.c
|
||||
.PATH: ${.CURDIR}/../../sys/ufs
|
||||
pass5.c preen.c setup.c utilities.c ffs_subr.c ffs_tables.c
|
||||
.PATH: ${.CURDIR}/../../sys/ufs/ffs
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
151
sbin/fsck_ffs/SMM.doc/0.t
Normal file
151
sbin/fsck_ffs/SMM.doc/0.t
Normal file
@ -0,0 +1,151 @@
|
||||
.\" Copyright (c) 1986, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)0.t 8.1 (Berkeley) 6/8/93
|
||||
.\" $Id: 0.t,v 1.1 1994/06/08 19:00:49 mycroft Exp $
|
||||
.\"
|
||||
.if n .ND
|
||||
.TL
|
||||
Fsck \- The UNIX\(dg File System Check Program
|
||||
.EH 'SMM:3-%''The \s-2UNIX\s+2 File System Check Program'
|
||||
.OH 'The \s-2UNIX\s+2 File System Check Program''SMM:3-%'
|
||||
.AU
|
||||
Marshall Kirk McKusick
|
||||
.AI
|
||||
Computer Systems Research Group
|
||||
Computer Science Division
|
||||
Department of Electrical Engineering and Computer Science
|
||||
University of California, Berkeley
|
||||
Berkeley, CA 94720
|
||||
.AU
|
||||
T. J. Kowalski
|
||||
.AI
|
||||
Bell Laboratories
|
||||
Murray Hill, New Jersey 07974
|
||||
.AB
|
||||
.FS
|
||||
\(dgUNIX is a trademark of Bell Laboratories.
|
||||
.FE
|
||||
.FS
|
||||
This work was done under grants from
|
||||
the National Science Foundation under grant MCS80-05144,
|
||||
and the Defense Advance Research Projects Agency (DoD) under
|
||||
Arpa Order No. 4031 monitored by Naval Electronic System Command under
|
||||
Contract No. N00039-82-C-0235.
|
||||
.FE
|
||||
This document reflects the use of
|
||||
.I fsck
|
||||
with the 4.2BSD and 4.3BSD file system organization. This
|
||||
is a revision of the
|
||||
original paper written by
|
||||
T. J. Kowalski.
|
||||
.PP
|
||||
File System Check Program (\fIfsck\fR)
|
||||
is an interactive file system check and repair program.
|
||||
.I Fsck
|
||||
uses the redundant structural information in the
|
||||
UNIX file system to perform several consistency checks.
|
||||
If an inconsistency is detected, it is reported
|
||||
to the operator, who may elect to fix or ignore
|
||||
each inconsistency.
|
||||
These inconsistencies result from the permanent interruption
|
||||
of the file system updates, which are performed every
|
||||
time a file is modified.
|
||||
Unless there has been a hardware failure,
|
||||
.I fsck
|
||||
is able to repair corrupted file systems
|
||||
using procedures based upon the order in which UNIX honors
|
||||
these file system update requests.
|
||||
.PP
|
||||
The purpose of this document is to describe the normal updating
|
||||
of the file system,
|
||||
to discuss the possible causes of file system corruption,
|
||||
and to present the corrective actions implemented
|
||||
by
|
||||
.I fsck.
|
||||
Both the program and the interaction between the
|
||||
program and the operator are described.
|
||||
.sp 2
|
||||
.LP
|
||||
Revised July 16, 1985
|
||||
.AE
|
||||
.LP
|
||||
.bp
|
||||
.ce
|
||||
.B "TABLE OF CONTENTS"
|
||||
.LP
|
||||
.sp 1
|
||||
.nf
|
||||
.B "1. Introduction"
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B "2. Overview of the file system
|
||||
2.1. Superblock
|
||||
2.2. Summary Information
|
||||
2.3. Cylinder groups
|
||||
2.4. Fragments
|
||||
2.5. Updates to the file system
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B "3. Fixing corrupted file systems
|
||||
3.1. Detecting and correcting corruption
|
||||
3.2. Super block checking
|
||||
3.3. Free block checking
|
||||
3.4. Checking the inode state
|
||||
3.5. Inode links
|
||||
3.6. Inode data size
|
||||
3.7. Checking the data associated with an inode
|
||||
3.8. File system connectivity
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B Acknowledgements
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B References
|
||||
.LP
|
||||
.sp .5v
|
||||
.nf
|
||||
.B "4. Appendix A
|
||||
4.1. Conventions
|
||||
4.2. Initialization
|
||||
4.3. Phase 1 - Check Blocks and Sizes
|
||||
4.4. Phase 1b - Rescan for more Dups
|
||||
4.5. Phase 2 - Check Pathnames
|
||||
4.6. Phase 3 - Check Connectivity
|
||||
4.7. Phase 4 - Check Reference Counts
|
||||
4.8. Phase 5 - Check Cyl groups
|
||||
4.9. Cleanup
|
||||
.ds RH Introduction
|
||||
.bp
|
84
sbin/fsck_ffs/SMM.doc/1.t
Normal file
84
sbin/fsck_ffs/SMM.doc/1.t
Normal file
@ -0,0 +1,84 @@
|
||||
.\" Copyright (c) 1982, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)1.t 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: 1.t,v 1.1 1994/06/08 19:01:21 mycroft Exp $
|
||||
.\"
|
||||
.ds RH Introduction
|
||||
.NH
|
||||
Introduction
|
||||
.PP
|
||||
This document reflects the use of
|
||||
.I fsck
|
||||
with the 4.2BSD and 4.3BSD file system organization. This
|
||||
is a revision of the
|
||||
original paper written by
|
||||
T. J. Kowalski.
|
||||
.PP
|
||||
When a UNIX
|
||||
operating system is brought up, a consistency
|
||||
check of the file systems should always be performed.
|
||||
This precautionary measure helps to insure
|
||||
a reliable environment for file storage on disk.
|
||||
If an inconsistency is discovered,
|
||||
corrective action must be taken.
|
||||
.I Fsck
|
||||
runs in two modes.
|
||||
Normally it is run non-interactively by the system after
|
||||
a normal boot.
|
||||
When running in this mode,
|
||||
it will only make changes to the file system that are known
|
||||
to always be correct.
|
||||
If an unexpected inconsistency is found
|
||||
.I fsck
|
||||
will exit with a non-zero exit status,
|
||||
leaving the system running single-user.
|
||||
Typically the operator then runs
|
||||
.I fsck
|
||||
interactively.
|
||||
When running in this mode,
|
||||
each problem is listed followed by a suggested corrective action.
|
||||
The operator must decide whether or not the suggested correction
|
||||
should be made.
|
||||
.PP
|
||||
The purpose of this memo is to dispel the
|
||||
mystique surrounding
|
||||
file system inconsistencies.
|
||||
It first describes the updating of the file system
|
||||
(the calm before the storm) and
|
||||
then describes file system corruption (the storm).
|
||||
Finally,
|
||||
the set of deterministic corrective actions
|
||||
used by
|
||||
.I fsck
|
||||
(the Coast Guard
|
||||
to the rescue) is presented.
|
||||
.ds RH Overview of the File System
|
266
sbin/fsck_ffs/SMM.doc/2.t
Normal file
266
sbin/fsck_ffs/SMM.doc/2.t
Normal file
@ -0,0 +1,266 @@
|
||||
.\" Copyright (c) 1982, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)2.t 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: 2.t,v 1.1 1994/06/08 19:01:22 mycroft Exp $
|
||||
.\"
|
||||
.ds RH Overview of the file system
|
||||
.NH
|
||||
Overview of the file system
|
||||
.PP
|
||||
The file system is discussed in detail in [Mckusick84];
|
||||
this section gives a brief overview.
|
||||
.NH 2
|
||||
Superblock
|
||||
.PP
|
||||
A file system is described by its
|
||||
.I "super-block" .
|
||||
The super-block is built when the file system is created (\c
|
||||
.I newfs (8))
|
||||
and never changes.
|
||||
The super-block
|
||||
contains the basic parameters of the file system,
|
||||
such as the number of data blocks it contains
|
||||
and a count of the maximum number of files.
|
||||
Because the super-block contains critical data,
|
||||
.I newfs
|
||||
replicates it to protect against catastrophic loss.
|
||||
The
|
||||
.I "default super block"
|
||||
always resides at a fixed offset from the beginning
|
||||
of the file system's disk partition.
|
||||
The
|
||||
.I "redundant super blocks"
|
||||
are not referenced unless a head crash
|
||||
or other hard disk error causes the default super-block
|
||||
to be unusable.
|
||||
The redundant blocks are sprinkled throughout the disk partition.
|
||||
.PP
|
||||
Within the file system are files.
|
||||
Certain files are distinguished as directories and contain collections
|
||||
of pointers to files that may themselves be directories.
|
||||
Every file has a descriptor associated with it called an
|
||||
.I "inode".
|
||||
The inode contains information describing ownership of the file,
|
||||
time stamps indicating modification and access times for the file,
|
||||
and an array of indices pointing to the data blocks for the file.
|
||||
In this section,
|
||||
we assume that the first 12 blocks
|
||||
of the file are directly referenced by values stored
|
||||
in the inode structure itself\(dg.
|
||||
.FS
|
||||
\(dgThe actual number may vary from system to system, but is usually in
|
||||
the range 5-13.
|
||||
.FE
|
||||
The inode structure may also contain references to indirect blocks
|
||||
containing further data block indices.
|
||||
In a file system with a 4096 byte block size, a singly indirect
|
||||
block contains 1024 further block addresses,
|
||||
a doubly indirect block contains 1024 addresses of further single indirect
|
||||
blocks,
|
||||
and a triply indirect block contains 1024 addresses of further doubly indirect
|
||||
blocks (the triple indirect block is never needed in practice).
|
||||
.PP
|
||||
In order to create files with up to
|
||||
2\(ua32 bytes,
|
||||
using only two levels of indirection,
|
||||
the minimum size of a file system block is 4096 bytes.
|
||||
The size of file system blocks can be any power of two
|
||||
greater than or equal to 4096.
|
||||
The block size of the file system is maintained in the super-block,
|
||||
so it is possible for file systems of different block sizes
|
||||
to be accessible simultaneously on the same system.
|
||||
The block size must be decided when
|
||||
.I newfs
|
||||
creates the file system;
|
||||
the block size cannot be subsequently
|
||||
changed without rebuilding the file system.
|
||||
.NH 2
|
||||
Summary information
|
||||
.PP
|
||||
Associated with the super block is non replicated
|
||||
.I "summary information" .
|
||||
The summary information changes
|
||||
as the file system is modified.
|
||||
The summary information contains
|
||||
the number of blocks, fragments, inodes and directories in the file system.
|
||||
.NH 2
|
||||
Cylinder groups
|
||||
.PP
|
||||
The file system partitions the disk into one or more areas called
|
||||
.I "cylinder groups".
|
||||
A cylinder group is comprised of one or more consecutive
|
||||
cylinders on a disk.
|
||||
Each cylinder group includes inode slots for files, a
|
||||
.I "block map"
|
||||
describing available blocks in the cylinder group,
|
||||
and summary information describing the usage of data blocks
|
||||
within the cylinder group.
|
||||
A fixed number of inodes is allocated for each cylinder group
|
||||
when the file system is created.
|
||||
The current policy is to allocate one inode for each 2048
|
||||
bytes of disk space;
|
||||
this is expected to be far more inodes than will ever be needed.
|
||||
.PP
|
||||
All the cylinder group bookkeeping information could be
|
||||
placed at the beginning of each cylinder group.
|
||||
However if this approach were used,
|
||||
all the redundant information would be on the top platter.
|
||||
A single hardware failure that destroyed the top platter
|
||||
could cause the loss of all copies of the redundant super-blocks.
|
||||
Thus the cylinder group bookkeeping information
|
||||
begins at a floating offset from the beginning of the cylinder group.
|
||||
The offset for
|
||||
the
|
||||
.I "i+1" st
|
||||
cylinder group is about one track further
|
||||
from the beginning of the cylinder group
|
||||
than it was for the
|
||||
.I "i" th
|
||||
cylinder group.
|
||||
In this way,
|
||||
the redundant
|
||||
information spirals down into the pack;
|
||||
any single track, cylinder,
|
||||
or platter can be lost without losing all copies of the super-blocks.
|
||||
Except for the first cylinder group,
|
||||
the space between the beginning of the cylinder group
|
||||
and the beginning of the cylinder group information stores data.
|
||||
.NH 2
|
||||
Fragments
|
||||
.PP
|
||||
To avoid waste in storing small files,
|
||||
the file system space allocator divides a single
|
||||
file system block into one or more
|
||||
.I "fragments".
|
||||
The fragmentation of the file system is specified
|
||||
when the file system is created;
|
||||
each file system block can be optionally broken into
|
||||
2, 4, or 8 addressable fragments.
|
||||
The lower bound on the size of these fragments is constrained
|
||||
by the disk sector size;
|
||||
typically 512 bytes is the lower bound on fragment size.
|
||||
The block map associated with each cylinder group
|
||||
records the space availability at the fragment level.
|
||||
Aligned fragments are examined
|
||||
to determine block availability.
|
||||
.PP
|
||||
On a file system with a block size of 4096 bytes
|
||||
and a fragment size of 1024 bytes,
|
||||
a file is represented by zero or more 4096 byte blocks of data,
|
||||
and possibly a single fragmented block.
|
||||
If a file system block must be fragmented to obtain
|
||||
space for a small amount of data,
|
||||
the remainder of the block is made available for allocation
|
||||
to other files.
|
||||
For example,
|
||||
consider an 11000 byte file stored on
|
||||
a 4096/1024 byte file system.
|
||||
This file uses two full size blocks and a 3072 byte fragment.
|
||||
If no fragments with at least 3072 bytes
|
||||
are available when the file is created,
|
||||
a full size block is split yielding the necessary 3072 byte
|
||||
fragment and an unused 1024 byte fragment.
|
||||
This remaining fragment can be allocated to another file, as needed.
|
||||
.NH 2
|
||||
Updates to the file system
|
||||
.PP
|
||||
Every working day hundreds of files
|
||||
are created, modified, and removed.
|
||||
Every time a file is modified,
|
||||
the operating system performs a
|
||||
series of file system updates.
|
||||
These updates, when written on disk, yield a consistent file system.
|
||||
The file system stages
|
||||
all modifications of critical information;
|
||||
modification can
|
||||
either be completed or cleanly backed out after a crash.
|
||||
Knowing the information that is first written to the file system,
|
||||
deterministic procedures can be developed to
|
||||
repair a corrupted file system.
|
||||
To understand this process,
|
||||
the order that the update
|
||||
requests were being honored must first be understood.
|
||||
.PP
|
||||
When a user program does an operation to change the file system,
|
||||
such as a
|
||||
.I write ,
|
||||
the data to be written is copied into an internal
|
||||
.I "in-core"
|
||||
buffer in the kernel.
|
||||
Normally, the disk update is handled asynchronously;
|
||||
the user process is allowed to proceed even though
|
||||
the data has not yet been written to the disk.
|
||||
The data,
|
||||
along with the inode information reflecting the change,
|
||||
is eventually written out to disk.
|
||||
The real disk write may not happen until long after the
|
||||
.I write
|
||||
system call has returned.
|
||||
Thus at any given time, the file system,
|
||||
as it resides on the disk,
|
||||
lags the state of the file system represented by the in-core information.
|
||||
.PP
|
||||
The disk information is updated to reflect the in-core information
|
||||
when the buffer is required for another use,
|
||||
when a
|
||||
.I sync (2)
|
||||
is done (at 30 second intervals) by
|
||||
.I "/etc/update" "(8),"
|
||||
or by manual operator intervention with the
|
||||
.I sync (8)
|
||||
command.
|
||||
If the system is halted without writing out the in-core information,
|
||||
the file system on the disk will be in an inconsistent state.
|
||||
.PP
|
||||
If all updates are done asynchronously, several serious
|
||||
inconsistencies can arise.
|
||||
One inconsistency is that a block may be claimed by two inodes.
|
||||
Such an inconsistency can occur when the system is halted before
|
||||
the pointer to the block in the old inode has been cleared
|
||||
in the copy of the old inode on the disk,
|
||||
and after the pointer to the block in the new inode has been written out
|
||||
to the copy of the new inode on the disk.
|
||||
Here,
|
||||
there is no deterministic method for deciding
|
||||
which inode should really claim the block.
|
||||
A similar problem can arise with a multiply claimed inode.
|
||||
.PP
|
||||
The problem with asynchronous inode updates
|
||||
can be avoided by doing all inode deallocations synchronously.
|
||||
Consequently,
|
||||
inodes and indirect blocks are written to the disk synchronously
|
||||
(\fIi.e.\fP the process blocks until the information is
|
||||
really written to disk)
|
||||
when they are being deallocated.
|
||||
Similarly inodes are kept consistent by synchronously
|
||||
deleting, adding, or changing directory entries.
|
||||
.ds RH Fixing corrupted file systems
|
440
sbin/fsck_ffs/SMM.doc/3.t
Normal file
440
sbin/fsck_ffs/SMM.doc/3.t
Normal file
@ -0,0 +1,440 @@
|
||||
.\" Copyright (c) 1982, 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)3.t 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: 3.t,v 1.1 1994/06/08 19:01:23 mycroft Exp $
|
||||
.\"
|
||||
.ds RH Fixing corrupted file systems
|
||||
.NH
|
||||
Fixing corrupted file systems
|
||||
.PP
|
||||
A file system
|
||||
can become corrupted in several ways.
|
||||
The most common of these ways are
|
||||
improper shutdown procedures
|
||||
and hardware failures.
|
||||
.PP
|
||||
File systems may become corrupted during an
|
||||
.I "unclean halt" .
|
||||
This happens when proper shutdown
|
||||
procedures are not observed,
|
||||
physically write-protecting a mounted file system,
|
||||
or a mounted file system is taken off-line.
|
||||
The most common operator procedural failure is forgetting to
|
||||
.I sync
|
||||
the system before halting the CPU.
|
||||
.PP
|
||||
File systems may become further corrupted if proper startup
|
||||
procedures are not observed, e.g.,
|
||||
not checking a file system for inconsistencies,
|
||||
and not repairing inconsistencies.
|
||||
Allowing a corrupted file system to be used (and, thus, to be modified
|
||||
further) can be disastrous.
|
||||
.PP
|
||||
Any piece of hardware can fail at any time.
|
||||
Failures
|
||||
can be as subtle as a bad block
|
||||
on a disk pack, or as blatant as a non-functional disk-controller.
|
||||
.NH 2
|
||||
Detecting and correcting corruption
|
||||
.PP
|
||||
Normally
|
||||
.I fsck
|
||||
is run non-interactively.
|
||||
In this mode it will only fix
|
||||
corruptions that are expected to occur from an unclean halt.
|
||||
These actions are a proper subset of the actions that
|
||||
.I fsck
|
||||
will take when it is running interactively.
|
||||
Throughout this paper we assume that
|
||||
.I fsck
|
||||
is being run interactively,
|
||||
and all possible errors can be encountered.
|
||||
When an inconsistency is discovered in this mode,
|
||||
.I fsck
|
||||
reports the inconsistency for the operator to
|
||||
chose a corrective action.
|
||||
.PP
|
||||
A quiescent\(dd
|
||||
.FS
|
||||
\(dd I.e., unmounted and not being written on.
|
||||
.FE
|
||||
file system may be checked for structural integrity
|
||||
by performing consistency checks on the
|
||||
redundant data intrinsic to a file system.
|
||||
The redundant data is either read from
|
||||
the file system,
|
||||
or computed from other known values.
|
||||
The file system
|
||||
.B must
|
||||
be in a quiescent state when
|
||||
.I fsck
|
||||
is run,
|
||||
since
|
||||
.I fsck
|
||||
is a multi-pass program.
|
||||
.PP
|
||||
In the following sections,
|
||||
we discuss methods to discover inconsistencies
|
||||
and possible corrective actions
|
||||
for the cylinder group blocks, the inodes, the indirect blocks, and
|
||||
the data blocks containing directory entries.
|
||||
.NH 2
|
||||
Super-block checking
|
||||
.PP
|
||||
The most commonly corrupted item in a file system
|
||||
is the summary information
|
||||
associated with the super-block.
|
||||
The summary information is prone to corruption
|
||||
because it is modified with every change to the file
|
||||
system's blocks or inodes,
|
||||
and is usually corrupted
|
||||
after an unclean halt.
|
||||
.PP
|
||||
The super-block is checked for inconsistencies
|
||||
involving file-system size, number of inodes,
|
||||
free-block count, and the free-inode count.
|
||||
The file-system size must be larger than the
|
||||
number of blocks used by the super-block
|
||||
and the number of blocks used by the list of inodes.
|
||||
The file-system size and layout information
|
||||
are the most critical pieces of information for
|
||||
.I fsck .
|
||||
While there is no way to actually check these sizes,
|
||||
since they are statically determined by
|
||||
.I newfs ,
|
||||
.I fsck
|
||||
can check that these sizes are within reasonable bounds.
|
||||
All other file system checks require that these sizes be correct.
|
||||
If
|
||||
.I fsck
|
||||
detects corruption in the static parameters of the default super-block,
|
||||
.I fsck
|
||||
requests the operator to specify the location of an alternate super-block.
|
||||
.NH 2
|
||||
Free block checking
|
||||
.PP
|
||||
.I Fsck
|
||||
checks that all the blocks
|
||||
marked as free in the cylinder group block maps
|
||||
are not claimed by any files.
|
||||
When all the blocks have been initially accounted for,
|
||||
.I fsck
|
||||
checks that
|
||||
the number of free blocks
|
||||
plus the number of blocks claimed by the inodes
|
||||
equals the total number of blocks in the file system.
|
||||
.PP
|
||||
If anything is wrong with the block allocation maps,
|
||||
.I fsck
|
||||
will rebuild them,
|
||||
based on the list it has computed of allocated blocks.
|
||||
.PP
|
||||
The summary information associated with the super-block
|
||||
counts the total number of free blocks within the file system.
|
||||
.I Fsck
|
||||
compares this count to the
|
||||
number of free blocks it found within the file system.
|
||||
If the two counts do not agree, then
|
||||
.I fsck
|
||||
replaces the incorrect count in the summary information
|
||||
by the actual free-block count.
|
||||
.PP
|
||||
The summary information
|
||||
counts the total number of free inodes within the file system.
|
||||
.I Fsck
|
||||
compares this count to the number
|
||||
of free inodes it found within the file system.
|
||||
If the two counts do not agree, then
|
||||
.I fsck
|
||||
replaces the incorrect count in the
|
||||
summary information by the actual free-inode count.
|
||||
.NH 2
|
||||
Checking the inode state
|
||||
.PP
|
||||
An individual inode is not as likely to be corrupted as
|
||||
the allocation information.
|
||||
However, because of the great number of active inodes,
|
||||
a few of the inodes are usually corrupted.
|
||||
.PP
|
||||
The list of inodes in the file system
|
||||
is checked sequentially starting with inode 2
|
||||
(inode 0 marks unused inodes;
|
||||
inode 1 is saved for future generations)
|
||||
and progressing through the last inode in the file system.
|
||||
The state of each inode is checked for
|
||||
inconsistencies involving format and type,
|
||||
link count,
|
||||
duplicate blocks,
|
||||
bad blocks,
|
||||
and inode size.
|
||||
.PP
|
||||
Each inode contains a mode word.
|
||||
This mode word describes the type and state of the inode.
|
||||
Inodes must be one of six types:
|
||||
regular inode, directory inode, symbolic link inode,
|
||||
special block inode, special character inode, or socket inode.
|
||||
Inodes may be found in one of three allocation states:
|
||||
unallocated, allocated, and neither unallocated nor allocated.
|
||||
This last state suggests an incorrectly formated inode.
|
||||
An inode can get in this state if
|
||||
bad data is written into the inode list.
|
||||
The only possible corrective action is for
|
||||
.I fsck
|
||||
is to clear the inode.
|
||||
.NH 2
|
||||
Inode links
|
||||
.PP
|
||||
Each inode counts the
|
||||
total number of directory entries
|
||||
linked to the inode.
|
||||
.I Fsck
|
||||
verifies the link count of each inode
|
||||
by starting at the root of the file system,
|
||||
and descending through the directory structure.
|
||||
The actual link count for each inode
|
||||
is calculated during the descent.
|
||||
.PP
|
||||
If the stored link count is non-zero and the actual
|
||||
link count is zero,
|
||||
then no directory entry appears for the inode.
|
||||
If this happens,
|
||||
.I fsck
|
||||
will place the disconnected file in the
|
||||
.I lost+found
|
||||
directory.
|
||||
If the stored and actual link counts are non-zero and unequal,
|
||||
a directory entry may have been added or removed without the inode being
|
||||
updated.
|
||||
If this happens,
|
||||
.I fsck
|
||||
replaces the incorrect stored link count by the actual link count.
|
||||
.PP
|
||||
Each inode contains a list,
|
||||
or pointers to
|
||||
lists (indirect blocks),
|
||||
of all the blocks claimed by the inode.
|
||||
Since indirect blocks are owned by an inode,
|
||||
inconsistencies in indirect blocks directly
|
||||
affect the inode that owns it.
|
||||
.PP
|
||||
.I Fsck
|
||||
compares each block number claimed by an inode
|
||||
against a list of already allocated blocks.
|
||||
If another inode already claims a block number,
|
||||
then the block number is added to a list of
|
||||
.I "duplicate blocks" .
|
||||
Otherwise, the list of allocated blocks
|
||||
is updated to include the block number.
|
||||
.PP
|
||||
If there are any duplicate blocks,
|
||||
.I fsck
|
||||
will perform a partial second
|
||||
pass over the inode list
|
||||
to find the inode of the duplicated block.
|
||||
The second pass is needed,
|
||||
since without examining the files associated with
|
||||
these inodes for correct content,
|
||||
not enough information is available
|
||||
to determine which inode is corrupted and should be cleared.
|
||||
If this condition does arise
|
||||
(only hardware failure will cause it),
|
||||
then the inode with the earliest
|
||||
modify time is usually incorrect,
|
||||
and should be cleared.
|
||||
If this happens,
|
||||
.I fsck
|
||||
prompts the operator to clear both inodes.
|
||||
The operator must decide which one should be kept
|
||||
and which one should be cleared.
|
||||
.PP
|
||||
.I Fsck
|
||||
checks the range of each block number claimed by an inode.
|
||||
If the block number is
|
||||
lower than the first data block in the file system,
|
||||
or greater than the last data block,
|
||||
then the block number is a
|
||||
.I "bad block number" .
|
||||
Many bad blocks in an inode are usually caused by
|
||||
an indirect block that was not written to the file system,
|
||||
a condition which can only occur if there has been a hardware failure.
|
||||
If an inode contains bad block numbers,
|
||||
.I fsck
|
||||
prompts the operator to clear it.
|
||||
.NH 2
|
||||
Inode data size
|
||||
.PP
|
||||
Each inode contains a count of the number of data blocks
|
||||
that it contains.
|
||||
The number of actual data blocks
|
||||
is the sum of the allocated data blocks
|
||||
and the indirect blocks.
|
||||
.I Fsck
|
||||
computes the actual number of data blocks
|
||||
and compares that block count against
|
||||
the actual number of blocks the inode claims.
|
||||
If an inode contains an incorrect count
|
||||
.I fsck
|
||||
prompts the operator to fix it.
|
||||
.PP
|
||||
Each inode contains a thirty-two bit size field.
|
||||
The size is the number of data bytes
|
||||
in the file associated with the inode.
|
||||
The consistency of the byte size field is roughly checked
|
||||
by computing from the size field the maximum number of blocks
|
||||
that should be associated with the inode,
|
||||
and comparing that expected block count against
|
||||
the actual number of blocks the inode claims.
|
||||
.NH 2
|
||||
Checking the data associated with an inode
|
||||
.PP
|
||||
An inode can directly or indirectly
|
||||
reference three kinds of data blocks.
|
||||
All referenced blocks must be the same kind.
|
||||
The three types of data blocks are:
|
||||
plain data blocks, symbolic link data blocks, and directory data blocks.
|
||||
Plain data blocks
|
||||
contain the information stored in a file;
|
||||
symbolic link data blocks
|
||||
contain the path name stored in a link.
|
||||
Directory data blocks contain directory entries.
|
||||
.I Fsck
|
||||
can only check the validity of directory data blocks.
|
||||
.PP
|
||||
Each directory data block is checked for
|
||||
several types of inconsistencies.
|
||||
These inconsistencies include
|
||||
directory inode numbers pointing to unallocated inodes,
|
||||
directory inode numbers that are greater than
|
||||
the number of inodes in the file system,
|
||||
incorrect directory inode numbers for ``\fB.\fP'' and ``\fB..\fP'',
|
||||
and directories that are not attached to the file system.
|
||||
If the inode number in a directory data block
|
||||
references an unallocated inode,
|
||||
then
|
||||
.I fsck
|
||||
will remove that directory entry.
|
||||
Again,
|
||||
this condition can only arise when there has been a hardware failure.
|
||||
.PP
|
||||
If a directory entry inode number references
|
||||
outside the inode list, then
|
||||
.I fsck
|
||||
will remove that directory entry.
|
||||
This condition occurs if bad data is written into a directory data block.
|
||||
.PP
|
||||
The directory inode number entry for ``\fB.\fP''
|
||||
must be the first entry in the directory data block.
|
||||
The inode number for ``\fB.\fP''
|
||||
must reference itself;
|
||||
e.g., it must equal the inode number
|
||||
for the directory data block.
|
||||
The directory inode number entry
|
||||
for ``\fB..\fP'' must be
|
||||
the second entry in the directory data block.
|
||||
Its value must equal the inode number for the
|
||||
parent of the directory entry
|
||||
(or the inode number of the directory
|
||||
data block if the directory is the
|
||||
root directory).
|
||||
If the directory inode numbers are
|
||||
incorrect,
|
||||
.I fsck
|
||||
will replace them with the correct values.
|
||||
If there are multiple hard links to a directory,
|
||||
the first one encountered is considered the real parent
|
||||
to which ``\fB..\fP'' should point;
|
||||
\fIfsck\fP recommends deletion for the subsequently discovered names.
|
||||
.NH 2
|
||||
File system connectivity
|
||||
.PP
|
||||
.I Fsck
|
||||
checks the general connectivity of the file system.
|
||||
If directories are not linked into the file system, then
|
||||
.I fsck
|
||||
links the directory back into the file system in the
|
||||
.I lost+found
|
||||
directory.
|
||||
This condition only occurs when there has been a hardware failure.
|
||||
.ds RH "References"
|
||||
.SH
|
||||
\s+2Acknowledgements\s0
|
||||
.PP
|
||||
I thank Bill Joy, Sam Leffler, Robert Elz and Dennis Ritchie
|
||||
for their suggestions and help in implementing the new file system.
|
||||
Thanks also to Robert Henry for his editorial input to
|
||||
get this document together.
|
||||
Finally we thank our sponsors,
|
||||
the National Science Foundation under grant MCS80-05144,
|
||||
and the Defense Advance Research Projects Agency (DoD) under
|
||||
Arpa Order No. 4031 monitored by Naval Electronic System Command under
|
||||
Contract No. N00039-82-C-0235. (Kirk McKusick, July 1983)
|
||||
.PP
|
||||
I would like to thank Larry A. Wehr for advice that lead
|
||||
to the first version of
|
||||
.I fsck
|
||||
and Rick B. Brandt for adapting
|
||||
.I fsck
|
||||
to
|
||||
UNIX/TS. (T. Kowalski, July 1979)
|
||||
.sp 2
|
||||
.SH
|
||||
\s+2References\s0
|
||||
.LP
|
||||
.IP [Dolotta78] 20
|
||||
Dolotta, T. A., and Olsson, S. B. eds.,
|
||||
.I "UNIX User's Manual, Edition 1.1\^" ,
|
||||
January 1978.
|
||||
.IP [Joy83] 20
|
||||
Joy, W., Cooper, E., Fabry, R., Leffler, S., McKusick, M., and Mosher, D.
|
||||
4.2BSD System Manual,
|
||||
.I "University of California at Berkeley" ,
|
||||
.I "Computer Systems Research Group Technical Report"
|
||||
#4, 1982.
|
||||
.IP [McKusick84] 20
|
||||
McKusick, M., Joy, W., Leffler, S., and Fabry, R.
|
||||
A Fast File System for UNIX,
|
||||
\fIACM Transactions on Computer Systems 2\fP, 3.
|
||||
pp. 181-197, August 1984.
|
||||
.IP [Ritchie78] 20
|
||||
Ritchie, D. M., and Thompson, K.,
|
||||
The UNIX Time-Sharing System,
|
||||
.I "The Bell System Technical Journal"
|
||||
.B 57 ,
|
||||
6 (July-August 1978, Part 2), pp. 1905-29.
|
||||
.IP [Thompson78] 20
|
||||
Thompson, K.,
|
||||
UNIX Implementation,
|
||||
.I "The Bell System Technical Journal\^"
|
||||
.B 57 ,
|
||||
6 (July-August 1978, Part 2), pp. 1931-46.
|
||||
.ds RH Appendix A \- Fsck Error Conditions
|
||||
.bp
|
1425
sbin/fsck_ffs/SMM.doc/4.t
Normal file
1425
sbin/fsck_ffs/SMM.doc/4.t
Normal file
File diff suppressed because it is too large
Load Diff
8
sbin/fsck_ffs/SMM.doc/Makefile
Normal file
8
sbin/fsck_ffs/SMM.doc/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/8/93
|
||||
# $Id: Makefile,v 1.1 1994/06/08 19:01:26 mycroft Exp $
|
||||
|
||||
DIR= smm/03.fsck
|
||||
SRCS= 0.t 1.t 2.t 3.t 4.t
|
||||
MACROS= -ms
|
||||
|
||||
.include <bsd.doc.mk>
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,18 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)dir.c 5.19 (Berkeley) 7/26/91";*/
|
||||
static char rcsid[] = "$Id: dir.c,v 1.6 1994/04/25 18:28:20 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)dir.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: dir.c,v 1.7 1994/06/08 19:00:19 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#define KERNEL
|
||||
#include <ufs/dir.h>
|
||||
#undef KERNEL
|
||||
#include <stddef.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
@ -51,7 +48,14 @@ static char rcsid[] = "$Id: dir.c,v 1.6 1994/04/25 18:28:20 cgd Exp $";
|
||||
char *lfname = "lost+found";
|
||||
int lfmode = 01777;
|
||||
struct dirtemplate emptydir = { 0, DIRBLKSIZ };
|
||||
struct dirtemplate dirhead = { 0, 12, 1, ".", 0, DIRBLKSIZ - 12, 2, ".." };
|
||||
struct dirtemplate dirhead = {
|
||||
0, 12, DT_DIR, 1, ".",
|
||||
0, DIRBLKSIZ - 12, DT_DIR, 2, ".."
|
||||
};
|
||||
struct odirtemplate odirhead = {
|
||||
0, 12, 1, ".",
|
||||
0, DIRBLKSIZ - 12, 2, ".."
|
||||
};
|
||||
|
||||
struct direct *fsck_readdir();
|
||||
struct bufarea *getdirblk();
|
||||
@ -107,8 +111,29 @@ dirscan(idesc)
|
||||
for (dp = fsck_readdir(idesc); dp != NULL; dp = fsck_readdir(idesc)) {
|
||||
dsize = dp->d_reclen;
|
||||
bcopy((char *)dp, dbuf, (size_t)dsize);
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
if (!newinofmt) {
|
||||
struct direct *tdp = (struct direct *)dbuf;
|
||||
u_char tmp;
|
||||
|
||||
tmp = tdp->d_namlen;
|
||||
tdp->d_namlen = tdp->d_type;
|
||||
tdp->d_type = tmp;
|
||||
}
|
||||
# endif
|
||||
idesc->id_dirp = (struct direct *)dbuf;
|
||||
if ((n = (*idesc->id_func)(idesc)) & ALTERED) {
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
if (!newinofmt && !doinglevel2) {
|
||||
struct direct *tdp;
|
||||
u_char tmp;
|
||||
|
||||
tdp = (struct direct *)dbuf;
|
||||
tmp = tdp->d_namlen;
|
||||
tdp->d_namlen = tdp->d_type;
|
||||
tdp->d_type = tmp;
|
||||
}
|
||||
# endif
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
bcopy(dbuf, bp->b_un.b_buf + idesc->id_loc - dsize,
|
||||
(size_t)dsize);
|
||||
@ -130,39 +155,34 @@ fsck_readdir(idesc)
|
||||
{
|
||||
register struct direct *dp, *ndp;
|
||||
register struct bufarea *bp;
|
||||
long blksiz, new_id_filesize;
|
||||
int fix, new_id_loc, new_reclen, orig_id_loc, size;
|
||||
long size, blksiz, fix, dploc;
|
||||
|
||||
blksiz = idesc->id_numfrags * sblock.fs_fsize;
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
orig_id_loc = idesc->id_loc;
|
||||
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))
|
||||
goto dpok;
|
||||
/*
|
||||
* See below about recursion.
|
||||
*/
|
||||
new_id_loc = idesc->id_loc + DIRBLKSIZ;
|
||||
new_id_filesize = idesc->id_filesize - DIRBLKSIZ;
|
||||
fix = dofix(idesc, "DIRECTORY CORRUPTED");
|
||||
idesc->id_loc = new_id_loc;
|
||||
idesc->id_filesize = new_id_filesize;
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
dp = (struct direct *)(bp->b_un.b_buf + orig_id_loc);
|
||||
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
|
||||
dp->d_reclen = DIRBLKSIZ;
|
||||
dp->d_ino = 0;
|
||||
dp->d_type = 0;
|
||||
dp->d_namlen = 0;
|
||||
dp->d_name[0] = '\0';
|
||||
if (fix)
|
||||
dirty(bp);
|
||||
idesc->id_loc += DIRBLKSIZ;
|
||||
idesc->id_filesize -= DIRBLKSIZ;
|
||||
return (dp);
|
||||
}
|
||||
dpok:
|
||||
if (idesc->id_filesize <= 0 || idesc->id_loc >= blksiz)
|
||||
return NULL;
|
||||
dp = (struct direct *)(bp->b_un.b_buf + idesc->id_loc);
|
||||
dploc = idesc->id_loc;
|
||||
dp = (struct direct *)(bp->b_un.b_buf + dploc);
|
||||
idesc->id_loc += dp->d_reclen;
|
||||
idesc->id_filesize -= dp->d_reclen;
|
||||
if ((idesc->id_loc % DIRBLKSIZ) == 0)
|
||||
@ -171,23 +191,12 @@ dpok:
|
||||
if (idesc->id_loc < blksiz && idesc->id_filesize > 0 &&
|
||||
dircheck(idesc, ndp) == 0) {
|
||||
size = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
||||
/*
|
||||
* dofix() may recurse here. Don't let it cause multiple
|
||||
* fixups.
|
||||
*/
|
||||
new_id_loc = idesc->id_loc + size;
|
||||
new_id_filesize = idesc->id_filesize - size;
|
||||
new_reclen = dp->d_reclen + size;
|
||||
idesc->id_loc += size;
|
||||
idesc->id_filesize -= size;
|
||||
fix = dofix(idesc, "DIRECTORY CORRUPTED");
|
||||
idesc->id_loc = new_id_loc;
|
||||
idesc->id_filesize = new_id_filesize;
|
||||
/*
|
||||
* dofix() calls fsck_readdir() and getdirblk() discards
|
||||
* the lock on bp so bp may now be invalid.
|
||||
*/
|
||||
bp = getdirblk(idesc->id_blkno, blksiz);
|
||||
dp = (struct direct *)(bp->b_un.b_buf + orig_id_loc);
|
||||
dp->d_reclen = new_reclen;
|
||||
dp = (struct direct *)(bp->b_un.b_buf + dploc);
|
||||
dp->d_reclen += size;
|
||||
if (fix)
|
||||
dirty(bp);
|
||||
}
|
||||
@ -204,22 +213,34 @@ dircheck(idesc, dp)
|
||||
{
|
||||
register int size;
|
||||
register char *cp;
|
||||
u_char namlen, type;
|
||||
int spaceleft;
|
||||
|
||||
size = DIRSIZ(!newinofmt, dp);
|
||||
spaceleft = DIRBLKSIZ - (idesc->id_loc % DIRBLKSIZ);
|
||||
if (spaceleft < offsetof(struct direct, d_name))
|
||||
return (0); /* dp is bad; don't use it */
|
||||
size = DIRSIZ(dp);
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
if (!newinofmt) {
|
||||
type = dp->d_namlen;
|
||||
namlen = dp->d_type;
|
||||
} else {
|
||||
namlen = dp->d_namlen;
|
||||
type = dp->d_type;
|
||||
}
|
||||
# else
|
||||
namlen = dp->d_namlen;
|
||||
type = dp->d_type;
|
||||
# endif
|
||||
if (dp->d_ino < maxino &&
|
||||
dp->d_reclen != 0 &&
|
||||
dp->d_reclen <= spaceleft &&
|
||||
(dp->d_reclen & 0x3) == 0 &&
|
||||
dp->d_reclen >= size &&
|
||||
idesc->id_filesize >= size &&
|
||||
dp->d_namlen <= MAXNAMLEN) {
|
||||
namlen <= MAXNAMLEN &&
|
||||
type <= 15) {
|
||||
if (dp->d_ino == 0)
|
||||
return (1);
|
||||
for (cp = dp->d_name, size = 0; size < dp->d_namlen; size++)
|
||||
for (cp = dp->d_name, size = 0; size < namlen; size++)
|
||||
if (*cp == 0 || (*cp++ == '/'))
|
||||
return (0);
|
||||
if (*cp == 0)
|
||||
@ -297,9 +318,9 @@ mkentry(idesc)
|
||||
int newlen, oldlen;
|
||||
|
||||
newent.d_namlen = strlen(idesc->id_name);
|
||||
newlen = DIRSIZ(&newent);
|
||||
newlen = DIRSIZ(0, &newent);
|
||||
if (dirp->d_ino != 0)
|
||||
oldlen = DIRSIZ(dirp);
|
||||
oldlen = DIRSIZ(0, dirp);
|
||||
else
|
||||
oldlen = 0;
|
||||
if (dirp->d_reclen - oldlen < newlen)
|
||||
@ -308,6 +329,10 @@ mkentry(idesc)
|
||||
dirp->d_reclen = oldlen;
|
||||
dirp = (struct direct *)(((char *)dirp) + oldlen);
|
||||
dirp->d_ino = idesc->id_parent; /* ino to be entered is in id_parent */
|
||||
if (newinofmt)
|
||||
dirp->d_type = typemap[idesc->id_parent];
|
||||
else
|
||||
dirp->d_type = 0;
|
||||
dirp->d_reclen = newent.d_reclen;
|
||||
dirp->d_namlen = newent.d_namlen;
|
||||
bcopy(idesc->id_name, dirp->d_name, (size_t)dirp->d_namlen + 1);
|
||||
@ -322,6 +347,10 @@ chgino(idesc)
|
||||
if (bcmp(dirp->d_name, idesc->id_name, (int)dirp->d_namlen + 1))
|
||||
return (KEEPON);
|
||||
dirp->d_ino = idesc->id_parent;
|
||||
if (newinofmt)
|
||||
dirp->d_type = typemap[idesc->id_parent];
|
||||
else
|
||||
dirp->d_type = 0;
|
||||
return (ALTERED|STOP);
|
||||
}
|
||||
|
||||
@ -551,17 +580,22 @@ allocdir(parent, request, mode)
|
||||
char *cp;
|
||||
struct dinode *dp;
|
||||
register struct bufarea *bp;
|
||||
struct dirtemplate *dirp;
|
||||
|
||||
ino = allocino(request, IFDIR|mode);
|
||||
dirhead.dot_ino = ino;
|
||||
dirhead.dotdot_ino = parent;
|
||||
if (newinofmt)
|
||||
dirp = &dirhead;
|
||||
else
|
||||
dirp = (struct dirtemplate *)&odirhead;
|
||||
dirp->dot_ino = ino;
|
||||
dirp->dotdot_ino = parent;
|
||||
dp = ginode(ino);
|
||||
bp = getdirblk(dp->di_db[0], sblock.fs_fsize);
|
||||
if (bp->b_errs) {
|
||||
freeino(ino);
|
||||
return (0);
|
||||
}
|
||||
bcopy((char *)&dirhead, bp->b_un.b_buf, sizeof dirhead);
|
||||
bcopy((char *)dirp, bp->b_un.b_buf, sizeof(struct dirtemplate));
|
||||
for (cp = &bp->b_un.b_buf[DIRBLKSIZ];
|
||||
cp < &bp->b_un.b_buf[sblock.fs_fsize];
|
||||
cp += DIRBLKSIZ)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -30,8 +30,8 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)fsck.h 5.17 (Berkeley) 7/27/90
|
||||
* $Id: fsck.h,v 1.5 1994/05/02 10:18:21 pk Exp $
|
||||
* from: @(#)fsck.h 8.1 (Berkeley) 6/5/93
|
||||
* $Id: fsck.h,v 1.6 1994/06/08 19:00:21 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define MAXDUP 10 /* limit on dup blks (per inode) */
|
||||
@ -78,6 +78,7 @@ struct bufarea sblk; /* file system superblock */
|
||||
struct bufarea cgblk; /* cylinder group blocks */
|
||||
struct bufarea *pdirbp; /* current directory contents */
|
||||
struct bufarea *pbp; /* current inode block */
|
||||
struct bufarea *getdatablk();
|
||||
|
||||
#define dirty(bp) (bp)->b_dirty = 1
|
||||
#define initbarea(bp) \
|
||||
@ -99,7 +100,7 @@ struct inodesc {
|
||||
ino_t id_parent; /* for DATA nodes, their parent */
|
||||
daddr_t id_blkno; /* current block number being examined */
|
||||
int id_numfrags; /* number of frags contained in block */
|
||||
long id_filesize; /* for DATA nodes, the size of the directory */
|
||||
quad_t id_filesize; /* for DATA nodes, the size of the directory */
|
||||
int id_loc; /* for DATA nodes, current location in dir */
|
||||
int id_entryno; /* for DATA nodes, current entry number */
|
||||
struct direct *id_dirp; /* for DATA nodes, ptr to current entry */
|
||||
@ -161,14 +162,17 @@ struct inoinfo {
|
||||
} **inphead, **inpsort;
|
||||
long numdirs, listmax, inplast;
|
||||
|
||||
char *devname; /* name of device being checked */
|
||||
char *cdevname; /* name of device being checked */
|
||||
long dev_bsize; /* computed value of DEV_BSIZE */
|
||||
long secsize; /* actual disk sector size */
|
||||
char nflag; /* assume a no response */
|
||||
char yflag; /* assume a yes response */
|
||||
int bflag; /* location of alternate super block */
|
||||
int debug; /* output debugging info */
|
||||
int cvtflag; /* convert to old file system format */
|
||||
int cvtlevel; /* convert to newer file system format */
|
||||
int doinglevel1; /* converting to new cylinder group format */
|
||||
int doinglevel2; /* converting to new inode format */
|
||||
int newinofmt; /* filesystem has new inode format */
|
||||
char preen; /* just fix normal inconsistencies */
|
||||
char hotroot; /* checking root device */
|
||||
char havesb; /* superblock has been read */
|
||||
@ -181,6 +185,7 @@ char *blockmap; /* ptr to primary blk allocation map */
|
||||
ino_t maxino; /* number of inodes in file system */
|
||||
ino_t lastino; /* last inode in use */
|
||||
char *statemap; /* ptr to inode state table */
|
||||
char *typemap; /* ptr to inode type table */
|
||||
short *lncntp; /* ptr to link count table */
|
||||
|
||||
ino_t lfdir; /* lost & found directory inode number */
|
||||
@ -203,32 +208,9 @@ struct dinode zino;
|
||||
#define ALTERED 0x08
|
||||
#define FOUND 0x10
|
||||
|
||||
int ckinode __P((struct dinode *, struct inodesc *));
|
||||
int iblock __P((struct inodesc *, long, u_long));
|
||||
int chkrange __P((daddr_t, int));
|
||||
struct dinode *ginode __P((ino_t));
|
||||
struct dinode *getnextinode __P((ino_t));
|
||||
void cacheino __P((struct dinode *, ino_t));
|
||||
struct inoinfo *getinoinfo __P((ino_t));
|
||||
void resetinodebuf __P((void));
|
||||
void freeinodebuf __P((void));
|
||||
void inocleanup __P((void));
|
||||
void inodirty __P((void));
|
||||
void clri __P((struct inodesc *, char *, int));
|
||||
int findname __P((struct inodesc *));
|
||||
int findino __P((struct inodesc *));
|
||||
void pinode __P((ino_t));
|
||||
void blkerror __P((ino_t, char *, daddr_t));
|
||||
ino_t allocino __P((ino_t, int));
|
||||
void freeino __P((ino_t));
|
||||
|
||||
int ftypeok __P((struct dinode *));
|
||||
struct bufarea *getdatablk __P((daddr_t, long));
|
||||
void getblk __P((struct bufarea *, daddr_t, long));
|
||||
void flush __P((int, struct bufarea *));
|
||||
int bread __P((int, char *, daddr_t, long));
|
||||
int bwrite __P((int, char *, daddr_t, long));
|
||||
int allocblk __P((long));
|
||||
void freeblk __P((daddr_t, long));
|
||||
void getpathname __P((char *, ino_t, ino_t));
|
||||
|
||||
time_t time();
|
||||
struct dinode *ginode();
|
||||
struct inoinfo *getinoinfo();
|
||||
void getblk();
|
||||
ino_t allocino();
|
||||
int findino();
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 1980, 1989 Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1980, 1989, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -29,33 +29,32 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)fsck.8 6.9 (Berkeley) 4/20/91
|
||||
.\" $Id: fsck_ffs.8,v 1.6 1994/04/13 10:12:33 deraadt Exp $
|
||||
.\" from: @(#)fsck.8 8.2 (Berkeley) 12/11/93
|
||||
.\" $Id: fsck_ffs.8,v 1.7 1994/06/08 19:00:20 mycroft Exp $
|
||||
.\"
|
||||
.Dd April 20, 1991
|
||||
.Dd December 11, 1993
|
||||
.Dt FSCK 8
|
||||
.Os BSD 4.2
|
||||
.de us
|
||||
\\$1\l'|0\(ul'
|
||||
..
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm fsck
|
||||
.Nd file system consistency check and interactive repair
|
||||
.Nm fsck
|
||||
.Nd filesystem consistency check and interactive repair
|
||||
.Sh SYNOPSIS
|
||||
.Nm fsck
|
||||
.Fl p
|
||||
.Op Fl m Ar mode
|
||||
.Nm fsck
|
||||
.Op Fl b Ar block#
|
||||
.Op Fl c
|
||||
.Op Fl c Ar level
|
||||
.Op Fl l Ar maxparallel
|
||||
.Op Fl y
|
||||
.Op Fl n
|
||||
.Op Fl m Ar mode
|
||||
.Op Ar filesystem ...
|
||||
.Op Ar filesystem
|
||||
.Ar ...
|
||||
.Sh DESCRIPTION
|
||||
The first form of
|
||||
.Nm fsck
|
||||
preens a standard set of filesystems or the specified file systems.
|
||||
preens a standard set of filesystems or the specified filesystems.
|
||||
It is normally used in the script
|
||||
.Pa /etc/rc
|
||||
during automatic reboot.
|
||||
@ -63,12 +62,8 @@ Here
|
||||
.Nm fsck
|
||||
reads the table
|
||||
.Pa /etc/fstab
|
||||
to determine which file systems to check.
|
||||
Only partitions in fstab that are mounted
|
||||
.Dq rw ,
|
||||
.Dq rq
|
||||
or
|
||||
.Dq ro
|
||||
to determine which filesystems to check.
|
||||
Only partitions in fstab that are mounted ``rw,'' ``rq'' or ``ro''
|
||||
and that have non-zero pass number are checked.
|
||||
Filesystems with pass number 1 (normally just the root filesystem)
|
||||
are checked one at a time.
|
||||
@ -78,10 +73,10 @@ The disk drive containing each filesystem is inferred from the longest prefix
|
||||
of the device name that ends in a digit; the remaining characters are assumed
|
||||
to be the partition designator.
|
||||
.Pp
|
||||
The system takes care that only a restricted class of innocuous
|
||||
The kernel takes care that only a restricted class of innocuous filesystem
|
||||
inconsistencies can happen unless hardware or software failures intervene.
|
||||
These are limited to the following:
|
||||
.Bl -item -offset indent
|
||||
.Bl -item -compact
|
||||
.It
|
||||
Unreferenced inodes
|
||||
.It
|
||||
@ -101,27 +96,29 @@ with the
|
||||
option will correct; if it encounters other inconsistencies, it exits
|
||||
with an abnormal return status and an automatic reboot will then fail.
|
||||
For each corrected inconsistency one or more lines will be printed
|
||||
identifying the file system on which the correction will take place,
|
||||
and the nature of the correction. After successfully correcting a file
|
||||
system,
|
||||
identifying the filesystem on which the correction will take place,
|
||||
and the nature of the correction. After successfully correcting a filesystem,
|
||||
.Nm fsck
|
||||
will print the number of files on that file system,
|
||||
will print the number of files on that filesystem,
|
||||
the number of used and free blocks,
|
||||
and the percentage of fragmentation.
|
||||
.Pp
|
||||
If sent a QUIT signal,
|
||||
If sent a
|
||||
.Dv QUIT
|
||||
signal,
|
||||
.Nm fsck
|
||||
will finish the file system checks, then exit with an abnormal
|
||||
will finish the filesystem checks, then exit with an abnormal
|
||||
return status that causes an automatic reboot to fail.
|
||||
This is useful when to finish the file system checks during an automatic reboot,
|
||||
This is useful when you want to finish the filesystem checks during an
|
||||
automatic reboot,
|
||||
but do not want the machine to come up multiuser after the checks complete.
|
||||
.Pp
|
||||
Without the
|
||||
.Fl p
|
||||
option,
|
||||
.Nm fsck
|
||||
audits and interactively repairs inconsistent conditions for file systems.
|
||||
If the file system is inconsistent the operator is prompted for concurrence
|
||||
audits and interactively repairs inconsistent conditions for filesystems.
|
||||
If the filesystem is inconsistent the operator is prompted for concurrence
|
||||
before each correction is attempted.
|
||||
It should be noted that some of the corrective actions which are not
|
||||
correctable under the
|
||||
@ -130,11 +127,11 @@ option will result in some loss of data.
|
||||
The amount and severity of data lost may be determined from the diagnostic
|
||||
output.
|
||||
The default action for each consistency correction
|
||||
is to wait for the operator to respond
|
||||
.Ic yes
|
||||
is to wait for the operator to respond
|
||||
.Li yes
|
||||
or
|
||||
.Ic no .
|
||||
If the operator does not have write permission on the file system
|
||||
.Li no .
|
||||
If the operator does not have write permission on the filesystem
|
||||
.Nm fsck
|
||||
will default to a
|
||||
.Fl n
|
||||
@ -143,19 +140,17 @@ action.
|
||||
.Nm Fsck
|
||||
has more consistency checks than
|
||||
its predecessors
|
||||
.Nm check ,
|
||||
.Nm dcheck ,
|
||||
.Nm fcheck ,
|
||||
.Em check , dcheck , fcheck ,
|
||||
and
|
||||
.Nm icheck
|
||||
.Em icheck
|
||||
combined.
|
||||
.Pp
|
||||
The following flags are interpreted by
|
||||
.Nm fsck.
|
||||
.Nm fsck .
|
||||
.Bl -tag -width indent
|
||||
.It Fl b
|
||||
Use the block specified immediately after the flag as
|
||||
the super block for the file system. Block 32 is usually
|
||||
the super block for the filesystem. Block 32 is usually
|
||||
an alternate super block.
|
||||
.It Fl l
|
||||
Limit the number of parallel checks to the number specified in the following
|
||||
@ -165,8 +160,9 @@ If a smaller limit is given, the disks are checked round-robin, one filesystem
|
||||
at a time.
|
||||
.It Fl m
|
||||
Use the mode specified in octal immediately after the flag as the
|
||||
permission bits to use when creating the lost+found directory
|
||||
rather than the default 1777.
|
||||
permission bits to use when creating the
|
||||
.Pa lost+found
|
||||
directory rather than the default 1777.
|
||||
In particular, systems that do not wish to have lost files accessible
|
||||
by all users on the system should use a more restrictive
|
||||
set of permissions such as 700.
|
||||
@ -178,50 +174,60 @@ to continue after essentially unlimited trouble has been encountered.
|
||||
.It Fl n
|
||||
Assume a no response to all questions asked by
|
||||
.Nm fsck
|
||||
except for
|
||||
.Dq CONTINUE? ,
|
||||
which is assumed to be affirmative; do not open the file system for writing.
|
||||
except for
|
||||
.Ql CONTINUE? ,
|
||||
which is assumed to be affirmative;
|
||||
do not open the filesystem for writing.
|
||||
.It Fl c
|
||||
If the file system is in the old (static table) format,
|
||||
convert it to the new (dynamic table) format.
|
||||
If the file system is in the new format,
|
||||
convert it to the old format provided the old format
|
||||
can support the filesystem configuration.
|
||||
Convert the filesystem to the specified level.
|
||||
Note that the level of a filesystem can only be raised.
|
||||
.Bl -tag -width indent
|
||||
There are currently three levels defined:
|
||||
.It 0
|
||||
The filesystem is in the old (static table) format.
|
||||
.It 1
|
||||
The filesystem is in the new (dynamic table) format.
|
||||
.It 2
|
||||
The filesystem supports 32-bit uid's and gid's,
|
||||
short symbolic links are stored in the inode,
|
||||
and directories have an added field showing the file type.
|
||||
.El
|
||||
.Pp
|
||||
In interactive mode,
|
||||
.Nm fsck
|
||||
will list the direction the conversion is to be made
|
||||
will list the conversion to be made
|
||||
and ask whether the conversion should be done.
|
||||
If a negative answer is given,
|
||||
no further operations are done on the filesystem.
|
||||
In preen mode,
|
||||
the direction of the conversion is listed and done if
|
||||
the conversion is listed and done if
|
||||
possible without user interaction.
|
||||
Conversion in preen mode is best used when all the file systems
|
||||
Conversion in preen mode is best used when all the filesystems
|
||||
are being converted at once.
|
||||
The format of a file system can be determined from the
|
||||
The format of a filesystem can be determined from the
|
||||
first line of output from
|
||||
.Xr dumpfs 8 .
|
||||
.El
|
||||
.Pp
|
||||
If no filesystems are given to
|
||||
.Nm fsck
|
||||
then a default list of file systems is read from
|
||||
then a default list of filesystems is read from
|
||||
the file
|
||||
.Pa /etc/fstab .
|
||||
.Pp
|
||||
.Bl -enum -indent indent -compact
|
||||
Inconsistencies checked are as follows:
|
||||
.Bl -enum -width indent -compact
|
||||
.It
|
||||
Blocks claimed by more than one inode or the free map.
|
||||
.It
|
||||
Blocks claimed by an inode outside the range of the file system.
|
||||
Blocks claimed by an inode outside the range of the filesystem.
|
||||
.It
|
||||
Incorrect link counts.
|
||||
.It
|
||||
Size checks:
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
Directory size not of proper format.
|
||||
.Bl -item -indent indent -compact
|
||||
.It
|
||||
Directory size not a multiple of DIRBLKSIZ.
|
||||
.It
|
||||
Partially truncated file.
|
||||
.El
|
||||
@ -231,8 +237,8 @@ Bad inode format.
|
||||
Blocks not accounted for anywhere.
|
||||
.It
|
||||
Directory checks:
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
.Bl -item -indent indent -compact
|
||||
.It
|
||||
File pointing to unallocated inode.
|
||||
.It
|
||||
Inode number out of range.
|
||||
@ -242,15 +248,15 @@ or having the wrong inode number.
|
||||
.El
|
||||
.It
|
||||
Super Block checks:
|
||||
.Bl -item -offset indent -compact
|
||||
.It
|
||||
More blocks for inodes than there are in the file system.
|
||||
.El
|
||||
.Bl -item -indent indent -compact
|
||||
.It
|
||||
More blocks for inodes than there are in the filesystem.
|
||||
.It
|
||||
Bad free block map format.
|
||||
.It
|
||||
Total free block and/or free inode count incorrect.
|
||||
.El
|
||||
.El
|
||||
.Pp
|
||||
Orphaned files and directories (allocated but unreferenced) are,
|
||||
with the operator's concurrence, reconnected by
|
||||
@ -266,15 +272,17 @@ If there is insufficient space its size is increased.
|
||||
Because of inconsistencies between the block device and the buffer cache,
|
||||
the raw device should always be used.
|
||||
.Sh FILES
|
||||
.Bl -tag -width indent-two -compact
|
||||
.Bl -tag -width /etc/fstab -compact
|
||||
.It Pa /etc/fstab
|
||||
contains default list of file systems to check.
|
||||
contains default list of filesystems to check.
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
The diagnostics produced by
|
||||
.Nm fsck
|
||||
are fully enumerated and explained in Appendix A of
|
||||
``Fsck \- The UNIX File System Check Program'' (SMM:5).
|
||||
.Rs
|
||||
.%T "Fsck \- The UNIX File System Check Program"
|
||||
.Re
|
||||
.Sh SEE ALSO
|
||||
.Xr fstab 5 ,
|
||||
.Xr fs 5 ,
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,15 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)inode.c 5.18 (Berkeley) 3/19/91";*/
|
||||
static char rcsid[] = "$Id: inode.c,v 1.8 1994/05/02 10:18:23 pk Exp $";
|
||||
/*static char sccsid[] = "from: @(#)inode.c 8.4 (Berkeley) 4/18/94";*/
|
||||
static char *rcsid = "$Id: inode.c,v 1.9 1994/06/08 19:00:23 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/dir.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#ifndef SMALL
|
||||
#include <pwd.h>
|
||||
#endif
|
||||
@ -50,7 +50,6 @@ static char rcsid[] = "$Id: inode.c,v 1.8 1994/05/02 10:18:23 pk Exp $";
|
||||
|
||||
static ino_t startinum;
|
||||
|
||||
int
|
||||
ckinode(dp, idesc)
|
||||
struct dinode *dp;
|
||||
register struct inodesc *idesc;
|
||||
@ -58,13 +57,17 @@ ckinode(dp, idesc)
|
||||
register daddr_t *ap;
|
||||
long ret, n, ndb, offset;
|
||||
struct dinode dino;
|
||||
quad_t remsize, sizepb;
|
||||
mode_t mode;
|
||||
|
||||
if (idesc->id_fix != IGNORE)
|
||||
idesc->id_fix = DONTKNOW;
|
||||
idesc->id_entryno = 0;
|
||||
idesc->id_filesize = dp->di_size;
|
||||
if ((dp->di_mode & IFMT) == IFBLK || (dp->di_mode & IFMT) == IFCHR ||
|
||||
DFASTLINK(*dp))
|
||||
mode = dp->di_mode & IFMT;
|
||||
if (mode == IFBLK || mode == IFCHR || (mode == IFLNK &&
|
||||
(dp->di_size < sblock.fs_maxsymlinklen ||
|
||||
(sblock.fs_maxsymlinklen == 0 && OLDFASTLINK(dp)))))
|
||||
return (KEEPON);
|
||||
dino = *dp;
|
||||
ndb = howmany(dino.di_size, sblock.fs_bsize);
|
||||
@ -85,28 +88,31 @@ ckinode(dp, idesc)
|
||||
return (ret);
|
||||
}
|
||||
idesc->id_numfrags = sblock.fs_frag;
|
||||
remsize = dino.di_size - sblock.fs_bsize * NDADDR;
|
||||
sizepb = sblock.fs_bsize;
|
||||
for (ap = &dino.di_ib[0], n = 1; n <= NIADDR; ap++, n++) {
|
||||
if (*ap) {
|
||||
idesc->id_blkno = *ap;
|
||||
ret = iblock(idesc, n,
|
||||
dino.di_size - sblock.fs_bsize * NDADDR);
|
||||
ret = iblock(idesc, n, remsize);
|
||||
if (ret & STOP)
|
||||
return (ret);
|
||||
}
|
||||
sizepb *= NINDIR(&sblock);
|
||||
remsize -= sizepb;
|
||||
}
|
||||
return (KEEPON);
|
||||
}
|
||||
|
||||
int
|
||||
iblock(idesc, ilevel, isize)
|
||||
struct inodesc *idesc;
|
||||
register long ilevel;
|
||||
u_long isize;
|
||||
long ilevel;
|
||||
quad_t isize;
|
||||
{
|
||||
register daddr_t *ap;
|
||||
register daddr_t *aplim;
|
||||
int i, n, (*func)(), nif, sizepb;
|
||||
register struct bufarea *bp;
|
||||
int i, n, (*func)(), nif;
|
||||
quad_t sizepb;
|
||||
char buf[BUFSIZ];
|
||||
extern int dirscan(), pass1check();
|
||||
|
||||
@ -122,7 +128,7 @@ iblock(idesc, ilevel, isize)
|
||||
ilevel--;
|
||||
for (sizepb = sblock.fs_bsize, i = 0; i < ilevel; i++)
|
||||
sizepb *= NINDIR(&sblock);
|
||||
nif = isize / sizepb + 1;
|
||||
nif = howmany(isize , sizepb);
|
||||
if (nif > NINDIR(&sblock))
|
||||
nif = NINDIR(&sblock);
|
||||
if (idesc->id_func == pass1check && nif < NINDIR(&sblock)) {
|
||||
@ -140,18 +146,19 @@ iblock(idesc, ilevel, isize)
|
||||
flush(fswritefd, bp);
|
||||
}
|
||||
aplim = &bp->b_un.b_indir[nif];
|
||||
for (ap = bp->b_un.b_indir, i = 1; ap < aplim; ap++, i++) {
|
||||
for (ap = bp->b_un.b_indir; ap < aplim; ap++) {
|
||||
if (*ap) {
|
||||
idesc->id_blkno = *ap;
|
||||
if (ilevel > 0)
|
||||
n = iblock(idesc, ilevel, isize - i * sizepb);
|
||||
else
|
||||
if (ilevel == 0)
|
||||
n = (*func)(idesc);
|
||||
else
|
||||
n = iblock(idesc, ilevel, isize);
|
||||
if (n & STOP) {
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
return (n);
|
||||
}
|
||||
}
|
||||
isize -= sizepb;
|
||||
}
|
||||
bp->b_flags &= ~B_INUSE;
|
||||
return (KEEPON);
|
||||
@ -161,7 +168,6 @@ iblock(idesc, ilevel, isize)
|
||||
* Check that a block in a legal block number.
|
||||
* Return 0 if in range, 1 if out of range.
|
||||
*/
|
||||
int
|
||||
chkrange(blk, cnt)
|
||||
daddr_t blk;
|
||||
int cnt;
|
||||
@ -208,7 +214,7 @@ ginode(inumber)
|
||||
errexit("bad inode number %d to ginode\n", inumber);
|
||||
if (startinum == 0 ||
|
||||
inumber < startinum || inumber >= startinum + INOPB(&sblock)) {
|
||||
iblk = itod(&sblock, inumber);
|
||||
iblk = ino_to_fsba(&sblock, inumber);
|
||||
if (pbp != 0)
|
||||
pbp->b_flags &= ~B_INUSE;
|
||||
pbp = getdatablk(iblk, sblock.fs_bsize);
|
||||
@ -237,7 +243,7 @@ getnextinode(inumber)
|
||||
errexit("bad inode number %d to nextinode\n", inumber);
|
||||
if (inumber >= lastinum) {
|
||||
readcnt++;
|
||||
dblk = fsbtodb(&sblock, itod(&sblock, lastinum));
|
||||
dblk = fsbtodb(&sblock, ino_to_fsba(&sblock, lastinum));
|
||||
if (readcnt % readpercg == 0) {
|
||||
size = partialsize;
|
||||
lastinum += partialcnt;
|
||||
@ -251,7 +257,6 @@ getnextinode(inumber)
|
||||
return (dp++);
|
||||
}
|
||||
|
||||
void
|
||||
resetinodebuf()
|
||||
{
|
||||
|
||||
@ -277,7 +282,6 @@ resetinodebuf()
|
||||
(void)getnextinode(nextino);
|
||||
}
|
||||
|
||||
void
|
||||
freeinodebuf()
|
||||
{
|
||||
|
||||
@ -293,7 +297,6 @@ freeinodebuf()
|
||||
*
|
||||
* Enter inodes into the cache.
|
||||
*/
|
||||
void
|
||||
cacheino(dp, inumber)
|
||||
register struct dinode *dp;
|
||||
ino_t inumber;
|
||||
@ -350,7 +353,6 @@ getinoinfo(inumber)
|
||||
/*
|
||||
* Clean up all the inode cache structure.
|
||||
*/
|
||||
void
|
||||
inocleanup()
|
||||
{
|
||||
register struct inoinfo **inpp;
|
||||
@ -363,15 +365,13 @@ inocleanup()
|
||||
free((char *)inpsort);
|
||||
inphead = inpsort = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
inodirty()
|
||||
{
|
||||
|
||||
dirty(pbp);
|
||||
}
|
||||
|
||||
void
|
||||
clri(idesc, type, flag)
|
||||
register struct inodesc *idesc;
|
||||
char *type;
|
||||
@ -396,7 +396,6 @@ clri(idesc, type, flag)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
findname(idesc)
|
||||
struct inodesc *idesc;
|
||||
{
|
||||
@ -408,7 +407,6 @@ findname(idesc)
|
||||
return (STOP|FOUND);
|
||||
}
|
||||
|
||||
int
|
||||
findino(idesc)
|
||||
struct inodesc *idesc;
|
||||
{
|
||||
@ -424,7 +422,6 @@ findino(idesc)
|
||||
return (KEEPON);
|
||||
}
|
||||
|
||||
void
|
||||
pinode(ino)
|
||||
ino_t ino;
|
||||
{
|
||||
@ -446,13 +443,12 @@ pinode(ino)
|
||||
printf("%u ", (unsigned)dp->di_uid);
|
||||
printf("MODE=%o\n", dp->di_mode);
|
||||
if (preen)
|
||||
printf("%s: ", devname);
|
||||
printf("SIZE=%lu ", dp->di_size);
|
||||
p = ctime(&dp->di_mtime);
|
||||
printf("%s: ", cdevname);
|
||||
printf("SIZE=%qu ", dp->di_size);
|
||||
p = ctime(&dp->di_mtime.ts_sec);
|
||||
printf("MTIME=%12.12s %4.4s ", &p[4], &p[20]);
|
||||
}
|
||||
|
||||
void
|
||||
blkerror(ino, type, blk)
|
||||
ino_t ino;
|
||||
char *type;
|
||||
@ -520,19 +516,19 @@ allocino(request, type)
|
||||
}
|
||||
dp->di_mode = type;
|
||||
(void)time(&dp->di_atime.ts_sec);
|
||||
dp->di_atime.ts_nsec = 0;
|
||||
dp->di_mtime = dp->di_ctime = dp->di_atime;
|
||||
dp->di_size = sblock.fs_fsize;
|
||||
dp->di_blocks = btodb(sblock.fs_fsize);
|
||||
n_files++;
|
||||
inodirty();
|
||||
if (newinofmt)
|
||||
typemap[ino] = IFTODT(type);
|
||||
return (ino);
|
||||
}
|
||||
|
||||
/*
|
||||
* deallocate an inode
|
||||
*/
|
||||
void
|
||||
freeino(ino)
|
||||
ino_t ino;
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,20 +32,21 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1980, 1986 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1980, 1986, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)main.c 5.27 (Berkeley) 8/7/90";*/
|
||||
static char rcsid[] = "$Id: main.c,v 1.12 1994/04/25 18:28:29 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)main.c 8.2 (Berkeley) 1/23/94";*/
|
||||
static char *rcsid = "$Id: main.c,v 1.13 1994/06/08 19:00:24 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <sys/mount.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <fstab.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -63,11 +64,11 @@ main(argc, argv)
|
||||
int ch;
|
||||
int ret, maxrun = 0;
|
||||
extern int docheck(), checkfilesys();
|
||||
extern char *optarg;
|
||||
extern char *optarg, *blockcheck();
|
||||
extern int optind;
|
||||
|
||||
sync();
|
||||
while ((ch = getopt(argc, argv, "cdpnNyYb:l:m:")) != EOF) {
|
||||
while ((ch = getopt(argc, argv, "dpnNyYb:c:l:m:")) != EOF) {
|
||||
switch (ch) {
|
||||
case 'p':
|
||||
preen++;
|
||||
@ -79,9 +80,9 @@ main(argc, argv)
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
cvtflag++;
|
||||
cvtlevel = argtoi('c', "conversion level", optarg, 10);
|
||||
break;
|
||||
|
||||
|
||||
case 'd':
|
||||
debug++;
|
||||
break;
|
||||
@ -121,7 +122,7 @@ main(argc, argv)
|
||||
(void)signal(SIGQUIT, catchquit);
|
||||
if (argc) {
|
||||
while (argc-- > 0)
|
||||
(void)checkfilesys(*argv++, (char *)0, 0L, 0);
|
||||
(void)checkfilesys(blockcheck(*argv++), 0, 0L, 0);
|
||||
exit(0);
|
||||
}
|
||||
ret = checkfstab(preen, maxrun, docheck, checkfilesys);
|
||||
@ -170,11 +171,11 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
daddr_t n_ffree, n_bfree;
|
||||
struct dups *dp;
|
||||
struct zlncnt *zlnp;
|
||||
int clean;
|
||||
int cylno;
|
||||
|
||||
if (preen && child)
|
||||
(void)signal(SIGQUIT, voidquit);
|
||||
devname = filesys;
|
||||
cdevname = filesys;
|
||||
if (debug && preen)
|
||||
pwarn("starting\n");
|
||||
if (setup(filesys) == 0) {
|
||||
@ -182,71 +183,55 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
pfatal("CAN'T CHECK FILE SYSTEM.");
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* 1: scan inodes tallying blocks used
|
||||
*/
|
||||
if (preen == 0) {
|
||||
printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
|
||||
if (hotroot)
|
||||
printf("** Root file system\n");
|
||||
printf("** Phase 1 - Check Blocks and Sizes\n");
|
||||
}
|
||||
pass1();
|
||||
|
||||
/*
|
||||
* 0: check whether file system is already clean
|
||||
* 1b: locate first references to duplicates, if any
|
||||
*/
|
||||
clean = preen && (sblock.fs_state == FSOKAY) && sblock.fs_clean;
|
||||
|
||||
#ifdef notyet
|
||||
if (clean) {
|
||||
#else
|
||||
if (0) {
|
||||
#endif
|
||||
printf("** filesystem clean -- skipping checks\n");
|
||||
} else {
|
||||
/*
|
||||
* 1: scan inodes tallying blocks used
|
||||
*/
|
||||
if (preen == 0) {
|
||||
printf("** Last Mounted on %s\n", sblock.fs_fsmnt);
|
||||
if (hotroot)
|
||||
printf("** Root file system\n");
|
||||
printf("** Phase 1 - Check Blocks and Sizes\n");
|
||||
}
|
||||
pass1();
|
||||
|
||||
/*
|
||||
* 1b: locate first references to duplicates, if any
|
||||
*/
|
||||
if (duplist) {
|
||||
if (preen)
|
||||
pfatal("INTERNAL ERROR: dups with -p");
|
||||
printf("** Phase 1b - Rescan For More DUPS\n");
|
||||
pass1b();
|
||||
}
|
||||
|
||||
/*
|
||||
* 2: traverse directories from root to mark all connected
|
||||
* directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 2 - Check Pathnames\n");
|
||||
pass2();
|
||||
|
||||
/*
|
||||
* 3: scan inodes looking for disconnected directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 3 - Check Connectivity\n");
|
||||
pass3();
|
||||
|
||||
/*
|
||||
* 4: scan inodes looking for disconnected files; check
|
||||
* reference counts
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 4 - Check Reference Counts\n");
|
||||
pass4();
|
||||
|
||||
/*
|
||||
* 5: check and repair resource counts in cylinder groups
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 5 - Check Cyl groups\n");
|
||||
pass5();
|
||||
if (duplist) {
|
||||
if (preen)
|
||||
pfatal("INTERNAL ERROR: dups with -p");
|
||||
printf("** Phase 1b - Rescan For More DUPS\n");
|
||||
pass1b();
|
||||
}
|
||||
|
||||
/*
|
||||
* 2: traverse directories from root to mark all connected directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 2 - Check Pathnames\n");
|
||||
pass2();
|
||||
|
||||
/*
|
||||
* 3: scan inodes looking for disconnected directories
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 3 - Check Connectivity\n");
|
||||
pass3();
|
||||
|
||||
/*
|
||||
* 4: scan inodes looking for disconnected files; check reference counts
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 4 - Check Reference Counts\n");
|
||||
pass4();
|
||||
|
||||
/*
|
||||
* 5: check and repair resource counts in cylinder groups
|
||||
*/
|
||||
if (preen == 0)
|
||||
printf("** Phase 5 - Check Cyl groups\n");
|
||||
pass5();
|
||||
|
||||
/*
|
||||
* print out summary statistics
|
||||
*/
|
||||
@ -254,8 +239,9 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
n_bfree = sblock.fs_cstotal.cs_nbfree;
|
||||
pwarn("%ld files, %ld used, %ld free ",
|
||||
n_files, n_blks, n_ffree + sblock.fs_frag * n_bfree);
|
||||
printf("(%ld frags, %ld blocks, %.1f%% fragmentation)\n",
|
||||
n_ffree, n_bfree, (float)(n_ffree * 100) / sblock.fs_dsize);
|
||||
printf("(%ld frags, %ld blocks, %d.%d%% fragmentation)\n",
|
||||
n_ffree, n_bfree, (n_ffree * 100) / sblock.fs_dsize,
|
||||
((n_ffree * 1000 + sblock.fs_dsize / 2) / sblock.fs_dsize) % 10);
|
||||
if (debug &&
|
||||
(n_files -= maxino - ROOTINO - sblock.fs_cstotal.cs_nifree))
|
||||
printf("%ld files missing\n", n_files);
|
||||
@ -281,30 +267,51 @@ checkfilesys(filesys, mntpt, auxdata, child)
|
||||
}
|
||||
zlnhead = (struct zlncnt *)0;
|
||||
duplist = (struct dups *)0;
|
||||
muldup = (struct dups *)0;
|
||||
inocleanup();
|
||||
#ifdef notyet
|
||||
if (!clean && !nflag && fswritefd != -1) {
|
||||
sblock.fs_state = FSOKAY;
|
||||
sblock.fs_clean = FS_CLEANFREQ;
|
||||
fsmodified = 1;
|
||||
}
|
||||
#endif
|
||||
if (fsmodified) {
|
||||
(void)time(&sblock.fs_time);
|
||||
sbdirty();
|
||||
}
|
||||
if (cvtlevel && sblk.b_dirty) {
|
||||
/*
|
||||
* Write out the duplicate super blocks
|
||||
*/
|
||||
for (cylno = 0; cylno < sblock.fs_ncg; cylno++)
|
||||
bwrite(fswritefd, (char *)&sblock,
|
||||
fsbtodb(&sblock, cgsblock(&sblock, cylno)), SBSIZE);
|
||||
}
|
||||
ckfini();
|
||||
free(blockmap);
|
||||
free(statemap);
|
||||
free((char *)lncntp);
|
||||
if (!fsmodified)
|
||||
return (0);
|
||||
if (!preen) {
|
||||
if (!preen)
|
||||
printf("\n***** FILE SYSTEM WAS MODIFIED *****\n");
|
||||
if (hotroot)
|
||||
printf("\n***** REBOOT NETBSD *****\n");
|
||||
}
|
||||
if (hotroot) {
|
||||
struct statfs stfs_buf;
|
||||
/*
|
||||
* We modified the root. Do a mount update on
|
||||
* it, unless it is read-write, so we can continue.
|
||||
*/
|
||||
if (statfs("/", &stfs_buf) == 0) {
|
||||
long flags = stfs_buf.f_flags;
|
||||
struct ufs_args args;
|
||||
int ret;
|
||||
|
||||
if (flags & MNT_RDONLY) {
|
||||
args.fspec = 0;
|
||||
args.export.ex_flags = 0;
|
||||
args.export.ex_root = 0;
|
||||
flags |= MNT_UPDATE | MNT_RELOAD;
|
||||
ret = mount(MOUNT_UFS, "/", flags, &args);
|
||||
if (ret == 0)
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
if (!preen)
|
||||
printf("\n***** REBOOT NOW *****\n");
|
||||
sync();
|
||||
return (4);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass1.c 5.16 (Berkeley) 3/19/91";*/
|
||||
static char rcsid[] = "$Id: pass1.c,v 1.6 1994/04/25 18:28:35 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass1.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass1.c,v 1.7 1994/06/08 19:00:25 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
@ -51,12 +52,9 @@ struct dinode *getnextinode();
|
||||
|
||||
pass1()
|
||||
{
|
||||
register int c, i, j;
|
||||
register struct dinode *dp;
|
||||
struct zlncnt *zlnp;
|
||||
int ndb, cgd;
|
||||
struct inodesc idesc;
|
||||
ino_t inumber;
|
||||
int c, i, cgd;
|
||||
struct inodesc idesc;
|
||||
|
||||
/*
|
||||
* Set file system reserved blocks in used block map.
|
||||
@ -84,123 +82,177 @@ pass1()
|
||||
for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
|
||||
if (inumber < ROOTINO)
|
||||
continue;
|
||||
dp = getnextinode(inumber);
|
||||
if ((dp->di_mode & IFMT) == 0) {
|
||||
if (bcmp((char *)dp->di_db, (char *)zino.di_db,
|
||||
NDADDR * sizeof(daddr_t)) ||
|
||||
bcmp((char *)dp->di_ib, (char *)zino.di_ib,
|
||||
NIADDR * sizeof(daddr_t)) ||
|
||||
dp->di_mode || dp->di_size) {
|
||||
pfatal("PARTIALLY ALLOCATED INODE I=%lu",
|
||||
inumber);
|
||||
if (reply("CLEAR") == 1) {
|
||||
dp = ginode(inumber);
|
||||
clearinode(dp);
|
||||
inodirty();
|
||||
}
|
||||
}
|
||||
statemap[inumber] = USTATE;
|
||||
continue;
|
||||
}
|
||||
lastino = inumber;
|
||||
/* is fast symlink? */
|
||||
if (DFASTLINK(*dp)) {
|
||||
lncntp[inumber] = dp->di_nlink;
|
||||
statemap[inumber] = FSTATE;
|
||||
n_files++;
|
||||
continue;
|
||||
}
|
||||
if (/* dp->di_size < 0 || */
|
||||
dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
|
||||
if (debug)
|
||||
printf("bad size %lu:", dp->di_size);
|
||||
goto unknown;
|
||||
}
|
||||
if (!preen && (dp->di_mode & IFMT) == IFMT &&
|
||||
reply("HOLD BAD BLOCK") == 1) {
|
||||
dp = ginode(inumber);
|
||||
dp->di_size = sblock.fs_fsize;
|
||||
dp->di_mode = IFREG|0600;
|
||||
inodirty();
|
||||
}
|
||||
ndb = howmany(dp->di_size, sblock.fs_bsize);
|
||||
if (ndb < 0) {
|
||||
if (debug)
|
||||
printf("bad size %lu ndb %d:",
|
||||
dp->di_size, ndb);
|
||||
goto unknown;
|
||||
}
|
||||
if ((dp->di_mode & IFMT) == IFBLK ||
|
||||
(dp->di_mode & IFMT) == IFCHR)
|
||||
ndb++;
|
||||
for (j = ndb; j < NDADDR; j++)
|
||||
if (dp->di_db[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad direct addr: %ld\n",
|
||||
dp->di_db[j]);
|
||||
goto unknown;
|
||||
}
|
||||
for (j = 0, ndb -= NDADDR; ndb > 0; j++)
|
||||
ndb /= NINDIR(&sblock);
|
||||
for (; j < NIADDR; j++)
|
||||
if (dp->di_ib[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad indirect addr: %ld\n",
|
||||
dp->di_ib[j]);
|
||||
goto unknown;
|
||||
}
|
||||
if (ftypeok(dp) == 0)
|
||||
goto unknown;
|
||||
n_files++;
|
||||
lncntp[inumber] = dp->di_nlink;
|
||||
if (dp->di_nlink <= 0) {
|
||||
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
||||
if (zlnp == NULL) {
|
||||
pfatal("LINK COUNT TABLE OVERFLOW");
|
||||
if (reply("CONTINUE") == 0)
|
||||
errexit("");
|
||||
} else {
|
||||
zlnp->zlncnt = inumber;
|
||||
zlnp->next = zlnhead;
|
||||
zlnhead = zlnp;
|
||||
}
|
||||
}
|
||||
if ((dp->di_mode & IFMT) == IFDIR) {
|
||||
if (dp->di_size == 0)
|
||||
statemap[inumber] = DCLEAR;
|
||||
else
|
||||
statemap[inumber] = DSTATE;
|
||||
cacheino(dp, inumber);
|
||||
} else
|
||||
statemap[inumber] = FSTATE;
|
||||
badblk = dupblk = 0;
|
||||
idesc.id_number = inumber;
|
||||
(void)ckinode(dp, &idesc);
|
||||
idesc.id_entryno *= btodb(sblock.fs_fsize);
|
||||
if (dp->di_blocks != idesc.id_entryno) {
|
||||
pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
|
||||
inumber, dp->di_blocks, idesc.id_entryno);
|
||||
if (preen)
|
||||
printf(" (CORRECTED)\n");
|
||||
else if (reply("CORRECT") == 0)
|
||||
continue;
|
||||
dp = ginode(inumber);
|
||||
dp->di_blocks = idesc.id_entryno;
|
||||
inodirty();
|
||||
}
|
||||
continue;
|
||||
unknown:
|
||||
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
||||
statemap[inumber] = FCLEAR;
|
||||
checkinode(inumber, &idesc);
|
||||
}
|
||||
}
|
||||
freeinodebuf();
|
||||
}
|
||||
|
||||
checkinode(inumber, idesc)
|
||||
ino_t inumber;
|
||||
register struct inodesc *idesc;
|
||||
{
|
||||
register struct dinode *dp;
|
||||
struct zlncnt *zlnp;
|
||||
int ndb, j;
|
||||
mode_t mode;
|
||||
char symbuf[MAXSYMLINKLEN];
|
||||
|
||||
dp = getnextinode(inumber);
|
||||
mode = dp->di_mode & IFMT;
|
||||
if (mode == 0) {
|
||||
if (bcmp((char *)dp->di_db, (char *)zino.di_db,
|
||||
NDADDR * sizeof(daddr_t)) ||
|
||||
bcmp((char *)dp->di_ib, (char *)zino.di_ib,
|
||||
NIADDR * sizeof(daddr_t)) ||
|
||||
dp->di_mode || dp->di_size) {
|
||||
pfatal("PARTIALLY ALLOCATED INODE I=%lu", inumber);
|
||||
if (reply("CLEAR") == 1) {
|
||||
statemap[inumber] = USTATE;
|
||||
dp = ginode(inumber);
|
||||
clearinode(dp);
|
||||
inodirty();
|
||||
}
|
||||
}
|
||||
statemap[inumber] = USTATE;
|
||||
return;
|
||||
}
|
||||
lastino = inumber;
|
||||
if (/* dp->di_size < 0 || */
|
||||
dp->di_size + sblock.fs_bsize - 1 < dp->di_size) {
|
||||
if (debug)
|
||||
printf("bad size %qu:", dp->di_size);
|
||||
goto unknown;
|
||||
}
|
||||
if (!preen && mode == IFMT && reply("HOLD BAD BLOCK") == 1) {
|
||||
dp = ginode(inumber);
|
||||
dp->di_size = sblock.fs_fsize;
|
||||
dp->di_mode = IFREG|0600;
|
||||
inodirty();
|
||||
}
|
||||
ndb = howmany(dp->di_size, sblock.fs_bsize);
|
||||
if (ndb < 0) {
|
||||
if (debug)
|
||||
printf("bad size %qu ndb %d:",
|
||||
dp->di_size, ndb);
|
||||
goto unknown;
|
||||
}
|
||||
if (mode == IFBLK || mode == IFCHR)
|
||||
ndb++;
|
||||
if (mode == IFLNK) {
|
||||
/*
|
||||
* Note that the old fastlink format always had di_blocks set
|
||||
* to 0. Other than that we no longer use the `spare' field
|
||||
* (which is now the extended uid) for sanity checking, the
|
||||
* new format is the same as the old. We simply ignore the
|
||||
* conversion altogether. - mycroft, 19MAY1994
|
||||
*/
|
||||
if (doinglevel2 &&
|
||||
dp->di_size > 0 && dp->di_size < MAXSYMLINKLEN &&
|
||||
dp->di_blocks != 0) {
|
||||
if (bread(fsreadfd, symbuf,
|
||||
fsbtodb(&sblock, dp->di_db[0]),
|
||||
(long)dp->di_size) != 0)
|
||||
errexit("cannot read symlink");
|
||||
if (debug) {
|
||||
symbuf[dp->di_size] = 0;
|
||||
printf("convert symlink %d(%s) of size %d\n",
|
||||
inumber, symbuf, (long)dp->di_size);
|
||||
}
|
||||
dp = ginode(inumber);
|
||||
bcopy(symbuf, (caddr_t)dp->di_shortlink,
|
||||
(long)dp->di_size);
|
||||
dp->di_blocks = 0;
|
||||
inodirty();
|
||||
}
|
||||
/*
|
||||
* Fake ndb value so direct/indirect block checks below
|
||||
* will detect any garbage after symlink string.
|
||||
*/
|
||||
if (dp->di_size < sblock.fs_maxsymlinklen ||
|
||||
(sblock.fs_maxsymlinklen == 0 && OLDFASTLINK(dp))) {
|
||||
ndb = howmany(dp->di_size, sizeof(daddr_t));
|
||||
if (ndb > NDADDR) {
|
||||
j = ndb - NDADDR;
|
||||
for (ndb = 1; j > 1; j--)
|
||||
ndb *= NINDIR(&sblock);
|
||||
ndb += NDADDR;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (j = ndb; j < NDADDR; j++)
|
||||
if (dp->di_db[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad direct addr: %ld\n", dp->di_db[j]);
|
||||
goto unknown;
|
||||
}
|
||||
for (j = 0, ndb -= NDADDR; ndb > 0; j++)
|
||||
ndb /= NINDIR(&sblock);
|
||||
for (; j < NIADDR; j++)
|
||||
if (dp->di_ib[j] != 0) {
|
||||
if (debug)
|
||||
printf("bad indirect addr: %ld\n",
|
||||
dp->di_ib[j]);
|
||||
goto unknown;
|
||||
}
|
||||
if (ftypeok(dp) == 0)
|
||||
goto unknown;
|
||||
n_files++;
|
||||
lncntp[inumber] = dp->di_nlink;
|
||||
if (dp->di_nlink <= 0) {
|
||||
zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
|
||||
if (zlnp == NULL) {
|
||||
pfatal("LINK COUNT TABLE OVERFLOW");
|
||||
if (reply("CONTINUE") == 0)
|
||||
errexit("");
|
||||
} else {
|
||||
zlnp->zlncnt = inumber;
|
||||
zlnp->next = zlnhead;
|
||||
zlnhead = zlnp;
|
||||
}
|
||||
}
|
||||
if (mode == IFDIR) {
|
||||
if (dp->di_size == 0)
|
||||
statemap[inumber] = DCLEAR;
|
||||
else
|
||||
statemap[inumber] = DSTATE;
|
||||
cacheino(dp, inumber);
|
||||
} else
|
||||
statemap[inumber] = FSTATE;
|
||||
typemap[inumber] = IFTODT(mode);
|
||||
if (doinglevel2 &&
|
||||
(dp->di_ouid != (u_short)-1 || dp->di_ogid != (u_short)-1)) {
|
||||
dp = ginode(inumber);
|
||||
dp->di_uid = dp->di_ouid;
|
||||
dp->di_ouid = -1;
|
||||
dp->di_gid = dp->di_ogid;
|
||||
dp->di_ogid = -1;
|
||||
inodirty();
|
||||
}
|
||||
badblk = dupblk = 0;
|
||||
idesc->id_number = inumber;
|
||||
(void)ckinode(dp, idesc);
|
||||
idesc->id_entryno *= btodb(sblock.fs_fsize);
|
||||
if (dp->di_blocks != idesc->id_entryno) {
|
||||
pwarn("INCORRECT BLOCK COUNT I=%lu (%ld should be %ld)",
|
||||
inumber, dp->di_blocks, idesc->id_entryno);
|
||||
if (preen)
|
||||
printf(" (CORRECTED)\n");
|
||||
else if (reply("CORRECT") == 0)
|
||||
return;
|
||||
dp = ginode(inumber);
|
||||
dp->di_blocks = idesc->id_entryno;
|
||||
inodirty();
|
||||
}
|
||||
return;
|
||||
unknown:
|
||||
pfatal("UNKNOWN FILE TYPE I=%lu", inumber);
|
||||
statemap[inumber] = FCLEAR;
|
||||
if (reply("CLEAR") == 1) {
|
||||
statemap[inumber] = USTATE;
|
||||
dp = ginode(inumber);
|
||||
clearinode(dp);
|
||||
inodirty();
|
||||
}
|
||||
freeinodebuf();
|
||||
}
|
||||
|
||||
pass1check(idesc)
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass1b.c 5.8 (Berkeley) 7/20/90";*/
|
||||
static char rcsid[] = "$Id: pass1b.c,v 1.5 1994/04/25 18:28:42 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass1b.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass1b.c,v 1.6 1994/06/08 19:00:26 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,17 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass2.c 5.17 (Berkeley) 12/28/90";*/
|
||||
static char rcsid[] = "$Id: pass2.c,v 1.5 1994/04/25 18:28:47 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass2.c 8.2 (Berkeley) 2/27/94";*/
|
||||
static char *rcsid = "$Id: pass2.c,v 1.6 1994/06/08 19:00:27 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#define KERNEL
|
||||
#include <ufs/dir.h>
|
||||
#undef KERNEL
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
@ -116,7 +114,6 @@ pass2()
|
||||
bzero((char *)&curino, sizeof(struct inodesc));
|
||||
curino.id_type = DATA;
|
||||
curino.id_func = pass2check;
|
||||
dino.di_mode = IFDIR;
|
||||
dp = &dino;
|
||||
inpend = &inpsort[inplast];
|
||||
for (inpp = inpsort; inpp < inpend; inpp++) {
|
||||
@ -146,6 +143,8 @@ pass2()
|
||||
dp = &dino;
|
||||
}
|
||||
}
|
||||
bzero((char *)&dino, sizeof(struct dinode));
|
||||
dino.di_mode = IFDIR;
|
||||
dp->di_size = inp->i_isize;
|
||||
bcopy((char *)&inp->i_blks[0], (char *)&dp->di_db[0],
|
||||
(size_t)inp->i_numblks);
|
||||
@ -177,7 +176,7 @@ pass2()
|
||||
continue;
|
||||
}
|
||||
fileerror(inp->i_parent, inp->i_number,
|
||||
"BAD INODE NUMBER FOR '..'");
|
||||
"BAD INODE NUMBER FOR '..'");
|
||||
if (reply("FIX") == 0)
|
||||
continue;
|
||||
lncntp[inp->i_dotdot]++;
|
||||
@ -203,6 +202,13 @@ pass2check(idesc)
|
||||
char namebuf[MAXPATHLEN + 1];
|
||||
char pathbuf[MAXPATHLEN + 1];
|
||||
|
||||
/*
|
||||
* If converting, set directory entry type.
|
||||
*/
|
||||
if (doinglevel2 && dirp->d_ino > 0 && dirp->d_ino < maxino) {
|
||||
dirp->d_type = typemap[dirp->d_ino];
|
||||
ret |= ALTERED;
|
||||
}
|
||||
/*
|
||||
* check for "."
|
||||
*/
|
||||
@ -215,13 +221,23 @@ pass2check(idesc)
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
if (newinofmt && dirp->d_type != DT_DIR) {
|
||||
direrror(idesc->id_number, "BAD TYPE VALUE FOR '.'");
|
||||
dirp->d_type = DT_DIR;
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
goto chk1;
|
||||
}
|
||||
direrror(idesc->id_number, "MISSING '.'");
|
||||
proto.d_ino = idesc->id_number;
|
||||
if (newinofmt)
|
||||
proto.d_type = DT_DIR;
|
||||
else
|
||||
proto.d_type = 0;
|
||||
proto.d_namlen = 1;
|
||||
(void)strcpy(proto.d_name, ".");
|
||||
entrysize = DIRSIZ(&proto);
|
||||
entrysize = DIRSIZ(0, &proto);
|
||||
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") != 0) {
|
||||
pfatal("CANNOT FIX, FIRST ENTRY IN DIRECTORY CONTAINS %s\n",
|
||||
dirp->d_name);
|
||||
@ -249,11 +265,15 @@ chk1:
|
||||
goto chk2;
|
||||
inp = getinoinfo(idesc->id_number);
|
||||
proto.d_ino = inp->i_parent;
|
||||
if (newinofmt)
|
||||
proto.d_type = DT_DIR;
|
||||
else
|
||||
proto.d_type = 0;
|
||||
proto.d_namlen = 2;
|
||||
(void)strcpy(proto.d_name, "..");
|
||||
entrysize = DIRSIZ(&proto);
|
||||
entrysize = DIRSIZ(0, &proto);
|
||||
if (idesc->id_entryno == 0) {
|
||||
n = DIRSIZ(dirp);
|
||||
n = DIRSIZ(0, dirp);
|
||||
if (dirp->d_reclen < n + entrysize)
|
||||
goto chk2;
|
||||
proto.d_reclen = dirp->d_reclen - n;
|
||||
@ -266,6 +286,12 @@ chk1:
|
||||
}
|
||||
if (dirp->d_ino != 0 && strcmp(dirp->d_name, "..") == 0) {
|
||||
inp->i_dotdot = dirp->d_ino;
|
||||
if (newinofmt && dirp->d_type != DT_DIR) {
|
||||
direrror(idesc->id_number, "BAD TYPE VALUE FOR '..'");
|
||||
dirp->d_type = DT_DIR;
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
goto chk2;
|
||||
}
|
||||
if (dirp->d_ino != 0 && strcmp(dirp->d_name, ".") != 0) {
|
||||
@ -332,10 +358,14 @@ again:
|
||||
case FCLEAR:
|
||||
if (idesc->id_entryno <= 2)
|
||||
break;
|
||||
if (statemap[dirp->d_ino] == DCLEAR)
|
||||
errmsg = "ZERO LENGTH DIRECTORY";
|
||||
else
|
||||
if (statemap[dirp->d_ino] == FCLEAR)
|
||||
errmsg = "DUP/BAD";
|
||||
else if (!preen)
|
||||
errmsg = "ZERO LENGTH DIRECTORY";
|
||||
else {
|
||||
n = 1;
|
||||
break;
|
||||
}
|
||||
fileerror(idesc->id_number, dirp->d_ino, errmsg);
|
||||
if ((n = reply("REMOVE")) == 1)
|
||||
break;
|
||||
@ -369,6 +399,13 @@ again:
|
||||
/* fall through */
|
||||
|
||||
case FSTATE:
|
||||
if (newinofmt && dirp->d_type != typemap[dirp->d_ino]) {
|
||||
fileerror(idesc->id_number, dirp->d_ino,
|
||||
"BAD TYPE VALUE");
|
||||
dirp->d_type = typemap[dirp->d_ino];
|
||||
if (reply("FIX") == 1)
|
||||
ret |= ALTERED;
|
||||
}
|
||||
lncntp[dirp->d_ino]--;
|
||||
break;
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass3.c 5.10 (Berkeley) 6/1/90";*/
|
||||
static char rcsid[] = "$Id: pass3.c,v 1.5 1994/04/25 18:28:51 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass3.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass3.c,v 1.6 1994/06/08 19:00:28 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include "fsck.h"
|
||||
|
||||
pass3()
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass4.c 5.10 (Berkeley) 7/20/90";*/
|
||||
static char rcsid[] = "$Id: pass4.c,v 1.5 1994/04/25 18:28:54 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass4.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: pass4.c,v 1.6 1994/06/08 19:00:29 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,14 +32,14 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)pass5.c 5.13 (Berkeley) 7/20/90";*/
|
||||
static char rcsid[] = "$Id: pass5.c,v 1.5 1994/04/25 18:28:57 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)pass5.c 8.2 (Berkeley) 2/2/94";*/
|
||||
static char *rcsid = "$Id: pass5.c,v 1.6 1994/06/08 19:00:30 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <string.h>
|
||||
#include "fsck.h"
|
||||
|
||||
@ -52,7 +52,6 @@ pass5()
|
||||
register daddr_t d;
|
||||
register long i, j;
|
||||
struct csum *cs;
|
||||
time_t now;
|
||||
struct csum cstotal;
|
||||
struct inodesc idesc[3];
|
||||
char buf[MAXBSIZE];
|
||||
@ -61,6 +60,45 @@ pass5()
|
||||
|
||||
bzero((char *)newcg, (size_t)fs->fs_cgsize);
|
||||
newcg->cg_niblk = fs->fs_ipg;
|
||||
if (cvtlevel > 3) {
|
||||
if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
|
||||
if (preen)
|
||||
pwarn("DELETING CLUSTERING MAPS\n");
|
||||
if (preen || reply("DELETE CLUSTERING MAPS")) {
|
||||
fs->fs_contigsumsize = 0;
|
||||
doinglevel1 = 1;
|
||||
sbdirty();
|
||||
}
|
||||
}
|
||||
if (fs->fs_maxcontig > 1) {
|
||||
char *doit = 0;
|
||||
|
||||
if (fs->fs_contigsumsize < 1) {
|
||||
doit = "CREAT";
|
||||
} else if (fs->fs_contigsumsize < fs->fs_maxcontig &&
|
||||
fs->fs_contigsumsize < FS_MAXCONTIG) {
|
||||
doit = "EXPAND";
|
||||
}
|
||||
if (doit) {
|
||||
i = fs->fs_contigsumsize;
|
||||
fs->fs_contigsumsize =
|
||||
MIN(fs->fs_maxcontig, FS_MAXCONTIG);
|
||||
if (CGSIZE(fs) > fs->fs_bsize) {
|
||||
pwarn("CANNOT %s CLUSTER MAPS\n", doit);
|
||||
fs->fs_contigsumsize = i;
|
||||
} else if (preen ||
|
||||
reply("CREATE CLUSTER MAPS")) {
|
||||
if (preen)
|
||||
pwarn("%sING CLUSTER MAPS\n",
|
||||
doit);
|
||||
fs->fs_cgsize =
|
||||
fragroundup(fs, CGSIZE(fs));
|
||||
doinglevel1 = 1;
|
||||
sbdirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
switch ((int)fs->fs_postblformat) {
|
||||
|
||||
case FS_42POSTBLFMT:
|
||||
@ -75,16 +113,27 @@ pass5()
|
||||
|
||||
case FS_DYNAMICPOSTBLFMT:
|
||||
newcg->cg_btotoff =
|
||||
&newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
|
||||
&newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
|
||||
newcg->cg_boff =
|
||||
newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
|
||||
newcg->cg_btotoff + fs->fs_cpg * sizeof(long);
|
||||
newcg->cg_iusedoff = newcg->cg_boff +
|
||||
fs->fs_cpg * fs->fs_nrpos * sizeof(short);
|
||||
fs->fs_cpg * fs->fs_nrpos * sizeof(short);
|
||||
newcg->cg_freeoff =
|
||||
newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
|
||||
newcg->cg_nextfreeoff = newcg->cg_freeoff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs),
|
||||
NBBY);
|
||||
newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
|
||||
if (fs->fs_contigsumsize <= 0) {
|
||||
newcg->cg_nextfreeoff = newcg->cg_freeoff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY);
|
||||
} else {
|
||||
newcg->cg_clustersumoff = newcg->cg_freeoff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY) -
|
||||
sizeof(long);
|
||||
newcg->cg_clustersumoff =
|
||||
roundup(newcg->cg_clustersumoff, sizeof(long));
|
||||
newcg->cg_clusteroff = newcg->cg_clustersumoff +
|
||||
(fs->fs_contigsumsize + 1) * sizeof(long);
|
||||
newcg->cg_nextfreeoff = newcg->cg_clusteroff +
|
||||
howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
|
||||
}
|
||||
newcg->cg_magic = CG_MAGIC;
|
||||
basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link);
|
||||
sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
|
||||
@ -96,10 +145,12 @@ pass5()
|
||||
fs->fs_postblformat);
|
||||
}
|
||||
bzero((char *)&idesc[0], sizeof idesc);
|
||||
for (i = 0; i < 3; i++)
|
||||
for (i = 0; i < 3; i++) {
|
||||
idesc[i].id_type = ADDR;
|
||||
if (doinglevel2)
|
||||
idesc[i].id_fix = FIX;
|
||||
}
|
||||
bzero((char *)&cstotal, sizeof(struct csum));
|
||||
(void)time(&now);
|
||||
j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
|
||||
for (i = fs->fs_size; i < j; i++)
|
||||
setbmap(i);
|
||||
@ -111,16 +162,15 @@ pass5()
|
||||
dmax = dbase + fs->fs_fpg;
|
||||
if (dmax > fs->fs_size)
|
||||
dmax = fs->fs_size;
|
||||
if (now > cg->cg_time)
|
||||
newcg->cg_time = cg->cg_time;
|
||||
else
|
||||
newcg->cg_time = now;
|
||||
newcg->cg_time = cg->cg_time;
|
||||
newcg->cg_cgx = c;
|
||||
if (c == fs->fs_ncg - 1)
|
||||
newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
|
||||
else
|
||||
newcg->cg_ncyl = fs->fs_cpg;
|
||||
newcg->cg_ndblk = dmax - dbase;
|
||||
if (fs->fs_contigsumsize > 0)
|
||||
newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag;
|
||||
newcg->cg_cs.cs_ndir = 0;
|
||||
newcg->cg_cs.cs_nffree = 0;
|
||||
newcg->cg_cs.cs_nbfree = 0;
|
||||
@ -188,10 +238,42 @@ pass5()
|
||||
j = cbtocylno(fs, i);
|
||||
cg_blktot(newcg)[j]++;
|
||||
cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
|
||||
if (fs->fs_contigsumsize > 0)
|
||||
setbit(cg_clustersfree(newcg),
|
||||
i / fs->fs_frag);
|
||||
} else if (frags > 0) {
|
||||
newcg->cg_cs.cs_nffree += frags;
|
||||
blk = blkmap(fs, cg_blksfree(newcg), i);
|
||||
fragacct(fs, blk, newcg->cg_frsum, 1);
|
||||
ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
|
||||
}
|
||||
}
|
||||
if (fs->fs_contigsumsize > 0) {
|
||||
long *sump = cg_clustersum(newcg);
|
||||
u_char *mapp = cg_clustersfree(newcg);
|
||||
int map = *mapp++;
|
||||
int bit = 1;
|
||||
int run = 0;
|
||||
|
||||
for (i = 0; i < newcg->cg_nclusterblks; i++) {
|
||||
if ((map & bit) != 0) {
|
||||
run++;
|
||||
} else if (run != 0) {
|
||||
if (run > fs->fs_contigsumsize)
|
||||
run = fs->fs_contigsumsize;
|
||||
sump[run]++;
|
||||
run = 0;
|
||||
}
|
||||
if ((i & (NBBY - 1)) != (NBBY - 1)) {
|
||||
bit <<= 1;
|
||||
} else {
|
||||
map = *mapp++;
|
||||
bit = 1;
|
||||
}
|
||||
}
|
||||
if (run != 0) {
|
||||
if (run > fs->fs_contigsumsize)
|
||||
run = fs->fs_contigsumsize;
|
||||
sump[run]++;
|
||||
}
|
||||
}
|
||||
cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
|
||||
@ -204,7 +286,7 @@ pass5()
|
||||
bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs);
|
||||
sbdirty();
|
||||
}
|
||||
if (cvtflag) {
|
||||
if (doinglevel1) {
|
||||
bcopy((char *)newcg, (char *)cg, (size_t)fs->fs_cgsize);
|
||||
cgdirty();
|
||||
continue;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1990 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,13 +32,12 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)preen.c 5.7 (Berkeley) 3/19/91";*/
|
||||
static char rcsid[] = "$Id: preen.c,v 1.5 1994/04/25 18:29:01 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)preen.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: preen.c,v 1.6 1994/06/08 19:00:31 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/wait.h>
|
||||
#include <fstab.h>
|
||||
#include <string.h>
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,20 +32,19 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)setup.c 5.33 (Berkeley) 2/22/91";*/
|
||||
static char rcsid[] = "$Id: setup.c,v 1.9 1994/04/25 18:33:42 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)setup.c 8.2 (Berkeley) 2/21/94";*/
|
||||
static char *rcsid = "$Id: setup.c,v 1.10 1994/06/08 19:00:32 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#define DKTYPENAMES
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disklabel.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/mount.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -56,22 +55,7 @@ struct bufarea asblk;
|
||||
#define altsblock (*asblk.b_un.b_fs)
|
||||
#define POWEROF2(num) (((num) & ((num) - 1)) == 0)
|
||||
|
||||
/*
|
||||
* The size of a cylinder group is calculated by CGSIZE. The maximum size
|
||||
* is limited by the fact that cylinder groups are at most one block.
|
||||
* Its size is derived from the size of the maps maintained in the
|
||||
* cylinder group and the (struct cg) size.
|
||||
*/
|
||||
#define CGSIZE(fs) \
|
||||
/* base cg */ (sizeof(struct cg) + \
|
||||
/* blktot size */ (fs)->fs_cpg * sizeof(long) + \
|
||||
/* blks size */ (fs)->fs_cpg * (fs)->fs_nrpos * sizeof(short) + \
|
||||
/* inode map */ howmany((fs)->fs_ipg, NBBY) + \
|
||||
/* block map */ howmany((fs)->fs_cpg * (fs)->fs_spc / NSPF(fs), NBBY))
|
||||
|
||||
char *index();
|
||||
struct disklabel *getdisklabel();
|
||||
char *getmntdev();
|
||||
|
||||
setup(dev)
|
||||
char *dev;
|
||||
@ -79,47 +63,17 @@ setup(dev)
|
||||
long cg, size, asked, i, j;
|
||||
long bmapsize;
|
||||
struct disklabel *lp;
|
||||
struct stat statb, statb2;
|
||||
off_t sizepb;
|
||||
struct stat statb;
|
||||
struct fs proto;
|
||||
char path2[MAXPATHLEN];
|
||||
char *dev2;
|
||||
|
||||
havesb = 0;
|
||||
fswritefd = -1;
|
||||
if (stat(dev, &statb) < 0) {
|
||||
printf("Can't stat %s: %s\n", dev, strerror(errno));
|
||||
return (0);
|
||||
}
|
||||
switch (statb.st_mode & S_IFMT) {
|
||||
case S_IFCHR:
|
||||
break;
|
||||
case S_IFDIR:
|
||||
dev2 = getmntdev(dev);
|
||||
if (dev2 != NULL && !strncmp(dev2, "/dev/", 5)) {
|
||||
snprintf(path2, sizeof(path2), "/dev/r%s", dev2 + 5);
|
||||
if (stat(path2, &statb2) == 0 &&
|
||||
(statb2.st_mode & S_IFMT) == S_IFCHR) {
|
||||
dev = path2;
|
||||
statb = statb2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
pfatal("%s is not a character device", dev);
|
||||
if (reply("CONTINUE") == 0)
|
||||
return (0);
|
||||
break;
|
||||
case S_IFBLK:
|
||||
if (!strncmp(dev, "/dev/", 5)) {
|
||||
sprintf(path2, "/dev/r%s", dev + 5);
|
||||
if (stat(path2, &statb2) == 0 &&
|
||||
(statb2.st_mode & S_IFMT) == S_IFCHR &&
|
||||
minor(statb2.st_rdev) == minor(statb.st_rdev)) {
|
||||
dev = path2;
|
||||
statb = statb2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
default:
|
||||
if ((statb.st_mode & S_IFMT) != S_IFCHR) {
|
||||
pfatal("%s is not a character device", dev);
|
||||
if (reply("CONTINUE") == 0)
|
||||
return (0);
|
||||
@ -150,14 +104,6 @@ setup(dev)
|
||||
dev_bsize = secsize = lp->d_secsize;
|
||||
else
|
||||
dev_bsize = secsize = DEV_BSIZE;
|
||||
#ifdef tahoe
|
||||
/*
|
||||
* On the tahoe, the disk label and the disk driver disagree.
|
||||
* The label knows that sectors are 512 bytes, but the disk
|
||||
* drivers will only transfer in 1024 sized pieces.
|
||||
*/
|
||||
secsize = 1024;
|
||||
#endif
|
||||
/*
|
||||
* Read in the superblock, looking for alternates if necessary
|
||||
*/
|
||||
@ -227,64 +173,55 @@ setup(dev)
|
||||
dirty(&asblk);
|
||||
}
|
||||
}
|
||||
if (cvtflag) {
|
||||
if (sblock.fs_postblformat == FS_42POSTBLFMT) {
|
||||
/*
|
||||
* Requested to convert from old format to new format
|
||||
*/
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO NEW FILE SYSTEM FORMAT\n");
|
||||
else if (!reply("CONVERT TO NEW FILE SYSTEM FORMAT"))
|
||||
return(0);
|
||||
sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT;
|
||||
sblock.fs_nrpos = 8;
|
||||
sblock.fs_postbloff =
|
||||
(char *)(&sblock.fs_opostbl[0][0]) -
|
||||
(char *)(&sblock.fs_link);
|
||||
sblock.fs_rotbloff = &sblock.fs_space[0] -
|
||||
(u_char *)(&sblock.fs_link);
|
||||
sblock.fs_cgsize =
|
||||
fragroundup(&sblock, CGSIZE(&sblock));
|
||||
/*
|
||||
* Planning now for future expansion.
|
||||
*/
|
||||
# if (BYTE_ORDER == BIG_ENDIAN)
|
||||
sblock.fs_qbmask.val[0] = 0;
|
||||
sblock.fs_qbmask.val[1] = ~sblock.fs_bmask;
|
||||
sblock.fs_qfmask.val[0] = 0;
|
||||
sblock.fs_qfmask.val[1] = ~sblock.fs_fmask;
|
||||
# endif /* BIG_ENDIAN */
|
||||
# if (BYTE_ORDER == LITTLE_ENDIAN)
|
||||
sblock.fs_qbmask.val[0] = ~sblock.fs_bmask;
|
||||
sblock.fs_qbmask.val[1] = 0;
|
||||
sblock.fs_qfmask.val[0] = ~sblock.fs_fmask;
|
||||
sblock.fs_qfmask.val[1] = 0;
|
||||
# endif /* LITTLE_ENDIAN */
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
} else if (sblock.fs_postblformat == FS_DYNAMICPOSTBLFMT) {
|
||||
/*
|
||||
* Requested to convert from new format to old format
|
||||
*/
|
||||
if (sblock.fs_nrpos != 8 || sblock.fs_ipg > 2048 ||
|
||||
sblock.fs_cpg > 32 || sblock.fs_cpc > 16) {
|
||||
printf(
|
||||
"PARAMETERS OF CURRENT FILE SYSTEM DO NOT\n\t");
|
||||
errexit(
|
||||
"ALLOW CONVERSION TO OLD FILE SYSTEM FORMAT\n");
|
||||
}
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO OLD FILE SYSTEM FORMAT\n");
|
||||
else if (!reply("CONVERT TO OLD FILE SYSTEM FORMAT"))
|
||||
return(0);
|
||||
sblock.fs_postblformat = FS_42POSTBLFMT;
|
||||
sblock.fs_cgsize = fragroundup(&sblock,
|
||||
sizeof(struct ocg) + howmany(sblock.fs_fpg, NBBY));
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
} else {
|
||||
errexit("UNKNOWN FILE SYSTEM FORMAT\n");
|
||||
if (sblock.fs_inodefmt >= FS_44INODEFMT) {
|
||||
newinofmt = 1;
|
||||
} else {
|
||||
sblock.fs_qbmask = ~sblock.fs_bmask;
|
||||
sblock.fs_qfmask = ~sblock.fs_fmask;
|
||||
newinofmt = 0;
|
||||
}
|
||||
/*
|
||||
* Convert to new inode format.
|
||||
*/
|
||||
if (cvtlevel >= 2 && sblock.fs_inodefmt < FS_44INODEFMT) {
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO NEW INODE FORMAT\n");
|
||||
else if (!reply("CONVERT TO NEW INODE FORMAT"))
|
||||
return(0);
|
||||
doinglevel2++;
|
||||
sblock.fs_inodefmt = FS_44INODEFMT;
|
||||
sizepb = sblock.fs_bsize;
|
||||
sblock.fs_maxfilesize = sblock.fs_bsize * NDADDR - 1;
|
||||
for (i = 0; i < NIADDR; i++) {
|
||||
sizepb *= NINDIR(&sblock);
|
||||
sblock.fs_maxfilesize += sizepb;
|
||||
}
|
||||
sblock.fs_maxsymlinklen = MAXSYMLINKLEN;
|
||||
sblock.fs_qbmask = ~sblock.fs_bmask;
|
||||
sblock.fs_qfmask = ~sblock.fs_fmask;
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
}
|
||||
/*
|
||||
* Convert to new cylinder group format.
|
||||
*/
|
||||
if (cvtlevel >= 1 && sblock.fs_postblformat == FS_42POSTBLFMT) {
|
||||
if (preen)
|
||||
pwarn("CONVERTING TO NEW CYLINDER GROUP FORMAT\n");
|
||||
else if (!reply("CONVERT TO NEW CYLINDER GROUP FORMAT"))
|
||||
return(0);
|
||||
doinglevel1++;
|
||||
sblock.fs_postblformat = FS_DYNAMICPOSTBLFMT;
|
||||
sblock.fs_nrpos = 8;
|
||||
sblock.fs_postbloff =
|
||||
(char *)(&sblock.fs_opostbl[0][0]) -
|
||||
(char *)(&sblock.fs_link);
|
||||
sblock.fs_rotbloff = &sblock.fs_space[0] -
|
||||
(u_char *)(&sblock.fs_link);
|
||||
sblock.fs_cgsize =
|
||||
fragroundup(&sblock, CGSIZE(&sblock));
|
||||
sbdirty();
|
||||
dirty(&asblk);
|
||||
}
|
||||
if (asblk.b_dirty) {
|
||||
bcopy((char *)&sblock, (char *)&altsblock,
|
||||
@ -324,6 +261,12 @@ setup(dev)
|
||||
(unsigned)(maxino + 1));
|
||||
goto badsb;
|
||||
}
|
||||
typemap = calloc((unsigned)(maxino + 1), sizeof(char));
|
||||
if (typemap == NULL) {
|
||||
printf("cannot alloc %u bytes for typemap\n",
|
||||
(unsigned)(maxino + 1));
|
||||
goto badsb;
|
||||
}
|
||||
lncntp = (short *)calloc((unsigned)(maxino + 1), sizeof(short));
|
||||
if (lncntp == NULL) {
|
||||
printf("cannot alloc %u bytes for lncntp\n",
|
||||
@ -384,6 +327,10 @@ readsb(listerr)
|
||||
super *= dev_bsize;
|
||||
dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1);
|
||||
sblk.b_bno = super / dev_bsize;
|
||||
if (bflag) {
|
||||
havesb = 1;
|
||||
return (1);
|
||||
}
|
||||
/*
|
||||
* Set all possible fields that could differ, then do check
|
||||
* of whole super block against an alternate super block.
|
||||
@ -392,10 +339,6 @@ readsb(listerr)
|
||||
getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
|
||||
if (asblk.b_errs)
|
||||
return (0);
|
||||
if (bflag) {
|
||||
havesb = 1;
|
||||
return (1);
|
||||
}
|
||||
altsblock.fs_link = sblock.fs_link;
|
||||
altsblock.fs_rlink = sblock.fs_rlink;
|
||||
altsblock.fs_time = sblock.fs_time;
|
||||
@ -403,7 +346,6 @@ readsb(listerr)
|
||||
altsblock.fs_cgrotor = sblock.fs_cgrotor;
|
||||
altsblock.fs_fmod = sblock.fs_fmod;
|
||||
altsblock.fs_clean = sblock.fs_clean;
|
||||
altsblock.fs_state = sblock.fs_state;
|
||||
altsblock.fs_ronly = sblock.fs_ronly;
|
||||
altsblock.fs_flags = sblock.fs_flags;
|
||||
altsblock.fs_maxcontig = sblock.fs_maxcontig;
|
||||
@ -424,6 +366,10 @@ readsb(listerr)
|
||||
altsblock.fs_interleave = sblock.fs_interleave;
|
||||
altsblock.fs_npsect = sblock.fs_npsect;
|
||||
altsblock.fs_nrpos = sblock.fs_nrpos;
|
||||
altsblock.fs_qbmask = sblock.fs_qbmask;
|
||||
altsblock.fs_qfmask = sblock.fs_qfmask;
|
||||
altsblock.fs_state = sblock.fs_state;
|
||||
altsblock.fs_maxfilesize = sblock.fs_maxfilesize;
|
||||
if (bcmp((char *)&sblock, (char *)&altsblock, (int)sblock.fs_sbsize)) {
|
||||
badsb(listerr,
|
||||
"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
|
||||
@ -441,7 +387,7 @@ badsb(listerr, s)
|
||||
if (!listerr)
|
||||
return;
|
||||
if (preen)
|
||||
printf("%s: ", devname);
|
||||
printf("%s: ", cdevname);
|
||||
pfatal("BAD SUPER BLOCK: %s\n", s);
|
||||
}
|
||||
|
||||
@ -519,20 +465,3 @@ getdisklabel(s, fd)
|
||||
}
|
||||
return (&lab);
|
||||
}
|
||||
|
||||
char *
|
||||
getmntdev(name)
|
||||
char *name;
|
||||
{
|
||||
long mntsize;
|
||||
register long i;
|
||||
struct statfs *mntbuf;
|
||||
|
||||
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
|
||||
for (i = 0; i < mntsize; i++) {
|
||||
if (!strncmp(mntbuf[i].f_fstypename, MOUNT_UFS, MFSNAMELEN) &&
|
||||
!strcmp(mntbuf[i].f_mntonname, name))
|
||||
return (mntbuf[i].f_mntfromname);
|
||||
}
|
||||
return ((char *)0);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,15 +32,15 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)utilities.c 5.30 (Berkeley) 7/26/91";*/
|
||||
static char rcsid[] = "$Id: utilities.c,v 1.8 1994/05/02 10:18:25 pk Exp $";
|
||||
/*static char sccsid[] = "from: @(#)utilities.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: utilities.c,v 1.9 1994/06/08 19:00:33 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
#include <ufs/dir.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ufs/dir.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -49,7 +49,6 @@ static char rcsid[] = "$Id: utilities.c,v 1.8 1994/05/02 10:18:25 pk Exp $";
|
||||
|
||||
long diskreads, totalreads; /* Disk cache statistics */
|
||||
|
||||
int
|
||||
ftypeok(dp)
|
||||
struct dinode *dp;
|
||||
{
|
||||
@ -71,7 +70,6 @@ ftypeok(dp)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
reply(question)
|
||||
char *question;
|
||||
{
|
||||
@ -107,7 +105,6 @@ reply(question)
|
||||
/*
|
||||
* Malloc buffers and set up cache.
|
||||
*/
|
||||
void
|
||||
bufinit()
|
||||
{
|
||||
register struct bufarea *bp;
|
||||
@ -192,7 +189,6 @@ getblk(bp, blk, size)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
flush(fd, bp)
|
||||
int fd;
|
||||
register struct bufarea *bp;
|
||||
@ -218,7 +214,6 @@ flush(fd, bp)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
rwerror(mesg, blk)
|
||||
char *mesg;
|
||||
daddr_t blk;
|
||||
@ -231,12 +226,15 @@ rwerror(mesg, blk)
|
||||
errexit("Program terminated\n");
|
||||
}
|
||||
|
||||
void
|
||||
ckfini()
|
||||
{
|
||||
register struct bufarea *bp, *nbp;
|
||||
int cnt = 0;
|
||||
|
||||
if (fswritefd < 0) {
|
||||
(void)close(fsreadfd);
|
||||
return;
|
||||
}
|
||||
flush(fswritefd, &sblk);
|
||||
if (havesb && sblk.b_bno != SBOFF / dev_bsize &&
|
||||
!preen && reply("UPDATE STANDARD SUPERBLOCK")) {
|
||||
@ -271,20 +269,23 @@ bread(fd, buf, blk, size)
|
||||
{
|
||||
char *cp;
|
||||
int i, errs;
|
||||
off_t offset;
|
||||
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
offset = blk;
|
||||
offset *= dev_bsize;
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
else if (read(fd, buf, (int)size) == size)
|
||||
return (0);
|
||||
rwerror("READ", blk);
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
errs = 0;
|
||||
bzero(buf, (size_t)size);
|
||||
printf("THE FOLLOWING DISK SECTORS COULD NOT BE READ:");
|
||||
for (cp = buf, i = 0; i < size; i += secsize, cp += secsize) {
|
||||
if (read(fd, cp, (int)secsize) != secsize) {
|
||||
(void)lseek(fd, blk * dev_bsize + i + secsize, 0);
|
||||
(void)lseek(fd, offset + i + secsize, 0);
|
||||
if (secsize != dev_bsize && dev_bsize != 1)
|
||||
printf(" %ld (%ld),",
|
||||
(blk * dev_bsize + i) / secsize,
|
||||
@ -306,22 +307,25 @@ bwrite(fd, buf, blk, size)
|
||||
{
|
||||
int i;
|
||||
char *cp;
|
||||
off_t offset;
|
||||
|
||||
if (fd < 0)
|
||||
return;
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
offset = blk;
|
||||
offset *= dev_bsize;
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
else if (write(fd, buf, (int)size) == size) {
|
||||
fsmodified = 1;
|
||||
return;
|
||||
}
|
||||
rwerror("WRITE", blk);
|
||||
if (lseek(fd, blk * dev_bsize, 0) < 0)
|
||||
if (lseek(fd, offset, 0) < 0)
|
||||
rwerror("SEEK", blk);
|
||||
printf("THE FOLLOWING SECTORS COULD NOT BE WRITTEN:");
|
||||
for (cp = buf, i = 0; i < size; i += dev_bsize, cp += dev_bsize)
|
||||
if (write(fd, cp, (int)dev_bsize) != dev_bsize) {
|
||||
(void)lseek(fd, blk * dev_bsize + i + dev_bsize, 0);
|
||||
(void)lseek(fd, offset + i + dev_bsize, 0);
|
||||
printf(" %ld,", blk + i / dev_bsize);
|
||||
}
|
||||
printf("\n");
|
||||
@ -361,7 +365,6 @@ allocblk(frags)
|
||||
/*
|
||||
* Free a previously allocated block
|
||||
*/
|
||||
void
|
||||
freeblk(blkno, frags)
|
||||
daddr_t blkno;
|
||||
long frags;
|
||||
@ -376,7 +379,6 @@ freeblk(blkno, frags)
|
||||
/*
|
||||
* Find a pathname
|
||||
*/
|
||||
void
|
||||
getpathname(namebuf, curdir, ino)
|
||||
char *namebuf;
|
||||
ino_t curdir, ino;
|
||||
@ -387,6 +389,10 @@ getpathname(namebuf, curdir, ino)
|
||||
static int busy = 0;
|
||||
extern int findname();
|
||||
|
||||
if (curdir == ino && ino == ROOTINO) {
|
||||
(void)strcpy(namebuf, "/");
|
||||
return;
|
||||
}
|
||||
if (busy ||
|
||||
(statemap[curdir] != DSTATE && statemap[curdir] != DFOUND)) {
|
||||
(void)strcpy(namebuf, "?");
|
||||
@ -432,7 +438,8 @@ getpathname(namebuf, curdir, ino)
|
||||
void
|
||||
catch()
|
||||
{
|
||||
ckfini();
|
||||
if (!doinglevel2)
|
||||
ckfini();
|
||||
exit(12);
|
||||
}
|
||||
|
||||
@ -522,11 +529,11 @@ pfatal(s, a1, a2, a3)
|
||||
{
|
||||
|
||||
if (preen) {
|
||||
printf("%s: ", devname);
|
||||
printf("%s: ", cdevname);
|
||||
printf(s, a1, a2, a3);
|
||||
printf("\n");
|
||||
printf("%s: UNEXPECTED INCONSISTENCY; RUN fsck MANUALLY.\n",
|
||||
devname);
|
||||
cdevname);
|
||||
exit(8);
|
||||
}
|
||||
printf(s, a1, a2, a3);
|
||||
@ -542,7 +549,7 @@ pwarn(s, a1, a2, a3, a4, a5, a6)
|
||||
{
|
||||
|
||||
if (preen)
|
||||
printf("%s: ", devname);
|
||||
printf("%s: ", cdevname);
|
||||
printf(s, a1, a2, a3, a4, a5, a6);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
# from: @(#)Makefile 5.5 (Berkeley) 5/11/90
|
||||
# $Id: Makefile,v 1.6 1993/10/08 00:51:12 cgd Exp $
|
||||
# from: @(#)Makefile 8.5 (Berkeley) 3/27/94
|
||||
# $Id: Makefile,v 1.7 1994/06/08 19:02:36 mycroft Exp $
|
||||
|
||||
PROG= mount
|
||||
CFLAGS+=-DNFS -DNFSCLIENT
|
||||
SRCS= mount.c mount_ufs.c getmntopts.c
|
||||
MAN8= mount.0
|
||||
MLINKS= mount.8 umount.8
|
||||
# We do NOT install the getmntopts.3 man page.
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
164
sbin/mount/getmntopts.3
Normal file
164
sbin/mount/getmntopts.3
Normal file
@ -0,0 +1,164 @@
|
||||
.\" Copyright (c) 1994
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)getmntopts.3 8.1 (Berkeley) 3/27/94
|
||||
.\" $Id: getmntopts.3,v 1.1 1994/06/08 19:02:37 mycroft Exp $
|
||||
.\"
|
||||
.Dd March 27, 1994
|
||||
.Dt GETMNTOPTS 3
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
.Nm getmntopts
|
||||
.Nd scan mount options
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <mntopts.h>
|
||||
.Ft void
|
||||
.Fn getmntopts "char *options" "struct mntopt *mopts" "int *flagp"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm getmntopts
|
||||
function takes a comma separated option list and a list
|
||||
of valid option names, and computes the bitmask
|
||||
corresponding to the requested set of options.
|
||||
.Pp
|
||||
The string
|
||||
.Dv options
|
||||
is broken down into a sequence of comma separated tokens.
|
||||
Each token is looked up in the table described by
|
||||
.Dv mopts
|
||||
and the bits in
|
||||
the word referenced by
|
||||
.Dv flagp
|
||||
are updated.
|
||||
The flag word is not initialized by
|
||||
.Nm getmntopt .
|
||||
The table,
|
||||
.Dv mopts ,
|
||||
has the following format:
|
||||
.Bd -literal
|
||||
struct mntopt {
|
||||
char *m_option; /* option name */
|
||||
int m_inverse; /* is this a negative option, eg "dev" */
|
||||
int m_flag; /* bit to set, eg MNT_RDONLY */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width m_inverse
|
||||
.It Fa m_option
|
||||
the option name,
|
||||
for example
|
||||
.Dq suid .
|
||||
.It Fa m_inverse
|
||||
tells
|
||||
.Nm getmntopts
|
||||
that the name has the inverse meaning of the
|
||||
bit.
|
||||
For example,
|
||||
.Dq suid
|
||||
is the string, whereas the
|
||||
mount flag is
|
||||
.Dv MNT_NOSUID .
|
||||
In this case, the sense of the string and the flag
|
||||
are inverted, so the
|
||||
.Dv m_inverse
|
||||
flag should be set.
|
||||
.It Fa m_flag
|
||||
the value of the bit to be set or cleared in
|
||||
the flag word when the option is recognized.
|
||||
The bit is set when the option is discovered,
|
||||
but cleared if the option name was preceded
|
||||
by the letters
|
||||
.Dq no .
|
||||
The
|
||||
.Dv m_inverse
|
||||
flag causes these two operations to be reversed.
|
||||
.El
|
||||
.Pp
|
||||
Each of the user visible
|
||||
.Dv MNT_
|
||||
flags has a corresponding
|
||||
.Dv MOPT_
|
||||
macro which defines an appropriate
|
||||
.Li "struct mntopt"
|
||||
entry.
|
||||
To simplify the program interface and ensure consistency across all
|
||||
programs, a general purpose macro,
|
||||
.Dv MOPT_STDOPTS ,
|
||||
is defined which
|
||||
contains an entry for all the generic VFS options.
|
||||
In addition, the macros
|
||||
.Dv MOPT_FORCE
|
||||
and
|
||||
.Dv MOPT_UPDATE
|
||||
exist to enable the
|
||||
.Dv MNT_FORCE
|
||||
and
|
||||
.Dv MNT_UPDATE
|
||||
flags to be set.
|
||||
Finally, the table must be terminated by an entry with a NULL
|
||||
first element.
|
||||
.Sh EXAMPLES
|
||||
Most commands will use the standard option set.
|
||||
Local filesystems which support the
|
||||
.Dv MNT_UPDATE
|
||||
flag, would also have an
|
||||
.Dv MOPT_UPDATE
|
||||
entry.
|
||||
This can be declared and used as follows:
|
||||
.Bd -literal
|
||||
#include "mntopts.h"
|
||||
|
||||
struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_UPDATE,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
...
|
||||
mntflags = 0;
|
||||
...
|
||||
getmntopts(options, mopts, &mntflags)
|
||||
...
|
||||
.Ed
|
||||
.Sh DIAGNOSTICS
|
||||
The
|
||||
.Nm getmntopts
|
||||
function displays an error message and exits if an
|
||||
unrecognized option is encountered.
|
||||
.Sh SEE ALSO
|
||||
.Xr err 3 ,
|
||||
.Xr mount 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn getmntopts
|
||||
function appeared in
|
||||
.Bx 4.4 .
|
88
sbin/mount/getmntopts.c
Normal file
88
sbin/mount/getmntopts.c
Normal file
@ -0,0 +1,88 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)getmntopts.c 8.1 (Berkeley) 3/27/94";*/
|
||||
static char *rcsid = "$Id: getmntopts.c,v 1.1 1994/06/08 19:02:38 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fstab.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mntopts.h"
|
||||
|
||||
void
|
||||
getmntopts(options, m0, flagp)
|
||||
const char *options;
|
||||
const struct mntopt *m0;
|
||||
int *flagp;
|
||||
{
|
||||
const struct mntopt *m;
|
||||
int negative;
|
||||
char *opt, *optbuf;
|
||||
|
||||
/* Copy option string, since it is about to be torn asunder... */
|
||||
if ((optbuf = strdup(options)) == NULL)
|
||||
err(1, NULL);
|
||||
|
||||
for (opt = optbuf; (opt = strtok(opt, ",")) != NULL; opt = NULL) {
|
||||
/* Check for "no" prefix. */
|
||||
if (opt[0] == 'n' && opt[1] == 'o') {
|
||||
negative = 1;
|
||||
opt += 2;
|
||||
} else
|
||||
negative = 0;
|
||||
|
||||
/* Scan option table. */
|
||||
for (m = m0; m->m_option != NULL; ++m)
|
||||
if (strcasecmp(opt, m->m_option) == 0)
|
||||
break;
|
||||
|
||||
/* Save flag, or fail if option is not recognised. */
|
||||
if (m->m_option) {
|
||||
if (negative == m->m_inverse)
|
||||
*flagp |= m->m_flag;
|
||||
else
|
||||
*flagp &= ~m->m_flag;
|
||||
} else
|
||||
errx(1, "-o %s: option not supported", opt);
|
||||
}
|
||||
|
||||
free(optbuf);
|
||||
}
|
78
sbin/mount/mntopts.h
Normal file
78
sbin/mount/mntopts.h
Normal file
@ -0,0 +1,78 @@
|
||||
/*-
|
||||
* Copyright (c) 1994
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* from: @(#)mntopts.h 8.3 (Berkeley) 3/27/94
|
||||
* $Id: mntopts.h,v 1.1 1994/06/08 19:02:39 mycroft Exp $
|
||||
*/
|
||||
|
||||
struct mntopt {
|
||||
const char *m_option; /* option name */
|
||||
int m_inverse; /* if a negative option, eg "dev" */
|
||||
int m_flag; /* bit to set, eg. MNT_RDONLY */
|
||||
};
|
||||
|
||||
/* User-visible MNT_ flags. */
|
||||
#define MOPT_ASYNC { "async", 0, MNT_ASYNC }
|
||||
#define MOPT_NODEV { "dev", 1, MNT_NODEV }
|
||||
#define MOPT_NOEXEC { "exec", 1, MNT_NOEXEC }
|
||||
#define MOPT_NOSUID { "suid", 1, MNT_NOSUID }
|
||||
#define MOPT_RDONLY { "rdonly", 0, MNT_RDONLY }
|
||||
#define MOPT_SYNC { "sync", 0, MNT_SYNCHRONOUS }
|
||||
#define MOPT_UNION { "union", 0, MNT_UNION }
|
||||
|
||||
/* Control flags. */
|
||||
#define MOPT_FORCE { "force", 1, MNT_FORCE }
|
||||
#define MOPT_UPDATE { "update", 0, MNT_UPDATE }
|
||||
#define MOPT_RELOAD { "reload", 0, MNT_RELOAD }
|
||||
|
||||
/* Support for old-style "ro", "rw" flags. */
|
||||
#define MOPT_RO { "ro", 0, MNT_RDONLY }
|
||||
#define MOPT_RW { "rw", 1, MNT_RDONLY }
|
||||
|
||||
/* This is parse by mount(8), but is ignored by specific mount_*(8)s. */
|
||||
#define MOPT_AUTO { "auto", 0, 0 }
|
||||
|
||||
#define MOPT_FSTAB_COMPAT \
|
||||
MOPT_RO, \
|
||||
MOPT_RW, \
|
||||
MOPT_AUTO
|
||||
|
||||
/* Standard options which all mounts can understand. */
|
||||
#define MOPT_STDOPTS \
|
||||
MOPT_FSTAB_COMPAT, \
|
||||
MOPT_NODEV, \
|
||||
MOPT_NOEXEC, \
|
||||
MOPT_NOSUID, \
|
||||
MOPT_RDONLY, \
|
||||
MOPT_UNION
|
||||
|
||||
void getmntopts __P((const char *, const struct mntopt *, int *));
|
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 1980, 1989, 1991 The Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1980, 1989, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -29,35 +29,27 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)mount.8 6.17 (Berkeley) 8/5/91
|
||||
.\" $Id: mount.8,v 1.6 1994/01/05 08:32:10 cgd Exp $
|
||||
.\" from: @(#)mount.8 8.7 (Berkeley) 3/27/94
|
||||
.\" $Id: mount.8,v 1.7 1994/06/08 19:02:42 mycroft Exp $
|
||||
.\"
|
||||
.Dd August 5, 1991
|
||||
.Dd March 27, 1994
|
||||
.Dt MOUNT 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm mount ,
|
||||
.Nm umount
|
||||
.Nd mount and dismount file systems
|
||||
.Nm mount
|
||||
.Nd mount file systems
|
||||
.Sh SYNOPSIS
|
||||
.Nm mount
|
||||
.Op Fl afrwu
|
||||
.Op Fl t Ar nfs | ufs | external_type
|
||||
.Op Fl adfruvw
|
||||
.Op Fl t Ar ufs | lfs | external_type
|
||||
.Nm mount
|
||||
.Op Fl frwu
|
||||
.Ar special| node
|
||||
.Nm mount
|
||||
.Op Fl frwu
|
||||
.Op Fl t Ar nfs | ufs | external_type
|
||||
.Op | Ar external_type
|
||||
.Op Fl o Ar options
|
||||
.Ar special node
|
||||
.Nm umount
|
||||
.Op Fl af
|
||||
.Op Fl t Ar nfs | ufs | external_type
|
||||
.Nm umount
|
||||
.Op Fl f
|
||||
.Op Fl dfruvw
|
||||
.Ar special | node
|
||||
.Nm mount
|
||||
.Op Fl dfruvw
|
||||
.Op Fl o Ar options
|
||||
.Op Fl t Ar ufs | lfs | external_type
|
||||
.Ar special node
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mount
|
||||
@ -65,17 +57,14 @@ command
|
||||
calls the
|
||||
.Xr mount 2
|
||||
system call to prepare and graft a
|
||||
.Ar special
|
||||
device or the remote node
|
||||
(rhost:path)
|
||||
on to the file system tree at the point
|
||||
.Ar node.
|
||||
.Ar "special device"
|
||||
or the remote node (rhost:path) on to the file system tree at the point
|
||||
.Ar node .
|
||||
If either
|
||||
.Ar special
|
||||
or
|
||||
.Ar node
|
||||
are not provided, the appropriate
|
||||
information is taken from the
|
||||
are not provided, the appropriate information is taken from the
|
||||
.Xr fstab 5
|
||||
file.
|
||||
.Pp
|
||||
@ -84,47 +73,61 @@ If no arguments are given to
|
||||
.Nm mount,
|
||||
this list is printed.
|
||||
.Pp
|
||||
Options available for the
|
||||
.Nm mount
|
||||
command:
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl F
|
||||
The standard mount options are parsed and
|
||||
passed to external program via the
|
||||
.Fl F
|
||||
option
|
||||
as a decimal number.
|
||||
(See example below.)
|
||||
.It Fl f
|
||||
Causes everything to be done except for the actual system call; if it's
|
||||
not obvious, this ``fakes'' mounting the file system.
|
||||
.It Fl d
|
||||
Causes everything to be done except for the actual system call.
|
||||
This option is useful in conjunction with the
|
||||
.Fl v
|
||||
flag to
|
||||
determine what the
|
||||
.Nm mount
|
||||
command is trying to do.
|
||||
.It Fl f
|
||||
Forces the revocation of write access when trying to downgrade
|
||||
a filesystem mount status from read-write to read-only.
|
||||
.It Fl o
|
||||
Options are specified with a
|
||||
.Fl o
|
||||
flag
|
||||
followed by a comma separated string of options.
|
||||
The following options apply to any file system that is being mounted:
|
||||
flag followed by a comma separated string of options.
|
||||
The following options are available:
|
||||
.Bl -tag -width indent
|
||||
.It async
|
||||
All
|
||||
.Tn I/O
|
||||
to the file system should be done asynchronously.
|
||||
This is a
|
||||
.Em dangerous
|
||||
flag to set,
|
||||
and should not be used unless you are prepared to recreate the file
|
||||
system should your system crash.
|
||||
.It force
|
||||
The same as
|
||||
.Fl f ;
|
||||
forces the revocation of write access when trying to downgrade
|
||||
a filesystem mount status from read-write to read-only.
|
||||
.It nodev
|
||||
Do not interpret character or block special devices on the file system.
|
||||
This option is useful for a server that has file systems containing
|
||||
special devices for architectures other than its own.
|
||||
.It noexec
|
||||
Do not allow execution of any binaries on the mounted file system.
|
||||
This options is useful for a server that has file systems containing
|
||||
This option is useful for a server that has file systems containing
|
||||
binaries for architectures other than its own.
|
||||
.It nosuid
|
||||
Do not allow set-user-identifier or set-group-identifier bits to take effect.
|
||||
.It nodev
|
||||
Do not interpret character or block special devices on the file system.
|
||||
This options is useful for a server that has file systems containing
|
||||
special devices for architectures other than its own.
|
||||
.It synchronous
|
||||
.It rdonly
|
||||
The same as
|
||||
.Fl r ;
|
||||
mount the file system read-only (even the super-user may not write it).
|
||||
.It sync
|
||||
All
|
||||
.Tn I/O
|
||||
to the file system should be done synchronously.
|
||||
.It update
|
||||
The same as
|
||||
.Fl u ;
|
||||
indicate that the status of an already mounted file system should be changed.
|
||||
.It union
|
||||
Causes the namespace at the mount point to appear as the union
|
||||
of the mounted filesystem root and the existing directory.
|
||||
@ -133,15 +136,50 @@ If those operations fail due to a non-existent file the underlying
|
||||
directory is then accessed.
|
||||
All creates are done in the mounted filesystem.
|
||||
.El
|
||||
.Pp
|
||||
Any additional options specific to a filesystem type that is not
|
||||
one of the internally known types (see the
|
||||
.Fl t
|
||||
option) may be passed as a comma separated list; these options are
|
||||
distinguished by a leading
|
||||
.Dq \&-
|
||||
(dash).
|
||||
Options that take a value are specified using the syntax -option=value.
|
||||
For example, the mount command:
|
||||
.Bd -literal -offset indent
|
||||
mount -t mfs -o nosuid,-N,-s=4000 /dev/dk0b /tmp
|
||||
.Ed
|
||||
.Pp
|
||||
causes
|
||||
.Nm mount
|
||||
to execute the equivalent of:
|
||||
.Bd -literal -offset indent
|
||||
/sbin/mount_mfs -o nosuid -N -s 4000 /dev/dk0b /tmp
|
||||
.Ed
|
||||
.It Fl r
|
||||
The file system object is to be mounted read-only.
|
||||
.It Fl t Ar "nfs \\*(Ba ufs \\*(Ba external type"
|
||||
The file system is to be mounted read-only.
|
||||
Mount the file system read-only (even the super-user may not write it).
|
||||
The same as the
|
||||
.Dq rdonly
|
||||
argument to the
|
||||
.Fl o
|
||||
option.
|
||||
.It Fl t Ar "ufs \\*(Ba lfs \\*(Ba external type"
|
||||
The argument following the
|
||||
.Fl t
|
||||
is used to indicate the file system type.
|
||||
The type
|
||||
.Ar ufs
|
||||
is the default.
|
||||
The \fI-t\fP option can be used
|
||||
to indicate that the actions should only be taken on
|
||||
filesystems of the specified type.
|
||||
More than one type may be specified in a comma separated list.
|
||||
The list of filesystem types can be prefixed with
|
||||
.Dq no
|
||||
to specify the filesystem types for which action should
|
||||
.Em not
|
||||
be taken.
|
||||
For example, the
|
||||
.Nm mount
|
||||
command:
|
||||
@ -160,6 +198,8 @@ mount will attempt to execute a program in
|
||||
where
|
||||
.Em XXX
|
||||
is replaced by the type name.
|
||||
For example, nfs filesystems are mounted by the program
|
||||
.Pa /sbin/mount_nfs .
|
||||
.It Fl u
|
||||
The
|
||||
.Fl u
|
||||
@ -169,7 +209,12 @@ Any of the options discussed above (the
|
||||
.Fl o
|
||||
option)
|
||||
may be changed;
|
||||
also a file system can be changed from read-only to read-write.
|
||||
also a file system can be changed from read-only to read-write
|
||||
or vice versa.
|
||||
An attempt to change from read-write to read-only will fail if any
|
||||
files on the filesystem are currently open for writing unless the
|
||||
.Fl f
|
||||
flag is also specified.
|
||||
The set of options is determined by first extracting the options
|
||||
for the file system from the
|
||||
.Xr fstab
|
||||
@ -186,112 +231,10 @@ option.
|
||||
Verbose mode.
|
||||
.It Fl w
|
||||
The file system object is to be read and write.
|
||||
.It Fl
|
||||
Any additional options specific to the program can
|
||||
be passed as a comma separated list;
|
||||
these options are distinguished by starting with a
|
||||
.Fl
|
||||
(dash).
|
||||
.El
|
||||
.Pp
|
||||
Those options that take a value are specified
|
||||
using the syntax -option=value.
|
||||
For example, the mount command:
|
||||
.Bd -literal -offset indent
|
||||
mount -t mfs -o nosuid,-N,-s=4000 /dev/dk0b /tmp
|
||||
.Ed
|
||||
.Pp
|
||||
causes mount to attempt to execute:
|
||||
.Bd -literal -offset indent
|
||||
/sbin/mount_mfs -F 8 -N -s 4000 /dev/dk0b /tmp
|
||||
.Ed
|
||||
.Pp
|
||||
The following list can be used to override
|
||||
the defaults for an nfs mount:
|
||||
.Bl -tag -width indent
|
||||
.It hard
|
||||
.Tn I/O
|
||||
system calls will retry until the server responds (default)
|
||||
.It soft
|
||||
.Tn I/O
|
||||
system calls will fail and return errno after
|
||||
.Em retrans
|
||||
request
|
||||
retransmissions
|
||||
.It spongy
|
||||
Soft semantics for the stat, lookup, fsstat, readlink and readdir
|
||||
filesystem operations and hard semantics for the others.
|
||||
This option is meant to be similar to hard,
|
||||
except that processes will not be hung forever when
|
||||
they trip over mount points to dead servers.
|
||||
.It bg
|
||||
If the first mount request times out, do retries in background
|
||||
.It intr
|
||||
.Tn I/O
|
||||
system calls can be interrupted.
|
||||
.It noconn
|
||||
Do not connect the socket.
|
||||
Used for
|
||||
.Tn UDP
|
||||
servers that send replies from a
|
||||
socket other than the nfs server socket.
|
||||
.It tcp
|
||||
Use
|
||||
.Tn TCP
|
||||
transport instead of
|
||||
.Tn UDP .
|
||||
.It rsize=#
|
||||
Set read size to
|
||||
.Ar #
|
||||
bytes.
|
||||
.It wsize=#
|
||||
Set write size to
|
||||
.Ar #
|
||||
bytes.
|
||||
.It retry=#
|
||||
Set mount retry count to
|
||||
.Ar # .
|
||||
.It retrans=#
|
||||
Set retransmission count for nfs rpc's to
|
||||
.Ar # .
|
||||
.It timeo=#
|
||||
Set initial nfs timeout to
|
||||
.Ar #
|
||||
in 0.1 sec intervals.
|
||||
.El
|
||||
.Pp
|
||||
.Nm Umount
|
||||
removes the
|
||||
.Ar special
|
||||
device
|
||||
grafted
|
||||
at point
|
||||
.Ar node
|
||||
from file system tree.
|
||||
.Pp
|
||||
Options for the
|
||||
.Nm umount
|
||||
command:
|
||||
.Bl -tag -width indent
|
||||
.It Fl f
|
||||
The file system is forcibly unmounted.
|
||||
Active special devices continue to work,
|
||||
but all other files return errors if further accesses are attempted.
|
||||
The root file system cannot be forcibly unmounted.
|
||||
.It Fl a
|
||||
All of the file systems described in
|
||||
.Xr fstab
|
||||
are unmounted.
|
||||
.It Fl t
|
||||
Is used to indicate the actions should only be taken on
|
||||
filesystems of the specified type.
|
||||
More than one type may be specified in a comma separated list.
|
||||
The list of filesystem types can be prefixed with ``no'' to
|
||||
specify the filesystem types on which no action should be taken.
|
||||
(See example above for the
|
||||
.Nm mount
|
||||
command.)
|
||||
.El
|
||||
The options specific to NFS filesystems are described in the
|
||||
.Xr mount_nfs 8
|
||||
manual page.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/fstab -compact
|
||||
.It Pa /etc/fstab
|
||||
@ -299,13 +242,24 @@ file system table
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr fstab 5 ,
|
||||
.Xr mount_XXX 8
|
||||
.Xr mount_cd9660 8 ,
|
||||
.Xr mount_fdesc 8 ,
|
||||
.Xr mount_kernfs 8 ,
|
||||
.Xr mount_lfs 8 ,
|
||||
.Xr mount_lofs 8 ,
|
||||
.Xr mount_mfs 8 ,
|
||||
.Xr mount_nfs 8 ,
|
||||
.Xr mount_null 8 ,
|
||||
.Xr mount_portal 8 ,
|
||||
.Xr mount_procfs 8 ,
|
||||
.Xr mount_umap 8 ,
|
||||
.Xr mount_union 8 ,
|
||||
.Xr umount 8
|
||||
.Sh BUGS
|
||||
It is possible for a corrupted file system to cause a crash.
|
||||
.Sh HISTORY
|
||||
A
|
||||
.Nm
|
||||
.Nm mount
|
||||
command appeared in
|
||||
.At v6 .
|
||||
|
1075
sbin/mount/mount.c
1075
sbin/mount/mount.c
File diff suppressed because it is too large
Load Diff
133
sbin/mount/mount_ufs.c
Normal file
133
sbin/mount/mount_ufs.c
Normal file
@ -0,0 +1,133 @@
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)mount_ufs.c 8.2 (Berkeley) 3/27/94";*/
|
||||
static char *rcsid = "$Id: mount_ufs.c,v 1.1 1994/06/08 19:02:45 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mntopts.h"
|
||||
|
||||
void ufs_usage __P((void));
|
||||
|
||||
static struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_ASYNC,
|
||||
MOPT_SYNC,
|
||||
MOPT_UPDATE,
|
||||
MOPT_RELOAD,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
int
|
||||
mount_ufs(argc, argv)
|
||||
int argc;
|
||||
char * const argv[];
|
||||
{
|
||||
extern int optreset;
|
||||
struct ufs_args args;
|
||||
int ch, mntflags;
|
||||
char *fs_name;
|
||||
|
||||
mntflags = 0;
|
||||
optind = optreset = 1; /* Reset for parse of new argv. */
|
||||
while ((ch = getopt(argc, argv, "o:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
ufs_usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
ufs_usage();
|
||||
|
||||
args.fspec = argv[0]; /* The name of the device file. */
|
||||
fs_name = argv[1]; /* The mount point. */
|
||||
|
||||
#define DEFAULT_ROOTUID -2
|
||||
args.export.ex_root = DEFAULT_ROOTUID;
|
||||
if (mntflags & MNT_RDONLY)
|
||||
args.export.ex_flags = MNT_EXRDONLY;
|
||||
else
|
||||
args.export.ex_flags = 0;
|
||||
|
||||
if (mount(MOUNT_UFS, fs_name, mntflags, &args) < 0) {
|
||||
(void)fprintf(stderr, "%s on %s: ", args.fspec, fs_name);
|
||||
switch (errno) {
|
||||
case EMFILE:
|
||||
(void)fprintf(stderr, "mount table full.\n");
|
||||
break;
|
||||
case EINVAL:
|
||||
if (mntflags & MNT_UPDATE)
|
||||
(void)fprintf(stderr,
|
||||
"Specified device does not match mounted device.\n");
|
||||
else
|
||||
(void)fprintf(stderr,
|
||||
"Incorrect super block.\n");
|
||||
break;
|
||||
default:
|
||||
(void)fprintf(stderr, "%s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
ufs_usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: mount_ufs [-o options] special node\n");
|
||||
exit(1);
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -30,10 +30,10 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)pathnames.h 6.4 (Berkeley) 6/1/90
|
||||
* $Id: pathnames.h,v 1.4 1993/08/01 18:26:29 mycroft Exp $
|
||||
* from: @(#)pathnames.h 8.2 (Berkeley) 3/27/94
|
||||
* $Id: pathnames.h,v 1.5 1994/06/08 19:02:46 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define _PATH_EXECDIR "/sbin"
|
||||
#define _PATH_EXPORTS "/etc/exports"
|
||||
#define _PATH_SBIN "/sbin"
|
||||
#define _PATH_USRSBIN "/usr/sbin"
|
||||
#define _PATH_MOUNTDPID "/var/run/mountd.pid"
|
||||
|
12
sbin/mount_cd9660/Makefile
Normal file
12
sbin/mount_cd9660/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# from: @(#)Makefile 8.3 (Berkeley) 3/27/94
|
||||
# $Id: Makefile,v 1.1 1994/06/08 19:08:27 mycroft Exp $
|
||||
|
||||
PROG= mount_cd9660
|
||||
SRCS= mount_cd9660.c getmntopts.c
|
||||
MAN8= mount_cd9660.0
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
101
sbin/mount_cd9660/mount_cd9660.8
Normal file
101
sbin/mount_cd9660/mount_cd9660.8
Normal file
@ -0,0 +1,101 @@
|
||||
.\" Copyright (c) 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software donated to Berkeley by
|
||||
.\" Christopher G. Demetriou.
|
||||
.\"
|
||||
.\" 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)mount_cd9660.8 8.3 (Berkeley) 3/27/94
|
||||
.\" $Id: mount_cd9660.8,v 1.1 1994/06/08 19:07:36 mycroft Exp $
|
||||
.\"
|
||||
.Dd March 27, 1994
|
||||
.Dt MOUNT_CD9660 8
|
||||
.Os BSD 4
|
||||
.Sh NAME
|
||||
.Nm mount_cd9660
|
||||
.Nd mount an ISO-9660 filesystem
|
||||
.Sh SYNOPSIS
|
||||
.Nm mount_cd9660
|
||||
.Op Fl egr
|
||||
.Op Fl o Ar options
|
||||
.Ar special | node
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mount_cd9660
|
||||
command attaches the ISO-9660 filesystem residing on the device
|
||||
.Pa special
|
||||
to the global filesystem namespace at the location indicated by
|
||||
.Pa node .
|
||||
This command is normally executed by
|
||||
.Xr mount 8
|
||||
at boot time.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl e
|
||||
Enable the use of extended attributes.
|
||||
.It Fl g
|
||||
Do not strip version numbers on files.
|
||||
(By default, if there are files with different version numbers on the disk,
|
||||
only the last one will be listed.)
|
||||
In either case, files may be opened without explicitly stating a
|
||||
version number.
|
||||
.It Fl o
|
||||
Options are specified with a
|
||||
.Fl o
|
||||
flag followed by a comma separated string of options.
|
||||
See the
|
||||
.Xr mount 8
|
||||
man page for possible options and their meanings.
|
||||
.It Fl r
|
||||
Do not use any Rockridge extensions included in the filesystem.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr fstab 5 ,
|
||||
.Xr mount 8
|
||||
.Sh BUGS
|
||||
The cd9660 filesystem does not support the original "High Sierra"
|
||||
("CDROM001") format.
|
||||
.Pp
|
||||
POSIX device node mapping is currently not supported.
|
||||
.Pp
|
||||
Version numbers are not stripped if Rockridge extensions are in use.
|
||||
In this case, accessing files that don't have Rockridge names without
|
||||
version numbers gets the one with the lowest version number and not
|
||||
the one with the highest.
|
||||
.Pp
|
||||
There is no ECMA support.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm mount_cd9660
|
||||
utility first appeared 4.4BSD.
|
128
sbin/mount_cd9660/mount_cd9660.c
Normal file
128
sbin/mount_cd9660/mount_cd9660.c
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
|
||||
* Support code is derived from software contributed to Berkeley
|
||||
* by Atsushi Murai (amurai@spec.co.jp).
|
||||
*
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1992, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)mount_cd9660.c 8.4 (Berkeley) 3/27/94";*/
|
||||
static char *rcsid = "$Id: mount_cd9660.c,v 1.1 1994/06/08 19:07:37 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#define CD9660
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mntopts.h"
|
||||
|
||||
struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_UPDATE,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
struct iso_args args;
|
||||
int ch, mntflags, opts;
|
||||
char *dev, *dir;
|
||||
|
||||
mntflags = opts = 0;
|
||||
while ((ch = getopt(argc, argv, "ego:r")) != EOF)
|
||||
switch (ch) {
|
||||
case 'e':
|
||||
opts |= ISOFSMNT_EXTATT;
|
||||
break;
|
||||
case 'g':
|
||||
opts |= ISOFSMNT_GENS;
|
||||
break;
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags);
|
||||
break;
|
||||
case 'r':
|
||||
opts |= ISOFSMNT_NORRIP;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
dev = argv[0];
|
||||
dir = argv[1];
|
||||
|
||||
#define DEFAULT_ROOTUID -2
|
||||
args.fspec = dev;
|
||||
args.export.ex_root = DEFAULT_ROOTUID;
|
||||
|
||||
if (mntflags & MNT_RDONLY)
|
||||
args.export.ex_flags = MNT_EXRDONLY;
|
||||
else
|
||||
args.export.ex_flags = 0;
|
||||
args.flags = opts;
|
||||
|
||||
if (mount(MOUNT_CD9660, dir, mntflags, &args) < 0)
|
||||
err(1, NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: mount_cd9660 [-egrt] [-o options] special node\n");
|
||||
exit(1);
|
||||
}
|
@ -1,7 +1,12 @@
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.3 1994/01/12 19:01:00 cgd Exp $
|
||||
# from: @(#)Makefile 8.2 (Berkeley) 3/27/94
|
||||
# $Id: Makefile,v 1.4 1994/06/08 19:11:36 mycroft Exp $
|
||||
|
||||
PROG= mount_fdesc
|
||||
SRCS= mount_fdesc.c getmntopts.c
|
||||
MAN8= mount_fdesc.0
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1992, 1993
|
||||
.\" Copyright (c) 1992, 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
@ -34,10 +34,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)mount_fdesc.8 8.1 (Berkeley) 6/9/93
|
||||
.\" $Id: mount_fdesc.8,v 1.2 1994/01/12 19:01:12 cgd Exp $
|
||||
.\" from: @(#)mount_fdesc.8 8.2 (Berkeley) 3/27/94
|
||||
.\" $Id: mount_fdesc.8,v 1.3 1994/06/08 19:11:37 mycroft Exp $
|
||||
.\"
|
||||
.Dd June 9, 1993
|
||||
.Dd March 27, 1994
|
||||
.Dt MOUNT_FDESC 8
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
@ -45,9 +45,9 @@
|
||||
.Nd mount the file-descriptor file system
|
||||
.Sh SYNOPSIS
|
||||
.Nm mount_fdesc
|
||||
.Op Fl F Ar fsoptions
|
||||
.Pa fdesc
|
||||
.Pa mount_point
|
||||
.Op Fl o Ar options
|
||||
.Ar fdesc
|
||||
.Ar mount_point
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mount_fdesc
|
||||
@ -62,6 +62,17 @@ This command is normally executed by
|
||||
.Xr mount 8
|
||||
at boot time.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl o
|
||||
Options are specified with a
|
||||
.Fl o
|
||||
flag followed by a comma separated string of options.
|
||||
See the
|
||||
.Xr mount 8
|
||||
man page for possible options and their meanings.
|
||||
.El
|
||||
.Pp
|
||||
The contents of the mount point are
|
||||
.Pa fd ,
|
||||
.Pa stderr ,
|
||||
@ -135,7 +146,8 @@ the real controlling terminal device.
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr tty 4 ,
|
||||
.Xr fstab 5
|
||||
.Xr fstab 5 ,
|
||||
.Xr mount 8
|
||||
.Sh CAVEATS
|
||||
No
|
||||
.Pa .
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1990, 1992 Jan-Simon Pendry
|
||||
* Copyright (c) 1992, 1993
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
@ -33,21 +33,36 @@
|
||||
* 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.
|
||||
*
|
||||
* from: @(#)mount_fdesc.c 8.1 (Berkeley) 6/5/93
|
||||
* $Id: mount_fdesc.c,v 1.4 1994/01/12 19:01:21 cgd Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1992, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)mount_fdesc.c 8.2 (Berkeley) 3/27/94";*/
|
||||
static char *rcsid = "$Id: mount_fdesc.c,v 1.5 1994/06/08 19:11:38 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void usage __P((void));
|
||||
#include "mntopts.h"
|
||||
|
||||
struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -57,10 +72,10 @@ main(argc, argv)
|
||||
int ch, mntflags;
|
||||
|
||||
mntflags = 0;
|
||||
while ((ch = getopt(argc, argv, "F:")) != EOF)
|
||||
switch(ch) {
|
||||
case 'F':
|
||||
mntflags = atoi(optarg);
|
||||
while ((ch = getopt(argc, argv, "o:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
@ -72,10 +87,8 @@ main(argc, argv)
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
if (mount(MOUNT_FDESC, argv[1], mntflags, NULL)) {
|
||||
(void)fprintf(stderr, "mount_fdesc: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (mount(MOUNT_FDESC, argv[1], mntflags, NULL))
|
||||
err(1, NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -83,6 +96,6 @@ void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: mount_fdesc [ -F fsoptions ] /dev/fd mount_point\n");
|
||||
"usage: mount_fdesc [-o options] fdesc mount_point\n");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -1,7 +1,12 @@
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.3 1994/01/12 19:11:02 cgd Exp $
|
||||
# from: @(#)Makefile 8.2 (Berkeley) 3/27/94
|
||||
# $Id: Makefile,v 1.4 1994/06/08 19:15:25 mycroft Exp $
|
||||
|
||||
PROG= mount_kernfs
|
||||
SRCS= mount_kernfs.c getmntopts.c
|
||||
MAN8= mount_kernfs.0
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\"
|
||||
.\" Copyright (c) 1992, 1993
|
||||
.\" Copyright (c) 1992, 1993, 1994
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
@ -34,10 +34,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)mount_kernfs.8 8.1 (Berkeley) 6/9/93
|
||||
.\" $Id: mount_kernfs.8,v 1.3 1994/01/12 19:11:09 cgd Exp $
|
||||
.\" from: @(#)mount_kernfs.8 8.2 (Berkeley) 3/27/94
|
||||
.\" $Id: mount_kernfs.8,v 1.4 1994/06/08 19:15:26 mycroft Exp $
|
||||
.\"
|
||||
.Dd June 9, 1993
|
||||
.Dd March 27, 1994
|
||||
.Dt MOUNT_KERNFS 8
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
@ -45,9 +45,9 @@
|
||||
.Nd mount the /kern file system
|
||||
.Sh SYNOPSIS
|
||||
.Nm mount_kernfs
|
||||
.Op Fl F Ar fsoptions
|
||||
.Pa /kern
|
||||
.Pa mount_point
|
||||
.Op Fl o Ar options
|
||||
.Ar /kern
|
||||
.Ar mount_point
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mount_kern
|
||||
@ -64,6 +64,17 @@ some of which can also be written.
|
||||
The contents of the files is in a machine-independent format,
|
||||
either a string, or an integer in decimal ASCII.
|
||||
Where numbers are returned, a trailing newline character is also added.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width indent
|
||||
.It Fl o
|
||||
Options are specified with a
|
||||
.Fl o
|
||||
flag followed by a comma separated string of options.
|
||||
See the
|
||||
.Xr mount 8
|
||||
man page for possible options and their meanings.
|
||||
.El
|
||||
.Sh FILES
|
||||
.Bl -tag -width copyright -compact
|
||||
.It Pa boottime
|
||||
@ -80,23 +91,23 @@ the frequency of the system clock (decimal ASCII).
|
||||
the 1, 5 and 15 minute load average in kernel fixed-point format.
|
||||
The final integer is the fix-point scaling factor.
|
||||
All numbers are in decimal ASCII.
|
||||
.\" .It Pa pagesize
|
||||
.\" the machine pagesize (decimal ASCII).
|
||||
.It Pa pagesize
|
||||
the machine pagesize (decimal ASCII).
|
||||
.It Pa physmem
|
||||
the number of pages of physical memory in the machine (decimal ASCII).
|
||||
.\" .It Pa root
|
||||
.\" the system root directory.
|
||||
.\" In a chroot'ed environment,
|
||||
.\" .Nm
|
||||
.\" can be used to create a new
|
||||
.\" .Pa /kern
|
||||
.\" mount point.
|
||||
.\" .Pa /kern/root
|
||||
.\" will then refer to the system global root, not the current process root.
|
||||
.It Pa root
|
||||
the system root directory.
|
||||
In a chroot'ed environment,
|
||||
.Nm
|
||||
can be used to create a new
|
||||
.Pa /kern
|
||||
mount point.
|
||||
.Pa /kern/root
|
||||
will then refer to the system global root, not the current process root.
|
||||
.It Pa rootdev
|
||||
the root device.
|
||||
.\" .It Pa rrootdev
|
||||
.\" the raw root device.
|
||||
.It Pa rrootdev
|
||||
the raw root device.
|
||||
.It Pa time
|
||||
the second and microsecond value of the system clock.
|
||||
Both numbers are in decimal ASCII.
|
||||
@ -110,7 +121,8 @@ can be generated by running:
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr fstab 5
|
||||
.Xr fstab 5 ,
|
||||
.Xr mount 8
|
||||
.Sh CAVEATS
|
||||
This filesystem may not be NFS-exported.
|
||||
.Sh HISTORY
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1990, 1992 Jan-Simon Pendry
|
||||
* Copyright (c) 1992, 1993
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
@ -33,21 +33,36 @@
|
||||
* 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.
|
||||
*
|
||||
* from: @(#)mount_kernfs.c 8.1 (Berkeley) 6/5/93
|
||||
* $Id: mount_kernfs.c,v 1.4 1994/01/12 19:11:10 cgd Exp $
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1992, 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)mount_kernfs.c 8.2 (Berkeley) 3/27/94";*/
|
||||
static char *rcsid = "$Id: mount_kernfs.c,v 1.5 1994/06/08 19:15:27 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <err.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
void usage __P((void));
|
||||
#include "mntopts.h"
|
||||
|
||||
struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
@ -57,10 +72,10 @@ main(argc, argv)
|
||||
int ch, mntflags;
|
||||
|
||||
mntflags = 0;
|
||||
while ((ch = getopt(argc, argv, "F:")) != EOF)
|
||||
switch(ch) {
|
||||
case 'F':
|
||||
mntflags = atoi(optarg);
|
||||
while ((ch = getopt(argc, argv, "o:")) != EOF)
|
||||
switch (ch) {
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
@ -72,10 +87,8 @@ main(argc, argv)
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
if (mount(MOUNT_KERNFS, argv[1], mntflags, NULL)) {
|
||||
(void)fprintf(stderr, "mount_kernfs: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
if (mount(MOUNT_KERNFS, argv[1], mntflags, NULL))
|
||||
err(1, NULL);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
@ -83,6 +96,6 @@ void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: mount_kernfs [ -F fsoptions ] /kern mount_point\n");
|
||||
"usage: mount_kernfs [-o options] /kern mount_point\n");
|
||||
exit(1);
|
||||
}
|
||||
|
12
sbin/mount_lfs/Makefile
Normal file
12
sbin/mount_lfs/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# from: @(#)Makefile 8.2 (Berkeley) 3/27/94
|
||||
# $Id: Makefile,v 1.1 1994/06/08 19:15:55 mycroft Exp $
|
||||
|
||||
PROG= mount_lfs
|
||||
SRCS= mount_lfs.c getmntopts.c
|
||||
MAN8= mount_lfs.0
|
||||
|
||||
MOUNT= ${.CURDIR}/../mount
|
||||
CFLAGS+= -I${MOUNT}
|
||||
.PATH: ${MOUNT}
|
||||
|
||||
.include <bsd.prog.mk>
|
126
sbin/mount_lfs/mount_lfs.8
Normal file
126
sbin/mount_lfs/mount_lfs.8
Normal file
@ -0,0 +1,126 @@
|
||||
.\" Copyright (c) 1993, 1994
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)mount_lfs.8 8.5 (Berkeley) 3/30/94
|
||||
.\" $Id: mount_lfs.8,v 1.1 1994/06/08 19:15:56 mycroft Exp $
|
||||
.\"
|
||||
.Dd "March 30, 1994"
|
||||
.Dt MOUNT_LFS 8
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
.Nm mount_lfs
|
||||
.Nd mount a log-structured file system
|
||||
.Sh SYNOPSIS
|
||||
.Nm mount_lfs
|
||||
.Op Fl dns
|
||||
.Op Fl o Ar options
|
||||
.Ar special
|
||||
.Ar node
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm mount_lfs
|
||||
command attaches a log-structured file system
|
||||
.Ar special
|
||||
device on to the file system tree at the point
|
||||
.Ar node .
|
||||
In addition, the
|
||||
.Xr lfs_cleanerd 8
|
||||
utility is invoked to clean the file system periodically.
|
||||
.Pp
|
||||
This command is normally executed by
|
||||
.Xr mount 8
|
||||
at boot time.
|
||||
.Pp
|
||||
The options are as follows:
|
||||
.Bl -tag -width Ds
|
||||
.It Fl d
|
||||
Run
|
||||
.Xr lfs_cleanerd 8
|
||||
in debug mode.
|
||||
.It Fl o
|
||||
Options are specified with a
|
||||
.Fl o
|
||||
flag followed by a comma separated string of options.
|
||||
See the
|
||||
.Xr mount 8
|
||||
man page for possible options and their meanings.
|
||||
.It Fl n
|
||||
Don't start
|
||||
.Xr lfs_cleanerd 8
|
||||
on the file system.
|
||||
.It Fl s
|
||||
Cause
|
||||
.Xr lfs_cleanerd 8
|
||||
to read data in small chunks when cleaning the file system.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr mount 2 ,
|
||||
.Xr unmount 2 ,
|
||||
.Xr fstab 5 ,
|
||||
.Xr lfs_cleanerd 8 ,
|
||||
.Xr mount 8
|
||||
.sp
|
||||
.Rs
|
||||
.%A Ousterhout and Douglis
|
||||
.%D 1989
|
||||
.%T "Beating the I/O Bottleneck: A Case for Log-structured File Systems"
|
||||
.%J "Operating Systems Review"
|
||||
.%V Vol. 23
|
||||
.%N No. 1
|
||||
.%P pp. 11-27
|
||||
.%O "also available as Technical Report UCB/CSD 88/467"
|
||||
.Re
|
||||
.Rs
|
||||
.%A Rosenblum and Ousterhout
|
||||
.%D 1991
|
||||
.%T "The Design and Implementation of a Log-Structured File System"
|
||||
.%J "ACM SIGOPS Operating Systems Review"
|
||||
.%V Vol. 25
|
||||
.%N No. 5
|
||||
.Re
|
||||
.Rs
|
||||
.%A Seltzer
|
||||
.%D 1992
|
||||
.%T "File System Performance and Transaction Support"
|
||||
.%B "PhD Thesis, University of California, Berkeley"
|
||||
.%O "also available as Technical Report UCB/ERL M92"
|
||||
.Re
|
||||
.Rs
|
||||
.%A Seltzer, Bostic, McKusick and Staelin
|
||||
.%D 1993
|
||||
.%T "An Implementation of a Log-Structured File System for UNIX"
|
||||
.%J "Proc. of the Winter 1993 USENIX Conf."
|
||||
.%P pp. 315-331
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm mount_lfs
|
||||
function first appeared in 4.4BSD.
|
148
sbin/mount_lfs/mount_lfs.c
Normal file
148
sbin/mount_lfs/mount_lfs.c
Normal file
@ -0,0 +1,148 @@
|
||||
/*-
|
||||
* Copyright (c) 1993, 1994
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1993, 1994\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)mount_lfs.c 8.3 (Berkeley) 3/27/94";*/
|
||||
static char *rcsid = "$Id: mount_lfs.c,v 1.1 1994/06/08 19:15:57 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "mntopts.h"
|
||||
#include "pathnames.h"
|
||||
|
||||
struct mntopt mopts[] = {
|
||||
MOPT_STDOPTS,
|
||||
MOPT_UPDATE,
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
void usage __P((void));
|
||||
void invoke_cleaner __P((char *));
|
||||
|
||||
int short_rds, cleaner_debug;
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
struct ufs_args args;
|
||||
int ch, mntflags, noclean;
|
||||
char *fs_name, *options;
|
||||
|
||||
options = NULL;
|
||||
mntflags = noclean = 0;
|
||||
while ((ch = getopt(argc, argv, "dno:s")) != EOF)
|
||||
switch (ch) {
|
||||
case 'd':
|
||||
cleaner_debug = 1;
|
||||
break;
|
||||
case 'n':
|
||||
noclean = 1;
|
||||
break;
|
||||
case 'o':
|
||||
getmntopts(optarg, mopts, &mntflags);
|
||||
break;
|
||||
case 's':
|
||||
short_rds = 1;
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 2)
|
||||
usage();
|
||||
|
||||
args.fspec = argv[0]; /* the name of the device file */
|
||||
fs_name = argv[1]; /* the mount point */
|
||||
|
||||
#define DEFAULT_ROOTUID -2
|
||||
args.export.ex_root = DEFAULT_ROOTUID;
|
||||
if (mntflags & MNT_RDONLY)
|
||||
args.export.ex_flags = MNT_EXRDONLY;
|
||||
else
|
||||
args.export.ex_flags = 0;
|
||||
|
||||
if (mount(MOUNT_LFS, fs_name, mntflags, &args))
|
||||
err(1, NULL);
|
||||
|
||||
if (!noclean)
|
||||
invoke_cleaner(fs_name);
|
||||
/* NOTREACHED */
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
invoke_cleaner(name)
|
||||
char *name;
|
||||
{
|
||||
char *args[6], **ap = args;
|
||||
|
||||
/* Build the argument list. */
|
||||
*ap++ = _PATH_LFS_CLEANERD;
|
||||
if (short_rds)
|
||||
*ap++ = "-s";
|
||||
if (cleaner_debug)
|
||||
*ap++ = "-d";
|
||||
*ap++ = name;
|
||||
*ap = NULL;
|
||||
|
||||
execv(args[0], args);
|
||||
err(1, "exec %s", _PATH_LFS_CLEANERD);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"usage: mount_lfs [-dns] [-o options] special node\n");
|
||||
exit(1);
|
||||
}
|
37
sbin/mount_lfs/pathnames.h
Normal file
37
sbin/mount_lfs/pathnames.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*-
|
||||
* Copyright (c) 1993
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* from: @(#)pathnames.h 8.1 (Berkeley) 6/8/93
|
||||
* $Id: pathnames.h,v 1.1 1994/06/08 19:15:59 mycroft Exp $
|
||||
*/
|
||||
|
||||
#define _PATH_LFS_CLEANERD "/usr/libexec/lfs_cleanerd"
|
@ -1,5 +1,5 @@
|
||||
# from: @(#)Makefile 5.3 (Berkeley) 5/11/90
|
||||
# $Id: Makefile,v 1.4 1993/08/01 05:38:06 mycroft Exp $
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/5/93
|
||||
# $Id: Makefile,v 1.5 1994/06/08 18:58:21 mycroft Exp $
|
||||
|
||||
PROG= dumpfs
|
||||
MAN8= dumpfs.0
|
||||
|
@ -1,5 +1,5 @@
|
||||
.\" Copyright (c) 1983, 1991 Regents of the University of California.
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -29,10 +29,10 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" from: @(#)dumpfs.8 6.2 (Berkeley) 3/16/91
|
||||
.\" $Id: dumpfs.8,v 1.4 1993/08/01 07:39:20 mycroft Exp $
|
||||
.\" from: @(#)dumpfs.8 8.1 (Berkeley) 6/5/93
|
||||
.\" $Id: dumpfs.8,v 1.5 1994/06/08 18:58:22 mycroft Exp $
|
||||
.\"
|
||||
.Dd March 16, 1991
|
||||
.Dd June 5, 1993
|
||||
.Dt DUMPFS 8
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1983 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 1983, 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
@ -32,27 +32,29 @@
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
char copyright[] =
|
||||
"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
|
||||
All rights reserved.\n";
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1983, 1992, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)dumpfs.c 5.10 (Berkeley) 6/1/90";*/
|
||||
static char rcsid[] = "$Id: dumpfs.c,v 1.5 1994/04/25 18:23:19 cgd Exp $";
|
||||
/*static char sccsid[] = "from: @(#)dumpfs.c 8.2 (Berkeley) 2/2/94";*/
|
||||
static char *rcsid = "$Id: dumpfs.c,v 1.6 1994/06/08 18:58:23 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <ufs/dinode.h>
|
||||
#include <ufs/fs.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/ffs/fs.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <fstab.h>
|
||||
|
||||
/*
|
||||
* dumpfs
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
union {
|
||||
struct fs fs;
|
||||
@ -68,46 +70,60 @@ union {
|
||||
|
||||
long dev_bsize = 1;
|
||||
|
||||
int dumpfs __P((char *));
|
||||
int dumpcg __P((char *, int, int));
|
||||
void pbits __P((void *, int));
|
||||
void usage __P((void));
|
||||
|
||||
int
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
register struct fstab *fs;
|
||||
int ch, eval;
|
||||
|
||||
argc--, argv++;
|
||||
if (argc < 1) {
|
||||
fprintf(stderr, "usage: dumpfs fs ...\n");
|
||||
exit(1);
|
||||
}
|
||||
for (; argc > 0; argv++, argc--) {
|
||||
fs = getfsfile(*argv);
|
||||
if (fs == 0)
|
||||
dumpfs(*argv);
|
||||
while ((ch = getopt(argc, argv, "")) != EOF)
|
||||
switch(ch) {
|
||||
case '?':
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc < 1)
|
||||
usage();
|
||||
|
||||
for (eval = 0; *argv; ++argv)
|
||||
if ((fs = getfsfile(*argv)) == NULL)
|
||||
eval |= dumpfs(*argv);
|
||||
else
|
||||
dumpfs(fs->fs_spec);
|
||||
}
|
||||
eval |= dumpfs(fs->fs_spec);
|
||||
exit(eval);
|
||||
}
|
||||
|
||||
int
|
||||
dumpfs(name)
|
||||
char *name;
|
||||
{
|
||||
int c, i, j, k, size;
|
||||
int fd, c, i, j, k, size;
|
||||
|
||||
if ((fd = open(name, O_RDONLY, 0)) < 0)
|
||||
goto err;
|
||||
if (lseek(fd, (off_t)SBOFF, SEEK_SET) == (off_t)-1)
|
||||
goto err;
|
||||
if (read(fd, &afs, SBSIZE) != SBSIZE)
|
||||
goto err;
|
||||
|
||||
close(0);
|
||||
if (open(name, 0) != 0) {
|
||||
perror(name);
|
||||
return;
|
||||
}
|
||||
lseek(0, SBOFF, 0);
|
||||
if (read(0, &afs, SBSIZE) != SBSIZE) {
|
||||
perror(name);
|
||||
return;
|
||||
}
|
||||
if (afs.fs_postblformat == FS_42POSTBLFMT)
|
||||
afs.fs_nrpos = 8;
|
||||
dev_bsize = afs.fs_fsize / fsbtodb(&afs, 1);
|
||||
printf("magic\t%x\tformat\t%s\ttime\t%s", afs.fs_magic,
|
||||
afs.fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic",
|
||||
printf("magic\t%x\ttime\t%s", afs.fs_magic,
|
||||
ctime(&afs.fs_time));
|
||||
printf("cylgrp\t%s\tinodes\t%s\n",
|
||||
afs.fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic",
|
||||
afs.fs_inodefmt < FS_44INODEFMT ? "4.2/4.3BSD" : "4.4BSD");
|
||||
printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n",
|
||||
afs.fs_cstotal.cs_nbfree, afs.fs_cstotal.cs_ndir,
|
||||
afs.fs_cstotal.cs_nifree, afs.fs_cstotal.cs_nffree);
|
||||
@ -128,8 +144,9 @@ dumpfs(name)
|
||||
afs.fs_rotdelay, afs.fs_headswitch, afs.fs_trkseek, afs.fs_rps);
|
||||
printf("ntrak\t%d\tnsect\t%d\tnpsect\t%d\tspc\t%d\n",
|
||||
afs.fs_ntrak, afs.fs_nsect, afs.fs_npsect, afs.fs_spc);
|
||||
printf("trackskew %d\tinterleave %d\n",
|
||||
afs.fs_trackskew, afs.fs_interleave);
|
||||
printf("symlinklen %d\ttrackskew %d\tinterleave %d\tcontigsumsize %d\n",
|
||||
afs.fs_maxsymlinklen, afs.fs_trackskew, afs.fs_interleave,
|
||||
afs.fs_contigsumsize);
|
||||
printf("nindir\t%d\tinopb\t%d\tnspf\t%d\n",
|
||||
afs.fs_nindir, afs.fs_inopb, afs.fs_nspf);
|
||||
printf("sblkno\t%d\tcblkno\t%d\tiblkno\t%d\tdblkno\t%d\n",
|
||||
@ -165,13 +182,13 @@ dumpfs(name)
|
||||
for (i = 0, j = 0; i < afs.fs_cssize; i += afs.fs_bsize, j++) {
|
||||
size = afs.fs_cssize - i < afs.fs_bsize ?
|
||||
afs.fs_cssize - i : afs.fs_bsize;
|
||||
afs.fs_csp[j] = (struct csum *)calloc(1, size);
|
||||
lseek(0, fsbtodb(&afs, (afs.fs_csaddr + j * afs.fs_frag)) *
|
||||
dev_bsize, 0);
|
||||
if (read(0, afs.fs_csp[j], size) != size) {
|
||||
perror(name);
|
||||
return;
|
||||
}
|
||||
afs.fs_csp[j] = calloc(1, size);
|
||||
if (lseek(fd,
|
||||
(off_t)(fsbtodb(&afs, (afs.fs_csaddr + j * afs.fs_frag)) *
|
||||
dev_bsize), SEEK_SET) == (off_t)-1)
|
||||
goto err;
|
||||
if (read(fd, afs.fs_csp[j], size) != size)
|
||||
goto err;
|
||||
}
|
||||
for (i = 0; i < afs.fs_ncg; i++) {
|
||||
struct csum *cs = &afs.fs_cs(&afs, i);
|
||||
@ -189,27 +206,37 @@ dumpfs(name)
|
||||
}
|
||||
printf("\n");
|
||||
for (i = 0; i < afs.fs_ncg; i++)
|
||||
dumpcg(name, i);
|
||||
close(0);
|
||||
if (dumpcg(name, fd, i))
|
||||
goto err;
|
||||
(void)close(fd);
|
||||
return (0);
|
||||
|
||||
err: if (fd != -1)
|
||||
(void)close(fd);
|
||||
(void)fprintf(stderr, "dumpfs: %s: %s\n", name, strerror(errno));
|
||||
return (1);
|
||||
};
|
||||
|
||||
dumpcg(name, c)
|
||||
int
|
||||
dumpcg(name, fd, c)
|
||||
char *name;
|
||||
int c;
|
||||
int fd, c;
|
||||
{
|
||||
int i,j;
|
||||
off_t cur;
|
||||
int i, j;
|
||||
|
||||
printf("\ncg %d:\n", c);
|
||||
lseek(0, fsbtodb(&afs, cgtod(&afs, c)) * dev_bsize, 0);
|
||||
i = lseek(0, 0, 1);
|
||||
if (read(0, (char *)&acg, afs.fs_bsize) != afs.fs_bsize) {
|
||||
printf("dumpfs: %s: error reading cg\n", name);
|
||||
return;
|
||||
if ((cur = lseek(fd, (off_t)(fsbtodb(&afs, cgtod(&afs, c)) * dev_bsize),
|
||||
SEEK_SET)) == (off_t)-1)
|
||||
return (1);
|
||||
if (read(fd, &acg, afs.fs_bsize) != afs.fs_bsize) {
|
||||
(void)fprintf(stderr, "dumpfs: %s: error reading cg\n", name);
|
||||
return (1);
|
||||
}
|
||||
printf("magic\t%x\ttell\t%x\ttime\t%s",
|
||||
printf("magic\t%x\ttell\t%qx\ttime\t%s",
|
||||
afs.fs_postblformat == FS_42POSTBLFMT ?
|
||||
((struct ocg *)&acg)->cg_magic : acg.cg_magic,
|
||||
i, ctime(&acg.cg_time));
|
||||
cur, ctime(&acg.cg_time));
|
||||
printf("cgx\t%d\tncyl\t%d\tniblk\t%d\tndblk\t%d\n",
|
||||
acg.cg_cgx, acg.cg_ncyl, acg.cg_niblk, acg.cg_ndblk);
|
||||
printf("nbfree\t%d\tndir\t%d\tnifree\t%d\tnffree\t%d\n",
|
||||
@ -221,7 +248,23 @@ dumpcg(name, c)
|
||||
printf("\t%d", acg.cg_frsum[i]);
|
||||
j += i * acg.cg_frsum[i];
|
||||
}
|
||||
printf("\nsum of frsum: %d\niused:\t", j);
|
||||
printf("\nsum of frsum: %d", j);
|
||||
if (afs.fs_contigsumsize > 0) {
|
||||
for (i = 1; i < afs.fs_contigsumsize; i++) {
|
||||
if ((i - 1) % 8 == 0)
|
||||
printf("\nclusters %d-%d:", i,
|
||||
afs.fs_contigsumsize - 1 < i + 7 ?
|
||||
afs.fs_contigsumsize - 1 : i + 7);
|
||||
printf("\t%d", cg_clustersum(&acg)[i]);
|
||||
}
|
||||
printf("\nclusters size %d and over: %d\n",
|
||||
afs.fs_contigsumsize,
|
||||
cg_clustersum(&acg)[afs.fs_contigsumsize]);
|
||||
printf("clusters free:\t");
|
||||
pbits(cg_clustersfree(&acg), acg.cg_nclusterblks);
|
||||
} else
|
||||
printf("\n");
|
||||
printf("iused:\t");
|
||||
pbits(cg_inosused(&acg), afs.fs_ipg);
|
||||
printf("free:\t");
|
||||
pbits(cg_blksfree(&acg), afs.fs_fpg);
|
||||
@ -238,26 +281,36 @@ dumpcg(name, c)
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
return (0);
|
||||
};
|
||||
|
||||
pbits(cp, max)
|
||||
register char *cp;
|
||||
void
|
||||
pbits(vp, max)
|
||||
register void *vp;
|
||||
int max;
|
||||
{
|
||||
register int i;
|
||||
int count = 0, j;
|
||||
register char *p;
|
||||
int count, j;
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
if (isset(cp, i)) {
|
||||
for (count = i = 0, p = vp; i < max; i++)
|
||||
if (isset(p, i)) {
|
||||
if (count)
|
||||
printf(",%s", count % 6 ? " " : "\n\t");
|
||||
count++;
|
||||
printf("%d", i);
|
||||
j = i;
|
||||
while ((i+1)<max && isset(cp, i+1))
|
||||
while ((i+1)<max && isset(p, i+1))
|
||||
i++;
|
||||
if (i != j)
|
||||
printf("-%d", i);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: dumpfs filesys | device\n");
|
||||
exit(1);
|
||||
}
|
||||
|
10
usr.sbin/dumplfs/Makefile
Normal file
10
usr.sbin/dumplfs/Makefile
Normal file
@ -0,0 +1,10 @@
|
||||
# from: @(#)Makefile 8.1 (Berkeley) 6/18/93
|
||||
# $Id: Makefile,v 1.1 1994/06/08 18:58:47 mycroft Exp $
|
||||
|
||||
PROG= dumplfs
|
||||
CFLAGS+=-I/sys/ufs/lfs
|
||||
SRCS= dumplfs.c lfs_cksum.c misc.c
|
||||
.PATH: /sys/ufs/lfs
|
||||
MAN8= dumplfs.0
|
||||
|
||||
.include <bsd.prog.mk>
|
60
usr.sbin/dumplfs/dumplfs.8
Normal file
60
usr.sbin/dumplfs/dumplfs.8
Normal file
@ -0,0 +1,60 @@
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. 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 the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
.\"
|
||||
.\" from: @(#)dumplfs.8 8.1 (Berkeley) 6/18/93
|
||||
.\" $Id: dumplfs.8,v 1.1 1994/06/08 18:58:48 mycroft Exp $
|
||||
.\"
|
||||
.Dd June 18, 1993
|
||||
.Dt DUMPLFS 8
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
.Nm dumplfs
|
||||
.Nd dump file system information
|
||||
.Sh SYNOPSIS
|
||||
.Nm dumplfs
|
||||
.Op Ar filesys No \&| Ar device
|
||||
.Sh DESCRIPTION
|
||||
.Nm Dumplfs
|
||||
prints out the file system layout information for the
|
||||
LFS file system or special device specified.
|
||||
The listing is very long and detailed.
|
||||
This command is useful mostly for finding out certain file system
|
||||
information such as the file system block size.
|
||||
.Sh SEE ALSO
|
||||
.Xr fs 5 ,
|
||||
.Xr disktab 5 ,
|
||||
.Xr disklabel 8 ,
|
||||
.Xr newlfs 8 ,
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm dumplfs
|
||||
command appeared in
|
||||
.Bx 4.4 .
|
613
usr.sbin/dumplfs/dumplfs.c
Normal file
613
usr.sbin/dumplfs/dumplfs.c
Normal file
@ -0,0 +1,613 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char copyright[] =
|
||||
"@(#) Copyright (c) 1991, 1993\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif /* not lint */
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)dumplfs.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: dumplfs.c,v 1.1 1994/06/08 18:58:50 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <ufs/ufs/dinode.h>
|
||||
#include <ufs/lfs/lfs.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <fstab.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "extern.h"
|
||||
|
||||
static void addseg __P((char *));
|
||||
static void dump_cleaner_info __P((struct lfs *, void *));
|
||||
static void dump_dinode __P((struct dinode *));
|
||||
static void dump_ifile __P((int, struct lfs *, int));
|
||||
static int dump_ipage_ifile __P((int, IFILE *, int));
|
||||
static int dump_ipage_segusage __P((struct lfs *, int, IFILE *, int));
|
||||
static void dump_segment __P((int, int, daddr_t, struct lfs *, int));
|
||||
static int dump_sum __P((int, struct lfs *, SEGSUM *, int, daddr_t));
|
||||
static void dump_super __P((struct lfs *));
|
||||
static void usage __P((void));
|
||||
|
||||
typedef struct seglist SEGLIST;
|
||||
struct seglist {
|
||||
SEGLIST *next;
|
||||
int num;
|
||||
};
|
||||
SEGLIST *seglist;
|
||||
|
||||
int daddr_shift;
|
||||
char *special;
|
||||
|
||||
/* Segment Usage formats */
|
||||
#define print_suheader \
|
||||
(void)printf("segnum\tflags\tnbytes\tninos\tnsums\tlastmod\n")
|
||||
|
||||
#define print_suentry(i, sp) \
|
||||
(void)printf("%d\t%c%c%c\t%d\t%d\t%d\t%s", i, \
|
||||
(((sp)->su_flags & SEGUSE_ACTIVE) ? 'A' : ' '), \
|
||||
(((sp)->su_flags & SEGUSE_DIRTY) ? 'D' : 'C'), \
|
||||
(((sp)->su_flags & SEGUSE_SUPERBLOCK) ? 'S' : ' '), \
|
||||
(sp)->su_nbytes, (sp)->su_ninos, (sp)->su_nsums, \
|
||||
ctime((time_t *)&(sp)->su_lastmod))
|
||||
|
||||
/* Ifile formats */
|
||||
#define print_iheader \
|
||||
(void)printf("inum\tstatus\tversion\tdaddr\t\tfreeptr\n")
|
||||
#define print_ientry(i, ip) \
|
||||
if (ip->if_daddr == LFS_UNUSED_DADDR) \
|
||||
(void)printf("%d\tFREE\t%d\t \t\t%d\n", \
|
||||
i, ip->if_version, ip->if_nextfree); \
|
||||
else \
|
||||
(void)printf("%d\tINUSE\t%d\t%8X \n", \
|
||||
i, ip->if_version, ip->if_daddr)
|
||||
int
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
struct lfs lfs_sb1, lfs_sb2, *lfs_master;
|
||||
daddr_t seg_addr;
|
||||
int ch, do_allsb, do_ientries, fd, segnum;
|
||||
|
||||
do_allsb = 0;
|
||||
do_ientries = 0;
|
||||
while ((ch = getopt(argc, argv, "ais:")) != EOF)
|
||||
switch(ch) {
|
||||
case 'a': /* Dump all superblocks */
|
||||
do_allsb = 1;
|
||||
break;
|
||||
case 'i': /* Dump ifile entries */
|
||||
do_ientries = 1;
|
||||
break;
|
||||
case 's': /* Dump out these segments */
|
||||
addseg(optarg);
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
}
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc != 1)
|
||||
usage();
|
||||
|
||||
special = argv[0];
|
||||
if ((fd = open(special, O_RDONLY, 0)) < 0)
|
||||
err("%s: %s", special, strerror(errno));
|
||||
|
||||
/* Read the first superblock */
|
||||
get(fd, LFS_LABELPAD, &lfs_sb1, sizeof(struct lfs));
|
||||
daddr_shift = lfs_sb1.lfs_bshift - lfs_sb1.lfs_fsbtodb;
|
||||
|
||||
/*
|
||||
* Read the second superblock and figure out which check point is
|
||||
* most up to date.
|
||||
*/
|
||||
get(fd,
|
||||
lfs_sb1.lfs_sboffs[1] << daddr_shift, &lfs_sb2, sizeof(struct lfs));
|
||||
|
||||
lfs_master = &lfs_sb1;
|
||||
if (lfs_sb1.lfs_tstamp < lfs_sb2.lfs_tstamp)
|
||||
lfs_master = &lfs_sb2;
|
||||
|
||||
(void)printf("Master Superblock:\n");
|
||||
dump_super(lfs_master);
|
||||
|
||||
dump_ifile(fd, lfs_master, do_ientries);
|
||||
|
||||
if (seglist != NULL)
|
||||
for (; seglist != NULL; seglist = seglist->next) {
|
||||
seg_addr = lfs_master->lfs_sboffs[0] + seglist->num *
|
||||
(lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb);
|
||||
dump_segment(fd,
|
||||
seglist->num, seg_addr, lfs_master, do_allsb);
|
||||
}
|
||||
else
|
||||
for (segnum = 0, seg_addr = lfs_master->lfs_sboffs[0];
|
||||
segnum < lfs_master->lfs_nseg; segnum++, seg_addr +=
|
||||
lfs_master->lfs_ssize << lfs_master->lfs_fsbtodb)
|
||||
dump_segment(fd,
|
||||
segnum, seg_addr, lfs_master, do_allsb);
|
||||
|
||||
(void)close(fd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We are reading all the blocks of an inode and dumping out the ifile table.
|
||||
* This code could be tighter, but this is a first pass at getting the stuff
|
||||
* printed out rather than making this code incredibly efficient.
|
||||
*/
|
||||
static void
|
||||
dump_ifile(fd, lfsp, do_ientries)
|
||||
int fd;
|
||||
struct lfs *lfsp;
|
||||
int do_ientries;
|
||||
{
|
||||
IFILE *ipage;
|
||||
struct dinode *dip, *dpage;
|
||||
daddr_t addr, *addrp, *dindir, *iaddrp, *indir;
|
||||
int block_limit, i, inum, j, nblocks, nsupb, psize;
|
||||
|
||||
psize = lfsp->lfs_bsize;
|
||||
addr = lfsp->lfs_idaddr;
|
||||
|
||||
if (!(dpage = malloc(psize)))
|
||||
err("%s", strerror(errno));
|
||||
get(fd, addr << daddr_shift, dpage, psize);
|
||||
|
||||
for (dip = dpage + INOPB(lfsp) - 1; dip >= dpage; --dip)
|
||||
if (dip->di_inumber == LFS_IFILE_INUM)
|
||||
break;
|
||||
|
||||
if (dip < dpage)
|
||||
err("unable to locate ifile inode");
|
||||
|
||||
(void)printf("\nIFILE inode\n");
|
||||
dump_dinode(dip);
|
||||
|
||||
(void)printf("\nIFILE contents\n");
|
||||
nblocks = dip->di_size >> lfsp->lfs_bshift;
|
||||
block_limit = MIN(nblocks, NDADDR);
|
||||
|
||||
/* Get the direct block */
|
||||
if ((ipage = malloc(psize)) == NULL)
|
||||
err("%s", strerror(errno));
|
||||
for (inum = 0, addrp = dip->di_db, i = 0; i < block_limit;
|
||||
i++, addrp++) {
|
||||
get(fd, *addrp << daddr_shift, ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
print_suheader;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i < (lfsp->lfs_segtabsz + lfsp->lfs_cleansz)) {
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
if (!inum)
|
||||
if(!do_ientries)
|
||||
goto e0;
|
||||
else
|
||||
print_iheader;
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb);
|
||||
|
||||
}
|
||||
|
||||
if (nblocks <= NDADDR)
|
||||
goto e0;
|
||||
|
||||
/* Dump out blocks off of single indirect block */
|
||||
if (!(indir = malloc(psize)))
|
||||
err("%s", strerror(errno));
|
||||
get(fd, dip->di_ib[0] << daddr_shift, indir, psize);
|
||||
block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
|
||||
for (addrp = indir; i < block_limit; i++, addrp++) {
|
||||
if (*addrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, *addrp << daddr_shift,ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
continue;
|
||||
} else
|
||||
i -= lfsp->lfs_cleansz;
|
||||
|
||||
if (i < lfsp->lfs_segtabsz) {
|
||||
inum = dump_ipage_segusage(lfsp, inum, ipage,
|
||||
lfsp->lfs_sepb);
|
||||
if (!inum)
|
||||
if(!do_ientries)
|
||||
goto e1;
|
||||
else
|
||||
print_iheader;
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum, ipage, lfsp->lfs_ifpb);
|
||||
}
|
||||
|
||||
if (nblocks <= lfsp->lfs_nindir * lfsp->lfs_ifpb)
|
||||
goto e1;
|
||||
|
||||
/* Get the double indirect block */
|
||||
if (!(dindir = malloc(psize)))
|
||||
err("%s", strerror(errno));
|
||||
get(fd, dip->di_ib[1] << daddr_shift, dindir, psize);
|
||||
for (iaddrp = dindir, j = 0; j < lfsp->lfs_nindir; j++, iaddrp++) {
|
||||
if (*iaddrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, *iaddrp << daddr_shift, indir, psize);
|
||||
block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
|
||||
for (addrp = indir; i < block_limit; i++, addrp++) {
|
||||
if (*addrp == LFS_UNUSED_DADDR)
|
||||
break;
|
||||
get(fd, *addrp << daddr_shift, ipage, psize);
|
||||
if (i < lfsp->lfs_cleansz) {
|
||||
dump_cleaner_info(lfsp, ipage);
|
||||
continue;
|
||||
} else
|
||||
i -= lfsp->lfs_cleansz;
|
||||
|
||||
if (i < lfsp->lfs_segtabsz) {
|
||||
inum = dump_ipage_segusage(lfsp,
|
||||
inum, ipage, lfsp->lfs_sepb);
|
||||
if (!inum)
|
||||
if(!do_ientries)
|
||||
goto e2;
|
||||
else
|
||||
print_iheader;
|
||||
} else
|
||||
inum = dump_ipage_ifile(inum,
|
||||
ipage, lfsp->lfs_ifpb);
|
||||
}
|
||||
}
|
||||
e2: free(dindir);
|
||||
e1: free(indir);
|
||||
e0: free(dpage);
|
||||
free(ipage);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_ipage_ifile(i, pp, tot)
|
||||
int i;
|
||||
IFILE *pp;
|
||||
int tot;
|
||||
{
|
||||
IFILE *ip;
|
||||
int cnt, max;
|
||||
|
||||
max = i + tot;
|
||||
|
||||
for (ip = pp, cnt = i; cnt < max; cnt++, ip++)
|
||||
print_ientry(cnt, ip);
|
||||
return (max);
|
||||
}
|
||||
|
||||
static int
|
||||
dump_ipage_segusage(lfsp, i, pp, tot)
|
||||
struct lfs *lfsp;
|
||||
int i;
|
||||
IFILE *pp;
|
||||
int tot;
|
||||
{
|
||||
SEGUSE *sp;
|
||||
int cnt, max;
|
||||
|
||||
max = i + tot;
|
||||
for (sp = (SEGUSE *)pp, cnt = i;
|
||||
cnt < lfsp->lfs_nseg && cnt < max; cnt++, sp++)
|
||||
print_suentry(cnt, sp);
|
||||
if (max >= lfsp->lfs_nseg)
|
||||
return (0);
|
||||
else
|
||||
return (max);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_dinode(dip)
|
||||
struct dinode *dip;
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)printf("%s%d\t%s%d\t%s%d\t%s%d\t%s%d\n",
|
||||
"mode ", dip->di_mode,
|
||||
"nlink ", dip->di_nlink,
|
||||
"uid ", dip->di_uid,
|
||||
"gid ", dip->di_gid,
|
||||
"size ", dip->di_size);
|
||||
(void)printf("%s%s%s%s%s%s",
|
||||
"atime ", ctime(&dip->di_atime.ts_sec),
|
||||
"mtime ", ctime(&dip->di_mtime.ts_sec),
|
||||
"ctime ", ctime(&dip->di_ctime.ts_sec));
|
||||
(void)printf("inum %d\n", dip->di_inumber);
|
||||
(void)printf("Direct Addresses\n");
|
||||
for (i = 0; i < NDADDR; i++) {
|
||||
(void)printf("\t0x%X", dip->di_db[i]);
|
||||
if ((i % 6) == 5)
|
||||
(void)printf("\n");
|
||||
}
|
||||
for (i = 0; i < NIADDR; i++)
|
||||
(void)printf("\t0x%X", dip->di_ib[i]);
|
||||
(void)printf("\n");
|
||||
}
|
||||
|
||||
static int
|
||||
dump_sum(fd, lfsp, sp, segnum, addr)
|
||||
struct lfs *lfsp;
|
||||
SEGSUM *sp;
|
||||
int fd, segnum;
|
||||
daddr_t addr;
|
||||
{
|
||||
FINFO *fp;
|
||||
long *dp;
|
||||
int i, j;
|
||||
int ck;
|
||||
int numblocks;
|
||||
struct dinode *inop;
|
||||
|
||||
if (sp->ss_sumsum != (ck = cksum(&sp->ss_datasum,
|
||||
LFS_SUMMARY_SIZE - sizeof(sp->ss_sumsum)))) {
|
||||
(void)printf("dumplfs: %s %d address 0x%lx\n",
|
||||
"corrupt summary block; segment", segnum, addr);
|
||||
return(0);
|
||||
}
|
||||
|
||||
(void)printf("Segment Summary Info at 0x%lx\n", addr);
|
||||
(void)printf(" %s0x%X\t%s%d\t%s%d\n %s0x%X\t%s0x%X",
|
||||
"next ", sp->ss_next,
|
||||
"nfinfo ", sp->ss_nfinfo,
|
||||
"ninos ", sp->ss_ninos,
|
||||
"sumsum ", sp->ss_sumsum,
|
||||
"datasum ", sp->ss_datasum );
|
||||
(void)printf("\tcreate %s", ctime((time_t *)&sp->ss_create));
|
||||
|
||||
numblocks = (sp->ss_ninos + INOPB(lfsp) - 1) / INOPB(lfsp);
|
||||
|
||||
/* Dump out inode disk addresses */
|
||||
dp = (daddr_t *)sp;
|
||||
dp += LFS_SUMMARY_SIZE / sizeof(daddr_t);
|
||||
inop = malloc(1 << lfsp->lfs_bshift);
|
||||
printf(" Inode addresses:");
|
||||
for (dp--, i = 0; i < sp->ss_ninos; dp--) {
|
||||
printf("\t0x%X {", *dp);
|
||||
get(fd, *dp << (lfsp->lfs_bshift - lfsp->lfs_fsbtodb), inop,
|
||||
(1 << lfsp->lfs_bshift));
|
||||
for (j = 0; i < sp->ss_ninos && j < INOPB(lfsp); j++, i++) {
|
||||
if (j > 0)
|
||||
(void)printf(", ");
|
||||
(void)printf("%d", inop[j].di_inumber);
|
||||
}
|
||||
(void)printf("}");
|
||||
if (((i/INOPB(lfsp)) % 4) == 3)
|
||||
(void)printf("\n");
|
||||
}
|
||||
free(inop);
|
||||
|
||||
printf("\n");
|
||||
for (fp = (FINFO *)(sp + 1), i = 0; i < sp->ss_nfinfo; i++) {
|
||||
numblocks += fp->fi_nblocks;
|
||||
(void)printf(" FINFO for inode: %d version %d nblocks %d\n",
|
||||
fp->fi_ino, fp->fi_version, fp->fi_nblocks);
|
||||
dp = &(fp->fi_blocks[0]);
|
||||
for (j = 0; j < fp->fi_nblocks; j++, dp++) {
|
||||
(void)printf("\t%d", *dp);
|
||||
if ((j % 8) == 7)
|
||||
(void)printf("\n");
|
||||
}
|
||||
if ((j % 8) != 0)
|
||||
(void)printf("\n");
|
||||
fp = (FINFO *)dp;
|
||||
}
|
||||
return (numblocks);
|
||||
}
|
||||
|
||||
static void
|
||||
dump_segment(fd, segnum, addr, lfsp, dump_sb)
|
||||
int fd, segnum;
|
||||
daddr_t addr;
|
||||
struct lfs *lfsp;
|
||||
int dump_sb;
|
||||
{
|
||||
struct lfs lfs_sb, *sbp;
|
||||
SEGSUM *sump;
|
||||
char sumblock[LFS_SUMMARY_SIZE];
|
||||
int did_one, nblocks, sb;
|
||||
off_t sum_offset, super_off;
|
||||
|
||||
(void)printf("\nSEGMENT %d (Disk Address 0x%X)\n",
|
||||
addr >> (lfsp->lfs_segshift - daddr_shift), addr);
|
||||
sum_offset = (addr << (lfsp->lfs_bshift - lfsp->lfs_fsbtodb));
|
||||
|
||||
sb = 0;
|
||||
did_one = 0;
|
||||
do {
|
||||
get(fd, sum_offset, sumblock, LFS_SUMMARY_SIZE);
|
||||
sump = (SEGSUM *)sumblock;
|
||||
if (sump->ss_sumsum != cksum (&sump->ss_datasum,
|
||||
LFS_SUMMARY_SIZE - sizeof(sump->ss_sumsum))) {
|
||||
sbp = (struct lfs *)sump;
|
||||
if (sb = (sbp->lfs_magic == LFS_MAGIC)) {
|
||||
super_off = sum_offset;
|
||||
sum_offset += LFS_SBPAD;
|
||||
} else if (did_one)
|
||||
break;
|
||||
else {
|
||||
printf("Segment at 0x%X corrupt\n", addr);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
nblocks = dump_sum(fd, lfsp, sump, segnum, sum_offset >>
|
||||
(lfsp->lfs_bshift - lfsp->lfs_fsbtodb));
|
||||
if (nblocks)
|
||||
sum_offset += LFS_SUMMARY_SIZE +
|
||||
(nblocks << lfsp->lfs_bshift);
|
||||
else
|
||||
sum_offset = 0;
|
||||
did_one = 1;
|
||||
}
|
||||
} while (sum_offset);
|
||||
|
||||
if (dump_sb && sb) {
|
||||
get(fd, super_off, &lfs_sb, sizeof(struct lfs));
|
||||
dump_super(&lfs_sb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_super(lfsp)
|
||||
struct lfs *lfsp;
|
||||
{
|
||||
int i;
|
||||
|
||||
(void)printf("%s0x%X\t%s0x%X\t%s%d\t%s%d\n",
|
||||
"magic ", lfsp->lfs_magic,
|
||||
"version ", lfsp->lfs_version,
|
||||
"size ", lfsp->lfs_size,
|
||||
"ssize ", lfsp->lfs_ssize);
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"dsize ", lfsp->lfs_dsize,
|
||||
"bsize ", lfsp->lfs_bsize,
|
||||
"fsize ", lfsp->lfs_fsize,
|
||||
"frag ", lfsp->lfs_frag);
|
||||
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"minfree ", lfsp->lfs_minfree,
|
||||
"inopb ", lfsp->lfs_inopb,
|
||||
"ifpb ", lfsp->lfs_ifpb,
|
||||
"nindir ", lfsp->lfs_nindir);
|
||||
|
||||
(void)printf("%s%d\t\t%s%d\t%s%d\t%s%d\n",
|
||||
"nseg ", lfsp->lfs_nseg,
|
||||
"nspf ", lfsp->lfs_nspf,
|
||||
"cleansz ", lfsp->lfs_cleansz,
|
||||
"segtabsz ", lfsp->lfs_segtabsz);
|
||||
|
||||
(void)printf("%s0x%X\t%s%d\t%s0x%X\t%s%d\n",
|
||||
"segmask ", lfsp->lfs_segmask,
|
||||
"segshift ", lfsp->lfs_segshift,
|
||||
"bmask ", lfsp->lfs_bmask,
|
||||
"bshift ", lfsp->lfs_bshift);
|
||||
|
||||
(void)printf("%s0x%X\t\t%s%d\t%s0x%X\t%s%d\n",
|
||||
"ffmask ", lfsp->lfs_ffmask,
|
||||
"ffshift ", lfsp->lfs_ffshift,
|
||||
"fbmask ", lfsp->lfs_fbmask,
|
||||
"fbshift ", lfsp->lfs_fbshift);
|
||||
|
||||
(void)printf("%s%d\t%s%d\t%s0x%X\t%s0x%qx\n",
|
||||
"sushift ", lfsp->lfs_sushift,
|
||||
"fsbtodb ", lfsp->lfs_fsbtodb,
|
||||
"cksum ", lfsp->lfs_cksum,
|
||||
"maxfilesize ", lfsp->lfs_maxfilesize);
|
||||
|
||||
(void)printf("Superblock disk addresses:\t");
|
||||
for (i = 0; i < LFS_MAXNUMSB; i++) {
|
||||
(void)printf(" 0x%X", lfsp->lfs_sboffs[i]);
|
||||
if ( i == (LFS_MAXNUMSB >> 1))
|
||||
(void)printf("\n\t\t\t\t");
|
||||
}
|
||||
(void)printf("\n");
|
||||
|
||||
(void)printf("Checkpoint Info\n");
|
||||
(void)printf("%s%d\t%s0x%X\t%s%d\n",
|
||||
"free ", lfsp->lfs_free,
|
||||
"idaddr ", lfsp->lfs_idaddr,
|
||||
"ifile ", lfsp->lfs_ifile);
|
||||
(void)printf("%s%d\t%s%d\t%s%d\n",
|
||||
"bfree ", lfsp->lfs_bfree,
|
||||
"avail ", lfsp->lfs_avail,
|
||||
"uinodes ", lfsp->lfs_uinodes);
|
||||
(void)printf("%s%d\t%s0x%X\t%s0x%X\n%s0x%X\t%s0x%X\t",
|
||||
"nfiles ", lfsp->lfs_nfiles,
|
||||
"lastseg ", lfsp->lfs_lastseg,
|
||||
"nextseg ", lfsp->lfs_nextseg,
|
||||
"curseg ", lfsp->lfs_curseg,
|
||||
"offset ", lfsp->lfs_offset);
|
||||
(void)printf("tstamp %s", ctime((time_t *)&lfsp->lfs_tstamp));
|
||||
(void)printf("\nIn-Memory Information\n");
|
||||
(void)printf("%s%d\t%s0x%X\t%s%d%s%d\t%s%d\n",
|
||||
"seglock ", lfsp->lfs_seglock,
|
||||
"iocount ", lfsp->lfs_iocount,
|
||||
"writer ", lfsp->lfs_writer,
|
||||
"dirops ", lfsp->lfs_dirops,
|
||||
"doifile ", lfsp->lfs_doifile);
|
||||
(void)printf("%s%d\t%s%d\t%s0x%X\t%s%d\n",
|
||||
"nactive ", lfsp->lfs_nactive,
|
||||
"fmod ", lfsp->lfs_fmod,
|
||||
"clean ", lfsp->lfs_clean,
|
||||
"ronly ", lfsp->lfs_ronly);
|
||||
}
|
||||
|
||||
static void
|
||||
addseg(arg)
|
||||
char *arg;
|
||||
{
|
||||
SEGLIST *p;
|
||||
|
||||
if ((p = malloc(sizeof(SEGLIST))) == NULL)
|
||||
err("%s", strerror(errno));
|
||||
p->next = seglist;
|
||||
p->num = atoi(arg);
|
||||
seglist = p;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_cleaner_info(lfsp, ipage)
|
||||
struct lfs *lfsp;
|
||||
void *ipage;
|
||||
{
|
||||
CLEANERINFO *cip;
|
||||
|
||||
cip = (CLEANERINFO *)ipage;
|
||||
(void)printf("segments clean\t%d\tsegments dirty\t%d\n\n",
|
||||
cip->clean, cip->dirty);
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "usage: dumplfs [-ai] [-s segnum] file\n");
|
||||
exit(1);
|
||||
}
|
40
usr.sbin/dumplfs/extern.h
Normal file
40
usr.sbin/dumplfs/extern.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*
|
||||
* from: @(#)extern.h 8.1 (Berkeley) 6/5/93
|
||||
* $Id: extern.h,v 1.1 1994/06/08 18:58:51 mycroft Exp $
|
||||
*/
|
||||
|
||||
void err __P((const char *, ...));
|
||||
void get __P((int, off_t, void *, size_t));
|
||||
|
||||
extern char *special;
|
91
usr.sbin/dumplfs/misc.c
Normal file
91
usr.sbin/dumplfs/misc.c
Normal file
@ -0,0 +1,91 @@
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
/*static char sccsid[] = "from: @(#)misc.c 8.1 (Berkeley) 6/5/93";*/
|
||||
static char *rcsid = "$Id: misc.c,v 1.1 1994/06/08 18:58:52 mycroft Exp $";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "extern.h"
|
||||
|
||||
void
|
||||
get(fd, off, p, len)
|
||||
int fd;
|
||||
off_t off;
|
||||
void *p;
|
||||
size_t len;
|
||||
{
|
||||
int rbytes;
|
||||
|
||||
if (lseek(fd, off, SEEK_SET) < 0)
|
||||
err("%s: %s", special, strerror(errno));
|
||||
if ((rbytes = read(fd, p, len)) < 0)
|
||||
err("%s: %s", special, strerror(errno));
|
||||
if (rbytes != len)
|
||||
err("%s: short read (%d, not %d)", special, rbytes, len);
|
||||
}
|
||||
|
||||
#if __STDC__
|
||||
#include <stdarg.h>
|
||||
#else
|
||||
#include <varargs.h>
|
||||
#endif
|
||||
|
||||
void
|
||||
#if __STDC__
|
||||
err(const char *fmt, ...)
|
||||
#else
|
||||
err(fmt, va_alist)
|
||||
char *fmt;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list ap;
|
||||
#if __STDC__
|
||||
va_start(ap, fmt);
|
||||
#else
|
||||
va_start(ap);
|
||||
#endif
|
||||
(void)fprintf(stderr, "dumplfs: ");
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
(void)fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
Loading…
Reference in New Issue
Block a user