Radix cross Linux

The main Radix cross Linux repository contains the build scripts of packages, which have the most complete and common functionality for desktop machines

452 Commits   2 Branches   1 Tag
Index: Makefile
===================================================================
--- Makefile	(nonexistent)
+++ Makefile	(revision 5)
@@ -0,0 +1,56 @@
+
+COMPONENT_TARGETS = $(HARDWARE_NOARCH)
+
+
+include ../../../../build-system/constants.mk
+
+
+url         = $(DOWNLOAD_SERVER)/sources/packages/a/jfsutils
+
+versions    = 1.1.15
+pkgname     = jfsutils
+suffix      = tar.gz
+
+tarballs    = $(addsuffix .$(suffix), $(addprefix $(pkgname)-, $(versions)))
+sha1s       = $(addsuffix .sha1sum, $(tarballs))
+
+patches     = $(CURDIR)/patches/jfsutils-1.1.15.patch
+
+.NOTPARALLEL: $(patches)
+
+
+BUILD_TARGETS = $(tarballs) $(sha1s) $(patches)
+
+
+include ../../../../build-system/core.mk
+
+
+.PHONY: download_clean
+
+
+$(tarballs):
+	@echo -e "\n======= Downloading source tarballs =======" ; \
+	 for tarball in $(tarballs) ; do \
+	   echo "$(url)/$$tarball" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & \
+	 done ; wait
+
+$(sha1s): $(tarballs)
+	@for sha in $@ ; do \
+	   echo -e "\n======= Downloading '$$sha' signature =======\n" ; \
+	   echo "$(url)/$$sha" | xargs -n 1 -P 100 wget $(WGET_OPTIONS) - & wait %1 ; \
+	   touch $$sha ; \
+	   echo -e "\n======= Check the '$$sha' sha1sum =======\n" ; \
+	   sha1sum --check $$sha ; ret="$$?" ; \
+	   if [ "$$ret" == "1" ]; then \
+	     echo -e "\n======= ERROR: Bad '$$sha' sha1sum =======\n" ; \
+	     exit 1 ; \
+	   fi ; \
+	 done
+
+$(patches): $(sha1s)
+	@echo -e "\n======= Create Patches =======\n" ; \
+	 ( cd create-1.1.15-patch ; ./create.patch.sh ) ; \
+	 echo -e "\n"
+
+download_clean:
+	@rm -f $(tarballs) $(sha1s) $(patches)
Index: create-1.1.15-patch/create.patch.sh
===================================================================
--- create-1.1.15-patch/create.patch.sh	(nonexistent)
+++ create-1.1.15-patch/create.patch.sh	(revision 5)
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+VERSION=1.1.15
+
+tar --files-from=file.list -xzvf ../jfsutils-$VERSION.tar.gz
+mv jfsutils-$VERSION jfsutils-$VERSION-orig
+
+cp -rf ./jfsutils-$VERSION-new ./jfsutils-$VERSION
+
+diff --unified -Nr  jfsutils-$VERSION-orig  jfsutils-$VERSION > jfsutils-$VERSION.patch
+
+mv jfsutils-$VERSION.patch ../patches
+
+rm -rf ./jfsutils-$VERSION
+rm -rf ./jfsutils-$VERSION-orig

