PERFORCE change 93014 for review

Kip Macy kmacy at FreeBSD.org
Wed Mar 8 21:39:21 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=93014

Change 93014 by kmacy at kmacy_storage:sun4v_work on 2006/03/09 05:38:25

	hacked up loader for booting off of solaris' UFS

Affected files ...

.. //depot/projects/kmacy_sun4v/src/lib/libstand/ufs.c#3 edit

Differences ...

==== //depot/projects/kmacy_sun4v/src/lib/libstand/ufs.c#3 (text+ko) ====

@@ -81,6 +81,7 @@
 #include <sys/param.h>
 #include <sys/disklabel.h>
 #include <sys/time.h>
+#include <sys/stddef.h>
 #include <ufs/ufs/dinode.h>
 #include <ufs/ufs/dir.h>
 #include <ufs/ffs/fs.h>
@@ -110,6 +111,134 @@
 	ufs_readdir
 };
 
+typedef int32_t daddr32_t;
+typedef int32_t time32_t;
+typedef unsigned char uchar_t;
+#define MAXCSBUFS 32
+typedef struct _quad { int val[2]; } squad_t;
+struct  solaris_fs {
+        uint32_t fs_link;               /* linked list of file systems */
+        uint32_t fs_rolled;             /* logging only: fs fully rolled */
+        daddr32_t fs_sblkno;            /* addr of super-block in filesys */
+        daddr32_t fs_cblkno;            /* offset of cyl-block in filesys */
+        daddr32_t fs_iblkno;            /* offset of inode-blocks in filesys */
+        daddr32_t fs_dblkno;            /* offset of first data after cg */
+        int32_t fs_cgoffset;            /* cylinder group offset in cylinder */
+        int32_t fs_cgmask;              /* used to calc mod fs_ntrak */
+        time32_t fs_time;               /* last time written */
+        int32_t fs_size;                /* number of blocks in fs */
+        int32_t fs_dsize;               /* number of data blocks in fs */
+        int32_t fs_ncg;                 /* number of cylinder groups */
+        int32_t fs_bsize;               /* size of basic blocks in fs */
+        int32_t fs_fsize;               /* size of frag blocks in fs */
+        int32_t fs_frag;                /* number of frags in a block in fs */
+/* these are configuration parameters */
+        int32_t fs_minfree;             /* minimum percentage of free blocks */
+        int32_t fs_rotdelay;            /* num of ms for optimal next block */
+        int32_t fs_rps;                 /* disk revolutions per second */
+/* these fields can be computed from the others */
+        int32_t fs_bmask;               /* ``blkoff'' calc of blk offsets */
+        int32_t fs_fmask;               /* ``fragoff'' calc of frag offsets */
+        int32_t fs_bshift;              /* ``lblkno'' calc of logical blkno */
+        int32_t fs_fshift;              /* ``numfrags'' calc number of frags */
+/* these are configuration parameters */
+        int32_t fs_maxcontig;           /* max number of contiguous blks */
+        int32_t fs_maxbpg;              /* max number of blks per cyl group */
+/* these fields can be computed from the others */
+        int32_t fs_fragshift;           /* block to frag shift */
+        int32_t fs_fsbtodb;             /* fsbtodb and dbtofsb shift constant */
+        int32_t fs_sbsize;              /* actual size of super block */
+        int32_t fs_csmask;              /* csum block offset */
+        int32_t fs_csshift;             /* csum block number */
+        int32_t fs_nindir;              /* value of NINDIR */
+        int32_t fs_inopb;               /* value of INOPB */
+        int32_t fs_nspf;                /* value of NSPF */
+/* yet another configuration parameter */
+        int32_t fs_optim;               /* optimization preference, see below */
+/* these fields are derived from the hardware */
+        /* USL SVR4 compatibility */
+#ifdef _LITTLE_ENDIAN
+        /*
+         * USL SVR4 compatibility
+         *
+         * There was a significant divergence here between Solaris and
+         * SVR4 for x86.  By swapping these two members in the superblock,
+         * we get read-only compatibility of SVR4 filesystems.  Otherwise
+         * there would be no compatibility.  This change was introduced
+         * during bootstrapping of Solaris on x86.  By making this ifdef'ed
+         * on byte order, we provide ongoing compatibility across all
+         * platforms with the same byte order, the highest compatibility
+         * that can be achieved.
+         */
+        int32_t fs_state;               /* file system state time stamp */
+#else
+        int32_t fs_npsect;              /* # sectors/track including spares */
+#endif
+        int32_t fs_si;                  /* summary info state - lufs only */
+        int32_t fs_trackskew;           /* sector 0 skew, per track */
+/* a unique id for this filesystem (currently unused and unmaintained) */
+/* In 4.3 Tahoe this space is used by fs_headswitch and fs_trkseek */
+/* Neither of those fields is used in the Tahoe code right now but */
+/* there could be problems if they are.                         */
+        int32_t fs_id[2];               /* file system id */
+/* sizes determined by number of cylinder groups and their sizes */
+        daddr32_t fs_csaddr;            /* blk addr of cyl grp summary area */
+        int32_t fs_cssize;              /* size of cyl grp summary area */
+        int32_t fs_cgsize;              /* cylinder group size */
+/* these fields are derived from the hardware */
+        int32_t fs_ntrak;               /* tracks per cylinder */
+        int32_t fs_nsect;               /* sectors per track */
+        int32_t fs_spc;                 /* sectors per cylinder */
+/* this comes from the disk driver partitioning */
+        int32_t fs_ncyl;                /* cylinders in file system */
+/* these fields can be computed from the others */
+        int32_t fs_cpg;                 /* cylinders per group */
+        int32_t fs_ipg;                 /* inodes per group */
+        int32_t fs_fpg;                 /* blocks per group * fs_frag */
+/* this data must be re-computed after crashes */
+        struct  csum fs_cstotal;        /* cylinder summary information */
+/* these fields are cleared at mount time */
+        char    fs_fmod;                /* super block modified flag */
+        char    fs_clean;               /* file system state flag */
+        char    fs_ronly;               /* mounted read-only flag */
+        char    fs_flags;               /* largefiles flag, etc. */
+        char    fs_fsmnt[512];    /* name mounted on */
+/* these fields retain the current block allocation info */
+        int32_t fs_cgrotor;             /* last cg searched */
+        /*
+         * The following used to be fs_csp[MAXCSBUFS]. It was not
+         * used anywhere except in old utilities.  We removed this
+         * in 5.6 and expect fs_u.fs_csp to be used instead.
+         * We no longer limit fs_cssize based on MAXCSBUFS.
+         */
+        union {                         /* fs_cs (csum) info */
+                uint32_t fs_csp_pad[MAXCSBUFS];
+                struct csum *fs_csp;
+        } fs_u;
+        int32_t fs_cpc;                 /* cyl per cycle in postbl */
+        short   fs_opostbl[16*8];      /* old rotation block list head */
+        int32_t fs_sparecon[51];        /* reserved for future constants */
+        int32_t fs_version;             /* minor version of MTB ufs */
+        int32_t fs_logbno;              /* block # of embedded log */
+        int32_t fs_reclaim;             /* reclaim open, deleted files */
+        int32_t fs_sparecon2;           /* reserved for future constant */
+#ifdef _LITTLE_ENDIAN
+         /* USL SVR4 compatibility */
+        int32_t fs_npsect;              /* # sectors/track including spares */
+#else
+        int32_t fs_state;               /* file system state time stamp */
+#endif
+        squad_t  fs_qbmask;              /* ~fs_bmask - for use with quad size */
+        squad_t  fs_qfmask;              /* ~fs_fmask - for use with quad size */
+        int32_t fs_postblformat;        /* format of positional layout tables */
+        int32_t fs_nrpos;               /* number of rotaional positions */
+        int32_t fs_postbloff;           /* (short) rotation block list head */
+        int32_t fs_rotbloff;            /* (uchar_t) blocks for each rotation */
+        int32_t fs_magic;               /* magic number */
+        uchar_t fs_space[1];            /* list of blocks for each rotation */
+/* actually longer */
+};
+
 /*
  * In-core open file.
  */
