iw.num_inodes = iw.inodes_left = argc-1;
- retval = ext2fs_open_inode_scan(fs, 0, &scan);
+ retval = ext2fs_open_inode_scan(current_fs, 0, &scan);
if (retval) {
com_err("ncheck", retval, "while opening inode scan");
goto error_out;
iw.position = 0;
iw.parent = ino;
- retval = ext2fs_dir_iterate(fs, ino, 0, 0,
+ retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
ncheck_proc, &iw);
if (retval) {
com_err("ncheck", retval,
for (i=0, iinfo = iw.iarray; i < iw.num_inodes; i++, iinfo++) {
if (iinfo->parent == 0)
continue;
- retval = ext2fs_get_pathname(fs, iinfo->parent,
+ retval = ext2fs_get_pathname(current_fs, iinfo->parent,
iinfo->ino, &iinfo->pathname);
if (retval)
com_err("ncheck", retval,
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
+#include <time.h>
#include "debugfs.h"
return(atoi(str+1));
}
- retval = ext2fs_namei(fs, root, cwd, str, &ino);
+ retval = ext2fs_namei(current_fs, root, cwd, str, &ino);
if (retval) {
com_err(str, retval, "");
return 0;
*/
int check_fs_open(char *name)
{
- if (!fs) {
+ if (!current_fs) {
com_err(name, 0, "Filesystem not open");
return 1;
}
*/
int check_fs_not_open(char *name)
{
- if (fs) {
+ if (current_fs) {
com_err(name, 0,
"Filesystem %s is still open. Close it first.\n",
- fs->device_name);
+ current_fs->device_name);
return 1;
}
return 0;
}
+/*
+ * This routine returns 1 if a filesystem is not opened read/write,
+ * and prints an error message to that effect.
+ */
+int check_fs_read_write(char *name)
+{
+ if (!(current_fs->flags & EXT2_FLAG_RW)) {
+ com_err(name, 0, "Filesystem opened read/only");
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * This function takes a __u32 time value and converts it to a string,
+ * using ctime
+ */
+char *time_to_string(__u32 cl)
+{
+ time_t t = (time_t) cl;
+
+ return ctime(&t);
+}
+
+
+
+
+Fri Aug 30 20:24:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * pass4.c (pass4): If the user refuses to connect an unattached
+ inode to lost+found, don't try to set i_links_count. This
+ is bad, since if the user says yes, the inode will be
+ marked as unused, which is not necessarily the right
+ thing, especially since the rest of the cleanup doesn't
+ happen here.
+
+ * pass2.c (deallocate_inode): Set inode_link_info[ino] when
+ dellocating an inode. (Not strictly necessary, but...)
+
+ * pass4.c (pass4): Add "bonehead" explanation to the "programming
+ error" message.
+
+Tue Aug 27 11:26:32 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * e2fsck.c (PRS,main): Added new options -s and -S. -s will
+ byte-swap the filesystem so that it is normalized. -S
+ will byte-swap the filesystem regardless of its current
+ byte-order.
+
+ * swapfs.c: New file, which will byte-swap a filesystem.
+
+Tue Aug 20 09:41:37 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * pass1.c (pass1): Change handling on files with non-zero dtime
+ and non-zero i_link_count; before we treated them as
+ deleted file per botched ext2 0.3c kernel behavior. We
+ now clear dtime instead.
+
+Mon Aug 19 23:33:57 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * e2fsck.c (main): If e2fsck sets the clean bit, even if
+ nothing else is changed, make sure FSCK_NONDESTRUCT is
+ set (since after all having the filesystem set to
+ invalid is an error. :-)
+
+Fri Aug 9 10:25:13 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * pass1.c (process_block): Make sure that meta data doesn't get
+ accidentally set in the dir_blocks array (which could
+ happen in some error condtions).
+
+ * pass1.c (pass1):
+ * pass2.c (process_bad_inode): Check for fragments in a
+ OS-independent fashion.
+
+Thu Aug 8 15:20:54 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * e2fsck.c (check_if_skip): Close the filesystem when skipping the
+ cleanup for the filesystem.
+
+Mon Jul 22 22:03:28 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * e2fsck.c: Improve corrupt_msg, so that it's less confusing.
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ..
+my_dir = e2fsck
INSTALL = @INSTALL@
LDFLAG_STATIC = @LDFLAG_STATIC@
PROGS= e2fsck extend @EXTRA_PROGS@
MANPAGES= e2fsck.8
-LIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
-DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
+LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBUUID)
+DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBUUID)
-STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
-STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(STATIC_LIBUUID)
+STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(STATIC_LIBUUID)
-PROFILED_LIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR)
-PROFILED_DEPLIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR)
+PROFILED_LIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) $(PROFILED_LIBUUID)
+PROFILED_DEPLIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR) $(PROFILED_LIBUUID)
.c.o:
$(CC) -c $(ALL_CFLAGS) $< -o $@
#MCHECK= -DMCHECK
OBJS= e2fsck.o pass1.o pass1b.o pass2.o pass3.o pass4.o pass5.o \
- badblocks.o util.o dirinfo.o ehandler.o $(MTRACE_OBJ)
+ swapfs.o badblocks.o util.o dirinfo.o ehandler.o $(MTRACE_OBJ)
PROFILED_OBJS= profiled/e2fsck.o profiled/pass1.o profiled/pass1b.o \
profiled/pass2.o profiled/pass3.o profiled/pass4.o profiled/pass5.o \
profiled/badblocks.o profiled/util.o profiled/dirinfo.o \
- profiled/ehandler.o
+ profiled/ehandler.o profiled/swapfs.o
SRCS= $(srcdir)/e2fsck.c \
$(srcdir)/pass1.c \
$(srcdir)/ehandler.c \
$(MTRACE_SRC)
-all:: profiled $(PROGS) e2fsck.static e2fsck.shared
+all:: profiled $(PROGS) e2fsck.static e2fsck.shared $(MANPAGES)
@PROFILE_CMT@all:: e2fsck.profiled
# Makefile dependencies follow. This must be the last section in
# the Makefile.in file
#
-e2fsck.o: $(srcdir)/e2fsck.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
- $(srcdir)/../version.h
+e2fsck.o: $(srcdir)/e2fsck.c $(top_srcdir)/lib/et/com_err.h \
+ $(top_srcdir)/lib/uuid/uuid.h $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../version.h
pass1.o: $(srcdir)/pass1.c $(top_srcdir)/lib/et/com_err.h \
$(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
-pass1b.o: $(srcdir)/pass1b.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h \
+pass1b.o: $(srcdir)/pass1b.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
-pass2.o: $(srcdir)/pass2.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
-pass3.o: $(srcdir)/pass3.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
+pass2.o: $(srcdir)/pass2.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
+pass3.o: $(srcdir)/pass3.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
pass4.o: $(srcdir)/pass4.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
pass5.o: $(srcdir)/pass5.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
-badblocks.o: $(srcdir)/badblocks.c \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
$(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
util.o: $(srcdir)/util.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
dirinfo.o: $(srcdir)/dirinfo.c $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/e2fsck.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h
-ehandler.o: $(srcdir)/ehandler.c \
- $(srcdir)/e2fsck.h \
+ $(srcdir)/e2fsck.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h
+ehandler.o: $(srcdir)/ehandler.c $(srcdir)/e2fsck.h \
$(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
$(top_srcdir)/lib/ext2fs/bitops.h
-
-
.SH SYNOPSIS
.B e2fsck
[
-.B \-pacnyrdfvtFV
+.B \-pacnyrdfvstFSV
]
[
.B \-b
.I -r
This option does nothing at all; it is provided only for backwards
compatibility.
+.IP
+.I -s
+This option will byte-swap the filesystem so that it is using the normalized,
+standard byte-order (which is i386 or little endian). If the filesystem is
+already in the standard byte-order, e2fsck will take no action.
+.TP
+.I -S
+This option will byte-swap the filesystem, regardless of its current
+byte-order.
.TP
.I -t
Print timing statistics for
* enforced (but it's not much fun on a character device :-).
*/
+#include <stdio.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <malloc.h>
#include "et/com_err.h"
+#include "uuid/uuid.h"
#include "e2fsck.h"
#include "../version.h"
int cflag = 0; /* check disk */
int preen = 0;
int rwflag = 1;
+int swapfs = 0;
+int normalize_swapfs = 0;
int inode_buffer_blocks = 0;
blk_t superblock;
int blocksize = 0;
static void usage(NOARGS)
{
fprintf(stderr,
- "Usage: %s [-panyrcdfvtFV] [-b superblock] [-B blocksize]\n"
+ "Usage: %s [-panyrcdfvstFSV] [-b superblock] [-B blocksize]\n"
"\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
"\t\t[-l|-L bad_blocks_file] device\n", program_name);
exit(FSCK_USAGE);
#define MIN_CHECK 1
#define MAX_CHECK 2
-static const char *corrupt_msg = "\nThe filesystem superblock is corrupt. "
- "Try running e2fsck with an alternate\n"
- "superblock using the -b option. "
- "(8193 is commonly an alternate superblock;\n"
- "Hence, 'e2fsck -b 8193 <device>' may recover the filesystem.)\n\n";
+static const char *corrupt_msg =
+"\nThe superblock could not be read or does not describe a correct ext2\n"
+"filesystem. If the device is valid and it really contains an ext2\n"
+"filesystem (and not swap or ufs or something else), then the superblock\n"
+"is corrupt, and you might try running e2fsck with an alternate superblock:\n"
+" e2fsck -b 8193 <device>\n\n";
static void check_super_value(const char *descr, unsigned long value,
int flags, unsigned long min, unsigned long max)
}
}
-static void relocate_hint()
+static void relocate_hint(void)
{
static hint_issued = 0;
static void check_super_block(ext2_filsys fs)
{
blk_t first_block, last_block;
- struct ext2_super_block *s = fs->super;
+ struct ext2fs_sb *s = (struct ext2fs_sb *) fs->super;
blk_t blocks_per_group = fs->super->s_blocks_per_group;
int i;
blk_t should_be;
first_block += fs->super->s_blocks_per_group;
last_block += fs->super->s_blocks_per_group;
}
+
+ /*
+ * If the UUID field isn't assigned, assign it.
+ */
+ if (rwflag && uuid_is_null(s->s_uuid)) {
+ if (preen)
+ printf("%s: Adding UUID to filesystem.\n",
+ device_name);
+ else
+ printf("Filesystem did not have a UUID; "
+ "generating one.\n\n");
+ uuid_generate(s->s_uuid);
+ ext2fs_mark_super_dirty(fs);
+ }
return;
}
{
const char *reason = NULL;
- if (force || bad_blocks_file || cflag)
+ if (force || bad_blocks_file || cflag || swapfs)
return;
if (fs->super->s_state & EXT2_ERROR_FS)
fs->super->s_inodes_count,
fs->super->s_blocks_count - fs->super->s_free_blocks_count,
fs->super->s_blocks_count);
+ ext2fs_close(fs);
exit(FSCK_OK);
}
}
if (argc && *argv)
program_name = *argv;
- while ((c = getopt (argc, argv, "panyrcB:dfvtFVM:b:I:P:l:L:N:")) != EOF)
+ while ((c = getopt (argc, argv, "panyrcB:dfvtFVM:b:I:P:l:L:N:Ss")) != EOF)
switch (c) {
case 'p':
case 'a':
case 'N':
device_name = optarg;
break;
+ case 's':
+ normalize_swapfs = 1;
+ case 'S':
+ swapfs = 1;
+ break;
default:
usage ();
}
return;
if (optind != argc - 1)
usage ();
- if (nflag && !bad_blocks_file && !cflag)
+ if (nflag && !bad_blocks_file && !cflag && !swapfs)
rwflag = 0;
filesystem_name = argv[optind];
if (device_name == 0)
fatal_error ("BLKFLSBUF not supported");
#endif /* BLKFLSBUF */
}
+ if (swapfs) {
+ if (cflag || bad_blocks_file) {
+ fprintf(stderr, "Incompatible options not "
+ "allowed when byte-swapping.\n");
+ fatal_error(0);
+ }
+ }
}
int main (int argc, char *argv[])
if (retval) {
com_err(program_name, retval, "while trying to open %s",
filesystem_name);
- switch (retval) {
- case EXT2_ET_REV_TOO_HIGH:
+ if (retval == EXT2_ET_REV_TOO_HIGH)
printf ("Get a newer version of e2fsck!\n");
- break;
- case EXT2_ET_SHORT_READ:
+ else if (retval == EXT2_ET_SHORT_READ)
printf ("Could this be a zero-length partition?\n");
- break;
- case EPERM:
- case EACCES:
+ else if ((retval == EPERM) || (retval == EACCES))
printf("You must have %s access to the "
"filesystem or be root\n",
rwflag ? "r/w" : "r/o");
- break;
- case ENXIO:
+ else if (retval == ENXIO)
printf("Possibly non-existent or swap device?\n");
- break;
- default:
+ else
printf(corrupt_msg);
- }
fatal_error(0);
}
else if (cflag)
test_disk(fs);
+ if (normalize_swapfs) {
+ if ((fs->flags & EXT2_SWAP_BYTES) == ext2fs_native_flag()) {
+ fprintf(stderr, "%s: Filesystem byte order "
+ "already normalized.\n", device_name);
+ fatal_error(0);
+ }
+ }
+ if (swapfs)
+ swap_filesys(fs);
+
/*
* Mark the system as valid, 'til proven otherwise
*/
ext2fs_mark_valid(fs);
-
+
pass1(fs);
free(invalid_inode_bitmap);
free(invalid_block_bitmap);
if (!ext2fs_test_valid(fs))
exit_value = FSCK_UNCORRECTED;
if (rwflag) {
- if (ext2fs_test_valid(fs))
+ if (ext2fs_test_valid(fs)) {
+ if (!(fs->super->s_state & EXT2_VALID_FS))
+ exit_value = FSCK_NONDESTRUCT;
fs->super->s_state = EXT2_VALID_FS;
- else
+ } else
fs->super->s_state &= ~EXT2_VALID_FS;
fs->super->s_mnt_count = 0;
fs->super->s_lastcheck = time(NULL);
* The last ext2fs revision level that this version of e2fsck is able to
* support
*/
-#define E2FSCK_CURRENT_REV 0
+#define E2FSCK_CURRENT_REV 1
/*
* Inode count arrays
extern int invalid_bitmaps;
/*
+ * For pass1_check_directory and pass1_get_blocks
+ */
+extern ino_t stashed_ino;
+extern struct ext2_inode *stashed_inode;
+
+/*
* Procedure declarations
*/
extern void pass4(ext2_filsys fs);
extern void pass5(ext2_filsys fs);
+/* pass1.c */
+extern errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino);
+extern errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
+extern errcode_t pass1_read_inode(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+extern errcode_t pass1_write_inode(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+
/* badblock.c */
extern void read_bad_blocks_file(ext2_filsys fs, const char *bad_blocks_file,
int replace_bad_blocks);
extern const char *ehandler_operation(const char *op);
extern void ehandler_init(io_channel channel);
+/* swapfs.c */
+void swap_filesys(ext2_filsys fs);
+
/* util.c */
extern void *allocate_memory(int size, const char *description);
extern int ask(const char * string, int def);
ext2fs_block_bitmap block_dup_map = 0;
ext2fs_block_bitmap block_illegal_map = 0;
-static int fix_link_count = -1;
-
unsigned short * inode_link_info = NULL;
static int process_block(ext2_filsys fs, blk_t *blocknr,
static void check_blocks(ext2_filsys fs, ino_t ino, struct ext2_inode *inode,
char *block_buf);
static void mark_table_blocks(ext2_filsys fs);
-static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino);
-static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
static void alloc_bad_map(ext2_filsys fs);
static void handle_fs_bad_blocks(ext2_filsys fs);
static void process_inodes(ext2_filsys fs, char *block_buf);
char *block_buf;
errcode_t retval;
struct resource_track rtrack;
+ unsigned char frag, fsize;
init_resource_track(&rtrack);
block_buf = allocate_memory(fs->blocksize * 3, "block interate buffer");
fs->get_blocks = pass1_get_blocks;
fs->check_directory = pass1_check_directory;
+ fs->read_inode = pass1_read_inode;
+ fs->write_inode = pass1_write_inode;
ehandler_operation("doing inode scan");
retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan);
if (retval) {
inode.i_dtime = 0;
e2fsck_write_inode(fs, ino, &inode,
"pass1");
- printf("Note: /lost+found will "
- "probably be deleted as well, "
- "due to the mke2fs bug.\n"
- "Be sure to run mklost+found "
- "to recreate it after e2fsck "
- "finishes.\n\n");
} else
ext2fs_unmark_valid(fs);
}
goto next;
}
/*
- * 0.3c ext2fs code didn't clear i_links_count for
+ * n.b. 0.3c ext2fs code didn't clear i_links_count for
* deleted files. Oops.
+ *
+ * Since all new ext2 implementations get this right,
+ * we now assume that the case of non-zero
+ * i_links_count and non-zero dtime means that we
+ * should keep the file, not delete it.
*
- * In the future, when the new ext2fs behavior is the
- * norm, we may want to handle the case of a non-zero
- * i_links_count and non-zero dtime by clearing dtime
- * and assuming the inode is in use, instead of
- * assuming the inode is not in use.
*/
if (inode.i_dtime) {
- if (fix_link_count == -1) {
- printf("\nDeleted inode detected with non-zero link count.\n");
- printf("This is probably due to old ext2fs kernel code. \n");
- fix_link_count = ask("Fix inode(s)", 1);
- }
- printf("Inode %lu is deleted w/ non-zero link_count. %s\n",
- ino, clear_msg[fix_link_count]);
- if (fix_link_count) {
- inode.i_links_count = 0;
- inode_link_info[ino] = 0;
+ printf("Inode %lu is in use, but has dtime set\n",
+ ino);
+ if (ask("Clear dtime", 1)) {
+ inode.i_dtime = 0;
e2fsck_write_inode(fs, ino, &inode, "pass1");
} else
ext2fs_unmark_valid(fs);
- goto next;
}
ext2fs_mark_inode_bitmap(inode_used_map, ino);
- if (inode.i_faddr
-#if HAVE_EXT2_FRAGS
- || inode.i_frag || inode.i_fsize
-#endif
+ switch (fs->super->s_creator_os) {
+ case EXT2_OS_LINUX:
+ frag = inode.osd2.linux2.l_i_frag;
+ fsize = inode.osd2.linux2.l_i_fsize;
+ break;
+ case EXT2_OS_HURD:
+ frag = inode.osd2.hurd2.h_i_frag;
+ fsize = inode.osd2.hurd2.h_i_fsize;
+ break;
+ case EXT2_OS_MASIX:
+ frag = inode.osd2.masix2.m_i_frag;
+ fsize = inode.osd2.masix2.m_i_fsize;
+ break;
+ default:
+ frag = fsize = 0;
+ }
+
+ if (inode.i_faddr || frag || fsize
|| inode.i_file_acl || inode.i_dir_acl) {
if (!inode_bad_map)
alloc_bad_map(fs);
}
pass1_dupblocks(fs, block_buf);
}
- fs->get_blocks = 0;
- fs->check_directory = 0;
free(inodes_to_process);
endit:
+ fs->get_blocks = 0;
+ fs->check_directory = 0;
+ fs->read_inode = 0;
+ fs->write_inode = 0;
+
free(block_buf);
ext2fs_free_block_bitmap(block_illegal_map);
block_illegal_map = 0;
if (blk == 0) {
if (p->is_dir == 0) {
+ /*
+ * Should never happen, since only directories
+ * get called with BLOCK_FLAG_HOLE
+ */
printf("process_block() called with blk == 0, "
"inode %lu???", p->ino);
return 0;
mark_block_used(fs, blk);
p->num_blocks++;
- if (blockcnt < 0)
- return 0;
-
- p->last_block = blockcnt;
+ if (blockcnt >= 0)
+ p->last_block = blockcnt;
mark_dir:
- if (p->is_dir) {
+ if (p->is_dir && (blockcnt >= 0)) {
if (dir_block_count >= dir_block_size) {
dir_block_size += 100;
dir_blocks = realloc(dir_blocks,
* structure, so there's no point in letting the ext2fs library read
* the inode again.
*/
-static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
+errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
{
int i;
exit(FSCK_ERROR);
}
-static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
+errcode_t pass1_read_inode(ext2_filsys fs, ino_t ino, struct ext2_inode *inode)
+{
+ if (ino != stashed_ino)
+ return EXT2_ET_CALLBACK_NOTHANDLED;
+ *inode = *stashed_inode;
+ return 0;
+}
+
+errcode_t pass1_write_inode(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode)
+{
+ if (ino == stashed_ino)
+ *stashed_inode = *inode;
+ return EXT2_ET_CALLBACK_NOTHANDLED;
+}
+
+errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
{
if (ino == stashed_ino) {
if (!LINUX_S_ISDIR(stashed_inode->i_mode))
static struct dup_inode *dup_ino = 0;
static int dup_inode_count = 0;
-/*
- * For pass1_check_directory and pass1_get_blocks
- */
-extern ino_t stashed_ino;
-extern struct ext2_inode *stashed_inode;
-
static ext2fs_inode_bitmap inode_dup_map;
/*
errcode_t retval;
struct ext2_inode inode;
+ inode_link_info[ino] = 0;
e2fsck_read_inode(fs, ino, &inode, "deallocate_inode");
inode.i_links_count = 0;
inode.i_dtime = time(0);
errcode_t retval;
int inode_modified = 0;
char *pathname;
+ unsigned char *frag, *fsize;
e2fsck_read_inode(fs, ino, &inode, "process_bad_inode");
retval = ext2fs_get_pathname(fs, dir, ino, &pathname);
}
check_for_zero_u32(fs, ino, pathname, "i_faddr", &inode.i_faddr,
&inode_modified);
-#if HAVE_EXT2_FRAGS
- check_for_zero_u8(fs, ino, pathname, "i_frag", &inode.i_frag,
- &inode_modified);
- check_for_zero_u8(fs, ino, pathname, "i_fsize", &inode.i_fsize,
- &inode_modified);
-#else
- /*
- * Even if the OS specific fields don't support i_frag and
- * i_fsize, make sure they are set to zero anyway. This may
- * cause problems if on some other OS these fields are reused
- * for something else, but that's probably a bad idea....
- */
- check_for_zero_u8(fs, ino, pathname, "i_frag",
- &inode.osd2.linux2.l_i_frag, &inode_modified);
- check_for_zero_u8(fs, ino, pathname, "i_fsize",
- &inode.osd2.linux2.l_i_fsize, &inode_modified);
-#endif
+
+ switch (fs->super->s_creator_os) {
+ case EXT2_OS_LINUX:
+ frag = &inode.osd2.linux2.l_i_frag;
+ fsize = &inode.osd2.linux2.l_i_fsize;
+ break;
+ case EXT2_OS_HURD:
+ frag = &inode.osd2.hurd2.h_i_frag;
+ fsize = &inode.osd2.hurd2.h_i_fsize;
+ break;
+ case EXT2_OS_MASIX:
+ frag = &inode.osd2.masix2.m_i_frag;
+ fsize = &inode.osd2.masix2.m_i_fsize;
+ break;
+ default:
+ frag = fsize = 0;
+ }
+ if (frag)
+ check_for_zero_u8(fs, ino, pathname, "i_frag", frag,
+ &inode_modified);
+ if (fsize)
+ check_for_zero_u8(fs, ino, pathname, "i_fsize", fsize,
+ &inode_modified);
+
check_for_zero_u32(fs, ino, pathname, "i_file_acl", &inode.i_file_acl,
&inode_modified);
check_for_zero_u32(fs, ino, pathname, "i_dir_acl", &inode.i_dir_acl,
if (ask("Connect to /lost+found", 1)) {
if (reconnect_file(fs, i))
ext2fs_unmark_valid(fs);
- } else
+ } else {
+ /*
+ * If we don't attach the inode, then
+ * skip the i_links_test since there's
+ * no point in trying to force
+ * i_links_count to zero.
+ */
ext2fs_unmark_valid(fs);
+ continue;
+ }
}
if (inode_count[i] != inode_link_info[i]) {
e2fsck_read_inode(fs, i, &inode, "pass4");
if (inode_link_info[i] != inode.i_links_count) {
printf("WARNING: PROGRAMMING BUG IN E2FSCK!\n");
+ printf("\tOR SOME BONEHEAD (YOU) IS CHECKING "
+ "A MOUNTED (LIVE) FILESYSTEM.\n");
printf("inode_link_info[%ld] is %u, "
"inode.i_links_count is %d. "
"They should be the same!\n",
--- /dev/null
+/*
+ * swapfs.c --- byte-swap an ext2 filesystem
+ */
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include <et/com_err.h>
+#include "e2fsck.h"
+
+struct swap_block_struct {
+ ino_t ino;
+ int isdir;
+ errcode_t errcode;
+ char *dir_buf;
+ struct ext2_inode *inode;
+};
+
+/*
+ * This is a helper function for block_iterate. We mark all of the
+ * indirect and direct blocks as changed, so that block_iterate will
+ * write them out.
+ */
+static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
+ void *private)
+{
+ errcode_t retval;
+
+ struct swap_block_struct *sb = (struct swap_block_struct *) private;
+
+ if (sb->isdir && (blockcnt >= 0) && *block_nr) {
+ retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
+ if (retval) {
+ sb->errcode = retval;
+ return BLOCK_ABORT;
+ }
+ retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
+ if (retval) {
+ sb->errcode = retval;
+ return BLOCK_ABORT;
+ }
+ }
+ if (blockcnt >= 0) {
+ if (blockcnt < EXT2_NDIR_BLOCKS)
+ return 0;
+ return BLOCK_CHANGED;
+ }
+ if (blockcnt == BLOCK_COUNT_IND) {
+ if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
+ return 0;
+ return BLOCK_CHANGED;
+ }
+ if (blockcnt == BLOCK_COUNT_DIND) {
+ if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
+ return 0;
+ return BLOCK_CHANGED;
+ }
+ if (blockcnt == BLOCK_COUNT_TIND) {
+ if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
+ return 0;
+ return BLOCK_CHANGED;
+ }
+ return BLOCK_CHANGED;
+}
+
+/*
+ * This function is responsible for byte-swapping all of the indirect,
+ * block pointers. It is also responsible for byte-swapping directories.
+ */
+static void swap_inode_blocks(ext2_filsys fs, ino_t ino, char *block_buf,
+ struct ext2_inode *inode)
+{
+ errcode_t retval;
+ struct swap_block_struct sb;
+
+ sb.ino = ino;
+ sb.inode = inode;
+ sb.dir_buf = block_buf + fs->blocksize*3;
+ sb.errcode = 0;
+ sb.isdir = 0;
+ if (LINUX_S_ISDIR(inode->i_mode))
+ sb.isdir = 1;
+
+ retval = ext2fs_block_iterate(fs, ino, 0, block_buf, swap_block, &sb);
+ if (retval) {
+ com_err("swap_inode_blocks", retval,
+ "while calling ext2fs_block_iterate");
+ fatal_error(0);
+ }
+ if (sb.errcode) {
+ com_err("swap_inode_blocks", sb.errcode,
+ "while calling iterator function");
+ fatal_error(0);
+ }
+}
+
+static void swap_inodes(ext2_filsys fs)
+{
+ int i, group;
+ ino_t ino = 1;
+ char *buf, *block_buf;
+ errcode_t retval;
+ struct ext2_inode * inode;
+
+ fs->read_inode = pass1_read_inode;
+ fs->get_blocks = pass1_get_blocks;
+
+
+ buf = malloc(fs->blocksize * fs->inode_blocks_per_group);
+ if (!buf) {
+ com_err("swap_inodes", ENOMEM,
+ "while allocating inode buffer");
+ fatal_error(0);
+ }
+ block_buf = allocate_memory(fs->blocksize * 4,
+ "block interate buffer");
+ for (group = 0; group < fs->group_desc_count; group++) {
+ retval = io_channel_read_blk(fs->io,
+ fs->group_desc[group].bg_inode_table,
+ fs->inode_blocks_per_group, buf);
+ if (retval) {
+ com_err("swap_inodes", retval,
+ "while reading inode table (group %d)",
+ group);
+ fatal_error(0);
+ }
+ inode = (struct ext2_inode *) buf;
+ for (i=0; i < fs->super->s_inodes_per_group; i++, ino++) {
+ if (fs->flags & EXT2_SWAP_BYTES_READ)
+ ext2fs_swap_inode(fs, inode, inode, 0);
+ stashed_ino = ino;
+ stashed_inode = inode;
+
+ if (inode->i_block[EXT2_IND_BLOCK] ||
+ inode->i_block[EXT2_DIND_BLOCK] ||
+ inode->i_block[EXT2_TIND_BLOCK] ||
+ LINUX_S_ISDIR(inode->i_mode))
+ swap_inode_blocks(fs, ino, block_buf, inode);
+
+ if (fs->flags & EXT2_SWAP_BYTES_WRITE)
+ ext2fs_swap_inode(fs, inode, inode, 1);
+ inode++;
+ }
+ retval = io_channel_write_blk(fs->io,
+ fs->group_desc[group].bg_inode_table,
+ fs->inode_blocks_per_group, buf);
+ if (retval) {
+ com_err("swap_inodes", retval,
+ "while writing inode table (group %d)",
+ group);
+ fatal_error(0);
+ }
+ }
+ free(buf);
+ free(block_buf);
+ fs->read_inode = 0;
+ fs->get_blocks = 0;
+}
+
+void swap_filesys(ext2_filsys fs)
+{
+ struct resource_track rtrack;
+
+ init_resource_track(&rtrack);
+
+ if (!preen)
+ printf("Pass 0: Doing byte-swap of filesystem\n");
+
+#ifdef MTRACE
+ mtrace_print("Byte swap");
+#endif
+
+ if (fs->super->s_mnt_count) {
+ fprintf(stderr, "%s: the filesystem must be freshly "
+ "checked using fsck\n"
+ "and not mounted before trying to "
+ "byte-swap it.\n", device_name);
+ fatal_error(0);
+ }
+ if (fs->flags & EXT2_SWAP_BYTES) {
+ fs->flags &= ~(EXT2_SWAP_BYTES|EXT2_SWAP_BYTES_WRITE);
+ fs->flags |= EXT2_SWAP_BYTES_READ;
+ } else {
+ fs->flags &= ~EXT2_SWAP_BYTES_READ;
+ fs->flags |= EXT2_SWAP_BYTES_WRITE;
+ }
+ swap_inodes(fs);
+ if (fs->flags & EXT2_SWAP_BYTES_WRITE)
+ fs->flags |= EXT2_SWAP_BYTES;
+ fs->flags &= ~(EXT2_SWAP_BYTES_READ|EXT2_SWAP_BYTES_WRITE);
+ ext2fs_flush(fs);
+
+ if (tflag > 1) {
+ printf("Byte swap: ");
+ print_resource_track(&rtrack);
+ }
+}
+
+
typedef unsigned char __u8;
typedef signed char __s8;
+#if (@SIZEOF_INT@ == 8)
+typedef int __s64;
+typedef unsigned int __u64;
+#elif (@SIZEOF_LONG@ == 8)
+typedef long __s64;
+typedef unsigned long __u64;
+#elif (@SIZEOF_LONG_LONG@ == 8)
+typedef long __s64;
+typedef unsigned long __u64;
+#endif
+
#if (@SIZEOF_INT@ == 2)
typedef int __s16;
typedef unsigned int __u16;
?== error: undefined 32 bit type
#endif
+#ifndef HAVE_INO_T
+typedef __u32 ino_t;
+#endif
+
#endif /* LINUX_TYPES_H */
+Wed Aug 28 15:20:26 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * Makefile.elf-lib (installdirs-elf-lib): Renamed from installdirs
+ to avoid making random directories only neeeded when installing
+ normal libraries.
+ (install-shlibs): Use installdirs-elf-lib instead of installdirs.
+
+Thu May 23 12:40:12 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.elf-lib: Install the .so files in /usr/lib, since the
+ .a files are stored there. (We were installing the .so
+ files in the wrong place before.)
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
$(LN) ../$(ELF_LIB) ../$(ELF_IMAGE).so
$(LN) ../$(ELF_LIB) ../$(ELF_SONAME)
-installdirs::
- $(top_srcdir)/mkinstalldirs $(DESTDIR)$(ELF_INSTALL_DIR)
+installdirs-elf-lib::
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(ELF_INSTALL_DIR) \
+ $(DESTDIR)$(ulibdir)
-install-shlibs install:: $(ELF_LIB) installdirs
+installdirs:: installdirs-elf-lib
+
+install-shlibs install:: $(ELF_LIB) installdirs-elf-lib
$(INSTALL_PROGRAM) $(ELF_LIB) $(DESTDIR)$(ELF_INSTALL_DIR)/$(ELF_LIB)
$(STRIP) --strip-debug \
$(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_LIB)
- $(LN) -sf $(ELF_LIB) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_SONAME)
- $(LN) -sf $(ELF_SONAME) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_IMAGE).so
+ $(LN_S) -f $(ELF_LIB) $(DESTDIR)$(DLL_INSTALL_DIR)/$(ELF_SONAME)
+ $(LN_S) -f $(DLL_INSTALL_DIR)/$(ELF_SONAME) \
+ $(DESTDIR)$(ulibdir)/$(ELF_IMAGE).so
-ldconfig
clean::
-e "s%@E2FSPROGS_MONTH@%$E2FSPROGS_MONTH%g" \
-e "s%@E2FSPROGS_YEAR@%$E2FSPROGS_YEAR%g" \
-e "s%@E2FSPROGS_VERSION@%$E2FSPROGS_VERSION%g" \
+ -e "s%@SIZEOF_LONG_LONG@%$SIZEOF_LONG_LONG%g" \
-e "s%@SIZEOF_LONG@%$SIZEOF_LONG%g" \
-e "s%@SIZEOF_INT@%$SIZEOF_INT%g" \
-e "s%@SIZEOF_SHORT@%$SIZEOF_SHORT%g" \
+Sat Sep 7 14:48:35 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ls.c (interval_string): Pretty print the check interval.
+
+Tue Aug 6 14:12:36 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ls.c (list_super): Display the OS, volume label, last mounted,
+ and UUID field if present.
+
+Mon Jun 24 09:55:58 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ps.c, pf.c, pe.c, ls.c, setversion.c, setflags.c, getversion.c,
+ fsetversion.c, fsetflags.c, fgetversion.c, fgetflags.c,
+ getflags.c: Remove include of ext2_fs.h, since it's
+ included by e2p.h; this also solves a sys/types.h vs
+ linux/types.h inclusion ordering problem with the GNU libc.
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
+++ /dev/null
-gcc -O2 -fomit-frame-pointer -I.. -c pe.c
-In file included from pe.c:19:
-/usr/include/linux/ext2_fs.h:127: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:127: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:128: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:129: parse error before `aclh_acle_count'
-/usr/include/linux/ext2_fs.h:129: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:130: parse error before `aclh_first_acle'
-/usr/include/linux/ext2_fs.h:130: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:135: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:135: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:136: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:137: parse error before `acle_type'
-/usr/include/linux/ext2_fs.h:137: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:138: parse error before `acle_tag'
-/usr/include/linux/ext2_fs.h:138: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:139: parse error before `acle_pad1'
-/usr/include/linux/ext2_fs.h:139: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:140: parse error before `acle_next'
-/usr/include/linux/ext2_fs.h:140: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:149: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:149: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:150: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:151: parse error before `bg_inode_table'
-/usr/include/linux/ext2_fs.h:151: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:152: parse error before `bg_free_blocks_count'
-/usr/include/linux/ext2_fs.h:152: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:153: parse error before `bg_free_inodes_count'
-/usr/include/linux/ext2_fs.h:153: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:158: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:158: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:159: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:160: parse error before `bg_inode_table'
-/usr/include/linux/ext2_fs.h:160: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:161: parse error before `bg_free_blocks_count'
-/usr/include/linux/ext2_fs.h:161: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:162: parse error before `bg_free_inodes_count'
-/usr/include/linux/ext2_fs.h:162: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:163: parse error before `bg_used_dirs_count'
-/usr/include/linux/ext2_fs.h:163: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:164: parse error before `bg_pad'
-/usr/include/linux/ext2_fs.h:164: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:165: parse error before `bg_reserved'
-/usr/include/linux/ext2_fs.h:165: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:166: parse error before `}'
-/usr/include/linux/ext2_fs.h:213: parse error before `__u16'
-/usr/include/linux/ext2_fs.h:213: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:214: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:215: parse error before `i_size'
-/usr/include/linux/ext2_fs.h:215: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:216: parse error before `i_atime'
-/usr/include/linux/ext2_fs.h:216: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:217: parse error before `i_ctime'
-/usr/include/linux/ext2_fs.h:217: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:218: parse error before `i_mtime'
-/usr/include/linux/ext2_fs.h:218: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:219: parse error before `i_dtime'
-/usr/include/linux/ext2_fs.h:219: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:220: parse error before `i_gid'
-/usr/include/linux/ext2_fs.h:220: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:221: parse error before `i_links_count'
-/usr/include/linux/ext2_fs.h:221: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:222: parse error before `i_blocks'
-/usr/include/linux/ext2_fs.h:222: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:223: parse error before `i_flags'
-/usr/include/linux/ext2_fs.h:223: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:226: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:226: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:226: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:227: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:229: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:229: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:230: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:232: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:232: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:233: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:234: parse error before `}'
-/usr/include/linux/ext2_fs.h:234: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:235: parse error before `i_block'
-/usr/include/linux/ext2_fs.h:235: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:236: parse error before `i_version'
-/usr/include/linux/ext2_fs.h:236: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:237: parse error before `i_file_acl'
-/usr/include/linux/ext2_fs.h:237: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:238: parse error before `i_dir_acl'
-/usr/include/linux/ext2_fs.h:238: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:239: parse error before `i_faddr'
-/usr/include/linux/ext2_fs.h:239: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:242: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:242: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:242: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:243: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:244: parse error before `i_pad1'
-/usr/include/linux/ext2_fs.h:244: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:245: parse error before `l_i_reserved2'
-/usr/include/linux/ext2_fs.h:245: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:246: parse error before `}'
-/usr/include/linux/ext2_fs.h:246: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:248: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:248: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:249: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:250: parse error before `h_i_mode_high'
-/usr/include/linux/ext2_fs.h:250: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:251: parse error before `h_i_uid_high'
-/usr/include/linux/ext2_fs.h:251: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:252: parse error before `h_i_gid_high'
-/usr/include/linux/ext2_fs.h:252: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:253: parse error before `h_i_author'
-/usr/include/linux/ext2_fs.h:253: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:254: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:256: parse error before `__u8'
-/usr/include/linux/ext2_fs.h:256: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:257: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:258: parse error before `m_pad1'
-/usr/include/linux/ext2_fs.h:258: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:259: parse error before `m_i_reserved2'
-/usr/include/linux/ext2_fs.h:259: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:260: parse error before `}'
-/usr/include/linux/ext2_fs.h:260: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:261: parse error before `}'
-/usr/include/linux/ext2_fs.h:261: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:262: parse error before `}'
-/usr/include/linux/ext2_fs.h:329: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:329: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:330: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:331: parse error before `s_r_blocks_count'
-/usr/include/linux/ext2_fs.h:331: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:332: parse error before `s_free_blocks_count'
-/usr/include/linux/ext2_fs.h:332: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:333: parse error before `s_free_inodes_count'
-/usr/include/linux/ext2_fs.h:333: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:334: parse error before `s_first_data_block'
-/usr/include/linux/ext2_fs.h:334: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:335: parse error before `s_log_block_size'
-/usr/include/linux/ext2_fs.h:335: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:336: parse error before `s_log_frag_size'
-/usr/include/linux/ext2_fs.h:336: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:337: parse error before `s_blocks_per_group'
-/usr/include/linux/ext2_fs.h:337: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:338: parse error before `s_frags_per_group'
-/usr/include/linux/ext2_fs.h:338: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:339: parse error before `s_inodes_per_group'
-/usr/include/linux/ext2_fs.h:339: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:340: parse error before `s_mtime'
-/usr/include/linux/ext2_fs.h:340: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:341: parse error before `s_wtime'
-/usr/include/linux/ext2_fs.h:341: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:342: parse error before `s_mnt_count'
-/usr/include/linux/ext2_fs.h:342: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:343: parse error before `s_max_mnt_count'
-/usr/include/linux/ext2_fs.h:343: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:344: parse error before `s_magic'
-/usr/include/linux/ext2_fs.h:344: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:345: parse error before `s_state'
-/usr/include/linux/ext2_fs.h:345: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:346: parse error before `s_errors'
-/usr/include/linux/ext2_fs.h:346: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:347: parse error before `s_pad'
-/usr/include/linux/ext2_fs.h:347: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:348: parse error before `s_lastcheck'
-/usr/include/linux/ext2_fs.h:348: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:349: parse error before `s_checkinterval'
-/usr/include/linux/ext2_fs.h:349: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:350: parse error before `s_creator_os'
-/usr/include/linux/ext2_fs.h:350: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:351: parse error before `s_rev_level'
-/usr/include/linux/ext2_fs.h:351: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:352: parse error before `s_def_resuid'
-/usr/include/linux/ext2_fs.h:352: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:353: parse error before `s_def_resgid'
-/usr/include/linux/ext2_fs.h:353: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:354: parse error before `s_reserved'
-/usr/include/linux/ext2_fs.h:354: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:355: parse error before `}'
-/usr/include/linux/ext2_fs.h:372: parse error before `__u32'
-/usr/include/linux/ext2_fs.h:372: warning: no semicolon at end of struct or union
-/usr/include/linux/ext2_fs.h:373: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:374: parse error before `name_len'
-/usr/include/linux/ext2_fs.h:374: warning: data definition has no type or storage class
-/usr/include/linux/ext2_fs.h:376: parse error before `}'
-make: *** [pe.o] Error 1
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ../..
+my_dir = lib/e2p
INSTALL = @INSTALL@
@MCONFIG@
OBJS= fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
getflags.o getversion.o iod.o ls.o pe.o pf.o ps.o \
- setflags.o setversion.o
+ setflags.o setversion.o uuid.o
SRCS= $(srcdir)/fgetflags.c $(srcdir)/fsetflags.c \
$(srcdir)/fgetversion.c $(srcdir)/fsetversion.c \
$(srcdir)/getflags.c $(srcdir)/getversion.c \
$(srcdir)/iod.c $(srcdir)/ls.c $(srcdir)/pe.c \
$(srcdir)/pf.c $(srcdir)/ps.c \
- $(srcdir)/setflags.c $(srcdir)/setversion.c
+ $(srcdir)/setflags.c $(srcdir)/setversion.c \
+ $(srcdir)/uuid.c
LIBRARY= libe2p
LIBDIR= e2p
DLL_MYDIR = e2p
DLL_INSTALL_DIR = $(libdir)
-ELF_VERSION = 2.1
+ELF_VERSION = 2.2
ELF_SO_VERSION = 2
ELF_IMAGE = libe2p
ELF_MYDIR = e2p
# the Makefile.in file
#
fgetflags.o: $(srcdir)/fgetflags.c $(srcdir)/e2p.h
-fsetflags.o: $(srcdir)/fsetflags.c $(srcdir)/e2p.h
+fsetflags.o: $(srcdir)/fsetflags.c $(srcdir)/e2p.h
fgetversion.o: $(srcdir)/fgetversion.c $(srcdir)/e2p.h
fsetversion.o: $(srcdir)/fsetversion.c $(srcdir)/e2p.h
getflags.o: $(srcdir)/getflags.c $(srcdir)/e2p.h
getversion.o: $(srcdir)/getversion.c $(srcdir)/e2p.h
iod.o: $(srcdir)/iod.c $(srcdir)/e2p.h
-ls.o: $(srcdir)/ls.c $(srcdir)/e2p.h
+ls.o: $(srcdir)/ls.c $(srcdir)/e2p.h
pe.o: $(srcdir)/pe.c $(srcdir)/e2p.h
pf.o: $(srcdir)/pf.c $(srcdir)/e2p.h
ps.o: $(srcdir)/ps.c $(srcdir)/e2p.h
setflags.o: $(srcdir)/setflags.c $(srcdir)/e2p.h
setversion.o: $(srcdir)/setversion.c $(srcdir)/e2p.h
+uuid.o: $(srcdir)/uuid.c
void print_fs_state (FILE * f, unsigned short state);
int setflags (int fd, unsigned long flags);
int setversion (int fd, unsigned long version);
+
+int e2p_is_null_uuid(void *uu);
+void e2p_uuid_to_str(void *uu, char *out);
#include <sys/ioctl.h>
#endif
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int fgetflags (const char * name, unsigned long * flags)
#include <fcntl.h>
#include <sys/ioctl.h>
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int fgetversion (const char * name, unsigned long * version)
#include <sys/ioctl.h>
#endif
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int fsetflags (const char * name, unsigned long flags)
#include <fcntl.h>
#include <sys/ioctl.h>
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int fsetversion (const char * name, unsigned long version)
#include <sys/ioctl.h>
#endif
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int getflags (int fd, unsigned long * flags)
#endif
#include <sys/ioctl.h>
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int getversion (int fd, unsigned long * version)
* Public License
*/
+#include <stdio.h>
#include <sys/types.h>
+#include <string.h>
#include <grp.h>
#include <pwd.h>
-#include <stdio.h>
#include <time.h>
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
+/*
+ * The ext2fs library private definition of the ext2 superblock, so we
+ * don't have to depend on the kernel's definition of the superblock,
+ * which might not have the latest features.
+ */
+struct ext2fs_sb {
+ __u32 s_inodes_count; /* Inodes count */
+ __u32 s_blocks_count; /* Blocks count */
+ __u32 s_r_blocks_count; /* Reserved blocks count */
+ __u32 s_free_blocks_count; /* Free blocks count */
+ __u32 s_free_inodes_count; /* Free inodes count */
+ __u32 s_first_data_block; /* First Data Block */
+ __u32 s_log_block_size; /* Block size */
+ __s32 s_log_frag_size; /* Fragment size */
+ __u32 s_blocks_per_group; /* # Blocks per group */
+ __u32 s_frags_per_group; /* # Fragments per group */
+ __u32 s_inodes_per_group; /* # Inodes per group */
+ __u32 s_mtime; /* Mount time */
+ __u32 s_wtime; /* Write time */
+ __u16 s_mnt_count; /* Mount count */
+ __s16 s_max_mnt_count; /* Maximal mount count */
+ __u16 s_magic; /* Magic signature */
+ __u16 s_state; /* File system state */
+ __u16 s_errors; /* Behaviour when detecting errors */
+ __u16 s_minor_rev_level; /* minor revision level */
+ __u32 s_lastcheck; /* time of last check */
+ __u32 s_checkinterval; /* max. time between checks */
+ __u32 s_creator_os; /* OS */
+ __u32 s_rev_level; /* Revision level */
+ __u16 s_def_resuid; /* Default uid for reserved blocks */
+ __u16 s_def_resgid; /* Default gid for reserved blocks */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ __u32 s_first_ino; /* First non-reserved inode */
+ __u16 s_inode_size; /* size of inode structure */
+ __u16 s_block_group_nr; /* block group # of this superblock */
+ __u32 s_feature_compat; /* compatible feature set */
+ __u32 s_feature_incompat; /* incompatible feature set */
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+ __u32 s_reserved[206]; /* Padding to the end of the block */
+};
+
static void print_user (unsigned short uid)
{
struct passwd *pw;
printf ("(group %s)\n", gr->gr_name);
}
+#define MONTH_INT (86400 * 30)
+#define WEEK_INT (86400 * 7)
+#define DAY_INT (86400)
+#define HOUR_INT (60 * 60)
+#define MINUTE_INT (60)
+
+static char *interval_string(unsigned int secs)
+{
+ static char buf[256], tmp[80];
+ int hr, min, num;
+
+ buf[0] = 0;
+
+ if (secs >= MONTH_INT) {
+ num = secs / MONTH_INT;
+ secs -= num*MONTH_INT;
+ sprintf(buf, "%d month%s", num, (num>1) ? "s" : "");
+ }
+ if (secs >= WEEK_INT) {
+ num = secs / WEEK_INT;
+ secs -= num*WEEK_INT;
+ sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "",
+ num, (num>1) ? "s" : "");
+ strcat(buf, tmp);
+ }
+ if (secs >= DAY_INT) {
+ num = secs / DAY_INT;
+ secs -= num*DAY_INT;
+ sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "",
+ num, (num>1) ? "s" : "");
+ strcat(buf, tmp);
+ }
+ if (secs > 0) {
+ hr = secs / HOUR_INT;
+ secs -= hr*HOUR_INT;
+ min = secs / MINUTE_INT;
+ secs -= min*MINUTE_INT;
+ sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "",
+ hr, min, secs);
+ strcat(buf, tmp);
+ }
+ return buf;
+}
+
+
#ifndef EXT2_INODE_SIZE
#define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
#endif
void list_super (struct ext2_super_block * s)
{
int inode_blocks_per_group;
+ struct ext2fs_sb *sb = (struct ext2fs_sb *) s;
+ char buf[80];
+ const char *os;
inode_blocks_per_group = (((s->s_inodes_per_group *
EXT2_INODE_SIZE(s)) +
EXT2_BLOCK_SIZE(s) - 1) /
EXT2_BLOCK_SIZE(s));
-
printf ("Filesystem magic number: 0x%04X\n", s->s_magic);
printf ("Filesystem revision #: %d\n", s->s_rev_level);
+ if (sb->s_volume_name[0]) {
+ memset(buf, 0, sizeof(buf));
+ strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name));
+ printf("Filesystem volume name: %s\n", buf);
+ }
+ if (sb->s_last_mounted[0]) {
+ memset(buf, 0, sizeof(buf));
+ strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted));
+ printf("Last mounted on: %s\n", buf);
+ }
+ if (!e2p_is_null_uuid(sb->s_uuid)) {
+ e2p_uuid_to_str(sb->s_uuid, buf);
+ printf("Filesystem UUID: %s\n", buf);
+ }
printf ("Filesystem state: ");
print_fs_state (stdout, s->s_state);
printf ("\n");
printf ("Errors behavior: ");
print_fs_errors (stdout, s->s_errors);
printf ("\n");
+ switch (s->s_creator_os) {
+ case EXT2_OS_LINUX: os = "Linux"; break;
+ case EXT2_OS_HURD: os = "GNU"; break;
+ case EXT2_OS_MASIX: os = "Masix"; break;
+ default: os = "unknown"; break;
+ }
+ printf ("Filesystem OS type: %s\n", os);
printf ("Inode count: %u\n", s->s_inodes_count);
printf ("Block count: %u\n", s->s_blocks_count);
printf ("Reserved block count: %u\n", s->s_r_blocks_count);
printf ("Mount count: %u\n", s->s_mnt_count);
printf ("Maximum mount count: %d\n", s->s_max_mnt_count);
printf ("Last checked: %s", ctime ((time_t *) &s->s_lastcheck));
- printf ("Check interval: %u\n", s->s_checkinterval);
+ printf ("Check interval: %u (%s)\n", s->s_checkinterval,
+ interval_string(s->s_checkinterval));
if (s->s_checkinterval)
{
time_t next;
}
#endif
}
+
+
+
+
#include <stdio.h>
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
void print_fs_errors (FILE * f, unsigned short errors)
*/
#include <stdio.h>
-#include <linux/ext2_fs.h>
#include "e2p.h"
#include <stdio.h>
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
void print_fs_state (FILE * f, unsigned short state)
#include <sys/ioctl.h>
#endif
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int setflags (int fd, unsigned long flags)
#endif
#include <sys/ioctl.h>
-#include <linux/ext2_fs.h>
-
#include "e2p.h"
int setversion (int fd, unsigned long version)
--- /dev/null
+/*
+ * uuid.c -- utility routines for manipulating UUID's.
+ */
+
+#include <stdio.h>
+#include <linux/types.h>
+
+struct uuid {
+ __u32 time_low;
+ __u16 time_mid;
+ __u16 time_hi_and_version;
+ __u16 clock_seq;
+ __u8 node[6];
+};
+
+/* Returns 1 if the uuid is the NULL uuid */
+int e2p_is_null_uuid(void *uu)
+{
+ __u8 *cp;
+ int i;
+
+ for (i=0, cp = uu; i < 16; i++)
+ if (*cp)
+ return 0;
+ return 1;
+}
+
+static void e2p_unpack_uuid(void *in, struct uuid *uu)
+{
+ __u8 *ptr = in;
+ __u32 tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_low = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_mid = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_hi_and_version = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->clock_seq = tmp;
+
+ memcpy(uu->node, ptr, 6);
+}
+
+void e2p_uuid_to_str(void *uu, char *out)
+{
+ struct uuid uuid;
+
+ e2p_unpack_uuid(uu, &uuid);
+ sprintf(out,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+ uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+ uuid.node[0], uuid.node[1], uuid.node[2],
+ uuid.node[3], uuid.node[4], uuid.node[5]);
+}
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ../..
+my_dir = lib/ss
INSTALL = @INSTALL@
@MCONFIG@
+Sat Sep 7 07:36:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c: Override the kernel's idea of default
+ checkinterval from 0 (never) to 180 days.
+
+Wed Aug 28 03:20:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * namei.c (ext2fs_namei_follow): New function which follows
+ symbolic link (if any) at the target.
+
+Tue Aug 27 01:48:43 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * inode.c (ext2fs_read_inode, ext2fs_write_inode): Add support
+ for shortcut function fs->read_inode() and fs->write_inode().
+ Added inode_cache to reduce CPU time spent in doing
+ byte swapping.
+
+ * swapfs.c (ext2fs_swap_super): Swap the new fields in a V2
+ superblock.
+
+ * namei.c (ext2fs_follow_link): New function.
+ (ext2fs_namei): Extended to have support for chasing
+ symbolic links. ext2fs_namei() still returns an inode
+ which is a symbolic link. Symbolic links are only chased
+ while resolving the containing directory. To chase
+ symbolic links of the final result, use
+ ext2fs_follow_link().
+
+Mon Aug 26 23:46:07 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2_err.et.in: Added new error code EXT2_ET_SYMLINK_LOOP.
+
+ * bitops.h (ext2fs_set_bit, ext2fs_celar_bit): Use asm inlines
+ provided by Pete A. Zaitcev (zaitcev@lab.sun.mcst.ru).
+
+Thu Aug 22 00:40:18 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * initialize.c (ext2fs_initialize): On systems where the byte
+ order is not i386 compatible, set the swap_byte flag.
+
+ * inode.c (inocpy_with_swap): Check to see if inode contains a
+ fast symlink before swapping the inode block fields. This
+ required adding a new argument to inocpy_with_swap to
+ determine whether the mode field is in host order or not.
+
+Wed Aug 21 00:45:42 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * bitops.h (ext2fs_set_bit, ext2fs_clear_bit, ext2fs_test_bit): On
+ the sparc, if EXT2_STD_BITOPS set, use the standard
+ i386-compatible bitmask operations, instead on the
+ non-standard native bitmask operators.
+
+Fri Aug 9 11:11:35 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * block.c (ext2fs_block_iterate): Cause block iterator to return
+ the HURD translator block (along with everything else).
+ If the flag BLOCK_FLAG_DATA_ONLY is passed to the block
+ iterator, then don't return any meta data blocks
+ (including the HURD translator).
+
+Wed Jul 17 17:13:34 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * gen_uuid.c: New file, which generates DCE-compatible UUIDs.
+
+ * uuid.c: New file, containing UUID utility functions.
+
+Tue Jul 16 10:19:16 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Add a definition of the "real" ext2 superblock.
+
+Fri May 24 14:54:55 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * ext2fs.h: Fix erroneous ino_t type used in block_bitmap type.
+
+Sun May 19 15:39:03 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * openfs.c (ext2fs_open): If the blocksize in the superblock is
+ zero, return the error EXT2_ET_CORRUPT_SUPERBLOCK, since
+ that's a basic value that must be correct for the rest of
+ the library to work.
+
+ * ext2_err.et.in (EXT2_ET_CORRUPT_SUPERBLOCK): Added new error
+ code.
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ../..
+my_dir = lib/ext2fs
INSTALL = @INSTALL@
@MCONFIG@
llseek.o \
mkdir.o \
namei.o \
+ native.o \
newdir.o \
openfs.o \
read_bb.o \
$(srcdir)/llseek.c \
$(srcdir)/mkdir.c \
$(srcdir)/namei.c \
+ $(srcdir)/native.c \
$(srcdir)/newdir.c \
$(srcdir)/openfs.c \
$(srcdir)/read_bb.c \
DLL_MYDIR = ext2fs
DLL_INSTALL_DIR = $(libdir)
-ELF_VERSION = 2.0
+ELF_VERSION = 2.1
ELF_SO_VERSION = 2
ELF_IMAGE = libext2fs
ELF_MYDIR = ext2fs
# the Makefile.in file
#
ext2_err.o: ext2_err.c
-alloc.o: $(srcdir)/alloc.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+alloc.o: $(srcdir)/alloc.c $(srcdir)/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
badblocks.o: $(srcdir)/badblocks.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
bb_inode.o: $(srcdir)/bb_inode.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
bitmaps.o: $(srcdir)/bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
bitops.o: $(srcdir)/bitops.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
block.o: $(srcdir)/block.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
check_desc.o: $(srcdir)/check_desc.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
closefs.o: $(srcdir)/closefs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
cmp_bitmaps.o: $(srcdir)/cmp_bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
dirblock.o: $(srcdir)/dirblock.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
expanddir.o: $(srcdir)/expanddir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
freefs.o: $(srcdir)/freefs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
get_pathname.o: $(srcdir)/get_pathname.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
getsize.o: $(srcdir)/getsize.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
initialize.o: $(srcdir)/initialize.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
inline.o: $(srcdir)/inline.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
inode.o: $(srcdir)/inode.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
ismounted.o: $(srcdir)/ismounted.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
link.o: $(srcdir)/link.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
-llseek.o: $(srcdir)/llseek.c $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+llseek.o: $(srcdir)/llseek.c $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/io.h
mkdir.o: $(srcdir)/mkdir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
namei.o: $(srcdir)/namei.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
+native.o: $(srcdir)/native.c $(srcdir)/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
newdir.o: $(srcdir)/newdir.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
openfs.o: $(srcdir)/openfs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
read_bb.o: $(srcdir)/read_bb.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
read_bb_file.o: $(srcdir)/read_bb_file.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
rw_bitmaps.o: $(srcdir)/rw_bitmaps.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
swapfs.o: $(srcdir)/swapfs.c $(srcdir)/ext2fs.h \
- $(top_srcdir)/lib/et/com_err.h $(srcdir)/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/bitops.h
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/bitops.h \
+ $(srcdir)/io.h $(top_builddir)/lib/ext2fs/ext2_err.h
unix_io.o: $(srcdir)/unix_io.c $(top_srcdir)/lib/et/com_err.h \
$(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/io.h
-
#include "ext2fs.h"
-errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
- const char *descr,
- ext2fs_inode_bitmap *ret)
+errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+ __u32 end,
+ __u32 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret)
{
ext2fs_inode_bitmap bitmap;
int size;
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-
- fs->write_bitmaps = ext2fs_write_bitmaps;
-
- bitmap = malloc(sizeof(struct ext2fs_struct_inode_bitmap));
+ bitmap = malloc(sizeof(struct ext2fs_struct_generic_bitmap));
if (!bitmap)
return ENOMEM;
- bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
- bitmap->fs = fs;
- bitmap->start = 1;
- bitmap->end = fs->super->s_inodes_count;
- bitmap->real_end = (EXT2_INODES_PER_GROUP(fs->super)
- * fs->group_desc_count);
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ bitmap->fs = NULL;
+ bitmap->start = start;
+ bitmap->end = end;
+ bitmap->real_end = real_end;
+ bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
if (descr) {
bitmap->description = malloc(strlen(descr)+1);
if (!bitmap->description) {
return 0;
}
+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
+ const char *descr,
+ ext2fs_inode_bitmap *ret)
+{
+ ext2fs_inode_bitmap bitmap;
+ errcode_t retval;
+ __u32 start, end, real_end;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ fs->write_bitmaps = ext2fs_write_bitmaps;
+
+ start = 1;
+ end = fs->super->s_inodes_count;
+ real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
+
+ retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ descr, &bitmap);
+ if (retval)
+ return retval;
+
+ bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
+ bitmap->fs = fs;
+ bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
+
+ *ret = bitmap;
+ return 0;
+}
+
errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret)
{
ext2fs_block_bitmap bitmap;
- int size;
+ errcode_t retval;
+ __u32 start, end, real_end;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
fs->write_bitmaps = ext2fs_write_bitmaps;
- bitmap = malloc(sizeof(struct ext2fs_struct_inode_bitmap));
- if (!bitmap)
- return ENOMEM;
+ start = fs->super->s_first_data_block;
+ end = fs->super->s_blocks_count-1;
+ real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
+ * fs->group_desc_count)-1 + start;
+
+ retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
+ descr, &bitmap);
+ if (retval)
+ return retval;
bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
bitmap->fs = fs;
- bitmap->start = fs->super->s_first_data_block;
- bitmap->end = fs->super->s_blocks_count-1;
- bitmap->real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)
- * fs->group_desc_count)-1 + bitmap->start;
- if (descr) {
- bitmap->description = malloc(strlen(descr)+1);
- if (!bitmap->description) {
- free(bitmap);
- return ENOMEM;
- }
- strcpy(bitmap->description, descr);
- } else
- bitmap->description = 0;
-
- size = ((bitmap->real_end - bitmap->start) / 8) + 1;
- bitmap->bitmap = malloc(size);
- if (!bitmap->bitmap) {
- free(bitmap->description);
- free(bitmap);
- return ENOMEM;
- }
-
- memset(bitmap->bitmap, 0, size);
+ bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
+
*ret = bitmap;
return 0;
}
com_err(0, errcode, "#%u", arg);
}
+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+ int code, unsigned long arg)
+{
+ if (bitmap->description)
+ com_err(0, bitmap->base_error_code+code,
+ "#%u for %s", arg, bitmap->description);
+ else
+ com_err(0, bitmap->base_error_code + code, "#%u", arg);
+}
+
extern const char *ext2fs_test_string;
extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
const char *description);
+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
+ int code, unsigned long arg);
extern void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
extern void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
#define _EXT2_HAVE_ASM_BITOPS_
+#ifndef EXT2_OLD_BITOPS
+
+/*
+ * Do the bitops so that we are compatible with the standard i386
+ * convention.
+ */
+
+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "or %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR |= mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
+{
+#if 1
+ int mask;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ __asm__ __volatile__("ldub [%0], %%g6\n\t"
+ "andn %%g6, %2, %%g5\n\t"
+ "stb %%g5, [%0]\n\t"
+ "and %%g6, %2, %0\n"
+ : "=&r" (ADDR)
+ : "0" (ADDR), "r" (mask)
+ : "g5", "g6");
+ return (int) ADDR;
+
+#else
+ int mask, retval;
+ unsigned char *ADDR = (unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ retval = (mask & *ADDR) != 0;
+ *ADDR &= ~mask;
+ return retval;
+#endif
+}
+
+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
+{
+ int mask;
+ const unsigned char *ADDR = (const unsigned char *) addr;
+
+ ADDR += nr >> 3;
+ mask = 1 << (nr & 0x07);
+ return ((mask & *ADDR) != 0);
+}
+
+#else
+
+/* Do things the old, unplesant way. */
+
_INLINE_ int ext2fs_set_bit(int nr, void *addr)
{
int mask, retval;
mask = 1 << (nr & 31);
return ((mask & *ADDR) != 0);
}
+#endif
#endif /* __sparc__ */
#endif /* !_EXT2_HAVE_ASM_SWAB */
-_INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
- blk_t block)
+_INLINE_ void ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ __u32 bitno)
{
- if ((block < bitmap->start) || (block > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
- bitmap->description);
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
return;
}
- ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
+ ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
}
-_INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
- blk_t block)
+_INLINE_ void ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
{
- if ((block < bitmap->start) || (block > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
- block, bitmap->description);
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
return;
}
- ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
+ ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
}
-_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
- blk_t block)
+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
+ blk_t bitno)
{
- if ((block < bitmap->start) || (block > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
- block, bitmap->description);
+ if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
+ ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
return 0;
}
- return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
+ return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
+}
+
+_INLINE_ void ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ void ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, block);
+}
+
+_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
+ blk_t block)
+{
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ block);
}
_INLINE_ void ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ino_t inode)
{
- if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
- inode, bitmap->description);
- return;
- }
- ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
+ ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ void ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
ino_t inode)
{
- if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
- inode, bitmap->description);
- return;
- }
- ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
+ ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, inode);
}
_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
ino_t inode)
{
- if ((inode < bitmap->start) || (inode > bitmap->end)) {
- ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
- inode, bitmap->description);
- return 0;
- }
- return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
+ return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap,
+ inode);
}
_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
int i, flags, limit;
blk_t *block_nr;
- if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
- ret = (*ctx->func)(ctx->fs, ind_block, -1, ctx->private);
+ if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
+ ret = (*ctx->func)(ctx->fs, ind_block,
+ BLOCK_COUNT_IND, ctx->private);
if (!*ind_block || (ret & BLOCK_ABORT))
return ret;
if (*ind_block >= ctx->fs->super->s_blocks_count ||
return ret;
}
limit = ctx->fs->blocksize >> 2;
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
block_nr = (blk_t *) ctx->ind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
}
}
if (changed & BLOCK_CHANGED) {
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->ind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
ret |= BLOCK_ERROR | BLOCK_ABORT;
}
if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
- ret |= (*ctx->func)(ctx->fs, ind_block, -1, ctx->private);
+ ret |= (*ctx->func)(ctx->fs, ind_block,
+ BLOCK_COUNT_IND, ctx->private);
return ret;
}
int i, flags, limit;
blk_t *block_nr;
- if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
- ret = (*ctx->func)(ctx->fs, dind_block, -2, ctx->private);
+ if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
+ ret = (*ctx->func)(ctx->fs, dind_block,
+ BLOCK_COUNT_DIND, ctx->private);
if (!*dind_block || (ret & BLOCK_ABORT))
return ret;
if (*dind_block >= ctx->fs->super->s_blocks_count ||
return ret;
}
limit = ctx->fs->blocksize >> 2;
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
block_nr = (blk_t *) ctx->dind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
}
}
if (changed & BLOCK_CHANGED) {
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->dind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
ret |= BLOCK_ERROR | BLOCK_ABORT;
}
if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
- ret |= (*ctx->func)(ctx->fs, dind_block, -2, ctx->private);
+ ret |= (*ctx->func)(ctx->fs, dind_block,
+ BLOCK_COUNT_DIND, ctx->private);
return ret;
}
int i, flags, limit;
blk_t *block_nr;
- if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE))
- ret = (*ctx->func)(ctx->fs, tind_block, -3, ctx->private);
+ if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
+ ret = (*ctx->func)(ctx->fs, tind_block,
+ BLOCK_COUNT_TIND, ctx->private);
if (!*tind_block || (ret & BLOCK_ABORT))
return ret;
if (*tind_block >= ctx->fs->super->s_blocks_count ||
return ret;
}
limit = ctx->fs->blocksize >> 2;
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_READ)) {
block_nr = (blk_t *) ctx->tind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
}
}
if (changed & BLOCK_CHANGED) {
- if (ctx->fs->flags & EXT2_SWAP_BYTES) {
+ if ((ctx->fs->flags & EXT2_SWAP_BYTES) ||
+ (ctx->fs->flags & EXT2_SWAP_BYTES_WRITE)) {
block_nr = (blk_t *) ctx->tind_buf;
for (i = 0; i < limit; i++, block_nr++)
*block_nr = ext2fs_swab32(*block_nr);
ret |= BLOCK_ERROR | BLOCK_ABORT;
}
if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
+ !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
!(ret & BLOCK_ABORT))
- ret |= (*ctx->func)(ctx->fs, tind_block, -3, ctx->private);
+ ret |= (*ctx->func)(ctx->fs, tind_block,
+ BLOCK_COUNT_TIND, ctx->private);
return ret;
}
void *private)
{
int i;
+ int got_inode = 0;
int ret = 0;
struct block_context ctx;
blk_t blocks[EXT2_N_BLOCKS]; /* directory data blocks */
}
ctx.dind_buf = ctx.ind_buf + fs->blocksize;
ctx.tind_buf = ctx.dind_buf + fs->blocksize;
+
+ /*
+ * Iterate over the HURD translator block (if present)
+ */
+ if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
+ !(flags & BLOCK_FLAG_DATA_ONLY) &&
+ inode.osd1.hurd1.h_i_translator) {
+ ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
+ if (ctx.errcode)
+ goto abort;
+ got_inode = 1;
+ ret |= (*func)(fs, &inode.osd1.hurd1.h_i_translator,
+ BLOCK_COUNT_TRANSLATOR, private);
+ if (ret & BLOCK_ABORT)
+ goto abort;
+ }
+ /*
+ * Iterate over normal data blocks
+ */
for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) {
ret |= (*func)(fs, &blocks[i], ctx.bcount, private);
if (ret & BLOCK_ABORT)
goto abort;
}
- if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND))
+ if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK, &ctx);
+ if (ret & BLOCK_ABORT)
+ goto abort;
+ }
abort:
if (ret & BLOCK_CHANGED) {
- retval = ext2fs_read_inode(fs, ino, &inode);
- if (retval)
- return retval;
+ if (!got_inode) {
+ retval = ext2fs_read_inode(fs, ino, &inode);
+ if (retval)
+ return retval;
+ }
for (i=0; i < EXT2_N_BLOCKS; i++)
inode.i_block[i] = blocks[i];
retval = ext2fs_write_inode(fs, ino, &inode);
retval = io_channel_read_blk(fs->io, block, 1, buf);
if (retval)
return retval;
- if ((fs->flags & EXT2_SWAP_BYTES) == 0)
+ if ((fs->flags & (EXT2_SWAP_BYTES|EXT2_SWAP_BYTES_READ)) == 0)
return 0;
p = buf;
end = (char *) buf + fs->blocksize;
char *buf = 0;
struct ext2_dir_entry *dirent;
- if (fs->flags & EXT2_SWAP_BYTES) {
+ if ((fs->flags & EXT2_SWAP_BYTES) ||
+ (fs->flags & EXT2_SWAP_BYTES_WRITE)) {
write_buf = buf = malloc(fs->blocksize);
if (!buf)
return ENOMEM;
ec EXT2_ET_MAGIC_INODE_BITMAP,
"Wrong magic number for inode_bitmap structure"
-ec EXT2_ET_MAGIC_RESERVED_1,
- "Wrong magic number --- RESERVED_1"
+ec EXT2_ET_MAGIC_GENERIC_BITMAP,
+ "Wrong magic number for generic_bitmap structure"
ec EXT2_ET_MAGIC_RESERVED_2,
"Wrong magic number --- RESERVED_2"
"Illegal or malformed device name"
ec EXT2_ET_MISSING_INODE_TABLE,
- "A block group is missing an inode table."
+ "A block group is missing an inode table"
- end
+ec EXT2_ET_CORRUPT_SUPERBLOCK,
+ "The ext2 superblock is corrupt"
+
+ec EXT2_ET_BAD_GENERIC_MARK,
+ "Illegal generic bit number passed to ext2fs_mark_generic_bitmap"
+
+ec EXT2_ET_BAD_GENERIC_UNMARK,
+ "Illegal generic bit number passed to ext2fs_unmark_generic_bitmap"
+
+ec EXT2_ET_BAD_GENERIC_TEST,
+ "Illegal generic bit number passed to ext2fs_test_generic_bitmap"
+ec EXT2_ET_SYMLINK_LOOP,
+ "Too many symbolic links encountered."
+
+ec EXT2_ET_CALLBACK_NOTHANDLED,
+ "The callback function will not handle this case"
+
+ end
*/
#define EXT2_LIB_CURRENT_REV 0
+#include <sys/types.h>
#include <linux/types.h>
typedef __u32 blk_t;
typedef struct struct_ext2_filsys *ext2_filsys;
-struct ext2fs_struct_inode_bitmap {
- int magic;
- ext2_filsys fs;
- ino_t start, end;
- ino_t real_end;
- char *description;
- char *bitmap;
- int reserved[8];
+struct ext2fs_struct_generic_bitmap {
+ int magic;
+ ext2_filsys fs;
+ __u32 start, end;
+ __u32 real_end;
+ char * description;
+ char * bitmap;
+ errcode_t base_error_code;
+ __u32 reserved[7];
};
-typedef struct ext2fs_struct_inode_bitmap *ext2fs_inode_bitmap;
+#define EXT2FS_MARK_ERROR 0
+#define EXT2FS_UNMARK_ERROR 1
+#define EXT2FS_TEST_ERROR 2
-struct ext2fs_struct_block_bitmap {
- int magic;
- ext2_filsys fs;
- blk_t start, end;
- ino_t real_end;
- char *description;
- char *bitmap;
- int reserved[8];
-};
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
-typedef struct ext2fs_struct_block_bitmap *ext2fs_block_bitmap;
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
+
+typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
#ifdef EXT2_DYNAMIC_REV
#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s)
#define EXT2_FLAG_IB_DIRTY 0x10
#define EXT2_FLAG_BB_DIRTY 0x20
#define EXT2_SWAP_BYTES 0x40
+#define EXT2_SWAP_BYTES_READ 0x80
+#define EXT2_SWAP_BYTES_WRITE 0x100
/*
* Special flag in the ext2 inode i_flag field that means that this is
errcode_t (*get_blocks)(ext2_filsys fs, ino_t ino, blk_t *blocks);
errcode_t (*check_directory)(ext2_filsys fs, ino_t ino);
errcode_t (*write_bitmaps)(ext2_filsys fs);
- int reserved[16];
+ errcode_t (*read_inode)(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+ errcode_t (*write_inode)(ext2_filsys fs, ino_t ino,
+ struct ext2_inode *inode);
+ __u32 reserved[14];
/*
* Not used by ext2fs library; reserved for the use of the
* of the blocks containined in the indirect blocks are processed.
* This is useful if you are going to be deallocating blocks from an
* inode.
+ *
+ * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
+ * called for data blocks only.
*/
#define BLOCK_FLAG_APPEND 1
#define BLOCK_FLAG_HOLE 1
#define BLOCK_FLAG_DEPTH_TRAVERSE 2
+#define BLOCK_FLAG_DATA_ONLY 4
+
+/*
+ * Magic "block count" return values for the block iterator function.
+ */
+#define BLOCK_COUNT_IND (-1)
+#define BLOCK_COUNT_DIND (-2)
+#define BLOCK_COUNT_TIND (-3)
+#define BLOCK_COUNT_TRANSLATOR (-4)
/*
* Return flags for the directory iterator functions
#define LINUX_S_ISGID 0002000
#define LINUX_S_ISVTX 0001000
+#define LINUX_S_IRWXU 00700
+#define LINUX_S_IRUSR 00400
+#define LINUX_S_IWUSR 00200
+#define LINUX_S_IXUSR 00100
+
+#define LINUX_S_IRWXG 00070
+#define LINUX_S_IRGRP 00040
+#define LINUX_S_IWGRP 00020
+#define LINUX_S_IXGRP 00010
+
+#define LINUX_S_IRWXO 00007
+#define LINUX_S_IROTH 00004
+#define LINUX_S_IWOTH 00002
+#define LINUX_S_IXOTH 00001
+
#define LINUX_S_ISLNK(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
#define LINUX_S_ISREG(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
#define LINUX_S_ISDIR(m) (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
#define EXT2_CHECK_MAGIC(struct, code) \
if ((struct)->magic != (code)) return (code)
+
+
+/*
+ * The ext2fs library private definition of the ext2 superblock, so we
+ * don't have to depend on the kernel's definition of the superblock,
+ * which might not have the latest features.
+ */
+struct ext2fs_sb {
+ __u32 s_inodes_count; /* Inodes count */
+ __u32 s_blocks_count; /* Blocks count */
+ __u32 s_r_blocks_count; /* Reserved blocks count */
+ __u32 s_free_blocks_count; /* Free blocks count */
+ __u32 s_free_inodes_count; /* Free inodes count */
+ __u32 s_first_data_block; /* First Data Block */
+ __u32 s_log_block_size; /* Block size */
+ __s32 s_log_frag_size; /* Fragment size */
+ __u32 s_blocks_per_group; /* # Blocks per group */
+ __u32 s_frags_per_group; /* # Fragments per group */
+ __u32 s_inodes_per_group; /* # Inodes per group */
+ __u32 s_mtime; /* Mount time */
+ __u32 s_wtime; /* Write time */
+ __u16 s_mnt_count; /* Mount count */
+ __s16 s_max_mnt_count; /* Maximal mount count */
+ __u16 s_magic; /* Magic signature */
+ __u16 s_state; /* File system state */
+ __u16 s_errors; /* Behaviour when detecting errors */
+ __u16 s_minor_rev_level; /* minor revision level */
+ __u32 s_lastcheck; /* time of last check */
+ __u32 s_checkinterval; /* max. time between checks */
+ __u32 s_creator_os; /* OS */
+ __u32 s_rev_level; /* Revision level */
+ __u16 s_def_resuid; /* Default uid for reserved blocks */
+ __u16 s_def_resgid; /* Default gid for reserved blocks */
+ /*
+ * These fields are for EXT2_DYNAMIC_REV superblocks only.
+ *
+ * Note: the difference between the compatible feature set and
+ * the incompatible feature set is that if there is a bit set
+ * in the incompatible feature set that the kernel doesn't
+ * know about, it should refuse to mount the filesystem.
+ *
+ * e2fsck's requirements are more strict; if it doesn't know
+ * about a feature in either the compatible or incompatible
+ * feature set, it must abort and not try to meddle with
+ * things it doesn't understand...
+ */
+ __u32 s_first_ino; /* First non-reserved inode */
+ __u16 s_inode_size; /* size of inode structure */
+ __u16 s_block_group_nr; /* block group # of this superblock */
+ __u32 s_feature_compat; /* compatible feature set */
+ __u32 s_feature_incompat; /* incompatible feature set */
+ __u32 s_feature_ro_compat; /* readonly-compatible feature set */
+ __u8 s_uuid[16]; /* 128-bit uuid for volume */
+ char s_volume_name[16]; /* volume name */
+ char s_last_mounted[64]; /* directory where last mounted */
+ __u32 s_reserved[206]; /* Padding to the end of the block */
+};
/*
* function prototypes
extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
+ __u32 end,
+ __u32 real_end,
+ const char *descr,
+ ext2fs_generic_bitmap *ret);
extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
const char *descr,
ext2fs_block_bitmap *ret);
/* freefs.c */
extern void ext2fs_free(ext2_filsys fs);
+extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
int namelen, char *buf, ino_t *inode);
extern errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
const char *name, ino_t *inode);
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode);
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ino_t root, ino_t cwd,
+ ino_t inode, ino_t *res_inode);
+
+/* native.c */
+int ext2fs_native_flag(void);
/* newdir.c */
extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ino_t dir_ino,
/* swapfs.c */
extern void ext2fs_swap_super(struct ext2_super_block * super);
extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
+ struct ext2_inode *f, int hostorder);
+
/* inline functions */
extern void ext2fs_mark_super_dirty(ext2_filsys fs);
free(fs);
}
-void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
{
- if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
return;
bitmap->magic = 0;
free(bitmap);
}
+void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
+{
+ if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
+ return;
+
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ ext2fs_free_generic_bitmap(bitmap);
+}
+
void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
{
if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
return;
- bitmap->magic = 0;
- if (bitmap->description) {
- free(bitmap->description);
- bitmap->description = 0;
- }
- if (bitmap->bitmap) {
- free(bitmap->bitmap);
- bitmap->bitmap = 0;
- }
- free(bitmap);
+ bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
+ ext2fs_free_generic_bitmap(bitmap);
}
/*
* initialize.c --- initialize a filesystem handle given superblock
* parameters. Used by mke2fs when initializing a filesystem.
+ *
+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
*/
#include <stdio.h>
#define CREATOR_OS EXT2_OS_LINUX /* by default */
#endif
+/*
+ * Note we override the kernel include file's idea of what the default
+ * check interval (never) should be. It's a good idea to check at
+ * least *occasionally*, specially since servers will never rarely get
+ * to reboot, since Linux is so robust these days. :-)
+ *
+ * 180 days (six months) seems like a good value.
+ */
+#ifdef EXT2_DFL_CHECKINTERVAL
+#undef EXT2_DFL_CHECKINTERVAL
+#endif
+#define EXT2_DFL_CHECKINTERVAL (86400 * 180)
+
errcode_t ext2fs_initialize(const char *name, int flags,
struct ext2_super_block *param,
io_manager manager, ext2_filsys *ret_fs)
memset(fs, 0, sizeof(struct struct_ext2_filsys));
fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
- fs->flags = flags | EXT2_FLAG_RW;
+ fs->flags = flags | EXT2_FLAG_RW | ext2fs_native_flag();
retval = manager->open(name, IO_FLAG_RW, &fs->io);
if (retval)
goto cleanup;
#include "ext2fs.h"
-static void inocpy_with_swap(struct ext2_inode *t, struct ext2_inode *f);
-
errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
ext2_inode_scan *ret_scan)
{
scan->ptr += scan->inode_size - extra_bytes;
scan->bytes_left -= scan->inode_size - extra_bytes;
- if (scan->fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(inode, (struct ext2_inode *)
- scan->temp_buffer);
+ if ((scan->fs->flags & EXT2_SWAP_BYTES) ||
+ (scan->fs->flags & EXT2_SWAP_BYTES_READ))
+ ext2fs_swap_inode(scan->fs, inode,
+ (struct ext2_inode *) scan->temp_buffer, 0);
else
*inode = *((struct ext2_inode *) scan->temp_buffer);
} else {
- if (scan->fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(inode, (struct ext2_inode *)
- scan->ptr);
+ if ((scan->fs->flags & EXT2_SWAP_BYTES) ||
+ (scan->fs->flags & EXT2_SWAP_BYTES_READ))
+ ext2fs_swap_inode(scan->fs, inode,
+ (struct ext2_inode *) scan->ptr, 0);
else
*inode = *((struct ext2_inode *) scan->ptr);
scan->ptr += scan->inode_size;
static char *inode_buffer = 0;
static blk_t inode_buffer_block = 0;
static int inode_buffer_size = 0;
+#define INODE_CACHE_SIZE 4
+#ifdef INODE_CACHE_SIZE
+static int cache_last = -1;
+static struct {
+ ino_t inode;
+ struct ext2_inode value;
+} inode_cache[INODE_CACHE_SIZE];
+#endif
+
errcode_t ext2fs_read_inode (ext2_filsys fs, unsigned long ino,
struct ext2_inode * inode)
unsigned long group, block, block_nr, offset;
char *ptr;
errcode_t retval;
- int clen, length;
+ int clen, length, i;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+ /* Check to see if user has an override function */
+ if (fs->read_inode) {
+ retval = (fs->read_inode)(fs, ino, inode);
+ if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+ return retval;
+ }
+ /* Check to see if it's in the inode cache */
+#ifdef INODE_CACHE_SIZE
+ if (cache_last == -1) {
+ for (i=0; i < INODE_CACHE_SIZE; i++)
+ inode_cache[i].inode = 0;
+ cache_last = INODE_CACHE_SIZE-1;
+ } else for (i=0; i < INODE_CACHE_SIZE; i++) {
+ if (inode_cache[i].inode == ino) {
+ *inode = inode_cache[i].value;
+ return 0;
+ }
+ }
+#endif
if (ino > fs->super->s_inodes_count)
return EXT2_ET_BAD_INODE_NUM;
if (inode_buffer_size != fs->blocksize) {
} else
memcpy((char *) inode, ptr, length);
- if (fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(inode, inode);
+ if ((fs->flags & EXT2_SWAP_BYTES) ||
+ (fs->flags & EXT2_SWAP_BYTES_READ))
+ ext2fs_swap_inode(fs, inode, inode, 0);
+
+ /* Update the inode cache */
+#ifdef INODE_CACHE_SIZE
+ cache_last = (cache_last + 1) % INODE_CACHE_SIZE;
+ inode_cache[cache_last].inode = ino;
+ inode_cache[cache_last].value = *inode;
+#endif
return 0;
}
errcode_t retval;
struct ext2_inode temp_inode;
char *ptr;
- int i, clen, length;
+ int clen, length, i;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+ /* Check to see if user provided an override function */
+ if (fs->write_inode) {
+ retval = (fs->write_inode)(fs, ino, inode);
+ if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
+ return retval;
+ }
+ /* Check to see if the inode cache needs to be updated */
+#ifdef INODE_CACHE_SIZE
+ for (i=0; i < INODE_CACHE_SIZE; i++) {
+ if (inode_cache[i].inode == ino) {
+ inode_cache[i].value = *inode;
+ break;
+ }
+ }
+#endif
if (!(fs->flags & EXT2_FLAG_RW))
return EXT2_ET_RO_FILSYS;
inode_buffer_size = fs->blocksize;
inode_buffer_block = 0;
}
- if (fs->flags & EXT2_SWAP_BYTES)
- inocpy_with_swap(&temp_inode, inode);
+ if ((fs->flags & EXT2_SWAP_BYTES) ||
+ (fs->flags & EXT2_SWAP_BYTES_WRITE))
+ ext2fs_swap_inode(fs, &temp_inode, inode, 1);
else
memcpy(&temp_inode, inode, sizeof(struct ext2_inode));
if (retval)
return retval;
if (!LINUX_S_ISDIR(inode.i_mode))
- return ENOTDIR;
+ return ENOTDIR;
return 0;
}
-static void inocpy_with_swap(struct ext2_inode *t, struct ext2_inode *f)
-{
- unsigned i;
-
- t->i_mode = ext2fs_swab16(f->i_mode);
- t->i_uid = ext2fs_swab16(f->i_uid);
- t->i_size = ext2fs_swab32(f->i_size);
- t->i_atime = ext2fs_swab32(f->i_atime);
- t->i_ctime = ext2fs_swab32(f->i_ctime);
- t->i_mtime = ext2fs_swab32(f->i_mtime);
- t->i_dtime = ext2fs_swab32(f->i_dtime);
- t->i_gid = ext2fs_swab16(f->i_gid);
- t->i_links_count = ext2fs_swab16(f->i_links_count);
- t->i_blocks = ext2fs_swab32(f->i_blocks);
- t->i_flags = ext2fs_swab32(f->i_flags);
- for (i = 0; i < EXT2_N_BLOCKS; i++)
- t->i_block[i] = ext2fs_swab32(f->i_block[i]);
- t->i_version = ext2fs_swab32(f->i_version);
- t->i_file_acl = ext2fs_swab32(f->i_file_acl);
- t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
- t->i_faddr = ext2fs_swab32(f->i_faddr);
- t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
- t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
- t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
-}
#include <errno.h>
#endif
+/* #define NAMEI_DEBUG */
+
#include <linux/ext2_fs.h>
#include "ext2fs.h"
return (ls.found) ? 0 : ENOENT;
}
-errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd, const char *name,
- ino_t *inode)
+
+static errcode_t open_namei(ext2_filsys fs, ino_t root, ino_t base,
+ const char *pathname, int pathlen, int follow,
+ int link_count, char *buf, ino_t *res_inode);
+
+static errcode_t follow_link(ext2_filsys fs, ino_t root, ino_t dir,
+ ino_t inode, int link_count,
+ char *buf, ino_t *res_inode)
{
- ino_t dir = cwd;
- char *buf;
- const char *p = name, *q;
- int len;
- errcode_t retval;
+ char *pathname;
+ char *buffer = 0;
+ errcode_t retval;
+ struct ext2_inode ei;
- EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+#ifdef NAMEI_DEBUG
+ printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
+ root, dir, inode, link_count);
+
+#endif
+ retval = ext2fs_read_inode (fs, inode, &ei);
+ if (retval) return retval;
+ if (!LINUX_S_ISLNK (ei.i_mode)) {
+ *res_inode = inode;
+ return 0;
+ }
+ if (link_count++ > 5) {
+ return EXT2_ET_SYMLINK_LOOP;
+ }
+ if (ei.i_blocks) {
+ buffer = malloc (fs->blocksize);
+ if (!buffer)
+ return ENOMEM;
+ retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
+ if (retval) {
+ free(buffer);
+ return retval;
+ }
+ pathname = buffer;
+ } else
+ pathname = (char *)&(ei.i_block[0]);
+ retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
+ link_count, buf, res_inode);
+ if (buffer)
+ free (buffer);
+ return retval;
+}
- buf = malloc(fs->blocksize);
- if (!buf)
- return ENOMEM;
- if (*p == '/') {
- p++;
- dir = root;
+/*
+ * This routine interprets a pathname in the context of the current
+ * directory and the root directory, and returns the inode of the
+ * containing directory, and a pointer to the filename of the file
+ * (pointing into the pathname) and the length of the filename.
+ */
+static errcode_t dir_namei(ext2_filsys fs, ino_t root, ino_t dir,
+ const char *pathname, int pathlen,
+ int link_count, char *buf,
+ const char **name, int *namelen, ino_t *res_inode)
+{
+ char c;
+ const char *thisname;
+ int len;
+ ino_t inode;
+ errcode_t retval;
+
+ if ((c = *pathname) == '/') {
+ dir = root;
+ pathname++;
+ pathlen--;
}
- while (*p) {
- q = strchr(p, '/');
- if (q)
- len = q - p;
- else
- len = strlen(p);
- if (len) {
- retval = ext2fs_lookup(fs, dir, p, len, buf, &dir);
- if (retval) {
- free(buf);
- return retval;
- }
+ while (1) {
+ thisname = pathname;
+ for (len=0; --pathlen >= 0;len++) {
+ c = *(pathname++);
+ if (c == '/')
+ break;
}
- if (q)
- p = q+1;
- else
+ if (pathlen < 0)
break;
+ retval = ext2fs_lookup (fs, dir, thisname, len, buf, &inode);
+ if (retval) return retval;
+ retval = follow_link (fs, root, dir, inode,
+ link_count, buf, &dir);
+ if (retval) return retval;
+ }
+ *name = thisname;
+ *namelen = len;
+ *res_inode = dir;
+ return 0;
+}
+
+static errcode_t open_namei(ext2_filsys fs, ino_t root, ino_t base,
+ const char *pathname, int pathlen, int follow,
+ int link_count, char *buf, ino_t *res_inode)
+{
+ const char *basename;
+ int namelen;
+ ino_t dir, inode;
+ errcode_t retval;
+
+#ifdef NAMEI_DEBUG
+ printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n",
+ root, base, pathlen, pathname, link_count);
+#endif
+ retval = dir_namei(fs, root, base, pathname, pathlen,
+ link_count, buf, &basename, &namelen, &dir);
+ if (retval) return retval;
+ if (!namelen) { /* special case: '/usr/' etc */
+ *res_inode=dir;
+ return 0;
}
- *inode = dir;
- free(buf);
+ retval = ext2fs_lookup (fs, dir, basename, namelen, buf, &inode);
+ if (retval)
+ return retval;
+ if (follow) {
+ retval = follow_link(fs, root, dir, inode, link_count,
+ buf, &inode);
+ if (retval)
+ return retval;
+ }
+#ifdef NAMEI_DEBUG
+ printf("open_namei: (link_count=%d) returns %lu\n",
+ link_count, inode);
+#endif
+ *res_inode = inode;
return 0;
}
+
+errcode_t ext2fs_namei(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode)
+{
+ char *buf;
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ buf = malloc(fs->blocksize);
+ if (!buf)
+ return ENOMEM;
+
+ retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
+ buf, inode);
+
+ free(buf);
+ return retval;
+}
+
+errcode_t ext2fs_namei_follow(ext2_filsys fs, ino_t root, ino_t cwd,
+ const char *name, ino_t *inode)
+{
+ char *buf;
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ buf = malloc(fs->blocksize);
+ if (!buf)
+ return ENOMEM;
+
+ retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
+ buf, inode);
+
+ free(buf);
+ return retval;
+}
+
+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ino_t root, ino_t cwd,
+ ino_t inode, ino_t *res_inode)
+{
+ char *buf;
+ errcode_t retval;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+
+ buf = malloc(fs->blocksize);
+ if (!buf)
+ return ENOMEM;
+
+ retval = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
+
+ free(buf);
+ return retval;
+}
+
--- /dev/null
+/*
+ * native.c --- returns the ext2_flag for a native byte order
+ *
+ * Copyright (C) 1996 Theodore Ts'o.
+ *
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ */
+
+#include <stdio.h>
+#include <linux/ext2_fs.h>
+
+#include "ext2fs.h"
+
+static int i386_byteorder(void)
+{
+ int one = 1;
+ char *cp = (char *) &one;
+
+ return (*cp == 1);
+}
+
+int ext2fs_native_flag(void)
+{
+ if (i386_byteorder())
+ return 0;
+ return EXT2_SWAP_BYTES;
+}
+
+
+
#endif
#endif
fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
+ if (fs->blocksize == 0) {
+ retval = EXT2_ET_CORRUPT_SUPERBLOCK;
+ goto cleanup;
+ }
fs->fragsize = EXT2_FRAG_SIZE(fs->super);
fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group *
EXT2_INODE_SIZE(fs->super) +
void ext2fs_swap_super(struct ext2_super_block * super)
{
+ struct ext2fs_sb *s = (struct ext2fs_sb *) super;
+
super->s_inodes_count = ext2fs_swab32(super->s_inodes_count);
super->s_blocks_count = ext2fs_swab32(super->s_blocks_count);
super->s_r_blocks_count = ext2fs_swab32(super->s_r_blocks_count);
super->s_magic = ext2fs_swab16(super->s_magic);
super->s_state = ext2fs_swab16(super->s_state);
super->s_errors = ext2fs_swab16(super->s_errors);
+ s->s_minor_rev_level = ext2fs_swab16(s->s_minor_rev_level);
super->s_lastcheck = ext2fs_swab32(super->s_lastcheck);
super->s_checkinterval = ext2fs_swab32(super->s_checkinterval);
super->s_creator_os = ext2fs_swab32(super->s_creator_os);
super->s_def_resuid = ext2fs_swab16(super->s_def_resuid);
super->s_def_resgid = ext2fs_swab16(super->s_def_resgid);
#endif
+ s->s_first_ino = ext2fs_swab32(s->s_first_ino);
+ s->s_inode_size = ext2fs_swab16(s->s_inode_size);
+ s->s_block_group_nr = ext2fs_swab16(s->s_block_group_nr);
+ s->s_feature_compat = ext2fs_swab32(s->s_feature_compat);
+ s->s_feature_incompat = ext2fs_swab32(s->s_feature_incompat);
+ s->s_feature_ro_compat = ext2fs_swab32(s->s_feature_ro_compat);
}
void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
}
+void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
+ struct ext2_inode *f, int hostorder)
+{
+ unsigned i;
+ int islnk = 0;
+ if (hostorder && LINUX_S_ISLNK(f->i_mode))
+ islnk = 1;
+ t->i_mode = ext2fs_swab16(f->i_mode);
+ if (!hostorder && LINUX_S_ISLNK(t->i_mode))
+ islnk = 1;
+ t->i_uid = ext2fs_swab16(f->i_uid);
+ t->i_size = ext2fs_swab32(f->i_size);
+ t->i_atime = ext2fs_swab32(f->i_atime);
+ t->i_ctime = ext2fs_swab32(f->i_ctime);
+ t->i_mtime = ext2fs_swab32(f->i_mtime);
+ t->i_dtime = ext2fs_swab32(f->i_dtime);
+ t->i_gid = ext2fs_swab16(f->i_gid);
+ t->i_links_count = ext2fs_swab16(f->i_links_count);
+ t->i_blocks = ext2fs_swab32(f->i_blocks);
+ t->i_flags = ext2fs_swab32(f->i_flags);
+ if (!islnk || f->i_blocks) {
+ for (i = 0; i < EXT2_N_BLOCKS; i++)
+ t->i_block[i] = ext2fs_swab32(f->i_block[i]);
+ } else if (t != f) {
+ for (i = 0; i < EXT2_N_BLOCKS; i++)
+ t->i_block[i] = f->i_block[i];
+ }
+ t->i_version = ext2fs_swab32(f->i_version);
+ t->i_file_acl = ext2fs_swab32(f->i_file_acl);
+ t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
+ t->i_faddr = ext2fs_swab32(f->i_faddr);
+ switch (fs->super->s_creator_os) {
+ case EXT2_OS_LINUX:
+ t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
+ t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
+ t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
+ break;
+ case EXT2_OS_HURD:
+ t->osd1.hurd1.h_i_translator =
+ ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
+ t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
+ t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
+ t->osd2.hurd2.h_i_mode_high =
+ ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
+ t->osd2.hurd2.h_i_uid_high =
+ ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
+ t->osd2.hurd2.h_i_gid_high =
+ ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
+ t->osd2.hurd2.h_i_author =
+ ext2fs_swab32 (f->osd2.hurd2.h_i_author);
+ break;
+ case EXT2_OS_MASIX:
+ t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
+ t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
+ t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
+ break;
+ }
+}
+
+Fri Aug 30 22:36:48 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * invocation.c (ss_create_invocation): Change function prototype
+ of invocation so that the first two arguments are const
+ char *, and that the info_ptr is a void *, not a char *.
+
+ * ss.h: Added declaration of ss_execute_line()
+
+Sat Aug 10 00:17:14 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * listen.c (ss_listen): Fix -Wall flames.
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ../..
+my_dir = lib/ss
INSTALL = @INSTALL@
@MCONFIG@
va_dcl
#endif
{
- register char const *whoami;
+ register char *whoami;
va_list pvar;
#ifndef HAVE_STDARG_H
int sci_idx;
* Notes:
*/
-ss_execute_command(sci_idx, argv)
+int ss_execute_command(sci_idx, argv)
int sci_idx;
register char *argv[];
{
int ss_create_invocation(subsystem_name, version_string, info_ptr,
request_table_ptr, code_ptr)
- char *subsystem_name, *version_string;
- char *info_ptr;
+ const char *subsystem_name, *version_string;
+ void *info_ptr;
ss_request_table *request_table_ptr;
int *code_ptr;
{
static ss_data *current_info;
static jmp_buf listen_jmpb;
-static sigret_t print_prompt()
+static sigret_t print_prompt(int sig)
{
#ifdef BSD
/* put input into a reasonable mode */
(void) fflush(stdout);
}
-static sigret_t listen_int_handler()
+static sigret_t listen_int_handler(int sig)
{
putc('\n', stdout);
signal(SIGINT, listen_int_handler);
longjmp(listen_jmpb, 1);
}
-int ss_listen (sci_idx)
- int sci_idx;
+int ss_listen (int sci_idx)
{
char *cp;
ss_data *info;
- sigret_t (*sig_int)(), (*sig_cont)(), (*old_sig_cont)();
+ sigret_t (*sig_int)(int), (*sig_cont)(int), (*old_sig_cont)(int);
char input[BUFSIZ];
char buffer[BUFSIZ];
char *end = buffer;
ss_data *old_info = current_info;
current_info = info = ss_info(sci_idx);
- sig_cont = (sigret_t (*)()) 0;
+ sig_cont = (sigret_t (*)(int)) 0;
info->abort = 0;
#ifdef POSIX_SIGNALS
sigemptyset(&igmask);
(void) sigsetmask(mask);
#endif
while(!info->abort) {
- print_prompt();
+ print_prompt(0);
*end = '\0';
old_sig_cont = sig_cont;
sig_cont = signal(SIGCONT, print_prompt);
return code;
}
-void ss_abort_subsystem(sci_idx, code)
- int sci_idx;
- int code;
+void ss_abort_subsystem(int sci_idx, int code)
{
ss_info(sci_idx)->abort = 1;
ss_info(sci_idx)->exit_status = code;
}
-int ss_quit(argc, argv, sci_idx, infop)
- int argc;
- char **argv;
- int sci_idx;
- pointer infop;
+void ss_quit(int argc, const char * const *argv, int sci_idx, pointer infop)
{
ss_abort_subsystem(sci_idx, 0);
}
#include "ss_internal.h"
#ifdef __STDC__
-#define DECLARE(name) void name(int argc,char **argv, int sci_idx)
+#define DECLARE(name) void name(int argc,const char * const *argv, \
+ int sci_idx, void *infop)
#else
-#define DECLARE(name) void name(argc,argv,sci_idx)int argc,sci_idx;char **argv;
+#define DECLARE(name) void name(argc,argv,sci_idx,info)int argc,sci_idx;char **argv;void *infop;
+
#endif
/*
char *ss_name(int sci_idx);
void ss_error (int, long, char const *, ...);
void ss_perror (int, long, char const *);
-int ss_create_invocation(char *, char *, char *, ss_request_table *, int *);
+int ss_create_invocation(const char *, const char *, void *,
+ ss_request_table *, int *);
void ss_delete_invocation(int);
int ss_listen(int);
+int ss_execute_line(int, char *);
void ss_add_request_table(int, ss_request_table *, int, int *);
void ss_delete_request_table(int, ss_request_table *, int *);
void ss_abort_subsystem(int sci_idx, int code);
+void ss_quit(int argc, const char * const *argv, int sci_idx, void *infop);
+void ss_self_identify(int argc, const char * const *argv, int sci_idx, void *infop);
+void ss_subsystem_name(int argc, const char * const *argv,
+ int sci_idx, void *infop);
+void ss_subsystem_version(int argc, const char * const *argv,
+ int sci_idx, void *infop);
+void ss_unimplemented(int argc, const char * const *argv,
+ int sci_idx, void *infop);
#else
char *ss_name();
void ss_error ();
int ss_create_invocation();
void ss_delete_invocation();
int ss_listen();
+int ss_execute_line();
void ss_add_request_table();
void ss_delete_request_table();
void ss_abort_subsystem();
+void ss_quit();
+void ss_self_identify();
+void ss_subsystem_name();
+void ss_subsystem_version();
+void ss_unimplemented();
#endif
extern ss_request_table ss_std_requests;
#endif /* _ss_h */
typedef struct _ss_data { /* init values */
/* this subsystem */
- char *subsystem_name;
- char *subsystem_version;
+ const char *subsystem_name;
+ const char *subsystem_version;
/* current request info */
int argc;
char **argv; /* arg list */
* $Locker$
*
* $Log$
- * Revision 1.7 1997/04/29 14:34:41 tytso
- * Checked in e2fsprogs 1.04.
+ * Revision 1.8 1997/04/29 14:52:31 tytso
+ * Checked in e2fsprogs 1.05
*
* Revision 1.1 1993/06/03 12:31:25 tytso
* Initial revision
E2FSPROGS_MONTH=@E2FSPROGS_MONTH@
E2FSPROGS_YEAR=@E2FSPROGS_YEAR@
E2FSPROGS_VERSION=@E2FSPROGS_VERSION@
+SIZEOF_LONG_LONG=@SIZEOF_LONG_LONG@
SIZEOF_LONG=@SIZEOF_LONG@
SIZEOF_INT=@SIZEOF_INT@
SIZEOF_SHORT=@SIZEOF_SHORT@
--- /dev/null
+Tue Aug 27 16:50:43 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * uuid/gen_uuid.c [HAVE_NET_IF_H] <net/if.h>: Include guarded.
+ [HAVE_NETINET_IN_H] <netinet/in.h>: Include guarded.
+ (get_node_id): Surround bulk of function with #ifdef HAVE_NET_IF_H.
+
+Tue Aug 27 16:50:16 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * gen_uuid.c (get_node_id): Add a specific ifdef for the HURD,
+ since it is broken w.r.t getting hardware addresses.
--- /dev/null
+# Makefile for the second extended file system utility functions
+#
+# Copyright (C) 1993 Remy Card (card@masi.ibp.fr)
+#
+# This file can be redistributed under the terms of the GNU General
+# Public License
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ../..
+my_dir = lib/uuid
+INSTALL = @INSTALL@
+
+@MCONFIG@
+
+all::
+
+OBJS= clear.o \
+ compare.o \
+ copy.o \
+ gen_uuid.o \
+ isnull.o \
+ pack.o \
+ parse.o \
+ unpack.o \
+ unparse.o
+
+SRCS= $(srcdir)/clear.c \
+ $(srcdir)/compare.c \
+ $(srcdir)/copy.c \
+ $(srcdir)/gen_uuid.c \
+ $(srcdir)/isnull.c \
+ $(srcdir)/pack.c \
+ $(srcdir)/parse.c \
+ $(srcdir)/unpack.c \
+ $(srcdir)/unparse.c
+
+LIBRARY= libuuid
+LIBDIR= uuid
+
+DLL_ADDRESS = 0x66980000
+DLL_JUMPSIZE = 0x1000
+DLL_GOTSIZE = 0x1000
+DLL_VERSION = 1.0
+DLL_IMAGE = libuuid
+DLL_STUB = libuuid
+DLL_MYDIR = uuid
+DLL_INSTALL_DIR = $(libdir)
+
+ELF_VERSION = 1.0
+ELF_SO_VERSION = 1
+ELF_IMAGE = libuuid
+ELF_MYDIR = uuid
+ELF_INSTALL_DIR = $(libdir)
+
+BSDLIB_VERSION = 1.0
+BSDLIB_IMAGE = libuuid
+BSDLIB_MYDIR = uuid
+BSDLIB_INSTALL_DIR = $(libdir)
+
+@MAKEFILE_LIBRARY@
+@MAKEFILE_DLL@
+@MAKEFILE_ELF@
+@MAKEFILE_BSDLIB@
+@MAKEFILE_PROFILE@
+@MAKEFILE_CHECKER@
+
+.c.o:
+ $(CC) $(ALL_CFLAGS) -c $< -o $@
+@PROFILE_CMT@ $(CC) $(ALL_CFLAGS) -pg -o profiled/$*.o -c $<
+@CHECKER_CMT@ $(CC) $(ALL_CFLAGS) -checker -g -o checker/$*.o -c $<
+@DLL_CMT@ (export JUMP_DIR=`pwd`/jump; $(CC) -B$(JUMP_PREFIX) $(ALL_CFLAGS) \
+@DLL_CMT@ -o jump/$*.o -c $<)
+@ELF_CMT@ $(CC) $(ALL_CFLAGS) -fPIC -o elfshared/$*.o -c $<
+@BSDLIB_CMT@ $(CC) $(ALL_CFLAGS) -fpic -o pic/$*.o -c $<
+
+all:: tst_uuid
+
+tst_uuid: tst_uuid.o $(LIBUUID)
+ $(CC) $(ALL_LDFLAGS) -o tst_uuid tst_uuid.o $(LIBUUID)
+
+installdirs::
+ $(top_srcdir)/mkinstalldirs $(DESTDIR)$(ulibdir) \
+ $(DESTDIR)$(includedir)/uuid
+
+install:: all installdirs
+ $(INSTALL_DATA) libuuid.a $(DESTDIR)$(ulibdir)/libuuid.a
+ $(CHMOD) 644 $(DESTDIR)$(ulibdir)/libuuid.a
+ -$(RANLIB) $(DESTDIR)$(ulibdir)/libuuid.a
+ $(CHMOD) $(LIBMODE) $(DESTDIR)$(ulibdir)/libuuid.a
+ $(INSTALL_DATA) $(srcdir)/uuid.h $(DESTDIR)$(includedir)/uuid/uuid.h
+
+uninstall::
+ $(RM) -f $(ulibdir)/libuuid.a
+
+clean::
+ $(RM) -f \#* *.s *.o *.a *~ *.bak core profiled/* checker/*
+ $(RM) -f ../libuuid.a ../libuuid_p.a tst_uuid
+
+mostlyclean:: clean
+distclean:: clean
+ $(RM) -f .depend Makefile
+
+# +++ Dependency line eater +++
+#
+# Makefile dependencies follow. This must be the last section in
+# the Makefile.in file
+#
+clear.o: $(srcdir)/clear.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+compare.o: $(srcdir)/compare.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+copy.o: $(srcdir)/copy.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+gen_uuid.o: $(srcdir)/gen_uuid.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+isnull.o: $(srcdir)/isnull.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+pack.o: $(srcdir)/pack.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+parse.o: $(srcdir)/parse.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+unpack.o: $(srcdir)/unpack.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
+unparse.o: $(srcdir)/unparse.c $(srcdir)/uuidP.h $(srcdir)/uuid.h
--- /dev/null
+/*
+ * clear.c -- Clear a UUID
+ */
+
+#include "uuidP.h"
+
+void uuid_clear(uuid_t uu)
+{
+ memset(uu, 0, 16);
+}
+
--- /dev/null
+/*
+ * compare.c --- compare whether or not two UUID's are the same
+ *
+ * Returns 0 if the two UUID's are different, and 1 if they are the same.
+ */
+
+#include "uuidP.h"
+
+int uuid_compare(uuid_t uu1, uuid_t uu2)
+{
+ unsigned char *cp1, *cp2;
+ int i;
+
+ for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
+ if (*cp1++ != *cp2++)
+ return 0;
+ return 1;
+}
+
--- /dev/null
+/*
+ * copy.c --- copy UUIDs
+ */
+
+#include "uuidP.h"
+
+void uuid_copy(uuid_t uu1, uuid_t uu2)
+{
+ unsigned char *cp1, *cp2;
+ int i;
+
+ for (i=0, cp1 = uu1, cp2 = uu2; i < 16; i++)
+ *cp1++ = *cp2++;
+}
--- /dev/null
+/*
+ * gen_uuid.c --- generate a DCE-compatible uuid
+ */
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#include <string.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+#ifdef HAVE_NET_IF_H
+#include <net/if.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+#include "uuidP.h"
+
+#ifdef HAVE_SRANDOM
+#define srand(x) srandom(x)
+#define rand() random()
+#endif
+
+/*
+ * Generate a series of random bytes. Use /dev/urandom if possible,
+ * and if not, use srandom/random.
+ */
+static void get_random_bytes(void *buf, int nbytes)
+{
+ static int fd = -2;
+ int i;
+ char *cp = (char *) buf;
+
+ if (fd == -2) {
+ fd = open("/dev/urandom", O_RDONLY);
+ srand((getpid() << 16) ^ getuid() ^ time(0));
+ }
+ if (fd > 0) {
+ i = read(fd, cp, nbytes);
+ if (i == nbytes)
+ return;
+ if (i > 0) {
+ nbytes -= i;
+ cp += i;
+ }
+ }
+ for (i=0; i < nbytes; i++)
+ *cp++ = rand() & 0xFF;
+}
+
+/*
+ * Get the ethernet hardware address, if we can find it...
+ */
+static int get_node_id(unsigned char *node_id)
+{
+#ifdef HAVE_NET_IF_H
+ int sd;
+ struct ifreq ifr, *ifrp;
+ struct ifconf ifc;
+ char buf[1024];
+ int n, i;
+ unsigned char *a;
+
+/*
+ * BSD 4.4 defines the size of an ifreq to be
+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
+ * However, under earlier systems, sa_len isn't present, so the size is
+ * just sizeof(struct ifreq)
+ */
+#ifdef HAVE_SA_LEN
+#ifndef max
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#endif
+#define ifreq_size(i) max(sizeof(struct ifreq),\
+ sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
+#else
+#define ifreq_size(i) sizeof(struct ifreq)
+#endif /* HAVE_SA_LEN*/
+
+ sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (sd < 0) {
+ return -1;
+ }
+ memset(buf, 0, sizeof(buf));
+ ifc.ifc_len = sizeof(buf);
+ ifc.ifc_buf = buf;
+ if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
+ close(sd);
+ return -1;
+ }
+ n = ifc.ifc_len;
+ for (i = 0; i < n; i+= ifreq_size(*ifr) ) {
+ ifrp = (struct ifreq *)((caddr_t) ifc.ifc_buf+i);
+ strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
+#ifdef SIOCGIFHWADDR
+ if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
+#else
+#ifdef SIOCGENADDR
+ if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
+ continue;
+ a = (unsigned char *) ifr.ifr_enaddr;
+#else
+ /*
+ * XXX we don't have a way of getting the hardware
+ * address
+ */
+ close(sd);
+ return 0;
+#endif /* SIOCGENADDR */
+#endif /* SIOCGIFHWADDR */
+ if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
+ continue;
+ if (node_id) {
+ memcpy(node_id, a, 6);
+ close(sd);
+ return 1;
+ }
+ }
+ close(sd);
+#endif
+ return 0;
+}
+
+/* Assume that the gettimeofday() has microsecond granularity */
+#define MAX_ADJUSTMENT 10
+
+static int get_clock(__u32 *clock_high, __u32 *clock_low, __u16 *ret_clock_seq)
+{
+ static int adjustment = 0;
+ static struct timeval last = {0, 0};
+ static __u16 clock_seq;
+ struct timeval tv;
+ unsigned long long clock;
+
+try_again:
+ gettimeofday(&tv, 0);
+ if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
+ get_random_bytes(&clock_seq, sizeof(clock_seq));
+ clock_seq &= 0x1FFF;
+ last = tv;
+ last.tv_sec--;
+ }
+ if ((tv.tv_sec < last.tv_sec) ||
+ ((tv.tv_sec == last.tv_sec) &&
+ (tv.tv_usec < last.tv_usec))) {
+ clock_seq = (clock_seq+1) & 0x1FFF;
+ adjustment = 0;
+ } else if ((tv.tv_sec == last.tv_sec) &&
+ (tv.tv_usec == last.tv_usec)) {
+ if (adjustment >= MAX_ADJUSTMENT)
+ goto try_again;
+ adjustment++;
+ } else
+ adjustment = 0;
+
+ clock = tv.tv_usec*10 + adjustment;
+ clock += ((unsigned long long) tv.tv_sec)*10000000;
+ clock += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
+
+ *clock_high = clock >> 32;
+ *clock_low = clock;
+ *ret_clock_seq = clock_seq;
+ return 0;
+}
+
+void uuid_generate(uuid_t out)
+{
+ static unsigned char node_id[6];
+ static int has_init = 0;
+ struct uuid uu;
+ __u32 clock_mid;
+
+ if (!has_init) {
+ if (get_node_id(node_id) <= 0)
+ get_random_bytes(node_id, 6);
+ has_init = 1;
+ }
+ get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
+ uu.clock_seq |= 0x8000;
+ uu.time_mid = (__u16) clock_mid;
+ uu.time_hi_and_version = (clock_mid >> 16) | 0x1000;
+ memcpy(uu.node, node_id, 6);
+ uuid_pack(&uu, out);
+}
--- /dev/null
+/*
+ * isnull.c --- Check whether or not the UUID is null
+ */
+
+#include "uuidP.h"
+
+/* Returns 1 if the uuid is the NULL uuid */
+int uuid_is_null(uuid_t uu)
+{
+ unsigned char *cp;
+ int i;
+
+ for (i=0, cp = uu; i < 16; i++)
+ if (*cp++)
+ return 0;
+ return 1;
+}
+
--- /dev/null
+/*
+ * Internal routine for packing UUID's
+ */
+
+#include "uuidP.h"
+
+void uuid_pack(struct uuid *uu, uuid_t ptr)
+{
+ __u32 tmp;
+ unsigned char *out = ptr;
+
+ tmp = uu->time_low;
+ out[3] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[2] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[1] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[0] = (unsigned char) tmp;
+
+ tmp = uu->time_mid;
+ out[5] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[4] = (unsigned char) tmp;
+
+ tmp = uu->time_hi_and_version;
+ out[7] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[6] = (unsigned char) tmp;
+
+ tmp = uu->clock_seq;
+ out[9] = (unsigned char) tmp;
+ tmp >>= 8;
+ out[8] = (unsigned char) tmp;
+
+ memcpy(out+10, uu->node, 6);
+}
+
--- /dev/null
+/*
+ * parse.c --- UUID parsing
+ */
+
+#include <stdio.h>
+
+#include "uuidP.h"
+
+int uuid_parse(char *in, uuid_t uu)
+{
+ struct uuid uuid;
+ int i;
+ char *cp, buf[3];
+
+ if (strlen(in) != 36)
+ return -1;
+ for (i=0, cp = in; i <= 36; i++,cp++) {
+ if ((i == 8) || (i == 13) || (i == 18) ||
+ (i == 23))
+ if (*cp == '-')
+ continue;
+ if (i== 36)
+ if (*cp == 0)
+ continue;
+ if (!isxdigit(*cp))
+ return -1;
+ }
+ uuid.time_low = strtoul(in, NULL, 16);
+ uuid.time_mid = strtoul(in+9, NULL, 16);
+ uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
+ uuid.clock_seq = strtoul(in+19, NULL, 16);
+ cp = in+24;
+ buf[2] = 0;
+ for (i=0; i < 6; i++) {
+ buf[0] = *cp++;
+ buf[1] = *cp++;
+ uuid.node[i] = strtoul(buf, NULL, 16);
+ }
+
+ uuid_pack(&uuid, uu);
+ return 0;
+}
--- /dev/null
+#include <stdio.h>
+#include <linux/ext2_fs.h>
+
+#include "uuid.h"
+
+int
+main(int argc, char *argv)
+{
+ uuid_t buf, tst;
+ char str[100];
+ unsigned char *cp;
+ int i;
+ int failed = 0;
+
+ uuid_generate(buf);
+ uuid_unparse(buf, str);
+ printf("UUID string = %s\n", str);
+ printf("UUID: ");
+ for (i=0, cp = (unsigned char *) &buf; i < 16; i++) {
+ printf("%02x", *cp++);
+ }
+ printf("\n");
+ uuid_parse(str, tst);
+ if (uuid_compare(buf, tst))
+ printf("UUID parse and compare succeeded.\n");
+ else {
+ printf("UUID parse and compare failed!\n");
+ failed++;
+ }
+ uuid_clear(tst);
+ if (uuid_is_null(tst))
+ printf("UUID clear and is null succeeded.\n");
+ else {
+ printf("UUID clear and is null failed!\n");
+ failed++;
+ }
+ uuid_copy(buf, tst);
+ if (uuid_compare(buf, tst))
+ printf("UUID copy and compare succeeded.\n");
+ else {
+ printf("UUID copy and compare failed!\n");
+ failed++;
+ }
+ if (failed) {
+ printf("%d failures.\n", failed);
+ exit(1);
+ }
+ return 0;
+}
+
+
+
--- /dev/null
+/*
+ * Internal routine for unpacking UUID
+ */
+
+#include "uuidP.h"
+
+void uuid_unpack(uuid_t in, struct uuid *uu)
+{
+ __u8 *ptr = in;
+ __u32 tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_low = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_mid = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->time_hi_and_version = tmp;
+
+ tmp = *ptr++;
+ tmp = (tmp << 8) | *ptr++;
+ uu->clock_seq = tmp;
+
+ memcpy(uu->node, ptr, 6);
+}
+
--- /dev/null
+/*
+ * uuid_to_str.c -- convert a UUID to string
+ */
+
+#include <stdio.h>
+
+#include "uuidP.h"
+
+void uuid_unparse(uuid_t uu, char *out)
+{
+ struct uuid uuid;
+
+ uuid_unpack(uu, &uuid);
+ sprintf(out,
+ "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
+ uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
+ uuid.node[0], uuid.node[1], uuid.node[2],
+ uuid.node[3], uuid.node[4], uuid.node[5]);
+}
+
--- /dev/null
+/*
+ * Public include file for the UUID library
+ */
+
+typedef unsigned char uuid_t[16];
+
+/* clear.c */
+void uuid_clear(uuid_t uu);
+
+/* compare.c */
+int uuid_compare(uuid_t uu1, uuid_t uu2);
+
+/* copy.c */
+void uuid_copy(uuid_t uu1, uuid_t uu2);
+
+/* gen_uuid.c */
+void uuid_generate(uuid_t out);
+
+/* isnull.c */
+int uuid_is_null(uuid_t uu);
+
+/* parse.c */
+int uuid_parse(char *in, uuid_t uu);
+
+/* unparse.c */
+void uuid_unparse(uuid_t uu, char *out);
+
+
+
--- /dev/null
+/*
+ * uuid.h -- private header file for uuids
+ */
+
+#include <sys/types.h>
+#include <linux/types.h>
+
+#include "uuid.h"
+
+/*
+ * Offset between 15-Oct-1582 and 1-Jan-70
+ */
+#define TIME_OFFSET_HIGH 0x01B21DD2
+#define TIME_OFFSET_LOW 0x13814000
+
+struct uuid {
+ __u32 time_low;
+ __u16 time_mid;
+ __u16 time_hi_and_version;
+ __u16 clock_seq;
+ __u8 node[6];
+};
+
+
+/*
+ * prototypes
+ */
+void uuid_pack(struct uuid *uu, uuid_t ptr);
+void uuid_unpack(uuid_t in, struct uuid *uu);
+
+
+
+
+Sat Sep 7 07:34:11 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * tune2fs.c (main): Add support for new option -C, which sets the
+ current number of mounts.
+ (main): Allow the interval to be specified in seconds,
+ mostly for debugging.
+
+Tue Aug 27 17:27:43 1996 Miles Bader <miles@gnu.ai.mit.edu>
+
+ * Makefile.in (SMANPAGES): Use @FSCK_MAN@ instead of fsck.8.
+ (SPROGS): Use @FSCK_PROG@ instead of fsck.
+
+Thu Aug 22 00:51:44 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * mke2fs.c (zap_bootblock): Don't do zap_bootblock on a
+ sparc.
+
+Tue Aug 20 00:15:46 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * chattr.c (main): Fixed bug so that chattr -v works. (Bug report
+ and fix sent by Charles Howes, chowes@eznet.ca)
+
+Fri Aug 9 11:52:42 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * tune2fs.8.in:
+ * tune2fs.c: Added support for the -L option which sets the volume
+ label, the -M option which sets the last mounted
+ directory, and the -U option which sets the filesystem UUID.
+
+ * mke2fs.8.in:
+ * mke2fs.c: Added support for the -o option, which overrides the
+ creator OS. Generate a UUID for the filesystem, if
+ applicable. Added support for the -L option which sets
+ the volume label, and the -M option which sets the last
+ mounted directory.
+
+Sat Jun 22 17:43:17 1996 Remy Card <card@bbj.linux.eu.org>
+
+ * chattr.c (decode_arg): Integrated Michael Nonweiler's fix to
+ avoid a segmentation fault when the "-v" option is used
+ and no version number is specified.
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ..
+my_dir = misc
INSTALL = @INSTALL@
@MCONFIG@
-SPROGS= mke2fs badblocks tune2fs dumpe2fs fsck
+SPROGS= mke2fs badblocks tune2fs dumpe2fs @FSCK_PROG@
USPROGS= mklost+found
-SMANPAGES= tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 fsck.8
+SMANPAGES= tune2fs.8 mklost+found.8 mke2fs.8 dumpe2fs.8 badblocks.8 \
+ @FSCK_MAN@
UPROGS= chattr lsattr
UMANPAGES= chattr.1 lsattr.1
all:: $(SPROGS) $(UPROGS) $(USPROGS) fix_substitute $(SMANPAGES) $(UMANPAGES)
-tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS_E2P)
- $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS_E2P)
+tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS_E2P) $(LIBUUID)
+ $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS_E2P) $(LIBUUID)
mklost+found: $(MKLPF_OBJS)
$(CC) $(ALL_LDFLAGS) -o mklost+found $(MKLPF_OBJS)
-mke2fs: $(MKE2FS_OBJS) $(DEPLIBS)
- $(CC) $(ALL_LDFLAGS) -o mke2fs $(MKE2FS_OBJS) $(LIBS)
+mke2fs: $(MKE2FS_OBJS) $(DEPLIBS) $(LIBUUID)
+ $(CC) $(ALL_LDFLAGS) -o mke2fs $(MKE2FS_OBJS) $(LIBS) $(LIBUUID)
-mke2fs.static: $(MKE2FS_OBJS) $(STATIC_DEPLIBS)
+mke2fs.static: $(MKE2FS_OBJS) $(STATIC_DEPLIBS) $(STATIC_LIBUUID)
$(CC) $(ALL_LDFLAGS) -static -o mke2fs.static $(MKE2FS_OBJS) \
- $(STATIC_LIBS)
+ $(STATIC_LIBS) $(STATIC_LIBUUID)
+
+resize2fs: resize2fs.o $(DEPLIBS)
+ $(CC) $(ALL_LDFLAGS) -o resize2fs resize2fs.o $(LIBS)
chattr: $(CHATTR_OBJS) $(DEPLIBS_E2P)
$(CC) $(ALL_LDFLAGS) -o chattr $(CHATTR_OBJS) $(LIBS_E2P)
# Makefile dependencies follow. This must be the last section in
# the Makefile.in file
#
-tune2fs.o: $(srcdir)/tune2fs.c \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/e2p/e2p.h \
+tune2fs.o: $(srcdir)/tune2fs.c $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/uuid/uuid.h $(top_srcdir)/lib/e2p/e2p.h \
$(srcdir)/../version.h
mklost+found.o: $(srcdir)/mklost+found.c $(srcdir)/../version.h
mke2fs.o: $(srcdir)/mke2fs.c $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
- $(srcdir)/../version.h
+ $(top_srcdir)/lib/uuid/uuid.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/bitops.h $(srcdir)/../version.h
chattr.o: $(srcdir)/chattr.c $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/e2p/e2p.h $(srcdir)/../version.h
lsattr.o: $(srcdir)/lsattr.c $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/e2p/e2p.h $(srcdir)/../version.h
-dumpe2fs.o: $(srcdir)/dumpe2fs.c \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(top_srcdir)/lib/ext2fs/bitops.h $(top_srcdir)/lib/e2p/e2p.h \
- $(srcdir)/../version.h
+dumpe2fs.o: $(srcdir)/dumpe2fs.c $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(top_srcdir)/lib/ext2fs/bitops.h \
+ $(top_srcdir)/lib/e2p/e2p.h $(srcdir)/../version.h
badblocks.o: $(srcdir)/badblocks.c $(top_srcdir)/lib/et/com_err.h \
$(top_srcdir)/lib/ext2fs/io.h
fsck.o: $(srcdir)/fsck.c $(srcdir)/../version.h $(srcdir)/fsck.h
-
rem = 1;
break;
case 'v':
+ (*i)++;
if (*i >= argc)
usage ();
- (*i)++;
version = strtol (argv[*i], &tmp, 0);
if (*tmp)
{
fprintf (stderr, "= is incompatible with - and +\n");
exit (1);
}
- if (!(add || rem || set))
+ if (!(add || rem || set || set_version))
{
- fprintf (stderr, "Must use =, - or +\n");
+ fprintf (stderr, "Must use '-v', =, - or +\n");
exit (1);
}
for (j = i; j < argc; j++)
badblocks_list_iterate_end(bb_iter);
}
+static int i386_byteorder(void)
+{
+ int one = 1;
+ char *cp = (char *) &one;
+
+ return (*cp == 1);
+}
void main (int argc, char ** argv)
{
errcode_t retval;
ext2_filsys fs;
int print_badblocks = 0;
+ int big_endian;
char c;
fprintf (stderr, "dumpe2fs %s, %s for EXT2 FS %s, %s\n",
ext2fs_close (fs);
exit (1);
}
+ big_endian = ((fs->flags & EXT2_SWAP_BYTES) != 0);
+ if (!i386_byteorder())
+ big_endian = !big_endian;
+ if (big_endian)
+ printf("Note: This is a byte-swapped filesystem\n");
list_super (fs->super);
list_bad_blocks (fs);
list_desc (fs);
.\" test
.\" |
.B \-l
-filename
+.I filename
]
[
.B \-b
-block-size
+.I block-size
]
[
.B \-f
-fragment-size
+.I fragment-size
]
[
.B \-i
-bytes-per-inode
+.I bytes-per-inode
]
[
.B \-m
-reserved-blocks-percentage
+.I reserved-blocks-percentage
+]
+[
+.B \-o
+.I creator-os
]
[
.B \-q
.B \-F
]
[
+.B \-L
+.I volume-label
+]
+[
+.B \-M
+.I last-mounted-directory
+]
+[
.B \-S
]
-device
+.I device
[
-blocks-count
+.I blocks-count
]
.SH DESCRIPTION
.B mke2fs
.\" Check the device for bad blocks before creating the file system
.\" using the specified test.
.TP
+.I -o
+Manually override the default value of the "creator os" field of the
+filesystem. Normally the creator field is set by default to the native OS
+of the mke2fs executable.
+.TP
.I -q
Quiet execution. Useful if mke2fs is run in a script.
.TP
Force mke2fs to run, even if the specified device is not a
block special device.
.TP
+.I -L
+Set the volume label for the filesystem.
+.TP
+.I -M
+Set the last mounted directory for the filesystem. This might be useful
+for the sake of utilities that key off of the last mounted directory to
+determine where the filesytem should be mounted.
+.TP
.I -S
Write superblock and group descriptors only. This is useful if all of
the superblock and backup superblocks are corrupted, and a last-ditch
#endif
#include "et/com_err.h"
+#include "uuid/uuid.h"
#include "ext2fs/ext2fs.h"
#include "../version.h"
#define STRIDE_LENGTH 8
+#ifndef sparc
+#define ZAP_BOOTBLOCK
+#endif
+
extern int isatty(int);
extern FILE *fpopen(const char *cmd, const char *mode);
char *bad_blocks_filename = 0;
struct ext2_super_block param;
+char *creator_os = NULL;
+char *volume_label = NULL;
+char *mount_dir = NULL;
static void usage(NOARGS)
{
- fprintf(stderr,
- "Usage: %s [-c|-t|-l filename] [-b block-size] "
- "[-f fragment-size]\n\t[-i bytes-per-inode] "
- "[-m reserved-blocks-percentage] [-qvS]\n"
- "\t[-g blocks-per-group] device [blocks-count]\n",
+ fprintf(stderr, "Usage: %s [-c|-t|-l filename] [-b block-size] "
+ "[-f fragment-size]\n\t[-i bytes-per-inode] "
+ "[-m reserved-blocks-percentage] [-qvS]\n\t"
+ "[-o creator-os] [-g blocks-per-group] [-L volume-label]\n\t"
+ "[-M last-mounted-directory] device [blocks-count]\n",
program_name);
exit(1);
}
ext2fs_mark_ib_dirty(fs);
}
+#ifdef ZAP_BOOTBLOCK
static void zap_bootblock(ext2_filsys fs)
{
char buf[512];
printf("Warning: could not erase block 0: %s\n",
error_message(retval));
}
+#endif
static void show_stats(ext2_filsys fs)
{
- struct ext2_super_block *s = fs->super;
+ struct ext2fs_sb *s = (struct ext2fs_sb *) fs->super;
+ char buf[80];
blk_t group_block;
int i, col_left;
printf("warning: %d blocks unused.\n\n",
param.s_blocks_count - s->s_blocks_count);
+ switch (fs->super->s_creator_os) {
+ case EXT2_OS_LINUX: printf ("Linux"); break;
+ case EXT2_OS_HURD: printf ("GNU/hurd"); break;
+ case EXT2_OS_MASIX: printf ("Masix"); break;
+ default: printf ("(unknown os)");
+ }
+ printf (" ext2 filesystem format\n");
+ memset(buf, 0, sizeof(buf));
+ strncpy(buf, s->s_volume_name, sizeof(s->s_volume_name));
+ printf("Filesystem label=%s\n", buf);
printf("%u inodes, %u blocks\n", s->s_inodes_count,
s->s_blocks_count);
printf("%u blocks (%2.2f%%) reserved for the super user\n",
printf("\n\n");
}
+#ifndef HAVE_STRCASECMP
+static int strcasecmp (char *s1, char *s2)
+{
+ while (*s1 && *s2) {
+ int ch1 = *s1++, ch2 = *s2++;
+ if (isupper (ch1))
+ ch1 = tolower (ch1);
+ if (isupper (ch2))
+ ch2 = tolower (ch2);
+ if (ch1 != ch2)
+ return ch1 - ch2;
+ }
+ return *s1 ? 1 : *s2 ? -1 : 0;
+}
+#endif
+
+/*
+ * Set the S_CREATOR_OS field. Return true if OS is known,
+ * otherwise, 0.
+ */
+static int set_os(struct ext2_super_block *sb, char *os)
+{
+ if (isdigit (*os))
+ sb->s_creator_os = atoi (os);
+ else if (strcasecmp(os, "linux") == 0)
+ sb->s_creator_os = EXT2_OS_LINUX;
+ else if (strcasecmp(os, "GNU") == 0 || strcasecmp(os, "hurd") == 0)
+ sb->s_creator_os = EXT2_OS_HURD;
+ else if (strcasecmp(os, "masix") == 0)
+ sb->s_creator_os = EXT2_OS_MASIX;
+ else
+ return 0;
+ return 1;
+}
+
#define PATH_SET "PATH=/sbin"
static void PRS(int argc, char *argv[])
EXT2FS_VERSION, EXT2FS_DATE);
if (argc && *argv)
program_name = *argv;
- while ((c = getopt (argc, argv, "b:cf:g:i:l:m:qr:tvI:SF")) != EOF)
+ while ((c = getopt (argc, argv,
+ "b:cf:g:i:l:m:o:qr:tvI:SFL:M:")) != EOF)
switch (c) {
case 'b':
size = strtoul(optarg, &tmp, 0);
exit(1);
}
break;
+ case 'o':
+ creator_os = optarg;
+ break;
case 'r':
param.s_rev_level = atoi(optarg);
break;
case 'F':
force = 1;
break;
+ case 'L':
+ volume_label = optarg;
+ break;
+ case 'M':
+ mount_dir = optarg;
+ break;
case 'S':
super_only = 1;
break;
EXT2_BLOCK_SIZE(¶m),
¶m.s_blocks_count);
if (retval) {
- com_err(program_name, 0,
+ com_err(program_name, retval,
"while trying to determine filesystem size");
exit(1);
}
errcode_t retval = 0;
ext2_filsys fs;
badblocks_list bb_list = 0;
+ struct ext2fs_sb *s;
PRS(argc, argv);
exit(1);
}
+ /*
+ * Generate a UUID for it...
+ */
+ s = (struct ext2fs_sb *) fs->super;
+ uuid_generate(s->s_uuid);
+
+ /*
+ * Override the creator OS, if applicable
+ */
+ if (creator_os && !set_os(fs->super, creator_os)) {
+ com_err (program_name, 0, "unknown os - %s", creator_os);
+ exit(1);
+ }
+
+ /*
+ * Set the volume label...
+ */
+ if (volume_label) {
+ memset(s->s_volume_name, 0, sizeof(s->s_volume_name));
+ strncpy(s->s_volume_name, volume_label,
+ sizeof(s->s_volume_name));
+ }
+
+ /*
+ * Set the last mount directory
+ */
+ if (mount_dir) {
+ memset(s->s_last_mounted, 0, sizeof(s->s_last_mounted));
+ strncpy(s->s_last_mounted, mount_dir,
+ sizeof(s->s_last_mounted));
+ }
+
if (!quiet)
show_stats(fs);
create_lost_and_found(fs);
reserve_inodes(fs);
create_bad_block_inode(fs, bb_list);
+#ifdef ZAP_BOOTBLOCK
zap_bootblock(fs);
+#endif
}
if (!quiet)
.B -g
.I group
]
+[
+.B -C
+.I mount-count
+]
+[
+.B -L
+.I volume-name
+]
+[
+.B -M
+.I last-mounted-directory
+]
+[
+.B -U
+.I UUID
+]
device
.SH DESCRIPTION
.BI tune2fs
set the user who can benefit from the reserved blocks.
.I user
can be a numerical uid or a user name.
+.IP
+.I -C mount-count
+set the number of times the filesystem has been mounted.
+.TP
+.I -L volume-label
+set the volume label of the filesystem.
+.TP
+.I -M last-mounted-directory
+set the last-mounted direcctory for the filesystem.
+.TP
+.I -U UUID
+set the UUID of the filesystem. A sample UUID looks like this:
+"c1b9d5a2-f162-11cf-9ece-0020afc76f16". The uuid may also be "null",
+which will set the filesystem UUID to the null UUID. The uuid may also
+be "random", which will generate a new random UUID for the filesystem.
.PP
.SH BUGS
We didn't find any bugs yet. Perhaps there are bugs but it's unlikely.
#include "ext2fs/ext2fs.h"
#include "et/com_err.h"
+#include "uuid/uuid.h"
#include "e2p/e2p.h"
#include "../version.h"
const char * program_name = "tune2fs";
char * device_name = NULL;
+char * new_label = NULL;
+char * new_last_mounted = NULL;
+char * new_UUID = NULL;
int c_flag = 0;
+int C_flag = 0;
int e_flag = 0;
int g_flag = 0;
int i_flag = 0;
int l_flag = 0;
+int L_flag = 0;
int m_flag = 0;
+int M_flag = 0;
int r_flag = 0;
int u_flag = 0;
-int max_mount_count;
+int U_flag = 0;
+int max_mount_count, mount_count;
unsigned long interval;
unsigned long reserved_ratio = 0;
unsigned long reserved_blocks = 0;
unsigned long resgid = 0;
unsigned long resuid = 0;
+#ifndef HAVE_STRCASECMP
+static int strcasecmp (char *s1, char *s2)
+{
+ while (*s1 && *s2) {
+ int ch1 = *s1++, ch2 = *s2++;
+ if (isupper (ch1))
+ ch1 = tolower (ch1);
+ if (isupper (ch2))
+ ch2 = tolower (ch2);
+ if (ch1 != ch2)
+ return ch1 - ch2;
+ }
+ return *s1 ? 1 : *s2 ? -1 : 0;
+}
+#endif
+
static volatile void usage (void)
{
fprintf (stderr, "Usage: %s [-c max-mounts-count] [-e errors-behavior] "
"[-g group]\n"
"\t[-i interval[d|m|w]] [-l] [-m reserved-blocks-percent]\n"
- "\t[-r reserved-blocks-count] [-u user] device\n", program_name);
+ "\t[-r reserved-blocks-count] [-u user] [-C mount-count]\n"
+ "\t[-L volume-label] [-M last-mounted-dir] [-U UUID] "
+ "device\n", program_name);
exit (1);
}
char * tmp;
errcode_t retval;
ext2_filsys fs;
+ struct ext2fs_sb *sb;
struct group * gr;
struct passwd * pw;
+ int open_flag = 0;
fprintf (stderr, "tune2fs %s, %s for EXT2 FS %s, %s\n",
E2FSPROGS_VERSION, E2FSPROGS_DATE,
if (argc && *argv)
program_name = *argv;
initialize_ext2_error_table();
- while ((c = getopt (argc, argv, "c:e:g:i:lm:r:u:")) != EOF)
+ while ((c = getopt (argc, argv, "c:e:g:i:lm:r:u:C:L:M:U:")) != EOF)
switch (c)
{
case 'c':
usage ();
}
c_flag = 1;
+ open_flag = EXT2_FLAG_RW;
+ break;
+ case 'C':
+ mount_count = strtoul (optarg, &tmp, 0);
+ if (*tmp || mount_count > 16000)
+ {
+ com_err (program_name, 0,
+ "bad mounts count - %s",
+ optarg);
+ usage ();
+ }
+ C_flag = 1;
+ open_flag = EXT2_FLAG_RW;
break;
case 'e':
if (strcmp (optarg, "continue") == 0)
usage ();
}
e_flag = 1;
+ open_flag = EXT2_FLAG_RW;
break;
case 'g':
resgid = strtoul (optarg, &tmp, 0);
usage ();
}
g_flag = 1;
+ open_flag = EXT2_FLAG_RW;
break;
case 'i':
interval = strtoul (optarg, &tmp, 0);
- switch (*tmp)
- {
- case '\0':
- case 'd':
- case 'D': /* days */
- interval *= 86400;
- if (*tmp != '\0')
- tmp++;
- break;
- case 'm':
- case 'M': /* months! */
- interval *= 86400 * 30;
- tmp++;
- break;
- case 'w':
- case 'W': /* weeks */
- interval *= 86400 * 7;
+ switch (*tmp) {
+ case 's':
+ tmp++;
+ break;
+ case '\0':
+ case 'd':
+ case 'D': /* days */
+ interval *= 86400;
+ if (*tmp != '\0')
tmp++;
- break;
+ break;
+ case 'm':
+ case 'M': /* months! */
+ interval *= 86400 * 30;
+ tmp++;
+ break;
+ case 'w':
+ case 'W': /* weeks */
+ interval *= 86400 * 7;
+ tmp++;
+ break;
}
if (*tmp || interval > (365 * 86400))
{
usage ();
}
i_flag = 1;
+ open_flag = EXT2_FLAG_RW;
break;
case 'l':
l_flag = 1;
break;
+ case 'L':
+ new_label = optarg;
+ L_flag = 1;
+ open_flag = EXT2_FLAG_RW;
+ break;
case 'm':
reserved_ratio = strtoul (optarg, &tmp, 0);
if (*tmp || reserved_ratio > 50)
usage ();
}
m_flag = 1;
+ open_flag = EXT2_FLAG_RW;
+ break;
+ case 'M':
+ new_last_mounted = optarg;
+ M_flag = 1;
+ open_flag = EXT2_FLAG_RW;
break;
case 'r':
reserved_blocks = strtoul (optarg, &tmp, 0);
usage ();
}
r_flag = 1;
+ open_flag = EXT2_FLAG_RW;
break;
case 'u':
resuid = strtoul (optarg, &tmp, 0);
usage ();
}
u_flag = 1;
+ open_flag = EXT2_FLAG_RW;
+ break;
+ case 'U':
+ new_UUID = optarg;
+ U_flag = 1;
+ open_flag = EXT2_FLAG_RW;
break;
default:
usage ();
}
if (optind < argc - 1 || optind == argc)
usage ();
- if (!c_flag && !e_flag && !g_flag && !i_flag && !l_flag && !m_flag
- && !r_flag && !u_flag)
- usage ();
+ if (!open_flag && !l_flag)
+ usage();
device_name = argv[optind];
- retval = ext2fs_open (device_name,
- (c_flag || e_flag || g_flag || i_flag || m_flag
- || r_flag || u_flag) ? EXT2_FLAG_RW : 0,
- 0, 0, unix_io_manager, &fs);
+ retval = ext2fs_open (device_name, open_flag, 0, 0,
+ unix_io_manager, &fs);
if (retval)
{
com_err (program_name, retval, "while trying to open %s",
printf("Couldn't find valid filesystem superblock.\n");
exit(1);
}
+ sb = (struct ext2fs_sb *) fs->super;
- if (c_flag)
- {
+ if (c_flag) {
fs->super->s_max_mnt_count = max_mount_count;
ext2fs_mark_super_dirty(fs);
- printf ("Setting maximal mount count to %d\n", max_mount_count);
+ printf ("Setting maximal mount count to %d\n",
+ max_mount_count);
}
- if (e_flag)
- {
+ if (C_flag) {
+ fs->super->s_mnt_count = mount_count;
+ ext2fs_mark_super_dirty(fs);
+ printf ("Setting current mount count to %d\n", mount_count);
+ }
+ if (e_flag) {
fs->super->s_errors = errors;
ext2fs_mark_super_dirty(fs);
printf ("Setting error behavior to %d\n", errors);
fs->super->s_r_blocks_count = (fs->super->s_blocks_count / 100)
* reserved_ratio;
ext2fs_mark_super_dirty(fs);
- printf ("Setting reserved blocks percentage to %lu (%lu blocks)\n",
+ printf ("Setting reserved blocks percentage to %lu (%u blocks)\n",
reserved_ratio, fs->super->s_r_blocks_count);
}
if (r_flag)
"The -u option is not supported by this version -- "
"Recompile with a newer kernel");
#endif
+ if (L_flag) {
+ memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name));
+ strncpy(sb->s_volume_name, new_label,
+ sizeof(sb->s_volume_name));
+ ext2fs_mark_super_dirty(fs);
+ }
+ if (M_flag) {
+ memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted));
+ strncpy(sb->s_last_mounted, new_last_mounted,
+ sizeof(sb->s_last_mounted));
+ ext2fs_mark_super_dirty(fs);
+ }
+ if (U_flag) {
+ if (strcasecmp(new_UUID, "null") == 0) {
+ uuid_clear(sb->s_uuid);
+ } else if (strcasecmp(new_UUID, "random") == 0) {
+ uuid_generate(sb->s_uuid);
+ } else if (uuid_parse(new_UUID, sb->s_uuid)) {
+ com_err(program_name, 0, "Invalid UUID format\n");
+ exit(1);
+ }
+ ext2fs_mark_super_dirty(fs);
+ }
+
if (l_flag)
list_super (fs->super);
ext2fs_close (fs);
--- /dev/null
+#
+# Relocation e2fsprogs prologue....
+#
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+top_builddir = ..
+my_dir = relocate
+INSTALL = @INSTALL@
+
+@MCONFIG@
+
+SRCS= $(srcdir)/resize2fs.c
+
+LIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
+DEPLIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
+
+STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+
+LIBS_E2P= $(LIBEXT2FS) $(LIBE2P) $(LIBCOM_ERR)
+DEPLIBS_E2P= $(LIBEXT2FS) $(LIBE2P) $(LIBCOM_ERR)
+
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+all:: resize2fs
+
+resize2fs: resize2fs.o $(DEPLIBS)
+ $(CC) $(ALL_LDFLAGS) -o resize2fs resize2fs.o $(LIBS)
+
+clean::
+ $(RM) -f resize2fs \#* *.s *.o *.a *~ core
--- /dev/null
+This directory is under construction still....
--- /dev/null
+/*
+ * relocate.c --- maintains the relocation table
+ *
+ * Copyright (C) 1996 Theodore Ts'o. This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+
+#include <et/com_err.h>
+
+/*
+ * This routine creates a relocation table
+ */
+errcode_t ext2fs_create_relocation_table(__u32 max, int size,
+ ext2_relocate_table *ret);
+{
+ ext2_relocate_table table;
+
+ table = malloc(sizeof(struct ext2_relocate_struct));
+ if (!table)
+ return -ENOMEM;
+ table->magic = 0;
+ table->count = 0;
+ table->size = size ? size : 30;
+ table->max = max;
+ table->entries = malloc(table->size * sizeof(ext2_relocate_entry));
+ if (table->entries == 0) {
+ free(table);
+ return ENOMEM;
+ }
+ memset(table->entries, 0, table->size * sizeof(ext2_relocate_entry));
+ *ret = table;
+ return 0;
+}
+
+/*
+ * Free a relocation table
+ */
+void ext2fs_free_relocation_table(ext2_relocate_table table)
+{
+ free(table->entries);
+ table->count = 0;
+ table->size = 0;
+ table->magic = 0;
+ free(table);
+}
+
+/*
+ * Add a relocation table entry
+ */
+errcode_t ext2fs_add_relocation(ext2_relocate_table table, __u32 old,
+ __u32 new, __u32 owner)
+{
+ struct ext2_relocate_entry *new;
+
+ if (table->count >= table->size) {
+ table->size += 30;
+ new = realloc(table->entries,
+ table->size * sizeof(ext2_relocate_entry));
+ if (!new)
+ return ENOMEM;
+ table->entries = new;
+ }
+ if (table->count && table->entries[table->count-1].old > old) {
+ for (i = table->count-1; i > 0; i--)
+ if (table->entries[i-1].old < old)
+ break;
+ new = &table->entries[i];
+ if (new->old != old)
+ for (j = table->count++; j > i; j--)
+ table->entries[j] = table_entries[j-1];
+ } else
+ new = &table->entries[table->coun++];
+
+ new->old = old;
+ new->new = new;
+ new->owner = owner;
+}
+
+/*
+ * ext2fs_get_reloc_by_old() --- given the source of the relcation
+ * entry, find the entry for it.
+ */
+struct relocate_entry *ext2fs_get_reloc_by_old(ext2_relocate_table tbl,
+ __u32 old)
+{
+ int low, high, mid;
+ int i, j;
+
+ low = 0;
+ high = tbl->count-1;
+ if (old == table->entries[low].old)
+ return &table->entries[low];
+ if (old == table->entries[high].old)
+ return &table->entries[high];
+
+ while (low < high) {
+ mid = (low+high)/2;
+ if (mid == low || mid == high)
+ break;
+ if (old == table->entries[mid].old)
+ return &table->entries[mid];
+ if (old < table->entries[mid].old)
+ high = mid;
+ else
+ low = mid;
+ }
+ return 0;
+}
+
+/*
+ * ext2fs_get_reloc_by_new() --- given the destination of the relcation
+ * entry, find the entry for it.
+ *
+ * Note: this is currently very slow...
+ */
+struct relocate_entry *ext2fs_get_reloc_by_new(ext2_relocate_table tbl,
+ __u32 new)
+{
+ int i;
+
+ for (i = 0; i < table->count; i++) {
+ if (tbl->entries[i].new == new)
+ return &table->entries[i];
+ }
+ return 0;
+}
+
+/*
+ * Find "loops" in the relocation tables
+ */
+{
+ int i;
+ struct ext2_relocate_entry *ent, *next;
+
+
+ for (i=0, ent=table->entries; i < table->size; i++, ent++) {
+ /*
+ * If we know this inode is OK, then keep going.
+ */
+ if (ext2fs_test_generic_bitmap(done_map, dir->old))
+ continue;
+ ext2fs_clear_generic_bitmap(loop_detect);
+ while (1) {
+ ext2fs_mark_generic_bitmap(loop_detect, dir->old);
+ next = ext2fs_get_reloc_by_old(table, dir->new);
+ if (next == NULL)
+ break;
+ if (ext2fs_test_generic_bitmap(loop_detect,
+ dir->new))
+ break_loop(table, dir);
+ ext2fs_mark_generic_bitmap(done_map, dir->old);
+ dir = next;
+ }
+ }
+}
+
+
+
+
--- /dev/null
+/*
+ * relocate.h
+ *
+ * Copyright (C) 1996 Theodore Ts'o. This file may be redistributed
+ * under the terms of the GNU Public License.
+ */
+
+struct ext2_relocate_entry {
+ __u32 new, old;
+ __u32 owner;
+}
+
+struct ext2_relocate_struct {
+ int magic;
+ int count;
+ int size;
+ int max;
+ struct ext2_relocate_entry *entries;
+};
+
+typedef struct ext2_relocate_struct *ext2_relocate_table;
--- /dev/null
+/*
+ * resize2fs.c - Resize the ext2 filesystem.
+ *
+ * Copyright (C) 1996 Theodore Ts'o
+ *
+ * This file can be redistributed under the terms of the GNU General
+ * Public License
+ */
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <linux/ext2_fs.h>
+
+#include "ext2fs/ext2fs.h"
+
+#include "../version.h"
+
+const char * program_name = "resize2fs";
+char * device_name = NULL;
+
+static volatile void usage (void)
+{
+ fprintf (stderr, "usage: %s device\n", program_name);
+ exit (1);
+}
+
+errcode_t ext2fs_resize_inode_bitmap(ext2_filsys fs,
+ ext2fs_inode_bitmap ibmap)
+{
+ ino_t new_end, new_real_end;
+ size_t size, new_size;
+ char *new_bitmap, *old_bitmap;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+ EXT2_CHECK_MAGIC(ibmap, EXT2_ET_MAGIC_INODE_BITMAP);
+
+ new_end = fs->super->s_inodes_count;
+ new_real_end = (EXT2_INODES_PER_GROUP(fs->super)
+ * fs->group_desc_count);
+
+ if (new_real_end == ibmap->real_end) {
+ ibmap->end = new_end;
+ return 0;
+ }
+
+ size = ((ibmap->real_end - ibmap->start) / 8) + 1;
+ new_size = ((new_real_end - ibmap->start) / 8) + 1;
+
+ new_bitmap = malloc(size);
+ if (!new_bitmap)
+ return ENOMEM;
+ if (size > new_size)
+ size = new_size;
+ memcpy(new_bitmap, ibmap->bitmap, size);
+ if (new_size > size)
+ memset(new_bitmap + size, 0, new_size - size);
+
+ old_bitmap = ibmap->bitmap;
+ ibmap->bitmap = new_bitmap;
+ free(old_bitmap);
+ ibmap->end = new_end;
+ ibmap->real_end = new_real_end;
+}
+
+errcode_t ext2fs_resize_block_bitmap(ext2_filsys fs,
+ ext2fs_inode_bitmap bbmap)
+{
+ ino_t new_end, new_real_end;
+ size_t size, new_size;
+ char *new_bitmap, *old_bitmap;
+
+ EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
+ EXT2_CHECK_MAGIC(bbmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
+
+ new_end = fs->super->s_inodes_count;
+ new_real_end = (EXT2_INODES_PER_GROUP(fs->super)
+ * fs->group_desc_count);
+
+ if (new_real_end == bbmap->real_end) {
+ bbmap->end = new_end;
+ return 0;
+ }
+
+ size = ((bbmap->real_end - bbmap->start) / 8) + 1;
+ new_size = ((new_real_end - bbmap->start) / 8) + 1;
+
+ new_bitmap = malloc(size);
+ if (!new_bitmap)
+ return ENOMEM;
+ if (size > new_size)
+ size = new_size;
+ memcpy(new_bitmap, bbmap->bitmap, size);
+ if (new_size > size)
+ memset(new_bitmap + size, 0, new_size - size);
+
+ old_bitmap = bbmap->bitmap;
+ bbmap->bitmap = new_bitmap;
+ free(old_bitmap);
+ bbmap->end = new_end;
+ bbmap->real_end = new_real_end;
+}
+
+
+
+errcode_t ext2fs_resize(ext2_filsys fs, blk_t new_size)
+{
+ __u32 new_block_groups, new_desc_blocks;
+
+ if (new_size = fs->super->s_blocks_count)
+ return 0;
+
+ new_block_groups = (fs->super->s_blocks_count -
+ fs->super->s_first_data_block +
+ EXT2_BLOCKS_PER_GROUP(fs->super) - 1)
+ / EXT2_BLOCKS_PER_GROUP(fs->super);
+ if (new_block_groups == 0)
+ return EXT2_ET_TOOSMALL;
+ new_desc_blocks = (new_block_groups +
+ EXT2_DESC_PER_BLOCK(fs->super) - 1)
+ / EXT2_DESC_PER_BLOCK(fs->super);
+
+}
+
+
+
+void main (int argc, char ** argv)
+{
+ errcode_t retval;
+ ext2_filsys fs;
+ int c;
+
+ fprintf (stderr, "resize2fs %s, %s for EXT2 FS %s, %s\n",
+ E2FSPROGS_VERSION, E2FSPROGS_DATE,
+ EXT2FS_VERSION, EXT2FS_DATE);
+ if (argc && *argv)
+ program_name = *argv;
+
+ while ((c = getopt (argc, argv, "h")) != EOF) {
+ switch (c) {
+ case 'h':
+ usage();
+ break;
+ default:
+ usage ();
+ }
+ }
+ if (optind > argc - 1)
+ usage ();
+ device_name = argv[optind++];
+ initialize_ext2_error_table();
+ retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0,
+ unix_io_manager, &fs);
+ if (retval) {
+ com_err (program_name, retval, "while trying to open %s",
+ device_name);
+ printf ("Couldn't find valid filesystem superblock.\n");
+ exit (1);
+ }
+ retval = ext2fs_read_bitmaps (fs);
+ if (retval) {
+ com_err (program_name, retval,
+ "while trying to read the bitmaps", device_name);
+ ext2fs_close (fs);
+ exit (1);
+ }
+ ext2fs_close (fs);
+ exit (0);
+}
+Mon Sep 9 23:09:47 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * Makefile.in (check): Add explicit ./ to test_script invokation,
+ since not all people will have "." in their path.
+
+Tue Sep 3 15:13:05 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * test_config (PAGER): Unset pager to prevent debugfs forking a
+ pager, since the escape sequences confuse the expect
+ script.
+
+Sun May 19 23:37:35 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
+
+ * test_script: New feature; second optional argument allows
+ developers to only run one test case.
+
+ * f_crashdisk: New test case which contains a patently illegal
+ superblock with a valid magic number.
+
Thu May 16 11:12:30 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* Release of E2fsprogs version 1.04
top_srcdir = @top_srcdir@
VPATH = @srcdir@
top_builddir = ..
+my_dir = tests
INSTALL = @INSTALL@
+@MCONFIG@
+
all:: @DO_TEST_SUITE@
-check::
+test_script: test_script.in Makefile
+ @echo "Creating test_script..."
+ @echo "#!/bin/sh" > test_script
+ @echo "SRCDIR=@srcdir@" >> test_script
+ @cat $(srcdir)/test_script.in >> test_script
+ @chmod +x test_script
+
+check:: test_script
@echo "Running e2fsprogs test suite..."
@echo " "
- @$(srcdir)/test_script $(srcdir)
+ @./test_script
clean::
- $(RM) -f *.log *.new *.failed *.ok test.img
+ $(RM) -f *.log *.new *.failed *.ok test.img test_script
distclean:: clean
$(RM) -f Makefile
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Remove illegal block(s) in bad block inode? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Directory 12, incorrect size, 182 (counted = 1024). Set size to counted? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Missing '.' in directory inode 12.
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Inode 12 (/motd) has a bad mode (0110444).
+++ /dev/null
-Pass 1: Checking inodes, blocks, and sizes
-
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.
-Fix inode(s)? yes
-
-Inode 13 is deleted w/ non-zero link_count. CLEARED
-Inode 15 is deleted w/ non-zero link_count. CLEARED
-Inode 16 is deleted w/ non-zero link_count. CLEARED
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-
-test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 29/32 files (0.0% non-contiguous), 32/100 blocks
-Exit status is 1
+++ /dev/null
-Pass 1: Checking inodes, blocks, and sizes
-Pass 2: Checking directory structure
-Pass 3: Checking directory connectivity
-Pass 4: Checking reference counts
-Pass 5: Checking group summary information
-test_filesys: 29/32 files (0.0% non-contiguous), 32/100 blocks
-Exit status is 0
+++ /dev/null
-deleted files with non-zero link count
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
The primary superblock (1) is on the bad block list.
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Root inode is not a directory. Clear? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Group 0's block bitmap (3) is bad. Relocate? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Group 0's inode bitmap (4) is bad. Relocate? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
--- /dev/null
+../e2fsck/e2fsck: The ext2 superblock is corrupt while trying to open ./test.img
+
+The superblock could not be read or does not describe a correct ext2
+filesystem. If the device is valid and it really contains an ext2
+filesystem (and not swap or ufs or something else), then the superblock
+is corrupt, and you might try running e2fsck with an alternate superblock:
+ e2fsck -b 8193 <device>
+
+Exit status is 8
--- /dev/null
+Superblock with illegal values
--- /dev/null
+ONE_PASS_ONLY="true"
+. $cmd_dir/run_e2fsck
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Entry 'quux' in /foo (12) is a link to directory /bar (13).
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Duplicate blocks found... invoking duplicate block passes.
Pass 1B: Rescan for duplicate/bad blocks
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Duplicate blocks found... invoking duplicate block passes.
Pass 1B: Rescan for duplicate/bad blocks
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 16/16 files (6.2% non-contiguous), 78/100 blocks
+test_filesys: 16/16 files (6.3% non-contiguous), 78/100 blocks
Exit status is 1
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Remove illegal block(s) in inode 12? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Remove illegal block(s) in inode 12? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Deleted inode 2 has zero dtime.
Set dtime? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Hole found in directory inode 11! (blkcnt=0)
Hole found in directory inode 11! (blkcnt=3)
Block bitmap for group 0 is not in group. (block 4096)
Relocate? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Relocating group 0's block bitmap to 4...
Pass 2: Checking directory structure
Inode bitmap group 0 not in group. (block 4000)
Relocate? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Relocating group 0's inode bitmap to 4...
Pass 2: Checking directory structure
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Remove illegal block(s) in inode 12? yes
-Pass 1: Checking inodes, blocks, and sizes
+Filesystem did not have a UUID; generating one.
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.
-Fix inode(s)? yes
+Pass 1: Checking inodes, blocks, and sizes
+Inode 13 is in use, but has dtime set
+Clear dtime? yes
-Inode 11 is deleted w/ non-zero link_count. CLEARED
-Inode 13 is deleted w/ non-zero link_count. CLEARED
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
-Unattached inode 14
+Unattached inode 13
Connect to /lost+found? yes
/lost+found not found. Create? yes
+Inode 13 has ref count 2, expecting 1.
+Set i_nlinks to count? yes
+
+Unattached inode 14
+Connect to /lost+found? yes
+
Inode 14 has ref count 2, expecting 1.
Set i_nlinks to count? yes
Pass 5: Checking group summary information
Fix summary information? yes
-Free blocks count wrong for group 0 (25, counted=38). FIXED
-Free blocks count wrong (39, counted=38). FIXED
-Free inodes count wrong for group #0 (2, counted=1). FIXED
+Block bitmap differences: +22 +23 +49 +57 +58. FIXED
+Free blocks count wrong for group 0 (25, counted=33). FIXED
+Free blocks count wrong (39, counted=33). FIXED
+Inode bitmap differences: +13. FIXED
+Free inodes count wrong for group #0 (2, counted=0). FIXED
Directories count wrong for group #0 (1, counted=2). FIXED
-Free inodes count wrong (2, counted=1). FIXED
+Free inodes count wrong (2, counted=0). FIXED
Padding at end of block bitmap is not set. Fix? yes
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 15/16 files (6.7% non-contiguous), 62/100 blocks
+test_filesys: 16/16 files (12.5% non-contiguous), 67/100 blocks
Exit status is 1
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 15/16 files (6.7% non-contiguous), 62/100 blocks
+test_filesys: 16/16 files (12.5% non-contiguous), 67/100 blocks
Exit status is 0
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Remove illegal block(s) in inode 14? yes
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Root inode has dtime set (probably due to old mke2fs). Fix? yes
-Note: /lost+found will probably be deleted as well, due to the mke2fs bug.
-Be sure to run mklost+found to recreate it after e2fsck finishes.
-
+Inode 11 is in use, but has dtime set
+Clear dtime? yes
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.
-Fix inode(s)? yes
+Inode 15 is in use, but has dtime set
+Clear dtime? yes
-Inode 11 is deleted w/ non-zero link_count. CLEARED
-Inode 15 is deleted w/ non-zero link_count. CLEARED
Pass 2: Checking directory structure
-Entry 'lost+found' in / (2) has deleted/unused inode 11.
-Clear? yes
-
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
-Inode 2 has ref count 4, expecting 3.
+Unattached inode 15
+Connect to /lost+found? yes
+
+Inode 15 has ref count 2, expecting 1.
Set i_nlinks to count? yes
Pass 5: Checking group summary information
Fix summary information? yes
-Block bitmap differences: -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20. FIXED
-Free blocks count wrong for group 0 (75, counted=87). FIXED
-Free blocks count wrong (75, counted=87). FIXED
-Inode bitmap differences: -11. FIXED
-Free inodes count wrong for group #0 (17, counted=18). FIXED
-Directories count wrong for group #0 (4, counted=3). FIXED
-Free inodes count wrong (17, counted=18). FIXED
+Inode bitmap differences: +15. FIXED
+Free inodes count wrong for group #0 (17, counted=16). FIXED
+Free inodes count wrong (17, counted=16). FIXED
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 14/32 files (0.0% non-contiguous), 13/100 blocks
+test_filesys: 16/32 files (0.0% non-contiguous), 25/100 blocks
Exit status is 1
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 14/32 files (0.0% non-contiguous), 13/100 blocks
+test_filesys: 16/32 files (0.0% non-contiguous), 25/100 blocks
Exit status is 0
-Pass 1: Checking inodes, blocks, and sizes
+Filesystem did not have a UUID; generating one.
-Deleted inode detected with non-zero link count.
-This is probably due to old ext2fs kernel code.
-Fix inode(s)? yes
+Pass 1: Checking inodes, blocks, and sizes
+Inode 15 is in use, but has dtime set
+Clear dtime? yes
-Inode 15 is deleted w/ non-zero link_count. CLEARED
Pass 2: Checking directory structure
Entry '..' in /lost+found (11) has deleted/unused inode 2.
Clear? yes
Inode 12 has ref count 4, expecting 3.
Set i_nlinks to count? yes
+Unattached inode 15
+Connect to /lost+found? yes
+
+Inode 15 has ref count 2, expecting 1.
+Set i_nlinks to count? yes
+
Pass 5: Checking group summary information
Fix summary information? yes
Free blocks count wrong for group 0 (75, counted=74). FIXED
Free blocks count wrong (75, counted=74). FIXED
-Free inodes count wrong for group #0 (17, counted=16). FIXED
+Inode bitmap differences: +15. FIXED
+Free inodes count wrong for group #0 (17, counted=15). FIXED
Directories count wrong for group #0 (4, counted=5). FIXED
-Free inodes count wrong (17, counted=16). FIXED
+Free inodes count wrong (17, counted=15). FIXED
test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
-test_filesys: 16/32 files (0.0% non-contiguous), 26/100 blocks
+test_filesys: 17/32 files (0.0% non-contiguous), 26/100 blocks
Exit status is 1
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
-test_filesys: 16/32 files (0.0% non-contiguous), 26/100 blocks
+test_filesys: 17/32 files (0.0% non-contiguous), 26/100 blocks
Exit status is 0
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
+
+test_filesys: ***** FILE SYSTEM WAS MODIFIED *****
test_filesys: 11/2048 files (0.0% non-contiguous), 274/8193 blocks
-Exit status is 0
+Exit status is 1
+Filesystem did not have a UUID; generating one.
+
Pass 1: Checking inodes, blocks, and sizes
Group 0's inode bitmap at 3 conflicts with some other fs block.
Relocate? yes
--- /dev/null
+ls
+stat sym
+stat double-indirect-test
+cat fluff
+quit
--- /dev/null
+Swapfs test
+e2fsck -yf -N test_filesys
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+e2fsck -Sy -N test_filesys
+Pass 0: Doing byte-swap of filesystem
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+Running debugfs....
+debugfs: ls
+2 (12) . 2 (12) .. 11 (20) lost+found 12 (16) fluff
+13 (28) indirect-fluff-test 14 (28) double-indirect-test 15 (20) sym
+16 (24) long-sym-test 17 (864) dir-test
+debugfs: stat sym
+Inode: 15 Type: symlink Mode: 0777 Flags: 0x0 Version: 1
+User: 0 Group: 0 Size: 5
+File ACL: 0 Directory ACL: 0
+Links: 1 Blockcount: 0
+Fragment: Address: 0 Number: 0 Size: 0
+ctime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+atime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+mtime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+Fast_link_dest: fluff
+debugfs: stat double-indirect-test
+Inode: 14 Type: regular Mode: 0644 Flags: 0x0 Version: 1
+User: 0 Group: 0 Size: 348960
+File ACL: 0 Directory ACL: 0
+Links: 1 Blockcount: 688
+Fragment: Address: 0 Number: 0 Size: 0
+ctime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+atime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+mtime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+BLOCKS:
+70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
+TOTAL: 344
+
+debugfs: cat fluff
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+
+debugfs: quit
+Exit status is 0
+e2fsck -yf -N test_filesys
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+e2fsck -sy -N test_filesys
+Pass 0: Doing byte-swap of filesystem
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
+Running debugfs....
+debugfs: ls
+2 (12) . 2 (12) .. 11 (20) lost+found 12 (16) fluff
+13 (28) indirect-fluff-test 14 (28) double-indirect-test 15 (20) sym
+16 (24) long-sym-test 17 (864) dir-test
+debugfs: stat sym
+Inode: 15 Type: symlink Mode: 0777 Flags: 0x0 Version: 1
+User: 0 Group: 0 Size: 5
+File ACL: 0 Directory ACL: 0
+Links: 1 Blockcount: 0
+Fragment: Address: 0 Number: 0 Size: 0
+ctime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+atime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+mtime: 0x322737e2 -- Fri Aug 30 18:50:10 1996
+Fast_link_dest: fluff
+debugfs: stat double-indirect-test
+Inode: 14 Type: regular Mode: 0644 Flags: 0x0 Version: 1
+User: 0 Group: 0 Size: 348960
+File ACL: 0 Directory ACL: 0
+Links: 1 Blockcount: 688
+Fragment: Address: 0 Number: 0 Size: 0
+ctime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+atime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+mtime: 0x322488cf -- Wed Aug 28 17:58:39 1996
+BLOCKS:
+70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413
+TOTAL: 344
+
+debugfs: cat fluff
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+yabba dabba doo. cocka doodle doo. yabba dabba doo. cocka doodle doo. yipyip
+
+debugfs: quit
+Exit status is 0
+e2fsck -yf -N test_filesys
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 4: Checking reference counts
+Pass 5: Checking group summary information
+test_filesys: 25/256 files (0.0% non-contiguous), 418/1024 blocks
+Exit status is 0
--- /dev/null
+checking the e2fsck swapfs functionality
--- /dev/null
+IMAGE=$test_dir/image.gz
+VERIFY_FSCK_OPT=-yf
+SWAP_FSCK_OPT=-Sy
+NATIVE_FSCK_OPT=-sy
+OUT=$test_name.log
+EXP=$test_dir/expect
+
+gunzip < $IMAGE > $TMPFILE
+
+echo "Swapfs test" > $OUT
+
+echo e2fsck $VERIFY_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $VERIFY_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo e2fsck $SWAP_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $SWAP_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo Running debugfs.... >> $OUT
+$DEBUGFS -f $test_dir/debugfs.cmd $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+echo e2fsck $VERIFY_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $VERIFY_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo e2fsck $NATIVE_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $NATIVE_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+
+echo Running debugfs.... >> $OUT
+$DEBUGFS -f $test_dir/debugfs.cmd $TMPFILE >> $OUT 2>&1
+status=$?
+echo Exit status is $status >> $OUT
+
+echo e2fsck $VERIFY_FSCK_OPT -N test_filesys > $OUT.new
+$FSCK $VERIFY_FSCK_OPT -N test_filesys $TMPFILE >> $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -e '2d' $OUT.new >> $OUT
+rm -f $OUT.new
+
+rm $TMPFILE
+
+#
+# Do the verification
+#
+
+rm -f $test_name.ok $test_name.failed
+cmp -s $OUT $EXP
+status=$?
+
+if [ "$status" = 0 ] ; then
+ echo "ok"
+ touch $test_name.ok
+else
+ echo "failed"
+ diff -c $EXP $OUT > $test_name.failed
+fi
+
+unset IMAGE VERIFY_FSCK_OPT SWAP_FSCK_OPT NATIVE_FSCK_OPT OUT EXP
fi
if [ "$SKIP_CLEANUP" != "true" ] ; then
- unset IMAGE FSCK_OPT SECOND_FSCK_OPT OUT1 OUT2 EXP1 EXP2
+ unset IMAGE FSCK_OPT SECOND_FSCK_OPT OUT1 OUT2 EXP1 EXP2 ONE_PASS_ONLY
fi
+
#
FSCK=../e2fsck/e2fsck
+DEBUGFS=../debugfs/debugfs
LD_LIBRARY_PATH=../lib:../lib/ext2fs:../lib/e2p:../lib/et:../lib/ss
export LD_LIBRARY_PATH
TZ=GMT
export TZ
+unset PAGER
#
if test "$1"x = x ; then
-SRCDIR=.
+ TESTS=$SRCDIR/[a-zA-Z]_*
else
-SRCDIR=$1
+ TESTS=
+ for i
+ do
+ TESTS="$TESTS $SRCDIR/$i"
+ done
fi
cmd_dir=$SRCDIR
. $SRCDIR/test_config
-for test_dir in $SRCDIR/[a-zA-Z]_*
+for test_dir in $TESTS
do
test_name=`echo $test_dir | sed -e 's;.*/;;'`
if [ -f $test_dir/name ]; then
fi
done
-num_ok=`ls *.ok | wc -l`
+num_ok=`ls *.ok 2>/dev/null | wc -l`
num_failed=`ls *.failed 2>/dev/null | wc -l`
echo "$num_ok tests succeeded $num_failed tests failed"