Property changes on: create-1.1.15-patch/create.patch.sh
___________________________________________________________________
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: create-1.1.15-patch/file.list
===================================================================
--- create-1.1.15-patch/file.list	(nonexistent)
+++ create-1.1.15-patch/file.list	(revision 5)
@@ -0,0 +1,5 @@
+jfsutils-1.1.15/fscklog/extract.c
+jfsutils-1.1.15/libfs/devices.c
+jfsutils-1.1.15/libfs/devices.h
+jfsutils-1.1.15/libfs/log_dump.c
+jfsutils-1.1.15/libfs/logredo.c
Index: create-1.1.15-patch/jfsutils-1.1.15-new/fscklog/extract.c
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new/fscklog/extract.c	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new/fscklog/extract.c	(revision 5)
@@ -0,0 +1,984 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2000-2002
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/*
+ *   COMPONENT_NAME: jfs_fscklog (formerly xchklog)
+ *
+ *      The jfs_fscklog tool provides 2 basic functions - fsck.jfs
+ *      service log extraction and display.  The code here extracts
+ *      the log.
+ *
+ */
+#include <config.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdint.h>
+
+#include "devices.h"
+#include "diskmap.h"
+#include "fsckwsp.h"
+#include "fsck_message.h"
+#include "jfs_endian.h"
+#include "jfs_fscklog.h"
+#include "super.h"
+#include "utilsubs.h"
+#include "xfsck.h"
+
+#define fsck_READ  1
+#define fsck_WRITE 2
+
+extern char file_name[128];
+
+FILE *outfp;
+
+extern struct fscklog_record fscklog_record;
+extern struct fscklog_record *local_recptr;
+
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+  *
+  * superblock I/O buffer and pointer
+  *
+  */
+struct superblock aggr_superblock;
+struct superblock *sb_ptr;
+
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+  *
+  * input:  fsck service log I/O buffer
+  * output: fsck extracted service log I/O buffer
+  *
+  */
+char fscklog_buffer[FSCKLOG_BUFSIZE];
+extern char xchklog_buffer[];
+
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+  *
+  * For message processing
+  *
+  *    values are assigned by the main jfs_fscklog routine
+  */
+extern char *Vol_Label;
+
+ /* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+  *
+  * Device information.
+  *
+  *     values are assigned when (if) the device is opened.
+  */
+FILE *Dev_IOPort;
+unsigned Dev_blksize;
+int Dev_SectorSize;
+
+/* VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV
+ *
+ * The following are internal to this file
+ *
+ */
+void extract_service_log(void);
+
+int xchklog_final_processing(void);
+
+int xchklog_fscklog_fill_buffer(void);
+
+int xchklog_initial_processing(struct fscklog_record *);
+
+int open_device_read(const char *);
+
+int open_outfile(void);
+
+int readwrite_device(int64_t, unsigned, unsigned *, void *, int);
+
+void record_msg(char *);
+
+int validate_super(int);
+
+int validate_superblock(void);
+
+/*****************************************************************************
+ * NAME: xchklog
+ *
+ * FUNCTION: Entry point for jfs read aggregate fsck service log
+ *
+ * PARAMETERS:
+ *           local_recptr - fscklog record
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int xchklog(struct fscklog_record *local_recptr)
+{
+	int rc = 0;
+
+	/*
+	 * some basic initializations
+	 */
+	sb_ptr = &aggr_superblock;
+
+	rc = xchklog_initial_processing(local_recptr);
+
+	if (rc == 0) {
+		/* we have a buffer and the device is open */
+		extract_service_log();
+	}
+
+	if (rc == 0) {
+		rc = xchklog_final_processing();
+	} else {
+		xchklog_final_processing();
+	}
+
+	return (rc);
+}
+
+/***************************************************************************
+ * NAME: extract_service_log
+ *
+ * FUNCTION:
+ *
+ * PARAMETERS:  none
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+void extract_service_log()
+{
+	char *msg_txt;
+	int dsl_rc = 0;
+	char *log_entry;
+	int log_entry_pos;
+	int bytes_left;
+	struct fscklog_entry_hdr *hdptr;
+
+	local_recptr->fscklog_last_read = 0;
+
+	while ((!local_recptr->fscklog_last_read) && (dsl_rc == 0)) {
+
+		dsl_rc = xchklog_fscklog_fill_buffer();
+		local_recptr->this_buffer_last_message = 0;
+		while ((!local_recptr->this_buffer_last_message)
+		       && (dsl_rc == 0)) {
+
+			hdptr = (struct fscklog_entry_hdr *)
+			    (local_recptr->infile_buf_ptr +
+			     local_recptr->infile_buf_data_len);
+			if (hdptr->entry_length == 0) {
+				/* no more entries in this buffer */
+				local_recptr->this_buffer_last_message = -1;
+			} else {
+				/* this entry_length != 0 */
+
+				/* swap if on big endian machine */
+				ujfs_swap_fscklog_entry_hdr(hdptr);
+
+				log_entry = (char *) hdptr;
+				log_entry_pos =
+				    sizeof (struct fscklog_entry_hdr);
+
+				/*
+				 * Each FSCKLOG_BUFSIZE boundary starts a new
+				 * log record.  Otherwise, we depend on a valid
+				 * entry_length to locate the next message.
+				 */
+				bytes_left = local_recptr->infile_buf_length -
+				    local_recptr->infile_buf_data_len;
+				if ((bytes_left < 0)
+				    || (hdptr->entry_length < 0)
+				    || (hdptr->entry_length > bytes_left)) {
+					/* this isn't a valid log record length */
+					send_msg(fsck_CHKLOGINVALRCD);
+					local_recptr->this_buffer_last_message =
+					    -1;
+				} else {
+					/* the log record length looks ok */
+					msg_txt = &log_entry[log_entry_pos];
+
+					/*
+					 * record the message in the output file
+					 */
+					record_msg(msg_txt);
+
+					/*
+					 * set up for the next record
+					 */
+					local_recptr->infile_buf_data_len +=
+					    hdptr->entry_length;
+					/*if (hdptr->msg_num == fsck_SESSEND) {
+						local_recptr->
+						    this_buffer_last_message =
+						    -1;
+						    }*/
+					if (local_recptr->infile_buf_data_len >=
+					    local_recptr->infile_buf_length) {
+						local_recptr->
+						    this_buffer_last_message =
+						    -1;
+					}
+				}
+			}
+		}
+	}
+
+	return;
+}
+
+/***************************************************************************
+ * NAME: xchklog_final_processing
+ *
+ * FUNCTION:  If processing read/write, replicate the superblock and the
+ *            aggregate inode structures (i.e., the Aggregate Inode Map
+ *            and the Aggregate Inode Table).
+ *
+ *            Notify the user about various things.
+ *
+ * PARAMETERS:  none
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int xchklog_final_processing()
+{
+	int pf_rc = 0;
+
+	/*
+	 * Close the device
+	 */
+	if (local_recptr->device_is_open) {
+		pf_rc = fclose(Dev_IOPort);
+	}
+
+	/*
+	 * Close the output file
+	 */
+	if (local_recptr->outfile_is_open) {
+		/*
+		 * flush the buffer if necessary
+		 */
+		if (local_recptr->outfile_buf_data_len != 0) {
+			fwrite((const void *) (local_recptr->outfile_buf_ptr),
+			       sizeof (char), local_recptr->outfile_buf_length,
+			       outfp);
+		}
+		fclose(outfp);
+	}
+
+	return (pf_rc);
+}
+
+/*****************************************************************************
+ * NAME: fscklog_fill_buffer
+ *
+ * FUNCTION:  If the current fsck session has write access to the aggregate,
+ *            and if the in-aggregate fsck log is not full, write the
+ *            contents of the current fscklog buffer into the in-aggregate
+ *            fsck log.
+ *
+ * PARAMETERS:  none
+ *
+ * NOTES:  o Unlike most _put_ routines in this module, fscklog_put_buffer
+ *           actually writes to the device.  This is done because the fsck
+ *           log contains information which provides crucial serviceability
+ *           should the fsck session be interrupted.
+ *
+ *         o Errors here are recorded in the control page of the fsck
+ *           in-aggregate workspace but never affect other fsck processing.
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int xchklog_fscklog_fill_buffer()
+{
+	int flfb_rc = 0;
+	int io_rc = 0;
+	unsigned bytes_read = 0;
+	unsigned log_bytes_left;
+
+	io_rc = readwrite_device(local_recptr->infile_agg_offset,
+				 local_recptr->infile_buf_length,
+				 &bytes_read,
+				 (void *) local_recptr->infile_buf_ptr,
+				 fsck_READ);
+
+	if ((io_rc != 0)
+	    || (bytes_read != (unsigned) local_recptr->infile_buf_length)) {
+		/*
+		 * write failed or didn't read
+		 * correct number of bytes
+		 */
+		send_msg(fsck_URCVWRT, fsck_ref_msg(fsck_metadata), Vol_Label);
+
+		send_msg(fsck_ERRONLOG, FSCK_BADREAD_FSCKLOG, io_rc, fsck_READ,
+			 (long long) local_recptr->infile_agg_offset,
+			 (long int) local_recptr->infile_buf_length,
+			 (long int) bytes_read);
+	}
+	/*
+	 * We want to reset the buffer no matter what.  If is useful
+	 * to keep going because the next section may be readable.
+	 */
+	local_recptr->infile_agg_offset += local_recptr->infile_buf_length;
+	local_recptr->infile_log_offset += local_recptr->infile_buf_length;
+	local_recptr->infile_buf_data_len = 0;
+
+	log_bytes_left = (local_recptr->ondev_fscklog_byte_length / 2) -
+	    local_recptr->infile_log_offset;
+	if (log_bytes_left < local_recptr->infile_buf_length) {
+		/* this is the last one */
+		local_recptr->fscklog_last_read = -1;
+	}
+	return (flfb_rc);
+}
+
+/*****************************************************************************
+ * NAME: xchklog_initial_processing
+ *
+ * FUNCTION: Parse and verify invocation parameters.
+ *           Open the device and verify that it contains a JFS file system.
+ *           Read the chkdsk workspace control page.
+ *           Calculate interesting aggregate offsets.
+ *
+ *
+ * PARAMETERS:  as specified to main()
+ *
+ * NOTES:
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int xchklog_initial_processing(struct fscklog_record *local_recptr)
+{
+	int pi_rc = 0;
+
+	/*
+	 * Initialize the fscklog control block
+	 */
+	local_recptr->infile_buf_length = FSCKLOG_BUFSIZE;
+	local_recptr->infile_buf_ptr = fscklog_buffer;
+	local_recptr->outfile_buf_length = XCHKLOG_BUFSIZE;
+	local_recptr->outfile_buf_ptr = xchklog_buffer;
+
+	/*
+	 * Open the device and verify that it contains a valid JFS aggregate
+	 * If it does, check/repair the superblock.
+	 */
+	pi_rc = open_device_read(Vol_Label);
+
+	if (pi_rc != 0) {
+		/*device open failed */
+		send_msg(fsck_CNTRESUPB);
+	} else {
+		/* device is open */
+		local_recptr->device_is_open = 1;
+		pi_rc = validate_superblock();
+		if (pi_rc == 0) {
+			/* a valid superblock */
+
+			/*
+			 * add some stuff to the local record which is based on
+			 * superblock fields
+			 */
+
+			/* length of the on-device fsck service log */
+			local_recptr->ondev_fscklog_byte_length =
+			    sb_ptr->s_fsckloglen * sb_ptr->s_bsize;
+			/* length of the on-device fsck service log */
+			local_recptr->ondev_fscklog_fsblk_length =
+			    sb_ptr->s_fsckloglen;
+			/* length of the on-device fsck workspace */
+			local_recptr->ondev_wsp_fsblk_length =
+			    lengthPXD(&(sb_ptr->s_fsckpxd)) -
+			    local_recptr->ondev_fscklog_fsblk_length;
+			/* length of the on-device fsck workspace */
+			local_recptr->ondev_wsp_byte_length =
+			    local_recptr->ondev_wsp_fsblk_length *
+			    sb_ptr->s_bsize;
+			/* aggregate block offset of the on-device fsck workspace */
+			local_recptr->ondev_wsp_fsblk_offset =
+			    addressPXD(&(sb_ptr->s_fsckpxd));
+			/* byte offset of the on-device fsck workspace */
+			local_recptr->ondev_wsp_byte_offset =
+			    local_recptr->ondev_wsp_fsblk_offset *
+			    sb_ptr->s_bsize;
+			/* aggregate block offset of the on-device fsck workspace */
+			local_recptr->ondev_fscklog_fsblk_offset =
+			    local_recptr->ondev_wsp_fsblk_offset +
+			    local_recptr->ondev_wsp_fsblk_length;
+			/* byte offset of the on-device fsck workspace */
+			local_recptr->ondev_fscklog_byte_offset =
+			    local_recptr->ondev_wsp_byte_offset +
+			    local_recptr->ondev_wsp_byte_length;
+			/*
+			 * The offsets now assume the most recent log is 1st in the
+			 * aggregate fsck service log space.  Adjust if needed.
+			 */
+			if (local_recptr->which_log == NEWLOG) {
+				/* most recent wanted */
+				if (sb_ptr->s_fscklog == 2) {
+					/* the 2nd is most recent */
+					local_recptr->
+					    ondev_fscklog_fsblk_offset +=
+					    local_recptr->
+					    ondev_fscklog_fsblk_length / 2;
+					local_recptr->
+					    ondev_fscklog_byte_offset +=
+					    local_recptr->
+					    ondev_fscklog_byte_length / 2;
+				}
+			} else {
+				/* previous log wanted */
+				if (sb_ptr->s_fscklog != 2) {
+					/* the 2nd is not most recent */
+					local_recptr->
+					    ondev_fscklog_fsblk_offset +=
+					    local_recptr->
+					    ondev_fscklog_fsblk_length / 2;
+					local_recptr->
+					    ondev_fscklog_byte_offset +=
+					    local_recptr->
+					    ondev_fscklog_byte_length / 2;
+				}
+			}
+			local_recptr->infile_agg_offset =
+			    local_recptr->ondev_fscklog_byte_offset;
+
+			pi_rc = open_outfile();
+		}
+	}
+
+	if (local_recptr->which_log == NEWLOG) {
+		send_msg(fsck_CHKLOGNEW);
+	} else {
+		send_msg(fsck_CHKLOGOLD);
+	}
+
+	return (pi_rc);
+}
+
+/*****************************************************************************
+ * NAME: open_device_read
+ *
+ * FUNCTION:  Open the specified device for read access.
+ *
+ * PARAMETERS:
+ *      Device  - input - the device specification
+ *
+ * NOTES:
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int open_device_read(const char *Device)
+{
+	Dev_IOPort = fopen(Device, "r");
+	if (Dev_IOPort == NULL) {
+		send_msg(fsck_DEVOPENRDRC, ERROR_FILE_NOT_FOUND);
+		return ERROR_FILE_NOT_FOUND;
+	}
+
+	Dev_blksize = Dev_SectorSize = PBSIZE;
+	return 0;
+}
+
+/*****************************************************************************
+ * NAME: open_outfile
+ *
+ * FUNCTION:  Open the output file.
+ *
+ * PARAMETERS:
+ *      Device  - input - the device specification
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int open_outfile()
+{
+	int openof_rc = 0;
+
+	if (!local_recptr->file_name_specified) {
+		/* no output file name given */
+		if (local_recptr->which_log == NEWLOG) {
+			/* most recent wanted */
+			memcpy((void *) file_name, (void *) default_logfile_new,
+			       default_logfile_name_len);
+		} else {
+			/* prior log wanted */
+			memcpy((void *) file_name, (void *) default_logfile_old,
+			       default_logfile_name_len);
+		}
+	}
+
+	outfp = fopen(file_name, "w");
+	if (outfp == NULL) {
+		/* output file open failed */
+		openof_rc = XCHKLOG_CANTOPENOUTFILE;
+		send_msg(fsck_XCHKLOGOPNFAIL, file_name);
+	} else {
+		/* output file is open */
+		local_recptr->outfile_is_open = -1;
+
+		/*
+		 * write the eyecatcher into the output buffer
+		 */
+		memcpy((void *) (local_recptr->outfile_buf_ptr),
+		       (void *) jfs_chklog_eyecatcher, 16);
+		local_recptr->outfile_buf_data_len = 16;
+
+		/*
+		 * announce the output file name
+		 */
+		if (local_recptr->which_log == NEWLOG) {
+			/* most recent */
+			send_msg(fsck_XCHKLOGNEW, file_name);
+		} else {
+			/* previous */
+			send_msg(fsck_XCHKLOGOLD, file_name);
+		}
+	}
+	return (openof_rc);
+}
+
+/*****************************************************************************
+ * NAME: readwrite_device
+ *
+ * FUNCTION:  Read data from or write data to the device on which the
+ *            aggregate resides.
+ *
+ * PARAMETERS:
+ *      dev_offset           - input - the offset, in bytes, into the aggregate
+ *                                     of the data to read or to which to write
+ *                                     the data.
+ *      requested_data_size  - input - the number of bytes requested
+ *      actual_data_size     - input - pointer to a variable in which to return
+ *                                     the number of bytes actually read or
+ *                                     written
+ *      data_buffer          - input - the address of the buffer in which to
+ *                                     put the data or from which to write
+ *                                     the data
+ *      mode                 - input - { fsck_READ | fsck_WRITE }
+ *
+ * NOTES:  This routine also exists in fsck code.  When there is time,
+ *	   examine both copies for differences and put the combined
+ *         copy in libfs to eliminate extra code.
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int readwrite_device(int64_t dev_offset,
+		     unsigned requested_data_size,
+		     unsigned *actual_data_size, void *data_buffer, int mode)
+{
+	int rwdb_rc = 0;
+
+	if ((dev_offset % Dev_SectorSize)
+	    || (requested_data_size % Dev_SectorSize)) {
+		rwdb_rc = FSCK_FAILED_SEEK;
+	} else {
+		switch (mode) {
+		case fsck_READ:
+			rwdb_rc =
+			    ujfs_rw_diskblocks(Dev_IOPort, dev_offset,
+					       requested_data_size, data_buffer,
+					       GET);
+			break;
+		case fsck_WRITE:
+			rwdb_rc =
+			    ujfs_rw_diskblocks(Dev_IOPort, dev_offset,
+					       requested_data_size, data_buffer,
+					       PUT);
+			break;
+		default:
+			rwdb_rc = FSCK_INTERNAL_ERROR_3;
+			break;
+		}
+	}
+
+	if (rwdb_rc == 0)
+		*actual_data_size = requested_data_size;
+	else
+		*actual_data_size = 0;
+
+	return (rwdb_rc);
+}
+
+/*****************************************************************************
+ * NAME: record_msg
+ *
+ * FUNCTION: Record an fsck service log message in the output file,
+ *           formatted for the common fsck service log display tool.
+ *
+ * PARAMETERS:
+ *      ?                 - input -
+ *      ?                 - returned -
+ *
+ * NOTES:  Any message designated fsck_debug is english-only, and
+ *         is issued in english, even if it is sent to stdout.
+ *
+ *         All other messages are local-language (in the nls context)
+ *         and, when sent to stdout or stderr, are issued in the
+ *         local language.
+ *
+ *         Regardless of the language used to send a message to
+ *         stdout and stderr, messages are ALWAYS LOGGED IN ENGLISH.
+ *
+ * RETURNS:
+ *	nothing
+ */
+void record_msg(char *msg_txt)
+{
+	char *msg;
+	char log_entry[4096];
+	int entry_length = sizeof (struct chklog_entry_hdr);
+	struct chklog_entry_hdr *hdptr;
+	int buffer_bytes_left;
+
+	hdptr = (struct chklog_entry_hdr *) log_entry;
+	msg = &log_entry[entry_length];
+	strcpy(msg, msg_txt);
+	entry_length += strlen(msg_txt);
+	/* add null terminator to string */
+	log_entry[entry_length++] = '\0';
+
+	/*
+	 * round the length up so the next entry will
+	 * start on a doubleword (4 byte) boundary
+	 */
+	entry_length = ((entry_length + 3) / 4) * 4;
+
+	hdptr->entry_length = entry_length;
+
+	buffer_bytes_left =
+	    local_recptr->outfile_buf_length -
+	    local_recptr->outfile_buf_data_len;
+	if (buffer_bytes_left < entry_length) {
+		/* won't fit */
+		local_recptr->last_msghdr->entry_length += buffer_bytes_left;
+		fwrite((const void *) (local_recptr->outfile_buf_ptr),
+		       sizeof (char), local_recptr->outfile_buf_length, outfp);
+		/* clear the buffer */
+		memset((void *) (local_recptr->outfile_buf_ptr), 0,
+		       local_recptr->outfile_buf_length);
+		local_recptr->outfile_buf_data_len = 0;
+	}
+	local_recptr->last_msghdr = (struct fscklog_entry_hdr *)
+	    (local_recptr->outfile_buf_ptr +
+	     local_recptr->outfile_buf_data_len);
+	memcpy((void *) local_recptr->last_msghdr, (void *) hdptr,
+	       entry_length);
+
+	local_recptr->outfile_buf_data_len += entry_length;
+
+	return;
+}
+
+/*****************************************************************************
+ * NAME: validate_super
+ *
+ * FUNCTION:  This routine validates the JFS superblock currently in the
+ *            buffer.  If any problem is detected, the which_superblock
+ *            input parm is used to tailor the message issued to notify
+ *            the user.
+ *
+ * PARAMETERS:
+ *      which_super  - input - specifies the superblock on which is in the
+ *                             buffer { fsck_primary | fsck_secondary }
+ *
+ * NOTES:  This routine also exists in fsck code.  When there is time,
+ *	   examine both copies for differences and put the combined
+ *         copy in libfs to eliminate extra code.
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int validate_super(int which_super)
+{
+	int vs_rc = 0;		/* assume the superblock is ok */
+	int64_t bytes_on_device;
+	int64_t agg_blks_in_aggreg = 0, agg_blks_on_device =
+	    0, dev_blks_on_device;
+	int64_t fsck_start_from_pxd, fsck_blkmap_start_blks;
+	uint32_t fsck_length_from_pxd, fsck_blkmap_size_blks,
+	    fsck_blkmap_size_pages;
+	int64_t jlog_start_from_pxd;
+	uint32_t jlog_length_from_pxd;
+	int agl2size;
+	unsigned expected_flag = JFS_GROUPCOMMIT;
+	unsigned agsize;
+	int bad_bsize = 0;
+
+	if (memcmp(sb_ptr->s_magic, JFS_MAGIC, sizeof (sb_ptr->s_magic)) != 0) {
+		vs_rc = FSCK_BADSBMGC;
+		send_msg(fsck_BADSBMGC, fsck_ref_msg(which_super));
+	} else if (sb_ptr->s_version > JFS_VERSION) {
+		vs_rc = FSCK_BADSBVRSN;
+		send_msg(fsck_BADSBVRSN, fsck_ref_msg(which_super));
+	} else {
+		/* the magic number and version number are correct so it
+		 * probably is a JFS superblock with the format we are expecting
+		 */
+
+		/* get physical device size */
+		ujfs_get_dev_size(Dev_IOPort, &bytes_on_device);
+
+		dev_blks_on_device = bytes_on_device / Dev_blksize;
+
+		if (sb_ptr->s_pbsize != Dev_blksize) {
+			vs_rc = FSCK_BADSBOTHR1;
+			send_msg(fsck_BADSBOTHR, "1", fsck_ref_msg(which_super));
+		}
+		if (sb_ptr->s_l2pbsize != log2shift(Dev_blksize)) {
+			vs_rc = FSCK_BADSBOTHR2;
+			send_msg(fsck_BADSBOTHR, "2", fsck_ref_msg(which_super));
+		}
+		if (!inrange(sb_ptr->s_bsize, 512, 4096)) {
+			bad_bsize = -1;
+			vs_rc = FSCK_BADSBOTHR3;
+			send_msg(fsck_BADSBBLSIZ, fsck_ref_msg(which_super));
+		} else {
+			/* else the filesystem block size is a legal value */
+			if (sb_ptr->s_l2bsize != log2shift(sb_ptr->s_bsize)) {
+				vs_rc = FSCK_BADSBOTHR4;
+				send_msg(fsck_BADSBOTHR, "4",
+					 fsck_ref_msg(which_super));
+			}
+			if (sb_ptr->s_l2bfactor !=
+			    log2shift(sb_ptr->s_bsize / Dev_blksize)) {
+				vs_rc = FSCK_BADSBOTHR5;
+				send_msg(fsck_BADSBOTHR, "5",
+					 fsck_ref_msg(which_super));
+			}
+			if (sb_ptr->s_bsize < Dev_blksize) {
+				bad_bsize = -1;
+				vs_rc = FSCK_BLSIZLTLVBLSIZ;
+				send_msg(fsck_BLSIZLTLVBLSIZ,
+					 fsck_ref_msg(which_super));
+			}
+		}
+
+		if (!bad_bsize) {
+			agg_blks_on_device = bytes_on_device / sb_ptr->s_bsize;
+		}
+
+		if (sb_ptr->s_size > dev_blks_on_device) {
+			vs_rc = FSCK_BADSBFSSIZ;
+			send_msg(fsck_BADSBFSSIZ, fsck_ref_msg(which_super));
+		}
+#ifdef	_JFS_DFS_LFS
+		s_size_inbytes = sb_ptr->s_size * Dev_blksize;
+		sum_inbytes = (int64_t) (sb_ptr->totalUsable * 1024) +
+		    (int64_t) (sb_ptr->minFree * 1024);
+		if ((sum_inbytes > s_size_inbytes)
+		    || ((s_size_inbytes - sum_inbytes) >= 1024)) {
+			/* the sum is greater or the difference is at least 1K */
+			vs_rc = FSCK_BADBLKCTTTL;
+			send_msg(fsck_BADBLKCTTTL, fsck_ref_msg(which_super));
+		}
+#endif
+		/* must have JFS_OS2 or JFS_LINUX */
+		if (!(((sb_ptr->s_flag & JFS_OS2) == JFS_OS2)
+		      || ((sb_ptr->s_flag & JFS_LINUX) == JFS_LINUX))) {
+			vs_rc = FSCK_BADSBOTHR6;
+			send_msg(fsck_BADSBOTHR, "6", fsck_ref_msg(which_super));
+		}
+
+		if ((sb_ptr->s_flag & expected_flag) != expected_flag) {
+			vs_rc = FSCK_BADSBOTHR6;
+			send_msg(fsck_BADSBOTHR, "6", fsck_ref_msg(which_super));
+		}
+		if (sb_ptr->s_agsize < (1 << L2BPERDMAP)) {
+			vs_rc = FSCK_BADSBAGSIZ;
+			send_msg(fsck_BADSBAGSIZ, fsck_ref_msg(which_super));
+		} else {
+			/* else the alloc group size is possibly correct */
+			agg_blks_in_aggreg =
+			    sb_ptr->s_size * sb_ptr->s_pbsize / sb_ptr->s_bsize;
+			agl2size =
+			    ujfs_getagl2size(agg_blks_in_aggreg,
+					     sb_ptr->s_bsize);
+			/* get the allocation group size */
+			agsize = (int64_t) 1 << agl2size;
+			if (sb_ptr->s_agsize != agsize) {
+				vs_rc = FSCK_BADAGFSSIZ;
+				send_msg(fsck_BADSBAGSIZ, fsck_ref_msg(which_super));
+			}
+		}
+
+		if (!vs_rc) {
+			/*
+			 * check out the fsck in-aggregate workspace
+			 */
+			fsck_length_from_pxd = lengthPXD(&(sb_ptr->s_fsckpxd));
+			fsck_start_from_pxd = addressPXD(&(sb_ptr->s_fsckpxd));
+			agg_blks_in_aggreg = fsck_length_from_pxd +
+			    (sb_ptr->s_size * sb_ptr->s_pbsize /
+			     sb_ptr->s_bsize);
+
+			if (agg_blks_in_aggreg > agg_blks_on_device) {
+				/* wsp length is bad */
+				vs_rc = FSCK_BADSBFWSL1;
+				send_msg(fsck_BADSBFWSL1, fsck_ref_msg(which_super));
+			} else {
+				fsck_blkmap_size_pages =
+				    ((agg_blks_in_aggreg +
+				      (BITSPERPAGE - 1)) / BITSPERPAGE) + 1 +
+				    50;
+				/* size in aggregate blocks */
+				fsck_blkmap_size_blks =
+				    (fsck_blkmap_size_pages << L2PSIZE) /
+				    sb_ptr->s_bsize;
+				/*
+				 * aggregate block offset of the
+				 * fsck workspace in the aggregate.
+				 */
+				fsck_blkmap_start_blks =
+				    agg_blks_in_aggreg - fsck_blkmap_size_blks;
+				if (fsck_length_from_pxd !=
+				    fsck_blkmap_size_blks) {
+					/*
+					 * length of fsck in-aggregate
+					 * workspace is incorrect
+					 */
+					vs_rc = FSCK_BADSBFWSL;
+					send_msg(fsck_BADSBFWSL,
+						 fsck_ref_msg(which_super));
+				}
+				if (fsck_start_from_pxd !=
+				    fsck_blkmap_start_blks) {
+					/*
+					 * address of fsck in-aggregate
+					 * workspace is incorrect
+					 */
+					vs_rc = FSCK_BADSBFWSA;
+					send_msg(fsck_BADSBFWSA,
+						 fsck_ref_msg(which_super));
+				}
+			}
+		}
+		if (!vs_rc) {
+			/*
+			 * check out the in-aggregate journal log
+			 *
+			 * if there is one it starts at the end of the fsck
+			 * in-aggregate workspace.
+			 */
+			jlog_length_from_pxd = lengthPXD(&(sb_ptr->s_logpxd));
+			jlog_start_from_pxd = addressPXD(&(sb_ptr->s_logpxd));
+
+			if (jlog_start_from_pxd != 0) {
+				/* there's one in there */
+				if (jlog_start_from_pxd != agg_blks_in_aggreg) {
+					/*
+					 * address of in-aggregate
+					 * journal log is incorrect
+					 */
+					vs_rc = FSCK_BADSBFJLA;
+					send_msg(fsck_BADSBFJLA,
+						 fsck_ref_msg(which_super));
+				}
+				agg_blks_in_aggreg += jlog_length_from_pxd;
+				if (agg_blks_in_aggreg > agg_blks_on_device) {
+					/* log length is bad */
+					vs_rc = FSCK_BADSBFJLL;
+					send_msg(fsck_BADSBFJLL,
+						 fsck_ref_msg(which_super));
+				}
+			}
+		}
+	}
+	return (vs_rc);
+}
+
+/*****************************************************************************
+ * NAME: validate_superblock
+ *
+ * FUNCTION:  Verify that the primary superblock is valid.
+ *            If not, verify that the secondary superblock is valid.
+ *
+ * PARAMETERS:  none
+ *
+ * NOTES:  If this routine returns 0 then the superblock
+ *         I/O buffer contains a valid superblock.
+ *
+ *	   This routine also exists in fsck code.  When there is time,
+ *	   examine both copies for differences and put the combined
+ *         copy in libfs to eliminate extra code.
+ *
+ * RETURNS:
+ *      success: 0
+ *      failure: something else
+ */
+int validate_superblock()
+{
+	int vsb_rc = 0;
+	int primary_sb_bad = 1;
+	int secondary_sb_bad = 1;
+	int which_sb = 0;
+
+	/* get primary  */
+	vsb_rc = ujfs_get_superblk(Dev_IOPort, sb_ptr, 1);
+
+	if (vsb_rc != 0) {
+		/* if read primary fails */
+		send_msg(fsck_CNTRESUPP);
+	} else {
+		/* got primary superblock */
+		which_sb = fsck_primary;
+		primary_sb_bad = validate_super(fsck_primary);
+	}
+
+	if (primary_sb_bad) {
+		/* can't use the primary superblock */
+		send_msg(fsck_SBBADP);
+
+		/* get 2ndary */
+		vsb_rc = ujfs_get_superblk(Dev_IOPort, sb_ptr, 0);
+
+		if (vsb_rc != 0) {
+			send_msg(fsck_CNTRESUPS);
+		} else {
+			/* got secondary superblock */
+			which_sb = fsck_secondary;
+			secondary_sb_bad = validate_super(fsck_secondary);
+		}
+
+		if (!secondary_sb_bad) {
+			/* secondary is ok */
+			vsb_rc = 0;
+		} else {
+			send_msg(fsck_SBBADS);
+		}
+	}
+	if ((!primary_sb_bad) || (!secondary_sb_bad)) {
+		/* the buffer holds a valid superblock */
+
+		/* aggregate block size */
+		local_recptr->ag_blk_size = sb_ptr->s_bsize;
+
+		send_msg(fsck_XCHKLOGSBOK, fsck_ref_msg(which_sb));
+	}
+
+	return (vsb_rc);
+}
Index: create-1.1.15-patch/jfsutils-1.1.15-new/fscklog
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new/fscklog	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new/fscklog	(revision 5)