@@ -142,7 +271,49 @@
 static int	buf_write_file(struct open_file *, char *, size_t *);
 static int	search_directory(char *, struct open_file *, ino_t *);
 
+
 /*
+ * Search a directory for a name and return its
+ * i_number.
+ */
+
+static void hdump(uint8_t *bp, int size)
+{
+	int i;
+	int f = 1;
+	uint8_t tmp[17];
+
+	tmp[16] = '\0';
+	
+	for (i=0; i<size; i++) {
+		uint8_t c;
+
+		c = bp[i];
+		if (f) {
+			printf("%04x : ", i);
+			f=0;
+		}
+		printf(" 0x%02x", c);
+
+		if (c<32 || c>126) c='.';
+		tmp[i&15] = c;
+
+		if ((i&15)==15) {
+			printf(" : %s\n", tmp);
+			f=1;
+		}
+	}
+	if (!f) {
+		for (i=(i&15); i<16; i++) {
+			printf(" --");
+			tmp[i]=' ';
+		}
+		printf(" : %s\n", tmp);
+	}
+}
+
+
+/*
  * Read a new inode into a file structure.
  */
 static int
@@ -159,6 +330,11 @@
 	if (fs == NULL)
 	    panic("fs == NULL");
 
+	printf("read_inode : inumber=0x%llx fsba=0x%llx dba=0x%llx\n",
+	       (uint64_t)inumber,
+	       (uint64_t)ino_to_fsba(fs, inumber),
+	       (uint64_t)fsbtodb(fs, ino_to_fsba(fs, inumber)) );
+
 	/*
 	 * Read inode and save it.
 	 */