Property changes on: create-1.1.15-patch/jfsutils-1.1.15-new/fscklog
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-1.1.15-patch/jfsutils-1.1.15-new/libfs/devices.c
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new/libfs/devices.c	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new/libfs/devices.c	(revision 5)
@@ -0,0 +1,474 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2000-2008
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * autoconf 2.61 causes fseeko to miscompile against glibc-2.3.
+ * Override config.h by defining _LARGEFILE_SOURCE here
+ */
+#define _LARGEFILE_SOURCE
+
+#include <config.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_MOUNT_H
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#include <sys/mount.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/sysmacros.h>
+#if defined(__DragonFly__)
+#include <machine/param.h>
+#include <sys/diskslice.h>
+#endif
+
+#ifdef HAVE_SYS_DISKLABEL_H
+#include <sys/disklabel.h>
+#endif
+
+#include "jfs_types.h"
+#include "jfs_filsys.h"
+#include "devices.h"
+#include "debug.h"
+
+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE64)
+#define BLKGETSIZE64 _IOR(0x12, 114, size_t)
+#endif
+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
+#define BLKGETSIZE _IO(0x12,96)	/* return device size (sectors) */
+#endif
+
+/*
+ * NAME: ujfs_device_is_valid
+ *
+ * FUNCTION: Check device validity by examining stat modes.
+ *
+ * PRE CONDITIONS: 'device' must refer to an open device handle.
+ *
+ * PARAMETERS:
+ *      device_handle  - open device handle to check
+ *      st             - stat information if device handle not provided
+ *
+ * RETURNS: 0 if successful; anything else indicates failures
+ */
+int ujfs_device_is_valid(FILE *device_handle, struct stat *st)
+{
+	struct stat stat_data;
+	int rc = 0;
+
+	if (device_handle != NULL) {
+		rc = fstat(fileno(device_handle), &stat_data);
+		if (rc)
+			return -1;
+		st = &stat_data;
+	}
+	else if (st == NULL) {
+		return -1;
+	}
+
+	/* Do we have a block special device or regular file? */
+#if defined(__DragonFly__)
+	if (!S_ISCHR(st->st_mode) && !S_ISREG(st->st_mode))
+#else /* __linux__ etc. */
+	if (!S_ISBLK(st->st_mode) && !S_ISREG(st->st_mode))
+#endif
+		return -1;
+
+	return (rc);
+}
+
+/*
+ * NAME: ujfs_get_dev_size
+ *
+ * FUNCTION: Uses the device driver interface to determine the raw capacity of
+ *      the specified device.
+ *
+ * PRE CONDITIONS:
+ *
+ * POST CONDITIONS:
+ *
+ * PARAMETERS:
+ *      device  - device
+ *      size    - filled in with size of device; not modified if failure occurs
+ *
+ * NOTES:
+ *
+ * DATA STRUCTURES:
+ *
+ * RETURNS: 0 if successful; anything else indicates failures
+ */
+int ujfs_get_dev_size(FILE *device, int64_t *size)
+{
+
+	off_t Starting_Position;	/* position within file/device upon
+					 * entry to this function. */
+	off_t Current_Position = 16777215;	/* position we are attempting
+						 * to read from. */
+	off_t Last_Valid_Position = 0;	/* Last position we could successfully
+					 * read from. */
+	off_t First_Invalid_Position;	/* first invalid position we attempted
+					 * to read from/seek to. */
+	int Seek_Result;	/* value returned by lseek. */
+	size_t Read_Result = 0;	/* value returned by read. */
+	int rc;
+	struct stat stat_data;
+	int devfd = fileno(device);
+
+	rc = fstat(devfd, &stat_data);
+	if (!rc && S_ISREG(stat_data.st_mode)) {
+		/* This is a regular file.  */
+		*size = (int64_t) ((stat_data.st_size / 1024) * 1024);
+		return NO_ERROR;
+	}
+#ifdef BLKGETSIZE64
+	{
+		uint64_t sz;
+		if (ioctl(devfd, BLKGETSIZE64, &sz) >= 0) {
+			*size = sz;
+			return 0;
+		}
+	}
+#endif
+#ifdef BLKGETSIZE
+	{
+		unsigned long num_sectors = 0;
+
+		if (ioctl(devfd, BLKGETSIZE, &num_sectors) >= 0) {
+			/* for now, keep size as multiple of 1024, *
+			 * not 512, so eliminate any odd sector.   */
+			*size = PBSIZE * (int64_t) ((num_sectors / 2) * 2);
+			return NO_ERROR;
+		}
+	}
+#endif
+#if defined(__DragonFly__)
+	{
+		struct diskslices dss;
+		struct disklabel dl;
+		struct diskslice *sliceinfo;
+		int slice;
+		dev_t dev = stat_data.st_rdev;
+
+		rc = ioctl(devfd, DIOCGSLICEINFO, &dss);
+		if (rc < 0)
+			return -1;
+
+		slice = dkslice(dev);
+		sliceinfo = &dss.dss_slices[slice];
+
+		DBG_TRACE(("ujfs_get_device_size: slice = %d\n", slice));
+
+		if (sliceinfo) {
+			if (slice == WHOLE_DISK_SLICE || slice == 0) {
+				*size = (int64_t) sliceinfo->ds_size * dss.dss_secsize;
+				DBG_TRACE(("ujfs_get_device_size: slice represents disk\n"));
+			} else {
+				if (sliceinfo->ds_label) {
+					DBG_TRACE(("ujfs_get_device_size: slice has disklabel\n"));
+					rc = ioctl(devfd, DIOCGDINFO, &dl);
+					if (!rc) {
+						*size = (int64_t) dl.d_secperunit * dss.dss_secsize;
+					} else {
+						return (-1);
+					}
+				}
+			}
+		} else {
+			return (-1);
+		}
+
+		DBG_TRACE(("ujfs_get_device_size: size in bytes = %ld\n", *size));
+		DBG_TRACE(("ujfs_get_device_size: size in megabytes = %ld\n",
+			*size / (1024 * 1024)));
+
+		return 0;
+	}
+#endif
+#if defined(HAVE_SYS_DISKLABEL_H) && !defined(__DragonFly__)
+	{
+		struct disklabel dl;
+		struct partition * part;
+		dev_t dev = stat_data.st_rdev;
+
+		rc = ioctl(devfd, DIOCGDINFO, &dl);
+		if (rc < 0)
+			return -1;
+		part = dl.d_partitions + DISKPART(dev);
+
+		*size = (dl.d_secsize * part->p_size);
+
+		DBG_TRACE(("ujfs_get_device_size: size in bytes = %ld\n", 
+			*size));
+		DBG_TRACE(("ujfs_get_device_size: size in megabytes = %ld\n",
+			*size / (1024 * 1024)));
+
+		return NO_ERROR;
+	}
+#endif
+
+
+	/*
+	 * If the ioctl above fails or is undefined, use a binary search to
+	 * find the last byte in the partition.  This works because an lseek to
+	 * a position within the partition does not return an error while an
+	 * lseek to a position beyond the end of the partition does.  Note that
+	 * some SCSI drivers may log an 'access beyond end of device' error
+	 * message.
+	 */
+
+	/* Save the starting position so that we can restore it when we are
+	 * done! */
+	Starting_Position = ftello(device);
+	if (Starting_Position < 0)
+		return ERROR_SEEK;
+
+	/*
+	 * Find a position beyond the end of the partition.  We will start by
+	 * attempting to seek to and read the 16777216th byte in the partition.
+	 * We start here because a JFS partition must be at least this big.  If
+	 * it is not, then we can not format it as JFS.
+	 */
+	do {
+		/* Seek to the location we wish to test. */
+		Seek_Result = fseeko(device, Current_Position, SEEK_SET);
+		if (Seek_Result == 0) {
+			/* Can we read from this location? */
+			Read_Result = fgetc(device);
+			if (Read_Result != EOF) {
+				/* The current test position is valid.  Save it
+				 * for future reference. */
+				Last_Valid_Position = Current_Position;
+
+				/* Lets calculate the next location to test. */
+				Current_Position = ((Current_Position + 1) * 2)
+						   - 1;
+
+			}
+		}
+	} while ((Seek_Result == 0) && (Read_Result == 1));
+
+	/*
+	 * We have exited the while loop, which means that Current Position is
+	 * beyond the end of the partition or is unreadable due to a hardware
+	 * problem (bad block).  Since the odds of hitting a bad block are very
+	 * low, we will ignore that condition for now.  If time becomes
+	 * available, then this issue can be revisited.
+	 */
+
+	/* Is the drive greater than 16MB? */
+	if (Last_Valid_Position == 0) {
+		/*
+		 * Determine if drive is readable at all.  If it is, the drive
+		 * is too small.  If not, it could be a newly created partion,
+		 * so we need to issue a different error message
+		 */
+		*size = 0;	/* Indicates not readable at all */
+		Seek_Result = fseeko(device, Last_Valid_Position, SEEK_SET);
+		if (Seek_Result == 0) {
+			/* Can we read from this location? */
+			Read_Result = fgetc(device);
+			if (Read_Result != EOF)
+				/* non-zero indicates readable, but too small */
+				*size = 1;
+		}
+		goto restore;
+	}
+	/*
+	 * The drive is larger than 16MB.  Now we must find out exactly how
+	 * large.
+	 *
+	 * We now have a point within the partition and one beyond it.  The end
+	 * of the partition must lie between the two.  We will use a binary
+	 * search to find it.
+	 */
+
+	/* Setup for the binary search. */
+	First_Invalid_Position = Current_Position;
+	Current_Position = Last_Valid_Position +
+			   ((Current_Position - Last_Valid_Position) / 2);
+
+	/*
+	 * Iterate until the difference between the last valid position and the
+	 * first invalid position is 2 or less.
+	 */
+	while ((First_Invalid_Position - Last_Valid_Position) > 2) {
+		/* Seek to the location we wish to test. */
+		Seek_Result = fseeko(device, Current_Position, SEEK_SET);
+		if (Seek_Result == 0) {
+			/* Can we read from this location? */
+			Read_Result = fgetc(device);
+			if (Read_Result != EOF) {
+				/* The current test position is valid.
+				 * Save it for future reference. */
+				Last_Valid_Position = Current_Position;
+
+				/*
+				 * Lets calculate the next location to test. It
+				 * should be half way between the current test
+				 * position and the first invalid position that
+				 * we know of.
+				 */
+				Current_Position = Current_Position +
+						   ((First_Invalid_Position -
+						     Last_Valid_Position) / 2);
+
+			}
+		} else
+			Read_Result = 0;
+
+		if (Read_Result != 1) {
+			/* Out test position is beyond the end of the partition.
+			 * It becomes our first known invalid position. */
+			First_Invalid_Position = Current_Position;
+
+			/* Our new test position should be half way between our
+			 * last known valid position and our current test
+			 * position. */
+			Current_Position =
+			    Last_Valid_Position +
+			    ((Current_Position - Last_Valid_Position) / 2);
+		}
+	}
+
+	/*
+	 * The size of the drive should be Last_Valid_Position + 1 as
+	 * Last_Valid_Position is an offset from the beginning of the partition.
+	 */
+	*size = Last_Valid_Position + 1;
+
+
+restore:
+	/* Restore the original position. */
+	if (fseeko(device, Starting_Position, SEEK_SET) != 0)
+		return ERROR_SEEK;
+
+	return NO_ERROR;
+}
+
+/*
+ * NAME: ujfs_rw_diskblocks
+ *
+ * FUNCTION: Read/Write specific number of bytes for an opened device.
+ *
+ * PRE CONDITIONS:
+ *
+ * POST CONDITIONS:
+ *
+ * PARAMETERS:
+ *      dev_ptr         - file handle of an opened device to read/write
+ *      disk_offset     - byte offset from beginning of device for start of disk
+ *                        block read/write
+ *      disk_count      - number of bytes to read/write
+ *      data_buffer     - On read this will be filled in with data read from
+ *                        disk; on write this contains data to be written
+ *      mode            - GET: read; PUT: write; VRFY: verify
+ *
+ * NOTES: A disk address is formed by {#cylinder, #head, #sector}
+ *
+ *      Also the DSK_READTRACK and DSK_WRITETRACK is a track based
+ *      function. If it needs to read/write crossing track boundary,
+ *      additional calls are used.
+ *
+ * DATA STRUCTURES:
+ *
+ * RETURNS:
+ */
+int ujfs_rw_diskblocks(FILE *dev_ptr,
+		       int64_t disk_offset,
+		       int32_t disk_count,
+		       void *data_buffer,
+		       int32_t mode)
+{
+	int Seek_Result;
+	size_t Bytes_Transferred;
+	int error = NO_ERROR;
+
+	Seek_Result = fseeko(dev_ptr, disk_offset, SEEK_SET);
+	if (Seek_Result != 0) {
+		error = ERROR_SEEK;
+		goto finished;
+	}
+
+	if (disk_count == 0) {
+		fprintf(stderr, "ujfs_rw_diskblocks: disk_count is 0\n");
+		error = ERROR_INVALID_PARAMETER;
+		goto finished;
+	}
+
+	switch (mode) {
+	case GET:
+		Bytes_Transferred = fread(data_buffer, 1, disk_count, dev_ptr);
+		break;
+	case PUT:
+		Bytes_Transferred = fwrite(data_buffer, 1, disk_count, dev_ptr);
+		break;
+	default:
+		DBG_ERROR(("Internal error: %s(%d): bad mode: %d\n", __FILE__,
+			   __LINE__, mode))
+			error = ERROR_INVALID_HANDLE;
+		    goto finished;
+		break;		/* Keep the compiler happy. */
+	}
+
+	if (Bytes_Transferred != disk_count) {
+		if (Bytes_Transferred == -1)
+			perror("ujfs_rw_diskblocks");
+		else
+			fprintf(stderr,
+				"ujfs_rw_diskblocks: %s %zd of %d bytes at offset %lld\n",
+				(mode == GET) ? "read" : "wrote",
+				Bytes_Transferred, disk_count, disk_offset);
+
+		if (mode == GET)
+			error = ERROR_READ_FAULT;
+		else
+			error = ERROR_WRITE_FAULT;
+		goto finished;
+	}
+
+finished:
+	if (error)
+		rewind(dev_ptr);
+	return (error);
+}
+
+#define RAMDISK_MAJOR 1
+
+int ujfs_flush_dev(FILE *fp)
+{
+	int fd = fileno(fp);
+	struct stat buf;
+
+	if (fsync(fd) == -1)
+		return errno;
+#ifdef BLKFLSBUF
+	fstat(fd, &buf);
+	if (major(buf.st_rdev) != RAMDISK_MAJOR)
+		return ioctl(fileno(fp), BLKFLSBUF, 0);
+#endif
+	return 0;
+}
Index: create-1.1.15-patch/jfsutils-1.1.15-new/libfs/devices.h
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new/libfs/devices.h	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new/libfs/devices.h	(revision 5)
@@ -0,0 +1,51 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2000-2002
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifndef H_DEVICES
+#define H_DEVICES
+
+#define GET	0
+#define PUT	1
+#define VRFY	2
+
+/* Macros used for determining open mode */
+#define READONLY	0
+#define RDWR_EXCL	1
+
+/* Error codes */
+#define NO_ERROR		0
+#define ERROR_INVALID_FUNCTION	1
+#define ERROR_FILE_NOT_FOUND	2
+#define ERROR_INVALID_HANDLE	6
+#define ERROR_NOT_ENOUGH_MEMORY 8
+#define ERROR_INVALID_ACCESS	12
+#define ERROR_SEEK		25
+#define ERROR_WRITE_FAULT	29
+#define ERROR_READ_FAULT	30
+#define ERROR_GEN_FAILURE	31
+#define ERROR_INVALID_PARAMETER	87
+#define ERROR_DISK_FULL		112
+
+#include <inttypes.h>
+
+struct stat;
+
+int ujfs_get_dev_size(FILE *, int64_t * size);
+int ujfs_rw_diskblocks(FILE *, int64_t, int32_t, void *, int32_t);
+int ujfs_flush_dev(FILE *);
+int ujfs_device_is_valid(FILE *, struct stat *);
+#endif				/* H_DEVICES */
Index: create-1.1.15-patch/jfsutils-1.1.15-new/libfs/log_dump.c
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new/libfs/log_dump.c	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new/libfs/log_dump.c	(revision 5)
@@ -0,0 +1,986 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2000-2002
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include "jfs_types.h"
+#include "jfs_endian.h"
+#include "jfs_filsys.h"
+#include "jfs_superblock.h"
+#include "jfs_dinode.h"
+#include "jfs_dtree.h"
+#include "jfs_xtree.h"
+#include "jfs_logmgr.h"
+#include "jfs_dmap.h"
+#include "jfs_imap.h"
+#include "logredo.h"
+#include "devices.h"
+#include "debug.h"
+
+extern int LogOpenMode;
+
+#define LOGDMP_OK 	0
+#define LOGDMP_FAILED	-1
+
+#define MAKEDEV(__x,__y)        (dev_t)(((__x)<<16) | (__y))
+
+#define LOGPNTOB(x)  ((x)<<L2LOGPSIZE)
+
+#define LOG2NUM(NUM, L2NUM)\
+{\
+        if ((NUM) <= 0)\
+                L2NUM = -1;\
+        else\
+        if ((NUM) == 1)\
+                L2NUM = 0;\
+        else\
+        {\
+                L2NUM = 0;\
+                while ( (NUM) > 1 )\
+                {\
+                        L2NUM++;\
+                        (NUM) >>= 1;\
+                }\
+        }\
+}
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ *
+ *       things for the log.
+ */
+int32_t logend;			/* address of the end of last log record */
+extern struct logsuper logsup;		/* log super block */
+extern int32_t numdoblk;		/* number of do blocks used     */
+extern int32_t numnodofile;		/* number of nodo file blocks used  */
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ *
+ * The output file.
+ *
+ */
+
+FILE *outfp;
+
+#define  output_filename  "./jfslog.dmp"
+
+int logdmp_outfile_is_open = 0;
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ *
+ *      open file system aggregate/lv array
+ *
+ * logredo() processes a single log.
+ * at the first release, logredo will process a single log
+ * related to one aggregate. But the future release, logredo needs to
+ * to process one single log related to multiple agreegates.
+ * In both cases, the aggregate(logical volume) where the log stays
+ * will be different from  the file system aggregate/lv.
+ *
+ * There will be one imap for the aggregate inode allocation map
+ * and a list of imap pointers to multiple fileset inode allocation maps.
+ *
+ * There is one block allocation map per aggregate and shared by all the
+ * filesets within the aggregate.
+ *
+ * the log and related aggregates (logical volumes) are all in
+ * the same volume group, i.e., each logical volume is uniquely specified
+ * by their minor number with the same major number,
+ * the maximum number of lvs in a volume group is NUMMINOR (256).
+ */
+
+/*
+ * We only deal with the log here.  No need for vopen array
+ */
+struct vopen volume;
+
+/*
+ *      log page buffer cache
+ *
+ * log has its own 4 page buffer pool.
+ */
+extern uint8_t afterdata[];	/* buffer to read in redopage data */
+
+/*
+ * Miscellaneous
+ */
+caddr_t prog;			/* Program name */
+int32_t mntcnt, bufsize;
+char *mntinfo;
+int32_t retcode;		/* return code from logredo    */
+
+/*
+ * external references
+ */
+extern char *optarg;
+extern int optind;
+extern int initMaps(int32_t);
+extern int updateMaps(int);
+extern int findEndOfLog(void);
+extern int logRead(int32_t, struct lrd *, char *);
+extern int logredoInit(void);
+extern int alloc_wrksp(uint32_t, int, int, void **);	/* defined in fsckwsp.c */
+
+/*
+ * forward references
+ */
+int open_outfile(void);
+int ldmp_readSuper(FILE *, struct superblock *);
+int ldmp_isLogging(caddr_t, int32_t, char *, int32_t);
+int ldmp_logError(int, int);
+int usage(void);
+
+int disp_updatemap(struct lrd *);
+int disp_redopage(struct lrd *);
+int disp_noredopage(struct lrd *);
+int disp_noredoinoext(struct lrd *);
+
+void ldmp_xdump(char *, int);
+int ldmp_x_scmp(char *, char *);
+void ldmp_x_scpy(char *, char *);
+int prtdesc(struct lrd *);
+
+/* --------------------------------------------------------------------
+ *
+ * NAME:        jfs_logdump()
+ *
+ * FUNCTION:
+ *
+ */
+
+int jfs_logdump(caddr_t pathname, FILE *fp, int32_t dump_all)
+{
+	int rc;
+	int32_t logaddr, nextaddr, lastaddr, nlogrecords;
+	struct lrd ld;
+	int32_t lowest_lr_byte = 2 * LOGPSIZE + LOGPHDRSIZE;
+	int32_t highest_lr_byte = 0;
+	int log_has_wrapped = 0;
+	int in_use;
+
+	rc = open_outfile();
+
+	if (rc == 0) {		/* output file is open */
+		/*
+		 * loop until we get enough memory to read vmount struct
+		 */
+		mntinfo = (char *) &bufsize;
+		bufsize = sizeof (int);
+
+		/*
+		 * Find and open the log
+		 */
+		LogOpenMode = O_RDONLY;
+		rc = findLog(fp, &in_use);
+
+		if (rc != 0) {
+			printf("JFS_LOGDUMP:Error occurred when open/read device\n");
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+			fprintf(outfp, "JFS_LOGDUMP:Error occurred when open/read device\n");
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+			return (rc);
+		}
+
+		/*
+		 * validate log superblock
+		 *
+		 * aggregate block size is for log file as well.
+		 */
+
+		rc = ujfs_rw_diskblocks(Log.fp,
+					(uint64_t) (Log.xaddr + LOGPNTOB(LOGSUPER_B)),
+					(unsigned) sizeof (struct logsuper), (char *) &logsup, GET);
+		if (rc != 0) {
+			printf("JFS_LOGDUMP:couldn't read log superblock:failure in %s\n", prog);
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+			fprintf(outfp, "JFS_LOGDUMP:couldn't read log superblock:failure in %s\n",
+				prog);
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+			return (LOGSUPER_READ_ERROR);
+		}
+		ujfs_swap_logsuper(&logsup);
+
+		fprintf(outfp, "JOURNAL SUPERBLOCK: \n");
+		fprintf(outfp, "------------------------------------------------------\n");
+		fprintf(outfp, "   magic number: x %x \n", logsup.magic);
+		fprintf(outfp, "   version     : x %x \n", logsup.version);
+		fprintf(outfp, "   serial      : x %x \n", logsup.serial);
+		fprintf(outfp, "   size        : t %d pages (4096 bytes/page)\n", logsup.size);
+		fprintf(outfp, "   bsize       : t %d bytes/block\n", logsup.bsize);
+		fprintf(outfp, "   l2bsize     : t %d \n", logsup.l2bsize);
+		fprintf(outfp, "   flag        : x %x \n", logsup.flag);
+		fprintf(outfp, "   state       : x %x \n", logsup.state);
+		fprintf(outfp, "   end         : x %x \n", logsup.end);
+		fprintf(outfp, "\n");
+		fprintf(outfp, "======================================================\n");
+		fprintf(outfp, "\n");
+
+		if (logsup.magic != LOGMAGIC) {
+			fprintf(outfp, "\n");
+			fprintf(outfp, "**WARNING** %s: %s is not a log file\n", prog, pathname);
+			fprintf(outfp, "\n");
+			fprintf(outfp, "======================================================\n");
+			fprintf(outfp, "\n");
+		}
+
+		if (logsup.version != LOGVERSION) {
+			fprintf(outfp, "\n");
+			fprintf(outfp, "**WARNING** %s and log file %s version mismatch\n", prog,
+				pathname);
+			fprintf(outfp, "\n");
+			fprintf(outfp, "======================================================\n");
+			fprintf(outfp, "\n");
+		}
+
+		if (logsup.state == LOGREDONE) {
+			fprintf(outfp, "\n");
+			fprintf(outfp, "**WARNING** %s and log file %s state is LOGREDONE\n", prog,
+				pathname);
+			fprintf(outfp, "\n");
+			fprintf(outfp, "======================================================\n");
+			fprintf(outfp, "\n");
+		}
+
+		Log.size = logsup.size;
+		Log.serial = logsup.serial;
+
+		/*
+		 * find the end of log
+		 */
+		logend = findEndOfLog();
+		if (logend < 0) {
+			printf("logend < 0\n");
+			ldmp_logError(LOGEND, 0);
+			ujfs_swap_logsuper(&logsup);
+			rc = ujfs_rw_diskblocks(Log.fp,
+						(uint64_t) (Log.xaddr + LOGPNTOB(LOGSUPER_B)),
+						(unsigned long) LOGPSIZE, (char *) &logsup, PUT);
+			rc = logend;
+			goto loopexit;
+		}
+
+		highest_lr_byte = logsup.size * LOGPSIZE - LOGRDSIZE;
+
+		if ((logend < lowest_lr_byte) || (logend > highest_lr_byte)) {
+			fprintf(outfp, "\n");
+			fprintf(outfp,
+				"**ERROR** logend address is not valid for a logrec. logend: 0x0%x\n",
+				logend);
+			fprintf(outfp, "\n");
+			fprintf(outfp, "======================================================\n");
+			fprintf(outfp, "\n");
+			return (INVALID_LOGEND);
+		}
+
+		/*
+		 *      replay log
+		 *
+		 * read log backwards and process records as we go.
+		 * reading stops at place specified by first SYNCPT we
+		 * encounter.
+		 */
+		nlogrecords = lastaddr = 0;
+		nextaddr = logend;
+		do {
+			logaddr = nextaddr;
+			nextaddr = logRead(logaddr, &ld, afterdata);
+			fprintf(outfp,
+				"logrec d %d   Logaddr= x %x   Nextaddr= x %x   Backchain = x %x\n",
+				nlogrecords, logaddr, nextaddr, ld.backchain);
+			fprintf(outfp, "\n");
+			nlogrecords += 1;
+			/*
+			 *
+			 * Validate the nextaddr as much as possible
+			 *
+			 */
+			if (nextaddr < 0) {
+				ldmp_logError(READERR, logaddr);
+				if (nextaddr == REFORMAT_ERROR) {
+					rc = nextaddr;
+					goto loopexit;
+				}
+				break;
+			}
+			/*
+			 * Certain errors we'll assume signal the end of the log
+			 * since we're just dumping everything from the latest
+			 * commit record to the earliest valid record.
+			 */
+			if ((nextaddr < lowest_lr_byte) || (nextaddr > highest_lr_byte)) {
+				lastaddr = logaddr;
+			}
+
+			if (nextaddr == logaddr) {
+				lastaddr = logaddr;
+			}
+
+			if (nextaddr > logaddr) {
+				if (log_has_wrapped) {
+					fprintf(outfp, "\n");
+					fprintf(outfp,
+						"**ERROR** log wrapped twice. logaddr:0x0%x nextaddr:0x0%x\n",
+						logaddr, nextaddr);
+					fprintf(outfp, "\n");
+					fprintf(outfp,
+						"======================================================\n");
+					fprintf(outfp, "\n");
+					lastaddr = logaddr;
+				} else {
+					log_has_wrapped = -1;
+				}
+			}
+			/*
+			 *
+			 * The addresses seem ok.  Process the current record.
+			 *
+			 */
+			if (lastaddr != logaddr) {
+				switch (ld.type) {
+				case LOG_COMMIT:
+					fprintf(outfp,
+						"LOG_COMMIT   (type = d %d)   logtid = d %d   aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d\n", ld.length);
+
+					break;
+
+				case LOG_MOUNT:
+					fprintf(outfp,
+						"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+					fprintf(outfp,
+						"LOG_MOUNT   (type = d %d)   logtid = d %d   aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d\n", ld.length);
+					fprintf(outfp,
+						"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n");
+					break;
+
+				case LOG_SYNCPT:
+					fprintf(outfp,
+						"****************************************************************\n");
+					fprintf(outfp,
+						"LOG_SYNCPT   (type = d %d)   logtid = d %d    aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d\n", ld.length);
+					fprintf(outfp, "\tsync = x %x\n", ld.log.syncpt.sync);
+					fprintf(outfp,
+						"****************************************************************\n");
+
+					rc = 0;
+					if (!dump_all) {	/* user just wants from last synch point forward */
+						if (lastaddr == 0) {
+							lastaddr = (ld.log.syncpt.sync == 0)
+							    ? logaddr : ld.log.syncpt.sync;
+						}
+					}	/* end user just wants from last synch point forward */
+					break;
+
+				case LOG_REDOPAGE:
+					fprintf(outfp,
+						"LOG_REDOPAGE   (type = d %d)   logtid = d %d    aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d    ", ld.length);
+					disp_redopage(&ld);
+					break;
+
+				case LOG_NOREDOPAGE:
+					fprintf(outfp,
+						"LOG_NOREDOPAGE   (type = d %d)   logtid = d %d   aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d    ", ld.length);
+					disp_noredopage(&ld);
+					break;
+
+				case LOG_NOREDOINOEXT:
+					fprintf(outfp,
+						"LOG_NOREDOINOEXT (type = d %d)   logtid = d %d   aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d    ", ld.length);
+					disp_noredoinoext(&ld);
+					break;
+
+				case LOG_UPDATEMAP:
+					fprintf(outfp,
+						"LOG_UPDATEMAP   (type = d %d)   logtid = d %d   aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d    ", ld.length);
+					disp_updatemap(&ld);
+					break;
+
+				default:
+					fprintf(outfp,
+						"*UNRECOGNIZED*   (type = d %d)   logtid = d %d   aggregate = d %d\n",
+						ld.type, ld.logtid, ld.aggregate);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "\tdata length = d %d\n", ld.length);
+					fprintf(outfp, "\n");
+					fprintf(outfp, "**ERROR** unrecognized log record type\n");
+					fprintf(outfp, "\n");
+					fprintf(outfp,
+						"======================================================\n");
+					fprintf(outfp, "\n");
+					return (UNRECOG_LOGRECTYP);
+				}
+
+				if (rc == 0) {
+					fprintf(outfp, "\n");
+					if (ld.length > 0) {
+						ldmp_xdump((char *) afterdata, ld.length);
+					}
+				}
+
+				fprintf(outfp, "\n");
+				fprintf(outfp,
+					"----------------------------------------------------------------------\n");
+			}
+			/* end if( lastaddr != logaddr )  */
+		} while (logaddr != lastaddr);
+
+	      loopexit:
+
+		/*
+		 * Close the output file
+		 */
+		if (logdmp_outfile_is_open) {
+			fclose(outfp);
+		}
+
+		if (rc == 0) {	/* log has been dumped successfully */
+			printf
+			    ("JFS_LOGDUMP: The current JFS log has been dumped into ./jfslog.dmp\n");
+		} else {
+			printf("JFS_LOGDUMP:Failed in %s\n", prog);
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+			fprintf(outfp, "JFS_LOGDUMP:Failed in %s\n", prog);
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		}
+	}
+	/* end output file is open */
+	return (rc < 0) ? (rc) : (0);
+}
+
+/*----------------------------------------------------------------
+ *
+ * NAME:        ldmp_readSuper(fp, sb)
+ *
+ * FUNCTION:    read the superblock for the file system described
+ *              by the file descriptor of the opened aggregate/lv.
+ *              if a read of primary superblock fails,
+ *              try to read the secondary superblock. report error only
+ *              when both reads failed.
+ */
+int ldmp_readSuper(FILE *fp,	/* file descriptor */
+		   struct superblock * sb)
+{				/* superblock of the opened aggregate/lv */
+	int rc;
+
+	union {
+		struct superblock super;
+		char block[PSIZE];
+	} super;
+
+	/*
+	 * seek to the postion of the primary superblock.
+	 * since at this time we don't know the aggregate/lv
+	 * logical block size yet, we have to use the fixed
+	 * byte offset address SUPER1_OFF to seek for.
+	 */
+
+	/*
+	 * read super block
+	 */
+	rc = ujfs_rw_diskblocks(fp, SUPER1_OFF, (unsigned) SIZE_OF_SUPER, super.block, GET);
+	if (rc != 0) {
+		printf
+		    ("ldmp_readSuper: read primary agg superblock failed. errno=%d  Continuing.\n",
+		     errno);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		fprintf(outfp,
+			"ldmp_readSuper: read primary agg superblock failed. errno=%d Continuing\n",
+			errno);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		/* read failed for the primary superblock:
+		 * try to read the secondary superblock
+		 */
+		rc = ujfs_rw_diskblocks(fp, SUPER2_OFF, (unsigned) SIZE_OF_SUPER, super.block, GET);
+		if (rc != 0) {
+			printf
+			    ("ldmp_readSuper: read 2ndary agg superblock failed. errno=%d  Cannot continue.\n",
+			     errno);
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+			fprintf(outfp,
+				"ldmp_readSuper: read 2ndary agg superblock failed. errno=%d  Cannot continue.\n",
+				errno);
+			fprintf(outfp, "??????????????????????????????????????????????????????\n");
+			return (MAJOR_ERROR);
+		}
+	}
+
+	*sb = super.super;
+
+	ujfs_swap_superblock(sb);
+
+	return (0);
+}
+
+extern void exit(int);
+
+/*----------------------------------------------------------------
+ *
+ *      ldmp_logError(type)
+ *
+ * error handling for log read errors.
+ */
+int ldmp_logError(int type, int logaddr)
+{
+	retcode = -1;
+	logsup.state = LOGREADERR;
+
+	switch (type) {
+	case LOGEND:
+		printf("ldmp_logError:find end of log failed \n");
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		fprintf(outfp, "ldmp_logError:find end of log failed \n");
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		break;
+	case READERR:
+		printf("log read failed 0x%x\n", logaddr);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		fprintf(outfp, "log read failed 0x%x\n", logaddr);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		break;
+	case UNKNOWNR:
+		printf("unknown log record type \nlog read failed 0x%x\n", logaddr);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		fprintf(outfp, "unknown log record type \nlog read failed 0x%x\n", logaddr);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		break;
+	case IOERROR:
+		printf("i/o error log reading page 0x%x\n", logaddr);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		fprintf(outfp, "i/o error log reading page 0x%x\n", logaddr);
+		fprintf(outfp, "??????????????????????????????????????????????????????\n");
+		break;
+	case LOGWRAP:
+		printf("log wrapped...\n");
+		fprintf(outfp, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
+		fprintf(outfp, "log wrapped...\n");
+		fprintf(outfp, "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n");
+	}
+
+	return (0);
+}
+
+/*----------------------------------------------------------------
+ *
+ *      ldmp_xdump()
+ *
+ * hex dump
+ */
+void ldmp_xdump(char *saddr, int count)
+{
+#define LINESZ     60
+#define ASCIISTRT  40
+#define HEXEND     36
+
+	int i, j, k, hexdigit;
+	int c;
+	char *hexchar;
+	char linebuf[LINESZ + 1];
+	char prevbuf[LINESZ + 1];
+	char *linestart;
+	int asciistart;
+	char asterisk = ' ';
+
+	hexchar = "0123456789ABCDEF";
+	prevbuf[0] = '\0';
+	i = (int) saddr % 4;
+	if (i != 0)
+		saddr = saddr - i;
+
+	for (i = 0; i < count;) {
+		for (j = 0; j < LINESZ; j++)
+			linebuf[j] = ' ';
+
+		linestart = saddr;
+		asciistart = ASCIISTRT;
+		for (j = 0; j < HEXEND;) {
+			for (k = 0; k < 4; k++) {
+				c = *(saddr++) & 0xFF;
+				if ((c >= 0x20) && (c <= 0x7e))
+					linebuf[asciistart++] = (char) c;
+				else
+					linebuf[asciistart++] = '.';
+				hexdigit = c >> 4;
+				linebuf[j++] = hexchar[hexdigit];
+				hexdigit = c & 0x0f;
+				linebuf[j++] = hexchar[hexdigit];
+				i++;
+			}
+			if (i >= count)
+				break;
+			linebuf[j++] = ' ';
+		}
+		linebuf[LINESZ] = '\0';
+		if (((j = ldmp_x_scmp(linebuf, prevbuf)) == 0) && (i < count)) {
+			if (asterisk == ' ') {
+				asterisk = '*';
+				fprintf(outfp, "    *\n");
+			}
+		} else {
+			fprintf(outfp, "    %p  %s\n", linestart, linebuf);
+			asterisk = ' ';
+			ldmp_x_scpy(prevbuf, linebuf);
+		}
+	}
+
+	return;
+}
+
+/*----------------------------------------------------------------
+ *
+ *      ldmp_x_scmp()
+ *
+ */
+int ldmp_x_scmp(char *s1, char *s2)
+{
+	while ((*s1) && (*s1 == *s2)) {
+		s1++;
+		s2++;
+	}
+	if (*s1 || *s2)
+		return (-1);
+	else
+		return (0);
+}
+
+/*----------------------------------------------------------------
+ *
+ *      ldmp_x_scpy()
+ *
+ */
+void ldmp_x_scpy(char *s1, char *s2)
+{
+	while ((*s1 = *s2) != '\0') {
+		s1++;
+		s2++;
+	}
+}
+
+/***************************************************************************
+ *
+ * NAME: disp_noredopage
+ *
+ * FUNCTION:
+ *
+ * PARAMETERS:  none
+ *
+ * NOTES:
+ *
+ * RETURNS:
+ *      success: LOGDMP_OK
+ *      failure: something else
+ */
+int disp_noredopage(struct lrd *lrd_ptr)
+{
+	fprintf(outfp, "fileset = d %d    inode = d %d (x %x)\n",
+		lrd_ptr->log.noredopage.fileset,
+		lrd_ptr->log.noredopage.inode, lrd_ptr->log.noredopage.inode);
+
+	switch (lrd_ptr->log.noredopage.type) {
+	case LOG_INODE:
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:INODE\n", lrd_ptr->log.noredopage.type);
+		break;
+	case LOG_XTREE:
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:XTREE\n  ", lrd_ptr->log.noredopage.type);
+		break;
+	case (LOG_XTREE | LOG_NEW):
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:XTREE_NEW\n  ",
+			lrd_ptr->log.noredopage.type);
+		break;
+	case (LOG_BTROOT | LOG_XTREE):
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:BTROOT_XTREE\n  ",
+			lrd_ptr->log.noredopage.type);
+		break;
+	case LOG_DTREE:
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:DTREE\n  ", lrd_ptr->log.noredopage.type);
+		break;
+	case (LOG_DTREE | LOG_NEW):
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:DTREE_NEW \n ",
+			lrd_ptr->log.noredopage.type);
+		break;
+	case (LOG_DTREE | LOG_EXTEND):
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:DTREE_EXTEND\n  ",
+			lrd_ptr->log.noredopage.type);
+		break;
+	case (LOG_BTROOT | LOG_DTREE):
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:BTROOT_DTREE\n  ",
+			lrd_ptr->log.noredopage.type);
+		break;
+	case (LOG_BTROOT | LOG_DTREE | LOG_NEW):
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:BTROOT_DTREE.NEW\n  ",
+			lrd_ptr->log.noredopage.type);
+		break;
+	case LOG_EA:
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:EA\n", lrd_ptr->log.noredopage.type);
+		break;
+	case LOG_ACL:
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:ACL\n", lrd_ptr->log.noredopage.type);
+		break;
+	case LOG_DATA:
+		fprintf(outfp, "\ttype = d %d NOREDOPAGE:DATA\n", lrd_ptr->log.noredopage.type);
+		break;
+/*
+    case LOG_NOREDOFILE:
+       fprintf( outfp, "\ttype = d %d NOREDOPAGE:NOREDOFILE\n",
+                lrd_ptr->log.noredopage.type );
+       break;
+*/
+	default:
+		fprintf(outfp, "\ttype = d %d ***UNRECOGNIZED***\n", lrd_ptr->log.noredopage.type);
+		break;
+	}
+
+	fprintf(outfp, "\tpxd length = d %d   phys offset = x %llx  (d %lld)\n",
+		lengthPXD(&(lrd_ptr->log.noredopage.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.noredopage.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.noredopage.pxd)));
+
+	return (LOGDMP_OK);
+}				/* end of disp_noredopage() */
+
+/***************************************************************************
+ *
+ * NAME: disp_noredoinoext
+ *
+ * FUNCTION:
+ *
+ * PARAMETERS:  none
+ *
+ * NOTES:
+ *
+ * RETURNS:
+ *      success: LOGDMP_OK
+ *      failure: something else
+ */
+int disp_noredoinoext(struct lrd * lrd_ptr)
+{
+	fprintf(outfp, "fileset = d %d  \n", lrd_ptr->log.noredoinoext.fileset);
+
+	fprintf(outfp, "\tiag number = d %d   extent index = d %d\n",
+		lrd_ptr->log.noredoinoext.iagnum, lrd_ptr->log.noredoinoext.inoext_idx);
+
+	fprintf(outfp, "\tpxd length = d %d   phys offset = x %llx  (d %lld)\n",
+		lengthPXD(&(lrd_ptr->log.noredoinoext.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.noredoinoext.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.noredoinoext.pxd)));
+
+	return (LOGDMP_OK);
+}				/* end of disp_noredopage() */
+
+/***************************************************************************
+ *
+ * NAME: disp_redopage
+ *
+ * FUNCTION:
+ *
+ * PARAMETERS:  none
+ *
+ * NOTES:
+ *
+ * RETURNS:
+ *      success: LOGDMP_OK
+ *      failure: something else
+ */
+int disp_redopage(struct lrd * lrd_ptr)
+{
+	fprintf(outfp, "fileset = d %d    inode = d %d (x %x)\n",
+		lrd_ptr->log.redopage.fileset, lrd_ptr->log.redopage.inode,
+		lrd_ptr->log.redopage.inode);
+
+	switch (lrd_ptr->log.redopage.type) {
+	case LOG_INODE:
+		fprintf(outfp, "\ttype = d %d REDOPAGE:INODE\n", lrd_ptr->log.redopage.type);
+		break;
+	case LOG_XTREE:
+		fprintf(outfp, "\ttype = d %d REDOPAGE:XTREE\n  ", lrd_ptr->log.redopage.type);
+		break;
+	case (LOG_XTREE | LOG_NEW):
+		fprintf(outfp, "\ttype = d %d REDOPAGE:XTREE_NEW\n  ", lrd_ptr->log.redopage.type);
+		break;
+	case (LOG_BTROOT | LOG_XTREE):
+		fprintf(outfp, "\ttype = d %d REDOPAGE:BTROOT_XTREE\n  ",
+			lrd_ptr->log.redopage.type);
+		break;
+	case LOG_DTREE:
+		fprintf(outfp, "\ttype = d %d REDOPAGE:DTREE\n  ", lrd_ptr->log.redopage.type);
+		break;
+	case (LOG_DTREE | LOG_NEW):
+		fprintf(outfp, "\ttype = d %d REDOPAGE:DTREE_NEW \n ", lrd_ptr->log.redopage.type);
+		break;
+	case (LOG_DTREE | LOG_EXTEND):
+		fprintf(outfp, "\ttype = d %d REDOPAGE:DTREE_EXTEND\n  ",
+			lrd_ptr->log.redopage.type);
+		break;
+	case (LOG_BTROOT | LOG_DTREE):
+		fprintf(outfp, "\ttype = d %d REDOPAGE:BTROOT_DTREE\n  ",
+			lrd_ptr->log.redopage.type);
+		break;
+	case (LOG_BTROOT | LOG_DTREE | LOG_NEW):
+		fprintf(outfp, "\ttype = d %d REDOPAGE:BTROOT_DTREE.NEW\n  ",
+			lrd_ptr->log.redopage.type);
+		break;
+	case LOG_EA:
+		fprintf(outfp, "\ttype = d %d REDOPAGE:EA\n", lrd_ptr->log.redopage.type);
+		break;
+	case LOG_ACL:
+		fprintf(outfp, "\ttype = d %d REDOPAGE:ACL\n", lrd_ptr->log.redopage.type);
+		break;
+	case LOG_DATA:
+		fprintf(outfp, "\ttype = d %d REDOPAGE:DATA\n", lrd_ptr->log.redopage.type);
+		break;
+/*
+    case LOG_NOREDOFILE:
+       fprintf( outfp, "\ttype = d %d REDOPAGE:NOREDOFILE\n",
+                lrd_ptr->log.redopage.type );
+       break;
+*/
+	default:
+		fprintf(outfp, "\ttype = d %d ***UNRECOGNIZED***\n", lrd_ptr->log.redopage.type);
+		break;
+	}
+	fprintf(outfp, "\tl2linesize = d %d    ", lrd_ptr->log.redopage.l2linesize);
+	fprintf(outfp, "pxd length = d %d   phys offset = x %llx  (d %lld)\n",
+		lengthPXD(&(lrd_ptr->log.redopage.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.redopage.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.redopage.pxd)));
+
+	return (LOGDMP_OK);
+}				/* end of disp_redopage() */
+
+/***************************************************************************
+ *
+ * NAME: disp_updatemap
+ *
+ * FUNCTION:
+ *
+ * PARAMETERS:  none
+ *
+ * NOTES:
+ *
+ * RETURNS:
+ *      success: LOGDMP_OK
+ *      failure: something else
+ */
+int disp_updatemap(struct lrd * lrd_ptr)
+{
+	int flag_unrecognized = -1;
+	fprintf(outfp, "fileset = d %d    inode = d %d (x %x)\n",
+		lrd_ptr->log.updatemap.fileset, lrd_ptr->log.updatemap.inode,
+		lrd_ptr->log.updatemap.inode);
+
+	fprintf(outfp, "\ttype = x %x UPDATEMAP: ", lrd_ptr->log.updatemap.type);
+
+	if ((lrd_ptr->log.updatemap.type & LOG_ALLOCXADLIST) == LOG_ALLOCXADLIST) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " ALLOCXADLIST");
+	}
+	if ((lrd_ptr->log.updatemap.type & LOG_ALLOCPXDLIST) == LOG_ALLOCPXDLIST) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " ALLOCPXDLIST");
+	}
+	if ((lrd_ptr->log.updatemap.type & LOG_ALLOCXAD) == LOG_ALLOCXAD) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " ALLOCXAD");
+	}
+	if ((lrd_ptr->log.updatemap.type & LOG_ALLOCPXD) == LOG_ALLOCPXD) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " ALLOCPXD");
+	}
+	if ((lrd_ptr->log.updatemap.type & LOG_FREEXADLIST) == LOG_FREEXADLIST) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " FREEXADLIST");
+	}
+	if ((lrd_ptr->log.updatemap.type & LOG_FREEPXDLIST) == LOG_FREEPXDLIST) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " FREEPXDLIST");
+	}
+	if ((lrd_ptr->log.updatemap.type & LOG_FREEXAD) == LOG_FREEXAD) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " FREEXAD");
+	}
+	if ((lrd_ptr->log.updatemap.type & LOG_FREEPXD) == LOG_FREEPXD) {
+		flag_unrecognized = 0;
+		fprintf(outfp, " FREEPXD");
+	}
+	if (flag_unrecognized) {
+		fprintf(outfp, " *** UNRECOGNIZED ***");
+	}
+
+	fprintf(outfp, "\n");
+
+	fprintf(outfp, "\tnxd = d %d  (number of extents)\n", lrd_ptr->log.updatemap.nxd);
+	fprintf(outfp, "\tpxd length = d %d   phys offset = x %llx  (d %lld)\n",
+		lengthPXD(&(lrd_ptr->log.updatemap.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.updatemap.pxd)),
+		(long long) addressPXD(&(lrd_ptr->log.updatemap.pxd)));
+
+	return (LOGDMP_OK);
+}				/* end of disp_updatemap() */
+
+/*****************************************************************************
+ * NAME: open_outfile
+ *
+ * FUNCTION:  Open the output file.
+ *
+ * PARAMETERS:
+ *      Device  - input - the device specification
+ *
+ * NOTES:
+ *
+ * RETURNS:
+ *      success: XCHKLOG_OK
+ *      failure: something else
+ */
+int open_outfile()
+{
+	int openof_rc = 0;
+
+	outfp = fopen(output_filename, "w");
+
+	if (outfp == NULL) {	/* output file open failed */
+		printf("LOG_DUMP: unable to open output file: ./jfslog.dmp\n");
+		openof_rc = -1;
+	} else {
+		logdmp_outfile_is_open = -1;
+	}
+
+	return (openof_rc);
+}				/* end of open_outfile ( ) */
Index: create-1.1.15-patch/jfsutils-1.1.15-new/libfs/logredo.c
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new/libfs/logredo.c	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new/libfs/logredo.c	(revision 5)
@@ -0,0 +1,1931 @@
+/*
+ *   Copyright (c) International Business Machines Corp., 2000-2002
+ *
+ *   This program is free software;  you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
+ *   the GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program;  if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include <config.h>
+#include <time.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "jfs_types.h"
+#include "jfs_endian.h"
+#include "jfs_filsys.h"
+#include "jfs_superblock.h"
+#include "jfs_dinode.h"
+#include "jfs_dtree.h"
+#include "jfs_xtree.h"
+#include "jfs_logmgr.h"
+#include "jfs_dmap.h"
+#include "jfs_imap.h"
+#include "logredo.h"
+#include "logform.h"
+#include "devices.h"
+#include "debug.h"
+#include "utilsubs.h"
+#include "fsck_message.h"		/* for chkdsk message logging facility */
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ *
+ *   L O C A L   M A C R O    D E F I N I T I O N S
+ *
+ */
+#define MAKEDEV(__x,__y)        (dev_t)(((__x)<<16) | (__y))
+
+#define LOGPNTOB(x)  ((x)<<L2LOGPSIZE)
+
+#define LOG2NUM(NUM, L2NUM)\
+{\
+        if ((NUM) <= 0)\
+                L2NUM = -1;\
+        else\
+        if ((NUM) == 1)\
+                L2NUM = 0;\
+        else\
+        {\
+                L2NUM = 0;\
+                while ( (NUM) > 1 )\
+                {\
+                        L2NUM++;\
+                        (NUM) >>= 1;\
+                }\
+        }\
+}
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ *
+ *    R E M E M B E R    M E M O R Y    A L L O C    F A I L U R E
+ *
+ */
+int32_t Insuff_memory_for_maps = 0;
+char *available_stg_addr = NULL;
+int32_t available_stg_bytes = 0;
+char *bmap_stg_addr = NULL;
+int32_t bmap_stg_bytes = 0;
+
+/* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ *
+ *    S T U F F    F O R    T H E    L O G
+ *
+ */
+struct logsuper logsup;		/* log super block */
+int32_t numdoblk;		/* number of do blocks used     */
+int32_t numnodofile;		/* number of nodo file blocks used  */
+int32_t numExtDtPg = 0;		/* number of extended dtpage blocks used  */
+
+/*
+ *      open file system aggregate/lv array
+ *
+ * logredo() processes a single log.
+ *
+ * In the first release, logredo will process a single log which relates
+ * to the single fileset in a single aggregate.  In some future release,
+ * a single log may be used for multiple filesets which may or may not all
+ * reside in the same aggregate.
+ *
+ */
+struct vopen vopen[MAX_ACTIVE];
+struct log_info Log;
+struct {
+	uuid_t uuid;
+	FILE *fp;
+} primary_vol;
+extern int LogOpenMode;		/* logdump sets this to O_RDONLY */
+
+/*
+ * if this flag is set then the primary superblock is
+ * corrupt.  The secondary superblock is good, but chkdsk
+ * wasn't able to fix the primary version.  logredo can
+ * run, but must use the secondary version of the
+ * aggregate superblock
+ */
+int32_t use_2ndary_agg_superblock;
+/*
+ *      file system page buffer cache
+ *
+ * for k > 0, bufhdr[k] describes contents of buffer[k-1].
+ * bufhdr[0] is reserved as anchor for free/lru list:
+ * bufhdr[0].next points to the MRU buffer (head),
+ * bufhdr[0].prev points to the LRU buffer (tail);
+ */
+
+/* buffer header table */
+struct bufhdr {
+	int16_t next;		/* 2: next on free/lru list */
+	int16_t prev;		/* 2: previous on free/lru list */
+	int16_t hnext;		/* 2: next on hash chain */
+	int16_t hprev;		/* 2: previous on hash chain */
+	char modify;		/* 1: buffer was modified */
+	char inuse;		/* 1: buffer on hash chain */
+	int16_t reserve;	/* 2 */
+	int32_t vol;		/* 4: minor of agrregate/lv number */
+	pxd_t pxd;		/* 8: on-disk page pxd */
+} bufhdr[NBUFPOOL];		/* (24) */
+
+/* buffer table */
+struct bufpool {
+	char bytes[PSIZE];
+} buffer[NBUFPOOL - 1];
+
+/*
+ *      log page buffer cache
+ *
+ * log has its own 4 page buffer pool.
+ */
+uint8_t afterdata[LOGPSIZE * 2];	/* buffer to read in redopage data */
+
+/*
+ * Miscellaneous
+ */
+extern caddr_t prog;			/* Program name */
+extern int32_t mntcnt;
+extern int32_t bufsize;
+extern char *mntinfo;
+extern int32_t retcode;		/* return code from logredo    */
+int end_of_transaction = 0;
+
+/*
+ * external references
+ */
+extern char *optarg;
+extern int optind;
+extern int initMaps(int32_t);
+extern int updateMaps(int);
+extern int findEndOfLog(void);
+extern int logRead(int32_t, struct lrd *, char *);
+extern int logredoInit(void);
+extern int doCommit(struct lrd *);
+extern int doExtDtPg(void);
+extern int doNoRedoFile(struct lrd *, uint32_t);
+extern int doNoRedoPage(struct lrd *);
+extern int doNoRedoInoExt(struct lrd *);
+extern int doAfter(struct lrd *, int32_t);
+extern int doUpdateMap(struct lrd *);
+extern int alloc_wrksp(uint32_t, int, int, void **);
+
+extern FILE * open_by_label(uuid_t, int, int, char *, int *);
+extern char log_device[];
+/*
+ * forward references
+ */
+int doMount(struct lrd *);
+int openVol(int32_t);
+int updateSuper(int vol);
+int rdwrSuper(FILE *, struct superblock *, int32_t);
+int bflush(int32_t, struct bufpool *);
+int logOpen(void);
+int fsError(int, int, int64_t);
+int logError(int, int);
+static int recoverExtendFS(FILE *);
+int alloc_storage(int32_t, void **, int32_t *);
+int alloc_dmap_bitrec(struct dmap_bitmaps **);
+
+/*
+ * debug control
+ */
+#ifdef _JFS_DEBUG
+int32_t dflag = 1;
+time_t *Tp;
+uint32_t tp_start, tp_end;
+int xdump(char *, int);
+int x_scmp(char *, char *);
+void x_scpy(char *, char *);
+int prtdesc(struct lrd *);
+#else
+int32_t dflag = 0;
+#endif
+
+/*
+ * NAME:        jfs_logredo()
+ *
+ * FUNCTION:	Replay all transactions committed since the most
+ *		recent synch point.
+ *
+ * NOTES:
+ *	>>>>>> 	The log replay is accomplished in one pass over the
+ *		log, reading backwards from logend to the first synch
+ *		point record encountered.  This means that the log
+ *		entries are read and processed in LIFO (Last-In-First-Out)
+ *		order.  In other words, the records logged latest in
+ *		time are the first records processed during log replay.
+ *
+ *	>>>>>> 	Inodes, index trees, and directory trees
+ *
+ *		Inodes, index tree structures, and directory tree
+ *		structures are handled by processing committed redopage
+ *		records which have not been superceded by noredo records.
+ *		This processing copies data from the log record into the
+ *		appropriate disk extent page(s).
+ *
+ *		To ensure that only the last (in time) updates to any
+ *		given disk page are applied during log replay, logredo
+ *		maintains a record (union structure summary1/summary2),
+ *		for each disk page which it has processed, of which
+ *		portions have been updated by log records encountered.
+ *
+ *	>>>>>> 	Inode Allocation Map processing
+
+ *		The xtree for the Inode Allocation Map is journaled, and
+ *		a careful write is used to update it during commit
+ *		processing.
+ * The imap index tree is also duplicated at the known location. (TBD)
+ * So at logredo time, the xtree for imap is always readable and correct.
+ * This is the basic requirement from logredo.
+ *
+ * the inode map control page (struct dinomap) is only flushed to disk at
+ * the umount time. For iag, pmap will go to disk at commit time.
+ * iagnum will not change in run-time.
+ * agstart field will stable without extendfs utility. It is TBD for
+ * how to handle agstart when extendfs utility is available.
+ * Other fields ( wmap. inosmap, extsmap ino free list pointers,
+ * ino ext free list pointers ) are at working status ( i.e they are
+ * updated in run-time. So the following
+ * meta-data of the imap need to be reconstructed at the logredo time:
+ *  1) IAGs, the pmap of imap and inoext array are contained in IAGs.
+ *  2) AG Free inode list
+ *  3) AG Free Inode Extent list
+ *  4) IAG Free list
+ *
+ * There are two imaps need to take care of :
+ *   1) aggregate imap
+ *   2) fileset imap
+ * For the first release, the aggregate imap is stable and we only
+ * need to deal with the fileset imap.
+ *
+ * Block Allocation Map (bmap file) is for an aggregate/lv. There are
+ * three fields related to the size of bmap file.
+ *  1) superblock.s_size: This field indicates aggregate size. It
+ *                        tells number of sector-size blocks for this
+ *                        aggregate. The size of aggregate determines
+ *                        the size of its bmap file.
+ *                        Since the aggregate's superblock is updated
+ *                        using sync-write, superblock.s_size is trustable
+ *                        at logredo time.
+ *               note1:   mkfs reserves the fsck space. So s_size really
+ *                        inidcate (size_of_aggregate - fsck_reserve_space)
+ *               note2:   At the mkfs time, "-s" parameter could be used
+ *                        to indicate how large the aggregate/filesystem is.
+ *                        One lv contains at most one aggregate/filesystem.
+ *                        If "-s" gives the value is smaller than the size
+ *                        of lv, it is ok. The space is just wasted.
+ *
+ *                        Without "-s" parameter, mkfs wil use the whole
+ *                        size of lv to make an aggregate/filesystem.
+ *                        That is usually the case. So we can also say
+ *                        an aggregate/lv. "-s" is often used for test.
+ *
+ *  2) dbmap.dn_mapsize: This field also indicates aggregate/lv size.
+ *                        It tells number of aggre. blocks in the
+ *                        aggregate/lv. Without extendfs, this field should
+ *                        be equivalent to superblock.s_size.
+ *                        With extendfs, this field may not be updated
+ *                        before a system crash happens. So logredo
+ *                        need to update it.
+ *  3) dinode.di_size:  For an inode of bmap file, this field indicates
+ *                        the logical size of the file. I.e. it contains
+ *                        the offset value of the last byte written
+ *                        in the file plus one.
+ *                        So di_size will include the bmap control page,
+ *                        the dmap control pages and dmap pages.
+ *                        In the JFS, if a file is a sparse file, the logical
+ *                        size is different from its physical size.
+ *                        The bmap file is a sparse file if the total of
+ *                        dmap pages is  ( < 1024) or ( < 1024 * 1024).
+ *                        In that case, physically L1.0, and/or L2 does
+ *                        not exist, but di_size will include their page
+ *                        size.
+ *
+ *              Note:     The di_size does NOT contain the logical
+ *                        structure of the file, i.e. the space allocated
+ *                        for the xtree stuff is not indicated in di_size.
+ *                        It is indicated in di_nblocks.
+ *
+ *                        In addition, the mkfs always put one more dmap
+ *                        page into the bmap file for preparing extendfs.
+ *                        This hidden dmap page cannot be figured out from
+ *                        superblock.s_size, but di_size includes it. Any
+ *                        dmapctl pages caused by this hidden dmap page
+ *                        are also included in di_size.
+ *
+ * The bmap control page, dmap control pages and dmap pages are all
+ * needed to rebuild at logredo time.
+ *
+ * In overall, the following actions are taken at logredo time:
+ *   1) apply log rec data to the specified page.
+ *   2) initialize freelist for dtree page or root.
+ *   3) rebuilt imap
+ *   4) rebuilt bmap
+ *   in addition, in order to ensure the log record only applying to a
+ *   certain portion of page one time, logredo will start NoRedoFile,
+ *   NoRedoExtent/NoRedoPage filter in the process for accuracy and
+ *   efficiency.
+ *
+ *  The three log rec types: REDOPAGE, NOREDOPAGE, NOREDOINOEXT, and
+ *  UPDATEMAP, are the main force to initiate these actions.  See
+ *  comments on doAfter(), updatePage(), doNoRedoPage(), doNoRedoInoExt,
+ *  and doUpdateMap() for detailed information.
+ *
+ * If the aggregate/lv has state of FM_DIRTY, then fsck will run
+ * after the logredo process since logredo could not get 100%
+ * recovery. Currently bmap rebuild is slow ( 1 min per 32 GB),
+ * so logredo will NOT rebuild imap and bmap if fsck will do it
+ * anyway. But logredo still read maps in and mark them for starting
+ * NoRedoExtent/NoRedoPage filter.
+ *
+ * The maps are rebuilt in the following way:
+ * at the init phase, storage is allocated for the whole map file for
+ * both imap and bmap. Reading in the map files from the disk.
+ * The wmap is inited to zero. At the logredo time, the wmap is used
+ * to track the bits in pmap. In the beginning of the logredo process
+ * the allocation status of every block is in doubt. As log records
+ * are processed, the allocation state is determined and the bit of pmap
+ * is updated. This fact is recorded in the corresponding bits in wmap.
+ * So a pmap bit is only updated once at logredo time and only updated
+ * by the latest in time log record.
+ * At the end of logredo, the control information, the freelist, etc.
+ * are built from the value of pmap; then pmap is copied to wmap and
+ * the whole map is written back to disk.
+ *
+ * the status field s_state in the superblock of each file-system is
+ * set to FM_CLEAN provided the initial status was either FM_CLEAN
+ * or FM_MOUNT and logredo processing was successful. If an error
+ * is detected in logredo the status is set to FM_LOGREDO. the status
+ * is not changed if its initial value was FM_MDIRTY. fsck should be
+ * run to clean-up the probable damage if the status after logredo
+ * is either FM_LOGREDO or FM_MDIRTY.
+ *
+ *  The log record has the format:
+ *   <LogRecordData><LogRecLRD>
+ *  At logredo time, the log is read backward. So for every log rec,
+ *  we read LogRecLRD, which tells how long the LogRecordData is.
+ *  see comments on updatePage() for detailed info of log record format.
+ *
+ *.....................................................................
+ * The logredo handles the log-within-file-system (aka inline log) issue:
+ *.....................................................................
+ * For AIX, we always deal with the outline log, i.e. the log resides
+ * in a separate logical volume. A log is associated with one volume
+ * group and can be shared by many file systems with this volume group.
+ * In AIX, the logredo received a device name. It then determines if
+ * this device is a log name  or a filesystem name. If it is a filesustem
+ * name, get the log minor number for this filesystem. If it is a log name,
+ * get its minor number.
+ *
+ * XJFS decided to put log inside the file system
+ *
+ * For supporting the inline log, the above AIX logic should be changed.
+ *
+ * Here is the outline:
+ *
+ * When the logredo received a device name, it first read the SIZE_OF_SUPER
+ * bytes from SUPER1_OFF  offset to see if it is a file system superblock.
+ * If yes, check the s_flag to see if it has a inline log or outline log.
+ * for an inline log the s_logdev should match the input device name's
+ * major and minor number. If not, an error is returned and logredo exit.
+ * If no error, the logredo read the log superblock according the log info
+ * in the fs superblock.
+ * If the device name does not represent a filesystem device, then logredo
+ * read the LOGPSIZE bytes from the log page 1 location. If it indicates
+ * a log device, then open the filesystems according to the log superblock's
+ * active list. For each filesystem in the active list, read its superblock
+ * if one of the superblock indicates that it uses an inline log, return
+ * an error. It is a system code bug if some filesystems use inline log
+ * and some use outline log.
+ * If the superblock indicates it used an outline log, check the superblock's
+ * s_logdev to match the input device name's major and minor numbers.
+ * If one of them does not match, return error. -- It is a system code bug,
+ * if some match and some not match; -- It should either match all or non of
+ * them match. The AIX logredo never check s_logdev with the input log device.
+ * We should check here.
+ *
+ * for outline log, logredo will be called once to cover all the file
+ * systems in the log superblock's active list.
+ * For inline log, logredo will be called many times. Each time is for
+ * one file system. The log superblock's active list has nothing. The
+ * logmajor and logminor contains file system's major and minor number.
+ *
+ *.....................................................................
+ * logredo handles support EA:
+ *.....................................................................
+ * There is 16-byte EA descriptor which is located in the section I of
+ * dinode.
+ * The EA can be inline or outline. If it is inlineEA then the data will
+ * occupy the section IV of the dinode. The dxd_t.flag will indicate so.
+ * If it is outlineEA, dxd_t.flag will indicate so and the single extent
+ * is described by EA descriptor.
+ *
+ * The section IV of dinode has 128 byte. It is shared by the xtroot and
+ * inlineEA. The sharing is in FCFS style. If xtree gets the section IV,
+ * xtree will never give it away even if xtree is shrink or split.
+ * If inlineEA gets it, there is a chance that later inlineEA is freed and
+ * so xtree still can get it.
+ *
+ * for outlineEA, the XJFS will syncly write the data portion out so there
+ * is no log rec for the data, but there is still an INODE log rec for EA
+ * descriptor changes and there is a UPDATEMAP log rec for the allocated
+ * pxd. If an outlineEA is freed, there are also two log records for it:
+ * one is INODE with EA descriptor zeroed out, another is the UPDATEMAP
+ * log rec for the freed pxd.
+ * For inlineEA, it has to be recorded in the log rec. It is not in a
+ * separate log rec. Just one additional segment is added into the
+ * INODE log rec. So an INODE log rec can have at most three segments:
+ * when the parent and child inodes are in the same page, then there are
+ * one segment for parent base inode; one segment for child base inode;
+ * and maybe the third one for the child inlineEA data.
+ *....................................................................
+ * 32-bit vs 64-bit
+ * At the first release. assume that a file system will not be larger
+ * than 32-bit.
+ *....................................................................
+ * TBD:
+ * the method for handling crashes in the middle of extending a file
+ * system is as follows. the size of a filesystem is established from
+ * the superblock.s_size field (i.e the sizes in the diskmap
+ * and inodemaps are ignored). in extendfs (jfs_cntl.c) the superblock
+ * is not updated before the maps have been extended and the new inodes
+ * formatted to zeros. no allocations in the new part of the filesystem
+ * occur prior to the change in map sizes. if a crash occurs just
+ * before updating the superblock, the map sizes will be their old
+ * values. in this case the maps as files may be bigger than necessary.
+ * if the crash occurs just after writing the super block, the map sizes
+ * are fixed up here.
+ */
+int jfs_logredo(caddr_t pathname, FILE *fp, int32_t use_2nd_aggSuper)
+{
+	int rc;
+	int k, logaddr, nextaddr, lastaddr, nlogrecords;
+	int syncrecord = 0;
+	struct lrd ld;
+	int lowest_lr_byte = 2 * LOGPSIZE + LOGPHDRSIZE;
+	int highest_lr_byte = 0;
+	int log_has_wrapped = 0;
+	int logend;
+	int in_use;
+
+	/*
+	 * store away the indicator of which aggregate superblock
+	 * to use
+	 */
+	use_2ndary_agg_superblock = use_2nd_aggSuper;
+
+	/*
+	 * loop until we get enough memory to read vmount struct
+	 */
+	mntinfo = (char *) &bufsize;
+	bufsize = sizeof (int);
+
+	/*
+	 * validate that the log is not currently in use;
+	 */
+	rc = findLog(fp, &in_use);
+	if (rc < 0) {
+		fsck_send_msg(lrdo_DEVOPNREADERROR);
+		return (rc);
+	}
+
+	/* recover from extendfs() ? */
+	if (Log.location & INLINELOG && (vopen[0].status & FM_EXTENDFS)) {
+		fsck_send_msg(lrdo_REXTNDBEGIN);
+		rc = recoverExtendFS(fp);
+		fsck_send_msg(lrdo_REXTNDDONE);
+		return rc;
+	}
+
+	/*
+	 * validate log superblock
+	 *
+	 * aggregate block size is for log file as well.
+	 */
+	rc = ujfs_rw_diskblocks(Log.fp,
+				(uint64_t) (Log.xaddr +
+					    LOGPNTOB(LOGSUPER_B)),
+				(unsigned) sizeof (struct logsuper), (char *) &logsup, GET);
+	if (rc != 0) {
+		fsck_send_msg(lrdo_CANTREADLOGSUP);
+		rc = LOGSUPER_READ_ERROR;
+		goto error_out;
+	}
+	ujfs_swap_logsuper(&logsup);
+
+	if (logsup.magic != LOGMAGIC) {
+		fsck_send_msg(lrdo_LOGSUPBADMGC);
+		rc = NOT_LOG_FILE_ERROR;
+		goto error_out;
+	}
+
+	if (logsup.version > LOGVERSION) {
+		fsck_send_msg(lrdo_LOGSUPBADVER);
+		rc = JFS_VERSION_ERROR;
+		goto error_out;
+	}
+
+	if (Log.location & OUTLINELOG) {
+		struct stat st;
+
+		if ((rc = fstat(fileno(Log.fp), &st)))
+			goto error_out;
+
+		Log.devnum = st.st_rdev;
+
+		if (in_use) {
+			fsck_send_msg(lrdo_LOGINUSE);
+			return LOG_IN_USE;
+		}
+	}
+
+	if (logsup.state == LOGREDONE) {
+		fsck_send_msg(lrdo_ALREADYREDONE);
+		if (Log.location & INLINELOG)
+			if ((rc = updateSuper(0)) != 0) {
+				fsck_send_msg(lrdo_CANTUPDLOGSUP);
+				return (rc);
+			}
+		return (0);
+	}
+
+	Log.size = logsup.size;
+	Log.serial = logsup.serial;
+
+	/*
+	 * find the end of log
+	 */
+	logend = findEndOfLog();
+
+	if (logend < 0) {
+		fsck_send_msg(lrdo_LOGEND, logend);
+
+		fsck_send_msg(lrdo_LOGENDBAD1);
+		logError(LOGEND, 0);
+		ujfs_swap_logsuper(&logsup);
+		rc = ujfs_rw_diskblocks(Log.fp,
+					(Log.xaddr + LOGPNTOB(LOGSUPER_B)),
+					(unsigned long) LOGPSIZE, (char *) &logsup, PUT);
+		rc = logend;
+		goto error_out;
+	}
+
+	/*
+	 * allocate/initialize logredo runtime data structures and
+	 * initialize each file system associated with the log based on
+	 * the contents of its superblock
+	 */
+	if ((rc = logredoInit()) != 0) {
+		fsck_send_msg(lrdo_INITFAILED, rc, errno);
+		goto error_out;
+	}
+
+	highest_lr_byte = logsup.size * LOGPSIZE - LOGRDSIZE;
+
+	if ((logend < lowest_lr_byte) || (logend > highest_lr_byte)) {
+		fsck_send_msg(lrdo_LOGEND, logend);
+
+		fsck_send_msg(lrdo_LOGENDBAD2);
+		rc = INVALID_LOGEND;
+		goto error_out;
+	}
+
+	/*
+	 *      replay log
+	 *
+	 * read log backwards and process records as we go.
+	 * reading stops at place specified by first SYNCPT we
+	 * encounter.
+	 */
+	nlogrecords = lastaddr = 0;
+	nextaddr = logend;
+
+	do {
+		logaddr = nextaddr;
+		nextaddr = logRead(logaddr, &ld, afterdata);
+		DBG_TRACE(("Logaddr=%x\nNextaddr=%x\n", logaddr, nextaddr))
+		    nlogrecords += 1;
+		/*
+		 *
+		 * Validate the nextaddr as much as possible
+		 *
+		 */
+		if (nextaddr < 0) {
+			fsck_send_msg(lrdo_NEXTADDRINVALID);
+			rc = nextaddr;
+			goto error_out;
+		}
+
+		if ((nextaddr < lowest_lr_byte)
+		    || (nextaddr > highest_lr_byte)) {
+			fsck_send_msg(lrdo_NEXTADDROUTRANGE, nextaddr);
+			rc = INVALID_NEXTADDR;
+			goto error_out;
+		}
+
+		if (nextaddr == logaddr) {
+			fsck_send_msg(lrdo_NEXTADDRSAME, nextaddr);
+			rc = NEXTADDR_SAME;
+			goto error_out;
+		}
+
+		if (nextaddr > logaddr) {
+			if (log_has_wrapped) {
+				fsck_send_msg(lrdo_LOGWRAPPED);
+				rc = LOG_WRAPPED_TWICE;
+				goto error_out;
+			} else {
+				log_has_wrapped = -1;
+			}
+		}
+		/*
+		 *
+		 * The addresses seem ok.  Process the current record.
+		 *
+		 */
+		switch (ld.type) {
+		case LOG_COMMIT:
+			rc = doCommit(&ld);
+			if (rc) {
+				fsck_send_msg(lrdo_BADCOMMIT, logaddr);
+
+				goto error_out;
+			}
+			break;
+		case LOG_MOUNT:
+			fsck_send_msg(lrdo_MOUNTRECORD, logaddr);
+
+			rc = doMount(&ld);
+			if (rc) {
+				fsck_send_msg(lrdo_BADMOUNT, logaddr);
+
+				goto error_out;
+			}
+			break;
+
+		case LOG_SYNCPT:
+			fsck_send_msg(lrdo_SYNCRECORD, logaddr);
+
+			rc = 0;
+			if (lastaddr == 0) {
+				syncrecord = logaddr;
+				lastaddr = (ld.log.syncpt.sync == 0)
+				    ? logaddr : ld.log.syncpt.sync;
+			}
+			break;
+
+		case LOG_REDOPAGE:
+			DBG_TRACE(("jfs_logredo:Case Log_redoPage"))
+			    rc = doAfter(&ld, logaddr);
+			if (rc) {
+				fsck_send_msg(lrdo_BADREDOPAGE, logaddr);
+				goto error_out;
+			}
+			break;
+
+		case LOG_NOREDOPAGE:
+			DBG_TRACE(("jfs_logredo:Case Log_noredopage"))
+			    rc = doNoRedoPage(&ld);
+			if (rc) {
+				fsck_send_msg(lrdo_BADNOREDOPAGE, logaddr);
+				goto error_out;
+			}
+			break;
+
+		case LOG_NOREDOINOEXT:
+			DBG_TRACE(("jfs_logredo:Case Log_noredoinoext"))
+			    rc = doNoRedoInoExt(&ld);
+			if (rc) {
+				fsck_send_msg(lrdo_BADNOREDOINOEXT, logaddr);
+				goto error_out;
+			}
+			break;
+
+		case LOG_UPDATEMAP:
+			rc = doUpdateMap(&ld);
+			if (rc) {
+				fsck_send_msg(lrdo_BADUPDATEMAP, logaddr);
+				goto error_out;
+			}
+			break;
+
+		default:
+			fsck_send_msg(lrdo_UNKNOWNTYPE, logaddr);
+			rc = UNRECOG_LOGRECTYP;
+			goto error_out;
+			break;
+		}
+
+		if (rc < 0) {
+			fsck_send_msg(lrdo_ERRORNEEDREFORMAT);
+			goto error_out;
+		}
+
+		if (rc != 0) {
+			fsck_send_msg(lrdo_ERRORCANTCONTIN);
+			goto error_out;
+		}
+
+		/*
+		 * If the transaction just completed was the last
+		 * for the current transaction, then flush the
+		 * buffers.
+		 */
+		if (end_of_transaction != 0) {
+			for (k = 1; k < NBUFPOOL; k++) {
+				if ((rc = bflush(k, &buffer[k - 1])) != 0)
+					goto error_out;
+			}
+			end_of_transaction = 0;
+		}
+
+	} while (logaddr != lastaddr);
+	/*
+	 * If any 'dtpage extend' records were processed, then we need
+	 * to go back and rebuild their freelists.  This cannot be done
+	 * when the 'dtpage extend' record is processed, since there may
+	 * be records processed later which affect the previous (shorter)
+	 * version of the dtpage.  Only after all these records are processed
+	 * can we safely and accurately rebuild the freelist.
+	 */
+	if (numExtDtPg != 0) {
+		rc = doExtDtPg();
+	}
+
+	/*
+	 * flush data page buffer cache
+	 */
+	for (k = 1; k < NBUFPOOL; k++) {
+		if ((rc = bflush(k, &buffer[k - 1])) != 0)
+			break;
+	}
+
+	/*
+	 *      finalize file systems
+	 *
+	 * update allocation map and superblock of file systems
+	 * of volumes which are open if they were modified here.
+	 * i.e. if they were not previously unmounted cleanly.
+	 */
+	for (k = 0; k < MAX_ACTIVE; k++) {
+		if (vopen[k].state != VOPEN_OPEN)
+			continue;
+
+		if ((rc = updateMaps(k)) != 0) {
+			fsck_send_msg(lrdo_ERRORCANTUPDMAPS);
+			goto error_out;
+		}
+
+		/* Make sure all changes are committed to disk before we
+		 * mark the superblock clean
+		 */
+		ujfs_flush_dev(vopen[k].fp);
+
+		if ((rc = updateSuper(k)) != 0) {
+			fsck_send_msg(lrdo_ERRORCANTUPDFSSUPER);
+			goto error_out;
+		}
+
+		/* sync superblock before journal is finalized */
+		ujfs_flush_dev(vopen[k].fp);
+	}
+
+	/*
+	 *      finalize log.
+	 *
+	 * clear active list.
+	 * If this is a fully replayed log then it can be moved to earlier
+	 * versions of the operating system.  Therefore switch the magic
+	 * number to the earliest level.
+	 */
+	if (logsup.state != LOGREADERR) {
+		for (k = 0; k < MAX_ACTIVE; k++)
+			uuid_clear(logsup.active[k]);
+
+		logsup.end = logend;
+		logsup.state = LOGREDONE;
+		logsup.magic = LOGMAGIC;
+	}
+	ujfs_swap_logsuper(&logsup);
+	rc = ujfs_rw_diskblocks(Log.fp, (Log.xaddr + LOGPNTOB(LOGSUPER_B)),
+				LOGPSIZE, (char *) &logsup, PUT);
+
+	/*
+	 * now log some info for the curious
+	 */
+	fsck_send_msg(lrdo_LOGEND, logend);
+
+	fsck_send_msg(lrdo_RPTSYNCNUM, syncrecord);
+
+	fsck_send_msg(lrdo_RPTSYNCADDR, lastaddr);
+
+	fsck_send_msg(lrdo_RPTNUMLOGREC, nlogrecords);
+
+	fsck_send_msg(lrdo_RPTNUMDOBLK, numdoblk);
+
+	fsck_send_msg(lrdo_RPTNUMNODOBLK, numnodofile);
+
+      error_out:
+
+	if (rc > 0) {
+		rc = rc * (-1);
+	}
+
+	/*
+	 * If everything went ok except that we didn't have
+	 * enough memory to deal with the block map, tell chkdsk
+	 * to be sure to do a full check and repair, but that a log
+	 * format is not necessary
+	 */
+	if ((rc == 0) && Insuff_memory_for_maps) {
+		rc = ENOMEM25;
+	}
+
+	return (rc);
+}
+
+/*
+ * NAME:        doMount(ld)
+ *
+ * FUNCTION:    a log mount record is the first-in-time record which is
+ *              put in the log so it is the last we want to process in
+ *              logredo. so we mark volume as cleanly unmounted in vopen
+ *              array. the mount record is imperative when the volume
+ *              is a newly made filesystem.
+ */
+int doMount(struct lrd *ld)
+{				/* pointer to record descriptor */
+	int vol, status;
+
+	vol = ld->aggregate;
+
+	status = vopen[vol].status;
+	DBG_TRACE(("Logredo:domount: status=%d\n", status))
+
+	    if (!(status & (FM_LOGREDO | FM_DIRTY)))
+		vopen[vol].status = FM_CLEAN;
+
+	return (0);
+}
+
+/*
+ * NAME:        openVol(vol)
+ *
+ * FUNCTION:    open the aggregate/volume specified.
+ *              check if it was cleanly unmounted. also check log
+ *              serial number. initialize disk and inode mpas.
+ */
+int openVol(int vol)
+{				/* device minor number of aggregate/lv */
+	int rc, l2agsize, agsize;
+	int64_t fssize;		/* number of aggr blks in the aggregate/lv */
+	struct superblock sb;
+	int aggsb_numpages;
+
+	if (Log.location & OUTLINELOG) {
+		/* First check if this is the already opened volume */
+		if (!uuid_compare(vopen[vol].uuid, primary_vol.uuid))
+			vopen[vol].fp = primary_vol.fp;
+		else {
+			vopen[vol].fp = open_by_label(vopen[vol].uuid, 0, 0,
+						      NULL, NULL);
+			if (vopen[vol].fp == NULL)
+				return ENOENT;
+		}
+	}
+
+	/* read superblock of the aggregate/volume */
+	if ((rc = rdwrSuper(vopen[vol].fp, &sb, PB_READ)) != 0) {
+		fsck_send_msg(lrdo_CANTREADFSSUPER);
+
+		fsError(READERR, vol, SUPER1_B);
+		vopen[vol].state = VOPEN_CLOSED;
+		return (FSSUPER_READERROR1);
+	}
+
+	/* check magic number and initialize version specific
+	 * values in the vopen struct for this vol.
+	 */
+	if (strncmp(sb.s_magic, JFS_MAGIC, (unsigned) strlen(JFS_MAGIC))) {
+		fsck_send_msg(lrdo_FSSUPERBADMAGIC);
+		vopen[vol].state = VOPEN_CLOSED;
+		return (LOGSUPER_BADMAGIC);
+	}
+	if (sb.s_version > JFS_VERSION) {
+		fsck_send_msg(lrdo_FSSUPERBADMAGIC);
+		vopen[vol].state = VOPEN_CLOSED;
+		return (LOGSUPER_BADVERSION);
+	}
+
+	if (Log.location & OUTLINELOG && (sb.s_flag & (JFS_INLINELOG == JFS_INLINELOG))) {
+		fsck_send_msg(lrdo_FSSUPERBADLOGLOC);
+		vopen[vol].state = VOPEN_CLOSED;
+		return (LOGSUPER_BADLOGLOC);
+	}
+	vopen[vol].lblksize = sb.s_bsize;
+	vopen[vol].l2bsize = sb.s_l2bsize;
+	vopen[vol].l2bfactor = sb.s_l2bfactor;
+	fssize = sb.s_size >> sb.s_l2bfactor;
+	vopen[vol].fssize = fssize;
+	vopen[vol].agsize = sb.s_agsize;
+	/* LOG2NUM will alter agsize, so use local var (Then why don't we
+	   fix LOG2NUM?) */
+	agsize = vopen[vol].agsize;
+	LOG2NUM(agsize, l2agsize);
+	vopen[vol].numag = fssize >> l2agsize;
+	if (fssize & (vopen[vol].agsize - 1))
+		vopen[vol].numag += 1;
+	vopen[vol].l2agsize = l2agsize;
+
+	if (Log.location & INLINELOG) {
+		/*
+		 * Now that the aggregate superblock has been read, do some
+		 * more validation of the log superblock
+		 */
+		if (logsup.bsize != vopen[vol].lblksize) {
+			fsck_send_msg(lrdo_LOGSUPBADBLKSZ);
+			return JFS_BLKSIZE_ERROR;
+		}
+
+		if (logsup.l2bsize != vopen[vol].l2bsize) {
+			fsck_send_msg(lrdo_LOGSUPBADL2BLKSZ);
+			return JFS_L2BLKSIZE_ERROR;
+		}
+
+		aggsb_numpages = lengthPXD(&sb.s_logpxd) * logsup.bsize / LOGPSIZE;
+		if (logsup.size != aggsb_numpages) {
+			fsck_send_msg(lrdo_LOGSUPBADLOGSZ);
+			return JFS_LOGSIZE_ERROR;
+		}
+	}
+	/*
+	 *set lbperpage in vopen.
+	 */
+	vopen[vol].lbperpage = PSIZE >> vopen[vol].l2bsize;
+
+	/*
+	 * was it cleanly umounted ?
+	 */
+	if (sb.s_state == FM_CLEAN) {
+		vopen[vol].status = FM_CLEAN;
+		vopen[vol].state = VOPEN_CLOSED;
+		return (0);
+	}
+
+	/*
+	 * get status of volume
+	 */
+	vopen[vol].status = sb.s_state;
+	vopen[vol].is_fsdirty = (sb.s_state & FM_DIRTY);
+
+	/*
+	 *check log serial number
+	 */
+	if (sb.s_logserial != Log.serial) {
+		fsck_send_msg(lrdo_FSSUPERBADLOGSER);
+		vopen[vol].state = VOPEN_CLOSED;
+		fsError(SERIALNO, vol, SUPER1_B);
+		return (LOGSUPER_BADSERIAL);
+	}
+
+	/* initialize the disk and inode maps
+	 */
+	if ((rc = initMaps(vol)) != 0) {
+		fsck_send_msg(lrdo_INITMAPSFAIL);
+		fsError(MAPERR, vol, 0);
+		return (rc);
+	}
+	vopen[vol].state = VOPEN_OPEN;
+	return 0;
+}
+
+/*
+ * NAME:         updateSuper(vol)
+ *
+ * FUNCTION:     updates primary aggregate/lv's superblock status and
+ *               writes it out.
+ */
+int updateSuper(int vol)
+{				/* device minor number of aggregate/lv */
+	int rc, status;
+	struct superblock sb;
+
+	/* read in superblock of the volume */
+	if ((rc = rdwrSuper(vopen[vol].fp, &sb, PB_READ)) != 0) {
+		fsck_send_msg(lrdo_READFSSUPERFAIL);
+		return (FSSUPER_READERROR2);
+	}
+
+	/* mark superblock state. write it out */
+	status = vopen[vol].status;
+	if (status & (FM_DIRTY | FM_LOGREDO))
+		sb.s_state = status & ~FM_EXTENDFS;
+	else
+		sb.s_state = FM_CLEAN;
+
+	if ((rc = rdwrSuper(vopen[vol].fp, &sb, PB_UPDATE)) != 0) {
+		fsck_send_msg(lrdo_WRITEFSSUPERFAIL);
+	}
+
+	return (rc);
+}
+
+/*
+ * NAME:        rdwrSuper(fp, sb, rwflag)
+ *
+ * FUNCTION:    read or write the superblock for the file system described
+ *              by the file descriptor of the opened aggregate/lv.
+ *              for read, if a read of primary superblock is failed,
+ *              try to read the secondary superblock. report error only
+ *              when both reads failed.
+ *              for write, any write failure should be reported.
+ */
+int rdwrSuper(FILE *fp, struct superblock * sb, int32_t rwflag)
+{
+	int rc;
+	uint64_t super_offset;
+	union {
+		struct superblock super;
+		char block[PSIZE];
+	} super;
+
+	if (use_2ndary_agg_superblock) {
+		super_offset = SUPER2_OFF;
+	} else {
+		super_offset = SUPER1_OFF;
+	}
+	/*
+	 * seek to the postion of the primary superblock.
+	 * since at this time we don't know the aggregate/lv
+	 * logical block size yet, we have to use the fixed
+	 * byte offset address super_offset to seek for.
+	 */
+
+	/*
+	 * read super block
+	 */
+	if (rwflag == PB_READ) {
+		rc = ujfs_rw_diskblocks(fp, super_offset,
+					(unsigned) SIZE_OF_SUPER, super.block, GET);
+		if (rc != 0) {
+			if (!use_2ndary_agg_superblock) {
+				fsck_send_msg(lrdo_READFSPRIMSBFAIL);
+				return (CANTREAD_PRIMFSSUPER);
+			} else {
+				fsck_send_msg(lrdo_READFS2NDSBFAIL);
+				return (CANTREAD_2NDFSSUPER);
+			}
+		}
+
+		*sb = super.super;
+
+		ujfs_swap_superblock(sb);
+
+		/*
+		 * write superblock
+		 */
+	} else {		/* PB_UPDATE */
+		/* ? memset(super.block, 0, SIZE_OF_SUPER); */
+		super.super = *sb;
+
+		ujfs_swap_superblock(&super.super);
+
+		/*
+		 * write whichever superblock we're working with.
+		 * chkdsk will take care of replicating it.
+		 */
+		rc = ujfs_rw_diskblocks(fp, super_offset,
+					(unsigned) SIZE_OF_SUPER, super.block, PUT);
+		if (rc != 0) {
+			if (!use_2ndary_agg_superblock) {
+				fsck_send_msg(lrdo_WRITEFSPRIMSBFAIL);
+				return (CANTWRITE_PRIMFSSUPER);
+			} else {
+				fsck_send_msg(lrdo_WRITEFS2NDSBFAIL);
+				return (CANTWRITE_2NDFSSUPER);
+			}
+		}
+	}
+
+	return (0);
+}
+
+/*
+ * NAME:        bflush()
+ *
+ * FUNCTION:    write out appropriate portion of buffer page if its modified.
+ *              Note that a dtree page may not be 4k, depending on the length
+ *              field specified in pxd. Write out only length that is needed.
+ */
+int bflush(int32_t k,		/*  The index in bufhdr that describes buf */
+	   struct bufpool *buf)
+{				/* pointer to buffer pool page */
+	FILE *fp = NULL;
+	int rc;
+	int32_t vol;
+	int32_t nbytes;
+	int64_t blkno;
+
+	/* nothing to do ? */
+	if (bufhdr[k].modify == 0)
+		return (0);
+
+	/* write it out */
+	vol = bufhdr[k].vol;
+	fp = vopen[vol].fp;
+	blkno = addressPXD(&bufhdr[k].pxd);
+	nbytes = lengthPXD(&bufhdr[k].pxd) << vopen[vol].l2bsize;
+	rc = ujfs_rw_diskblocks(fp,
+				(uint64_t) (blkno << vopen[vol].l2bsize),
+				(unsigned) nbytes, (char *) buf, PUT);
+	if (rc != 0) {
+		fsck_send_msg(lrdo_BUFFLUSHFAIL);
+		return (BFLUSH_WRITEERROR);
+	}
+
+	bufhdr[k].modify = 0;
+
+	return (0);
+}
+
+/*
+ * NAME:        findLog()
+ *
+ * FUNCTION:    open the device to see if it's a valid filesystem
+ * 		or journal.  If it is a filesystem, determine whether
+ * 		the log is inline or external.  If external, find
+ * 		the log device.
+ *
+ */
+int findLog(FILE *fp, int *in_use)
+{
+	struct logsuper logsup;
+	struct superblock sb;
+
+	*in_use = 0;
+	/*
+	 * try the LV as file system with in-line log
+	 */
+	if (rdwrSuper(fp, &sb, PB_READ)) {
+		fsck_send_msg(lrdo_NOTAFSDEV);
+		return NOT_FSDEV_ERROR;
+	}
+
+	/*
+	 * is the LV a file system ?
+	 */
+	if (memcmp(sb.s_magic, JFS_MAGIC, sizeof (sb.s_magic)) == 0) {
+		/*
+		 * does file system contains its in-line log ?
+		 */
+		if ((sb.s_flag & JFS_INLINELOG) == JFS_INLINELOG) {
+			Log.location = INLINELOG;
+			Log.fp = fp;
+			//Log.status = sb.s_state;
+			Log.l2bsize = sb.s_l2bsize;
+			Log.xaddr = addressPXD(&sb.s_logpxd) << sb.s_l2bsize;
+
+			/* vopen[0] represents fs if inline log */
+			vopen[0].status = sb.s_state;
+			vopen[0].fp = fp;
+
+			return 0;
+		}
+		/* Save fp and uuid */
+		primary_vol.fp = fp;
+		uuid_copy(primary_vol.uuid, sb.s_uuid);
+
+		/*
+		 * External log
+		 *
+		 * First check device specified on
+		 * command line
+		 */
+		Log.xaddr = 0;
+		if (log_device[0]) {
+			Log.fp = NULL;
+			if (LogOpenMode != O_RDONLY) {
+				Log.fp = fopen_excl(log_device, "r+");
+				if (Log.fp == NULL)
+					*in_use = 1;
+			}
+			if (Log.fp == NULL) {
+				Log.fp = fopen(log_device, "r");
+				if (Log.fp == NULL) {
+					printf("Invalid journal specified (%s)\n",
+					       log_device);
+					goto by_uuid;
+				}
+			}
+			ujfs_rw_diskblocks(Log.fp, LOGPNTOB(LOGSUPER_B),
+					   sizeof (struct logsuper), &logsup, GET);
+			ujfs_swap_logsuper(&logsup);
+			if ((logsup.magic != LOGMAGIC) || (uuid_compare(logsup.uuid, sb.s_loguuid))) {
+				fclose(Log.fp);
+				*in_use = 0;
+				goto by_uuid;
+			}
+			Log.location = OUTLINELOG;
+			return 0;
+		}
+	      by_uuid:
+		Log.fp = open_by_label(sb.s_loguuid, 0, 1, NULL, in_use);
+
+		if (Log.fp != NULL) {
+			Log.location |= OUTLINELOG;
+			return 0;
+		}
+
+		return NOT_INLINELOG_ERROR;
+	}
+	/*
+	 * is this an external log?
+	 */
+	ujfs_rw_diskblocks(fp, LOGPNTOB(LOGSUPER_B), sizeof (struct logsuper), &logsup, GET);
+	ujfs_swap_logsuper(&logsup);
+	if (logsup.magic != LOGMAGIC) {
+		fsck_send_msg(lrdo_NOTAFSDEV);
+		return NOT_FSDEV_ERROR;
+	}
+	Log.fp = fp;
+	Log.location = OUTLINELOG;
+
+	return 0;
+}
+
+extern void exit(int);
+
+/*
+ * NAME:        fsError(type,vol,bn)
+ *
+ * FUNCTION:    error handling code for the specified
+ *              aggregate/lv (filesystem).
+ */
+int fsError(int type,		/* error types */
+	    int vol,		/* the minor number of the aggregate/lv */
+	    int64_t bn)
+{				/* aggregate block No.  */
+
+	fsck_send_msg(lrdo_ERRORONVOL, vol);
+
+	retcode = -1;
+	vopen[vol].status = FM_LOGREDO;
+
+	switch (type) {
+	case OPENERR:
+		fsck_send_msg(lrdo_OPENFAILED);
+		break;
+	case MAPERR:
+		fsck_send_msg(lrdo_CANTINITMAPS);
+		break;
+	case DBTYPE:
+		fsck_send_msg(lrdo_BADDISKBLKNUM, (long long) bn);
+		break;
+	case INOTYPE:
+		fsck_send_msg(lrdo_BADINODENUM, (long long) bn);
+		break;
+	case READERR:
+		fsck_send_msg(lrdo_CANTREADBLK, (long long) bn);
+		break;
+	case SERIALNO:
+		fsck_send_msg(lrdo_BADLOGSER);
+		break;
+	case IOERROR:
+		fsck_send_msg(lrdo_IOERRREADINGBLK, (long long) bn);
+		break;
+	case LOGRCERR:
+		fsck_send_msg(lrdo_BADUPDMAPREC, (long long) bn);
+		break;
+	}
+	return (0);
+}
+
+/*
+ *      logError(type)
+ *
+ * error handling for log read errors.
+ */
+int logError(int type, int logaddr)
+{
+	int k;
+	retcode = -1;
+	logsup.state = LOGREADERR;
+	switch (type) {
+	case LOGEND:
+		fsck_send_msg(lrdo_FINDLOGENDFAIL);
+		break;
+	case READERR:
+		fsck_send_msg(lrdo_LOGREADFAIL, logaddr);
+		break;
+	case UNKNOWNR:
+		fsck_send_msg(lrdo_UNRECOGTYPE, logaddr);
+		break;
+	case IOERROR:
+		fsck_send_msg(lrdo_IOERRONLOG, logaddr);
+		break;
+	case LOGWRAP:
+		fsck_send_msg(lrdo_LOGWRAP);
+	}
+
+	/* mark all open volumes in error
+	 */
+	for (k = 0; k < MAX_ACTIVE; k++) {
+		if ((vopen[k].state == VOPEN_OPEN) && vopen[k].status != FM_CLEAN)
+			vopen[k].status = FM_LOGREDO;
+	}
+	return (0);
+}
+
+/*
+ *	recoverExtendFS()
+ *
+ * function: recover crash while in extendfs() for inline log;
+ *
+ * note: fs superblock fields remains pre-extendfs state,
+ * while that bmap file, fsck and inline log area may be in
+ * unknown state;
+ *
+ * at entry, only log type/lv has been validated;
+ * for inline log: vopen[0], fs fp = log fp;
+ */
+static int recoverExtendFS(FILE *fp)
+{
+	struct superblock *sbp;
+	struct dinode *dip1, *dip2;
+	struct dbmap *bgcp;
+	xtpage_t *p;
+	int64_t lmchild = 0, xaddr, xoff, barrier, t64, agsize;
+	uint8_t lmxflag;
+	int32_t i;
+	char *dip, *bp;
+	pxd_t temp_pxd;
+
+	/*
+	 * read bmap global control page
+	 */
+	/* read superblock yet again */
+	sbp = (struct superblock *) &buffer[0];
+	if (rdwrSuper(fp, sbp, PB_READ))
+		goto errout;
+
+	/* read primary block allocation map inode */
+	dip = (char *) &buffer[1];
+	if (ujfs_rw_diskblocks(fp, AITBL_OFF, PSIZE, dip, GET)) {
+		fsck_send_msg(lrdo_EXTFSREADFSSUPERFAIL);
+		goto errout;
+	}
+
+	/* locate the inode in the buffer page */
+	dip1 = (struct dinode *) dip;
+	dip1 += BMAP_I;
+
+	bp = (char *) &buffer[2];	/* utility buffer */
+
+	/* start from root in dinode */
+	p = (xtpage_t *) & dip1->di_btroot;
+	/* is this page leaf ? */
+	if (p->header.flag & BT_LEAF)
+		goto rdbgcp;
+
+	/* traverse down leftmost child node to leftmost leaf of xtree */
+	do {
+		/* read in the leftmost child page */
+		t64 = addressXAD(&p->xad[XTENTRYSTART]) << sbp->s_l2bsize;
+		if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {
+			fsck_send_msg(lrdo_EXTFSREADBLKMAPINOFAIL);
+			goto errout;
+		}
+
+		p = (xtpage_t *) bp;
+		/* is this page leaf ? */
+		if (p->header.flag & BT_LEAF)
+			break;
+	} while (1);
+
+      rdbgcp:
+	t64 = addressXAD(&p->xad[XTENTRYSTART]) << sbp->s_l2bsize;
+	if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {
+		fsck_send_msg(lrdo_EXTFSREADBLKFAIL1, (long long) t64);
+		goto errout;
+	}
+	bgcp = (struct dbmap *) bp;
+
+	/*
+	 * recover to pre- or post-extendfs state ?:
+	 */
+	if (__le64_to_cpu(bgcp->dn_mapsize) > (sbp->s_size >> sbp->s_l2bfactor)) {
+		agsize = __le64_to_cpu(bgcp->dn_agsize);
+		goto postx;
+	}
+
+	/*
+	 *    recover pre-extendfs state
+	 */
+	/*
+	 * reset block allocation map inode (xtree root)
+	 */
+	/* read 2ndary block allocation map inode */
+	t64 = addressPXD(&sbp->s_ait2) << sbp->s_l2bsize;
+	if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {
+		fsck_send_msg(lrdo_EXTFSREADBLKFAIL2, (long long) t64);
+		goto errout;
+	}
+	dip2 = (struct dinode *) bp;
+	dip2 += BMAP_I;
+
+	/*
+	 * Reset primary bam inode with 2ndary bam inode
+	 *
+	 * Not forgetting to reset di_ixpxd since they are in different
+	 * inode extents.
+	 */
+	memcpy((void *) &temp_pxd, (void *) &(dip1->di_ixpxd), sizeof (pxd_t));
+	memcpy(dip1, dip2, DISIZE);
+	memcpy((void *) &(dip1->di_ixpxd), (void *) &temp_pxd, sizeof (pxd_t));
+
+	if (ujfs_rw_diskblocks(fp, AITBL_OFF, PSIZE, dip, PUT)) {
+		fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL1, AITBL_OFF);
+		goto errout;
+	}
+
+	/*
+	 * backout bmap file to fs size:
+	 *
+	 * trim xtree to range specified by i_size:
+	 * xtree has been grown in append mode and
+	 * written from right to left, bottom-up;
+	 */
+	barrier = __le64_to_cpu(dip1->di_size) >> sbp->s_l2bsize;
+
+	/* start with root */
+	xaddr = 0;
+	p = (xtpage_t *) & dip1->di_btroot;
+	lmxflag = p->header.flag;
+	p->header.next = 0;
+	if (lmxflag & BT_INTERNAL) {
+		/* save leftmost child xtpage xaddr */
+		lmchild = addressXAD(&p->xad[XTENTRYSTART]);
+	}
+
+	/*
+	 * scan each level of xtree via leftmost descend
+	 */
+	while (1) {
+		/*
+		 * scan each xtpage of current level of xtree
+		 */
+		while (1) {
+			/*
+			 * scan each xad in current xtpage
+			 */
+			for (i = XTENTRYSTART; i < p->header.nextindex; i++) {
+				/* test if extent is of interest */
+				xoff = offsetXAD(&p->xad[i]);
+				if (xoff < barrier)
+					continue;
+
+				/*
+				 * barrier met in current page
+				 */
+				assert(i > XTENTRYSTART);
+				/* update current page */
+				p->header.nextindex = i;
+				if (xaddr) {
+					/* discard further right sibling
+					 * pages
+					 */
+					p->header.next = 0;
+					if (ujfs_rw_diskblocks(fp, t64, PSIZE, p, PUT)) {
+						fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL2, (long long) t64);
+						goto errout;
+					}
+				}
+
+				goto nextLevel;
+			}	/* end for current xtpage scan */
+
+			/* barrier was not met in current page */
+
+			/* read in next/right sibling xtpage */
+			xaddr = p->header.next;
+			if (xaddr) {
+				if (xaddr >= barrier) {
+					p->header.next = 0;
+					if (ujfs_rw_diskblocks(fp, t64, PSIZE, p, PUT)) {
+						fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL3, (long long) t64);
+						break;
+					}
+				}
+
+				t64 = xaddr << sbp->s_l2bsize;
+				if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {
+					fsck_send_msg(lrdo_EXTFSREADBLKFAIL3, (long long) t64);
+					goto errout;
+				}
+
+				p = (xtpage_t *) bp;
+			} else
+				break;
+		}		/* end while current level scan */
+
+		/*
+		 * descend: read leftmost xtpage of next lower level of xtree
+		 */
+	      nextLevel:
+		if (lmxflag & BT_INTERNAL) {
+			/* get the leftmost child page  */
+			xaddr = lmchild;
+			t64 = xaddr << sbp->s_l2bsize;
+			if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {
+				fsck_send_msg(lrdo_EXTFSREADBLKFAIL4, (long long) t64);
+				goto errout;
+			}
+
+			p = (xtpage_t *) bp;
+
+			lmxflag = p->header.flag;
+			if (lmxflag & BT_INTERNAL) {
+				/* save leftmost child xtpage xaddr */
+				lmchild = addressXAD(&p->xad[XTENTRYSTART]);
+			}
+		} else
+			break;
+	}			/* end while level scan */
+
+	/*
+	 * reconstruct map;
+	 *
+	 * readBmap() init blocks beyond fs size in the last
+	 * partial dmap page as allocated which might have been
+	 * marked as free by extendfs();
+	 */
+	/* fake log opend/validated */
+	Log.serial = sbp->s_logserial;
+
+	/*
+	 *  reconstruct maps
+	 */
+	/* open LV and initialize maps  */
+	if (logredoInit()) {
+		fsck_send_msg(lrdo_EXTFSINITLOGREDOFAIL);
+		goto errout;
+	}
+
+	/* bypass log replay */
+
+	/* update/write maps */
+	updateMaps(0);
+
+	/*
+	 * reformat log
+	 *
+	 * request reformat original log  (which might have been
+	 * overwritten by extendfs() and set superblock clean
+	 */
+	jfs_logform(fp, sbp->s_bsize, sbp->s_l2bsize, sbp->s_flag,
+		    addressPXD(&sbp->s_logpxd), lengthPXD(&sbp->s_logpxd), NULL, NULL);
+
+	/* update superblock */
+	updateSuper(0);
+
+	fsck_send_msg(lrdo_REXTNDTOPRE);
+
+	return 0;
+
+	/*
+	 *    recover post-extendfs state
+	 */
+      postx:
+	/*
+	 * update 2ndary bam inode
+	 */
+	/* read 2ndary block allocation map inode */
+	t64 = addressPXD(&sbp->s_ait2) << sbp->s_l2bsize;
+	if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, GET)) {
+		fsck_send_msg(lrdo_EXTFSREADBLKFAIL5, (long long) t64);
+		goto errout;
+	}
+	dip2 = (struct dinode *) bp;
+	dip2 += BMAP_I;
+
+	/*
+	 * Reset 2ndary bam inode with primary bam inode
+	 * Not forgetting to reset di_ixpxd since they are in different
+	 * inode extents.
+	 */
+	memcpy((void *) &temp_pxd, (void *) &(dip2->di_ixpxd), sizeof (pxd_t));
+	memcpy(dip2, dip1, DISIZE);
+	memcpy((void *) &(dip2->di_ixpxd), (void *) &temp_pxd, sizeof (pxd_t));
+
+	if (ujfs_rw_diskblocks(fp, t64, PSIZE, bp, PUT)) {
+		fsck_send_msg(lrdo_EXTFSWRITEBLKFAIL4, (long long) t64);
+		goto errout;
+	}
+
+	/*
+	 * update superblock
+	 */
+	if (!(sbp->s_state & (FM_DIRTY | FM_LOGREDO)))
+		sbp->s_state = FM_CLEAN;
+	else
+		sbp->s_state &= ~FM_EXTENDFS;
+	sbp->s_size = sbp->s_xsize;
+	sbp->s_agsize = agsize;
+	sbp->s_fsckpxd = sbp->s_xfsckpxd;
+	sbp->s_fscklog = 0;
+	sbp->s_logpxd = sbp->s_xlogpxd;
+	sbp->s_logserial = 1;
+
+	if (rdwrSuper(fp, sbp, PB_UPDATE)) {
+		fsck_send_msg(lrdo_EXTFSWRITEFSSUPERFAIL);
+		goto errout;
+	}
+
+	/*
+	 * finalize log
+	 *
+	 * note: new log is valid;
+	 */
+	/* read log superblock */
+	t64 = (addressPXD(&sbp->s_logpxd) << sbp->s_l2bsize) + LOGPSIZE;
+	if (ujfs_rw_diskblocks(fp, t64, LOGPSIZE, &logsup, GET)) {
+		fsck_send_msg(lrdo_EXTFSREADLOGSUPFAIL);
+		goto errout;
+	}
+
+	logsup.end = findEndOfLog();
+	logsup.state = LOGREDONE;
+
+	if (ujfs_rw_diskblocks(fp, t64, LOGPSIZE, &logsup, PUT)) {
+		fsck_send_msg(lrdo_EXTFSWRITELOGSUPFAIL);
+		goto errout;
+	}
+
+	fsck_send_msg(lrdo_REXTNDTOPOST);
+
+	return 0;
+
+      errout:
+	fsck_send_msg(lrdo_REXTNDFAIL, errno);
+	return (EXTENDFS_FAILRECOV);
+}
+
+/*
+ *
+ * NAME:        alloc_dmap_bitrec
+ *
+ * FUNCTION:    This routine allocates memory by calling the chkdsk
+ *		alloc_wrksp() routine (because that will allocate high
+ *		memory during autocheck).  If that fails then logredo
+ *                   cannot continue bmap processing, so it will set a flag
+ *                   and make the storage aleady allocated to the bmap
+ *                   available for other uses.
+ *		was successfully allocated and there's enough of it left,
+ *		this routine will return a piece of it.
+ */
+int alloc_dmap_bitrec(struct dmap_bitmaps ** dmap_bitrec)
+{
+	int adb_rc = 0;
+	int intermed_rc = 0;
+
+	*dmap_bitrec = NULL;
+
+	intermed_rc = alloc_wrksp((uint32_t) (sizeof (struct dmap_bitmaps)), 0,	/* not meaningful from logredo */
+				  -1,	/* I am logredo */
+				  (void **) dmap_bitrec);
+
+	if ((intermed_rc != 0) || ((*dmap_bitrec) == NULL)) {
+		Insuff_memory_for_maps = -1;
+		available_stg_addr = bmap_stg_addr;
+		available_stg_bytes = bmap_stg_bytes;
+		/*
+		 * initialize the storage for its new use
+		 */
+		memset((void *) available_stg_addr, 0, available_stg_bytes);
+	}
+
+	return (adb_rc);
+}				/* end alloc_dmap_bitrec() */
+
+/*
+ *
+ * NAME:        alloc_storage
+ *
+ * FUNCTION:    This routine allocates memory by calling the chkdsk
+ *		alloc_wrksp() routine (because that will allocate high
+ *		memory during autocheck).  If that fails and the bmap
+ *		was successfully allocated and there's enough of it left,
+ *		this routine will return a piece of it.
+ */
+int alloc_storage(int32_t size_in_bytes, void **addr_stg_ptr, int32_t * bmap_stg_returned)
+{
+	int as_rc = 0;
+	int intermed_rc = 0;
+
+	*bmap_stg_returned = 0;	/* assume we'll get it the usual way */
+	*addr_stg_ptr = NULL;
+
+	intermed_rc = alloc_wrksp((uint32_t) size_in_bytes, 0, -1, addr_stg_ptr);
+
+	if ((intermed_rc != 0) || ((*addr_stg_ptr) == NULL)) {
+		if ((!Insuff_memory_for_maps) && (bmap_stg_addr != NULL)) {
+			/*
+			 * we did allocate storage for the bmap
+			 * and haven't started cannibalizing it yet
+			 */
+			Insuff_memory_for_maps = -1;
+			available_stg_addr = bmap_stg_addr;
+			available_stg_bytes = bmap_stg_bytes;
+			/*
+			 * initialize the storage for its new use
+			 */
+			memset((void *) available_stg_addr, 0, available_stg_bytes);
+		}
+		/* end we did allocate storage for the bmap... */
+		if (Insuff_memory_for_maps & (available_stg_bytes != 0)) {
+			/*
+			 * we may be able to go on anyway
+			 */
+			if (available_stg_bytes < size_in_bytes) {
+				/*
+				 * not enough here
+				 */
+				return (ENOMEM0);
+			} else {
+				/* we can scavenge the memory we need */
+				*addr_stg_ptr = available_stg_addr;
+				available_stg_bytes -= size_in_bytes;
+				available_stg_addr = (char *) (available_stg_addr + size_in_bytes);
+				*bmap_stg_returned = -1;
+			}
+		} else {
+			return (ENOMEM1);
+		}
+	}
+
+	return (as_rc);
+}
+
+#ifdef  _JFS_WIP
+/*
+ *      nfsisloaded()
+ *
+ * check whether nfs is loaded
+ */
+static int nfsisloaded()
+{
+	int sav_errno;
+	int (*entry) ();
+	if (entry = load("/usr/sbin/probe", 0, 0))
+		return (1);
+	if (errno == ENOEXEC) {
+		DBG_TRACE(("%s: nfs is not loaded\n", prog))
+		    return (0);
+	}
+	sav_errno = errno;
+	DBG_TRACE(("%s: ", prog))
+	    errno = sav_errno;
+	perror("load");
+	return (0);
+}
+#endif				/* _JFS_WIP */
+
+#ifdef _JFS_DEBUG
+/*
+ *      xdump()
+ *
+ * hex dump
+ */
+xdump(char *saddr, int count)
+{
+#define LINESZ     60
+#define ASCIISTRT  40
+#define HEXEND     36
+	int i, j, k, hexdigit;
+	int c;
+	char *hexchar;
+	char linebuf[LINESZ + 1];
+	char prevbuf[LINESZ + 1];
+	char *linestart;
+	int asciistart;
+	char asterisk = ' ';
+	void x_scpy();
+	int x_scmp();
+	hexchar = "0123456789ABCDEF";
+	prevbuf[0] = '\0';
+	i = (int) saddr % 4;
+	if (i != 0)
+		saddr = saddr - i;
+	for (i = 0; i < count;) {
+		for (j = 0; j < LINESZ; j++)
+			linebuf[j] = ' ';
+		linestart = saddr;
+		asciistart = ASCIISTRT;
+		for (j = 0; j < HEXEND;) {
+			for (k = 0; k < 4; k++) {
+				c = *(saddr++) & 0xFF;
+				if ((c >= 0x20) && (c <= 0x7e))
+					linebuf[asciistart++] = (char) c;
+				else
+					linebuf[asciistart++] = '.';
+				hexdigit = c >> 4;
+				linebuf[j++] = hexchar[hexdigit];
+				hexdigit = c & 0x0f;
+				linebuf[j++] = hexchar[hexdigit];
+				i++;
+			}
+			if (i >= count)
+				break;
+			linebuf[j++] = ' ';
+		}
+		linebuf[LINESZ] = '\0';
+		if (((j = x_scmp(linebuf, prevbuf)) == 0) && (i < count)) {
+			if (asterisk == ' ') {
+				asterisk = '*';
+				DBG_TRACE(("    *\n"))
+			}
+		} else {
+			DBG_TRACE(("    %x  %s\n", linestart, linebuf))
+			    asterisk = ' ';
+			x_scpy(prevbuf, linebuf);
+		}
+	}
+	return (0);
+}
+
+int x_scmp(char *s1, char *s2)
+{
+	while ((*s1) && (*s1 == *s2)) {
+		s1++;
+		s2++;
+	}
+	if (*s1 || *s2)
+		return (-1);
+	else
+		return (0);
+}
+
+void x_scpy(char *s1, char *s2)
+{
+	while ((*s1 = *s2) != '\0') {
+		s1++;
+		s2++;
+	}
+}
+
+prtdesc(struct lrd *ld)
+{
+	switch (ld->log.redopage.type) {
+	case LOG_XTREE:
+		DBG_TRACE((" REDOPAGE:XTREE\n  "))
+		    break;
+	case (LOG_XTREE | LOG_NEW):
+		DBG_TRACE((" REDOPAGE:XTREE_NEW\n  "))
+		    break;
+	case (LOG_BTROOT | LOG_XTREE):
+		DBG_TRACE((" REDOPAGE:BTROOT_XTREE\n  "))
+		    break;
+	case LOG_DTREE:
+		DBG_TRACE((" REDOPAGE:DTREE\n  "))
+		    break;
+	case (LOG_DTREE | LOG_NEW):
+		DBG_TRACE((" REDOPAGE:DTREE_NEW \n "))
+		    break;
+	case (LOG_DTREE | LOG_EXTEND):
+		DBG_TRACE((" REDOPAGE:DTREE_EXTEND\n  "))
+		    break;
+	case (LOG_BTROOT | LOG_DTREE):
+		DBG_TRACE((" REDOPAGE:BTROOT_DTREE\n  "))
+		    break;
+	case (LOG_BTROOT | LOG_DTREE | LOG_NEW):
+		DBG_TRACE((" REDOPAGE:BTROOT_DTREE.NEW\n  "))
+		    break;
+	case LOG_INODE:
+		/*
+		 * logredo() updates imap for alloc of inode.
+		 */
+		DBG_TRACE((" REDOPAGE:INODE\n  "))
+		    break;
+	case LOG_EA:
+		DBG_TRACE((" REDOPAGE:EA\n  "))
+		    break;
+	case LOG_DATA:
+		DBG_TRACE((" REDOPAGE:DATA\n  "))
+		    break;
+	}
+	return (0);
+}
+#endif				/* _JFS_DEBUG */
Index: create-1.1.15-patch/jfsutils-1.1.15-new/libfs
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new/libfs	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new/libfs	(revision 5)

Property changes on: create-1.1.15-patch/jfsutils-1.1.15-new/libfs
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-1.1.15-patch/jfsutils-1.1.15-new
===================================================================
--- create-1.1.15-patch/jfsutils-1.1.15-new	(nonexistent)
+++ create-1.1.15-patch/jfsutils-1.1.15-new	(revision 5)

Property changes on: create-1.1.15-patch/jfsutils-1.1.15-new
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: create-1.1.15-patch
===================================================================
--- create-1.1.15-patch	(nonexistent)
+++ create-1.1.15-patch	(revision 5)

Property changes on: create-1.1.15-patch
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: patches/README
===================================================================
--- patches/README	(nonexistent)
+++ patches/README	(revision 5)
@@ -0,0 +1,6 @@
+
+/* begin *
+
+   TODO: Leave some comment here.
+
+ * end */
Index: patches
===================================================================
--- patches	(nonexistent)
+++ patches	(revision 5)

Property changes on: patches
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~
Index: .
===================================================================
--- .	(nonexistent)
+++ .	(revision 5)

Property changes on: .
___________________________________________________________________
Added: svn:ignore
## -0,0 +1,73 ##
+
+# install dir
+dist
+
+# Target build dirs
+.a1x-newlib
+.a2x-newlib
+.at91sam7s-newlib
+
+.build-machine
+
+.a1x-glibc
+.a2x-glibc
+.h3-glibc
+.h5-glibc
+.i586-glibc
+.i686-glibc
+.imx6-glibc
+.jz47xx-glibc
+.makefile
+.am335x-glibc
+.omap543x-glibc
+.p5600-glibc
+.power8-glibc
+.power8le-glibc
+.power9-glibc
+.power9le-glibc
+.m1000-glibc
+.riscv64-glibc
+.rk328x-glibc
+.rk33xx-glibc
+.rk339x-glibc
+.s8xx-glibc
+.s9xx-glibc
+.x86_64-glibc
+
+# Hidden files (each file)
+.makefile
+.dist
+.rootfs
+
+# src & hw requires
+.src_requires
+.src_requires_depend
+.requires
+.requires_depend
+
+# Tarballs
+*.gz
+*.bz2
+*.lz
+*.xz
+*.tgz
+*.txz
+
+# Signatures
+*.asc
+*.sig
+*.sign
+*.sha1sum
+
+# Patches
+*.patch
+
+# Descriptions
+*.dsc
+*.txt
+
+# Default linux config files
+*.defconfig
+
+# backup copies
+*~