@@ -327,6 +503,7 @@
 	file_block = lblkno(fs, fp->f_seekp);
 	block_size = sblksize(fs, DIP(fp, di_size), file_block);
 
+
 	rc = block_map(f, file_block, &disk_block);
 	if (rc)
 		return (rc);
@@ -393,6 +570,7 @@
 	struct file *fp = (struct file *)f->f_fsdata;
 	struct fs *fs = fp->f_fs;
 	long off;
+	size_t file_size;
 	ufs_lbn_t file_block;
 	ufs2_daddr_t disk_block;
 	size_t block_size;
@@ -400,8 +578,24 @@
 
 	off = blkoff(fs, fp->f_seekp);
 	file_block = lblkno(fs, fp->f_seekp);
-	block_size = sblksize(fs, DIP(fp, di_size), file_block);
+	file_size = DIP(fp, di_size);
+	block_size = sblksize(fs, file_size, file_block);
+#if 0
+	printf("buf_read_file: fs->f_seekp=0x%llx : off=0x%lx : file_block=0x%lx : block_size=0x%llx\n",
+	       (uint64_t)fp->f_seekp, off, file_block, (uint64_t)block_size);
+	printf("\tfile_size=0x%llx : fs_bsize=0x%llx\n", (uint64_t)file_size, (uint64_t)fs->fs_bsize);
+	printf("fragroundup[blkoff[%lld]=%lld]=%lld\n", file_size, blkoff(fs, file_size),
+	       fragroundup(fs, blkoff(fs, file_size)));
+	printf("fs->fs_qbmask=%llx fs->fs_qfmask=%llx fs->fs_fmask=%lx\n", fs->fs_qbmask, fs->fs_qfmask, fs->fs_fmask);
+#endif
 
+	if (block_size > 8192) {
+		block_size=8192;
+		printf("FORCE ROUND block_size\n");
+	}
+#if 0
+	printf("\tfp->f_buf_blkno = 0x%lx\n", fp->f_buf_blkno);
+#endif
 	if (file_block != fp->f_buf_blkno) {
 		if (fp->f_buf == (char *)0)
 			fp->f_buf = malloc(fs->fs_bsize);
@@ -409,17 +603,27 @@
 		rc = block_map(f, file_block, &disk_block);
 		if (rc)
 			return (rc);
-
+#if 0
+		printf("\tblock_map : disk_block = 0x%lx\n", disk_block);
+#endif
 		if (disk_block == 0) {
 			bzero(fp->f_buf, block_size);
 			fp->f_buf_size = block_size;
 		} else {
 			twiddle();
+#if 0
+			printf("\tcalling dev_strategy for block read fsbtodb[0x%lx]=0x%lx\n",
+			       disk_block, fsbtodb(fs, disk_block));
+#endif
 			rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
 				fsbtodb(fs, disk_block),
 				block_size, fp->f_buf, &fp->f_buf_size);
 			if (rc)
 				return (rc);
+#if 0
+			printf("\treturned from block read with 0x%lx bytes\n", fp->f_buf_size);
+			hdump(fp->f_buf, fp->f_buf_size);
+#endif
 		}
 
 		fp->f_buf_blkno = file_block;
@@ -442,10 +646,35 @@
 	return (0);
 }
 
-/*
- * Search a directory for a name and return its
- * i_number.
- */
+static void
+test_disk(struct open_file *f)
+{
+	int i, rc;
+	char *buf;
+	uint64_t  read_size;
+
+	struct file *fp = (struct file *)f->f_fsdata;
+	struct fs *fs = fp->f_fs;
+	
+	buf = (char *)malloc(512);
+	
+	for (i = 0; i < 10; i++) {	
+		rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
+					     fsbtodb(fs, i),
+					     512, buf, &read_size);
+
+	
+		if (rc || read_size != 512)
+			printf("strategy failed\n");
+		printf("%04d\n", i);
+#if 0
+		hdump(buf, 512);
+#endif		
+		
+	}
+
+}
+
 static int
 search_directory(name, f, inumber_p)
 	char *name;
@@ -459,18 +688,33 @@
 	size_t buf_size;
 	int namlen, length;
 	int rc;
+#if 0
+	test_disk(f);
+#endif
+	length = strlen(name);
 
-	length = strlen(name);
+	printf("search_directory: name=%s\n", name);
 
 	fp->f_seekp = 0;
 	while (fp->f_seekp < DIP(fp, di_size)) {
+		int i;
 		rc = buf_read_file(f, &buf, &buf_size);
 		if (rc)
 			return (rc);
 
+		printf("scan directory entries: @ 0x%llx (size=0x%llx)\n",
+		       (uint64_t)buf, (uint64_t)buf_size);
 		dp = (struct direct *)buf;
 		edp = (struct direct *)(buf + buf_size);
+		i = 0;
+#if 0
+		hdump(buf, buf_size);
+#endif
 		while (dp < edp) {
+#if 0
+			printf("\tdirent# %d  (dp=0x%llx edp=0x%llx\n", i,
+			       (uint64_t)dp, (uint64_t)edp);
+#endif
 			if (dp->d_ino == (ino_t)0)
 				goto next;
 #if BYTE_ORDER == LITTLE_ENDIAN
@@ -479,6 +723,9 @@
 			else
 #endif
 				namlen = dp->d_namlen;
+#if 0
+			printf("namlen: %d dp->d_name: %s\n", namlen, dp->d_name);
+#endif
 			if (namlen == length &&
 			    !strcmp(name, dp->d_name)) {
 				/* found entry */
@@ -487,6 +734,7 @@
 			}
 		next:
 			dp = (struct direct *)((char *)dp + dp->d_reclen);
+			i++;
 		}
 		fp->f_seekp += buf_size;
 	}
@@ -494,7 +742,31 @@
 }
 
 static int sblock_try[] = SBLOCKSEARCH;
+#define SOLARIS_SBLOCK_CONVERT 1
+void map_sblock(struct fs *fsp)
+{
+	struct solaris_fs sfs = *(struct solaris_fs *)fsp;
+
+	printf("fbsd fs_qfmask offset %lx solaris fs_qfmask offset %lx\n",
+	       offsetof(struct fs, fs_qfmask), offsetof(struct solaris_fs, fs_qfmask));
+	printf("fbsd fs_qbmask offset %lx solaris fs_qbmask offset %lx\n",
+	       offsetof(struct fs, fs_qbmask), offsetof(struct solaris_fs, fs_qbmask));
 
+
+	printf("	fsp->fs_qbmask: %llx = sfs.fs_qbmask %08lx%08lx;\n",
+	       fsp->fs_qbmask, sfs.fs_qbmask.val[0], sfs.fs_qbmask.val[1]);       	
+	fsp->fs_qbmask = ((uint64_t)sfs.fs_qbmask.val[0]) << 32 | sfs.fs_qbmask.val[1];
+	printf("	fsp->fs_qfmask: %llx = sfs.fs_qfmask %08lx%08lx;\n",
+	       fsp->fs_qfmask, sfs.fs_qfmask.val[0], sfs.fs_qfmask.val[1]);
+	fsp->fs_qfmask = ((uint64_t)sfs.fs_qfmask.val[0]) << 32 | sfs.fs_qfmask.val[1];
+
+}
+
+
+
+
+
+
 /*
  * Open a file.
  */
@@ -533,6 +805,16 @@
 		    (char *)fs, &buf_size);
 		if (rc)
 			goto out;
+
+
+
+
+#if 0
+		printf("fs->fs_magic: %x fs->fs_bsize: %x fs->fs_sblockloc: %lx\n", 
+		       fs->fs_magic, fs->fs_bsize, fs->fs_sblockloc);
+		printf("sblock_try[i]: %x buf_size %lx\n", 
+		       sblock_try[i], buf_size);
+#endif
 		if ((fs->fs_magic == FS_UFS1_MAGIC ||
 		     (fs->fs_magic == FS_UFS2_MAGIC &&
 		      fs->fs_sblockloc == sblock_try[i])) &&
@@ -545,6 +827,9 @@
 		rc = EINVAL;
 		goto out;
 	}
+#if 1
+	map_sblock(fs);
+#endif
 	/*
 	 * Calculate indirect block levels.
 	 */
@@ -560,9 +845,13 @@
 	}
 
 	inumber = ROOTINO;
-	if ((rc = read_inode(inumber, f)) != 0)
-		goto out;
+	if ((rc = read_inode(inumber, f)) != 0) {
+		printf("failed to read root inode \n");
+		goto out; 
 
+	}
+	printf("read root inode \n");
+		
 	cp = path = strdup(upath);
 	if (path == NULL) {
 	    rc = ENOMEM;
@@ -609,6 +898,8 @@
 		 * symbolic link.
 		 */
 		parent_inumber = inumber;
+		printf("-- searching %s @ inode = 0x%x - found @ 0x%x\n",
+		       ncp, parent_inumber, inumber);
 		rc = search_directory(ncp, f, &inumber);
 		*cp = c;
 		if (rc)


More information about the p4-projects mailing list