tech-userlevel archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: RT-11 filesystem support for makefs
In article <20130425194342.GA1210%mononoke.nyo@localhost>,
Sergey Svishchev <svs%ropnet.ru@localhost> wrote:
Looks good to me. There are some lines that are > 80 chars and a couple
of indentation issues from a 2 second glance. Also what does "All rights
reserved" mean in the copyright.
christos
>-=-=-=-=-=-
>-=-=-=-=-=-
>
>Hello,
>
>I added DEC RT-11 filesystem support to makefs, working from manuals on
>bitsavers.org [1][2], sources of PUTR [3] and arff [4], and advice from
>those who actually used the PDP-11; the images are accepted by RT-11 5.3
>in SIMH. It's still work in progress, please review it.
>
>I did not find documentation for certain features (the INIT/RESTORE data
>area, bad block relocation table, how to write boot blocks...).
>
>Number of directory segments is chosen automatically, depending on the
>size of filesystem, and is also settable via option. I'm not sure that
>'extra words in directory entry' feature is useful, so it's not there.
>Filesystem is not autosized yet, '-s' option is required.
>
>Volume and Owner IDs are fixed (makefs doesn't support string options).
>Timestamps can be written with or without 'age' field, and if a date
>cannot be represented in RT-11 format, it is written as zero ('no
>date').
>
>[1] AA-PD6PA-TC_RT-11_Volume_and_File_Formats_Manual_Aug91.pdf
>[2] AA-PE7VA-TC_RT-11_Device_Handlers_Manual_Aug91.pdf
>[3] http://www.dbit.com/pub/putr/putr.asm
>[4] ftp://ftp.mrynet.com/pub/os/UNIX/4.2BSD/etc/arff.c
>
>--
>Sergey Svishchev
>
>-=-=-=-=-=-
>
>diff --exclude .git -ruN makefs/Makefile makefs1/Makefile
>--- makefs/Makefile 2011-07-19 02:52:37.000000000 +0400
>+++ makefs1/Makefile 2013-04-20 19:10:45.000000000 +0400
>@@ -6,7 +6,7 @@
> .include <bsd.own.mk>
>
> PROG= makefs
>-SRCS= cd9660.c ffs.c v7fs.c \
>+SRCS= cd9660.c ffs.c rt11fs.c v7fs.c \
> getid.c \
> makefs.c misc.c \
> pack_dev.c \
>@@ -22,6 +22,7 @@
>
> .include "${.CURDIR}/cd9660/Makefile.inc"
> .include "${.CURDIR}/ffs/Makefile.inc"
>+.include "${.CURDIR}/rt11fs/Makefile.inc"
> .include "${.CURDIR}/v7fs/Makefile.inc"
>
> .if !defined(HOSTPROG)
>diff --exclude .git -ruN makefs/makefs.8 makefs1/makefs.8
>--- makefs/makefs.8 2012-01-28 06:35:46.000000000 +0400
>+++ makefs1/makefs.8 2013-04-20 17:27:49.000000000 +0400
>@@ -201,6 +201,8 @@
> ISO 9660 file system.
> .It Sy v7fs
> 7th Edition(V7) file system.
>+.It Sy rt11fs
>+RT-11 file system.
> .El
> .It Fl x
> Exclude file system nodes not explicitly listed in the specfile.
>diff --exclude .git -ruN makefs/makefs.c makefs1/makefs.c
>--- makefs/makefs.c 2012-01-28 06:35:46.000000000 +0400
>+++ makefs1/makefs.c 2013-04-15 21:56:20.000000000 +0400
>@@ -73,6 +73,8 @@
> { "ffs", ffs_prep_opts, ffs_parse_opts, ffs_cleanup_opts, ffs_makefs },
> { "cd9660", cd9660_prep_opts, cd9660_parse_opts, cd9660_cleanup_opts,
> cd9660_makefs},
>+ { "rt11fs", rt11fs_prep_opts, rt11fs_parse_opts, rt11fs_cleanup_opts,
>+ rt11fs_makefs },
> { "v7fs", v7fs_prep_opts, v7fs_parse_opts, v7fs_cleanup_opts,
> v7fs_makefs },
> { .type = NULL },
>diff --exclude .git -ruN makefs/makefs.h makefs1/makefs.h
>--- makefs/makefs.h 2012-01-28 06:35:46.000000000 +0400
>+++ makefs1/makefs.h 2013-04-15 20:58:17.000000000 +0400
>@@ -172,6 +172,11 @@
> void cd9660_cleanup_opts(fsinfo_t *);
> void cd9660_makefs(const char *, const char *, fsnode *, fsinfo_t *);
>
>+void rt11fs_prep_opts(fsinfo_t *);
>+int rt11fs_parse_opts(const char *, fsinfo_t *);
>+void rt11fs_cleanup_opts(fsinfo_t *);
>+void rt11fs_makefs(const char *, const char *, fsnode *, fsinfo_t *);
>+
> void v7fs_prep_opts(fsinfo_t *);
> int v7fs_parse_opts(const char *, fsinfo_t *);
> void v7fs_cleanup_opts(fsinfo_t *);
>diff --exclude .git -ruN makefs/rt11fs/Makefile.inc makefs1/rt11fs/Makefile.inc
>--- makefs/rt11fs/Makefile.inc 1970-01-01 03:00:00.000000000 +0300
>+++ makefs1/rt11fs/Makefile.inc 2013-04-19 00:51:15.000000000 +0400
>@@ -0,0 +1,7 @@
>+.PATH: ${.CURDIR}/rt11fs
>+
>+SRCS+= rt11fs_rad50.c
>+.if !defined(HOSTPROG)
>+LDADD+= -lz
>+DPADD+= ${LIBZ}
>+.endif
>diff --exclude .git -ruN makefs/rt11fs/rt11fs_rad50.c
>makefs1/rt11fs/rt11fs_rad50.c
>--- makefs/rt11fs/rt11fs_rad50.c 1970-01-01 03:00:00.000000000 +0300
>+++ makefs1/rt11fs/rt11fs_rad50.c 2013-04-20 17:57:35.000000000 +0400
>@@ -0,0 +1,101 @@
>+/*-
>+ * All rights reserved.
>+ */
>+
>+#if HAVE_NBTOOL_CONFIG_H
>+#include "nbtool_config.h"
>+#endif
>+
>+#include <sys/param.h>
>+#include <sys/stat.h>
>+
>+#include <assert.h>
>+#include <fcntl.h>
>+#include <stdio.h>
>+#include <stdlib.h>
>+#include <string.h>
>+#include <zlib.h>
>+
>+#include "makefs.h"
>+#include "rt11fs_makefs.h"
>+#include "rt11fs/rt11fs_rad50.h"
>+
>+/* taken from 4.2BSD's arff.c */
>+
>+static char table[256] = {
>+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
>+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
>+ 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
>+30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
>+29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
>+16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
>+29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
>+16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
>+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
>+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
>+ 0, 29, 29, 29, 27, 29, 29, 29, 29, 29, 29, 29, 29, 29, 28, 29,
>+30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 29, 29, 29, 29, 29, 29,
>+29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
>+16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29, 29,
>+29, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
>+16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 29, 29, 29, 29 };
>+
>+#define Ain1 03100
>+#define Ain2 050
>+
>+void
>+rad50 (const char *cp, uint16_t *out)
>+{
>+ int m;
>+ uint16_t temp;
>+
>+ for (m = 0; *cp; m++) {
>+ temp = Ain1 * table[(int)*cp++];
>+ if (*cp!=0) {
>+ temp += Ain2 * table[(int)*cp++];
>+ if(*cp!=0)
>+ temp += table[(int)*cp++];
>+ }
>+ out[m] = htole16(temp);
>+ }
>+}
>+
>+void
>+srad50 (char *name, uint16_t *rname)
>+{
>+ int m;
>+ char *cp;
>+ char file[7], ext[4];
>+
>+ /*
>+ * Find end of pathname
>+ */
>+ for (cp = name; *cp++; )
>+ ;
>+ while (cp >= name && *--cp != '/')
>+ ;
>+ cp++;
>+ /*
>+ * Change to rad50
>+ */
>+ for (m = 0; *cp; ) {
>+ file[m++] = *cp++;
>+ if (*cp == '.') {
>+ cp++;
>+ break;
>+ }
>+ if (m > 5) {
>+ break;
>+ }
>+ }
>+ file[m] = 0;
>+ for (m = 0; *cp; ) {
>+ ext[m++] = *cp++;
>+ if (*cp == '.' || m > 2)
>+ break;
>+ }
>+ ext[m]=0;
>+ rname[0] = rname[1] = rname[2] = 0;
>+ rad50((const char *)file, rname);
>+ rad50((const char *)ext, rname+2);
>+}
>diff --exclude .git -ruN makefs/rt11fs/rt11fs_rad50.h
>makefs1/rt11fs/rt11fs_rad50.h
>--- makefs/rt11fs/rt11fs_rad50.h 1970-01-01 03:00:00.000000000 +0300
>+++ makefs1/rt11fs/rt11fs_rad50.h 2013-04-20 17:57:35.000000000 +0400
>@@ -0,0 +1,13 @@
>+/*-
>+ * All rights reserved.
>+ */
>+
>+#ifndef _RT11FS_RAD50_H
>+#define _RT11FS_RAD50_H
>+
>+#include <sys/endian.h>
>+
>+void rad50 (const char *, uint16_t *);
>+void srad50 (char *, uint16_t *);
>+
>+#endif
>diff --exclude .git -ruN makefs/rt11fs.c makefs1/rt11fs.c
>--- makefs/rt11fs.c 1970-01-01 03:00:00.000000000 +0300
>+++ makefs1/rt11fs.c 2013-04-25 23:33:28.000000000 +0400
>@@ -0,0 +1,404 @@
>+/*-
>+ * All rights reserved.
>+ */
>+
>+#if HAVE_NBTOOL_CONFIG_H
>+#include "nbtool_config.h"
>+#endif
>+
>+#include <sys/endian.h>
>+#include <sys/param.h>
>+
>+#include <assert.h>
>+#include <errno.h>
>+#include <fcntl.h>
>+#include <string.h>
>+#include <time.h>
>+#include <unistd.h>
>+#include <util.h>
>+#include <stdio.h>
>+#include <stdlib.h>
>+
>+#include "makefs.h"
>+#include "rt11fs_makefs.h"
>+#include "rt11fs/rt11fs_rad50.h"
>+
>+static int rt11fs_create_image(const char *, fsinfo_t *);
>+static int rt11fs_estimate(const char *, fsnode *, fsinfo_t *);
>+static int rt11fs_populate(const char *, fsnode *, fsinfo_t *);
>+void rt11fs_name(char *, uint16_t *, int *);
>+void rt11fs_date(time_t, uint16_t *, int *);
>+
>+rt11fs_opt_t rt11fs_opts;
>+static struct rt_dir rt11fs_dir[RT_DIRSEGS];
>+static struct rt_home rt11fs_home;
>+
>+void
>+rt11fs_name(char *name, uint16_t * rtnamep, int *errp)
>+{
>+ srad50(name, rtnamep);
>+ *errp = 0;
>+}
>+
>+void
>+rt11fs_date(time_t mtime, uint16_t * rtdatp, int *errp)
>+{
>+ struct tm *rtp;
>+
>+ *errp = 0;
>+
>+ rtp = localtime(&mtime);
>+ if (!rtp) {
>+ *errp = errno;
>+ return;
>+ }
>+ if (rtp->tm_year < 72) {
>+ *rtdatp = 0;
>+ return;
>+ }
>+ if (rtp->tm_year > (rt11fs_opts.y2k_date ? 199 : 103)) {
>+ *rtdatp = 0;
>+ return;
>+ }
>+
>+ *rtdatp = (rtp->tm_year - 72) % 32;
>+ *rtdatp |= rtp->tm_mday << 5;
>+ *rtdatp |= (rtp->tm_mon + 1) << 10;
>+ *rtdatp |= ((rtp->tm_year - 72) / 32) << 14;
>+ /*
>+ 15-14 :2 Age (0-3)
>+ 13-10 :4 Month (1-12)
>+ 9-5 :5 Day (1-31)
>+ 4-0 :5 Year minus 1972 minus 32*Age
>+ */
>+}
>+
>+void
>+rt11fs_prep_opts(fsinfo_t * fsopts)
>+{
>+
>+ fsopts->fs_specific = &rt11fs_opts;
>+}
>+
>+void
>+rt11fs_cleanup_opts(fsinfo_t * fsopts)
>+{
>+ /* NO-OP */
>+}
>+
>+int
>+rt11fs_parse_opts(const char *option, fsinfo_t * fsopts)
>+{
>+ static option_t rt11fs_options[] = {
>+ {"sys_version", &rt11fs_opts.sys_version, 3, 5,
>+ "Home block version"},
>+ {"dir_segments", &rt11fs_opts.dir_segments, 1, 31,
>+ "Number of directory segments"},
>+ {"y2k_date", &rt11fs_opts.y2k_date, 0, 1,
>+ "Y2K-aware date format"},
>+ {.name = NULL}
>+ };
>+
>+ set_option(rt11fs_options, option, "1");
>+
>+ return 1;
>+}
>+
>+static int
>+rt11fs_create_image(const char *image, fsinfo_t * fsopts)
>+{
>+ uint16_t *p, sum;
>+ int m;
>+ char tmp[13];
>+
>+ assert(image != NULL);
>+ assert(fsopts != NULL);
>+
>+ rt11fs_home.rt_clsize = htole16(1);
>+ rt11fs_home.rt_dirblk = htole16(RT_DIRBLK);
>+ rad50("V3A", &rt11fs_home.rt_sysver); /* V05 and V4A also exist */
>+ snprintf(tmp, 13, "%-12s", "RT11A");
>+ memcpy(rt11fs_home.rt_volid, tmp, 12);
>+ snprintf(tmp, 13, "%-12s", "DECRT11A");
>+ memcpy(rt11fs_home.rt_sysid, tmp, 12);
>+ snprintf(tmp, 13, "%-12s", "makefs(8)");
>+ memcpy(rt11fs_home.rt_owner, tmp, 12);
>+
>+ sum = 0;
>+ p = (uint16_t *) (void *) &rt11fs_home;
>+ for (m = 0; m < 255; m++)
>+ sum += le16toh(*p++);
>+
>+ rt11fs_home.rt_cksum = htole16(sum);
>+
>+ if ((fsopts->fd = open(image, O_RDWR | O_CREAT | O_TRUNC, 0666)) == -1)
>{
>+ warn("Can't open `%s' for writing", image);
>+ return -1;
>+ }
>+ if (lseek(fsopts->fd, fsopts->maxsize - 1, SEEK_SET) == -1) {
>+ warn("Can't seek `%s' to %lld", image, fsopts->size - 1);
>+ return -1;
>+ }
>+ if (write(fsopts->fd, "\0", 1) != 1) {
>+ warn("Can't write `%s'", image);
>+ return -1;
>+ }
>+ if (lseek(fsopts->fd, RT_SECSIZE, SEEK_SET) == -1) {
>+ warn("Can't seek `%s' to home block", image);
>+ return -1;
>+ }
>+ if (write(fsopts->fd, (void *) &rt11fs_home, RT_SECSIZE) != RT_SECSIZE)
>{
>+ warn("Can't write home block to `%s'", image);
>+ return -1;
>+ }
>+ return fsopts->fd;
>+}
>+
>+static int
>+rt11fs_estimate(const char *dir, fsnode * root, fsinfo_t * fsopts)
>+{
>+ fsnode *cur;
>+ int failed;
>+ off_t size;
>+
>+ assert(dir != NULL);
>+ assert(root != NULL);
>+ assert(fsopts != NULL);
>+
>+ failed = 0;
>+
>+ if (fsopts->maxsize > RT_MAXSIZE) {
>+ errx(EXIT_FAILURE, "maxsize of %lld is greater than maximum
>supported
>of 32M.",
>+ fsopts->maxsize);
>+ }
>+
>+/* from PUTR.ASM:
>+rtnseg dw 512d ;Up to 512 blocks
>+ dw 1 ;we get 1 segment.
>+ dw 2048d ;Up to 2048 blocks
>+ dw 4 ;we get 4 segments.
>+ dw 12288d ;Up to 12288 blocks
>+ dw 16d ;we get 16 segments.
>+ dw -1 ;Over that
>+ dw 31d ;we get 31 segments (max allowed).
>+*/
>+ if (rt11fs_opts.dir_segments == 0) {
>+ if (fsopts->maxsize <= 512 * RT_SECSIZE)
>+ rt11fs_opts.dir_segments = 1;
>+ else if (fsopts->maxsize <= 2048 * RT_SECSIZE)
>+ rt11fs_opts.dir_segments = 4;
>+ else if (fsopts->maxsize <= 12288 * RT_SECSIZE)
>+ rt11fs_opts.dir_segments = 16;
>+ else
>+ rt11fs_opts.dir_segments = 31;
>+ };
>+ fsopts->size = RT_SECSIZE * (6 + 2 * rt11fs_opts.dir_segments);
>+
>+ for (cur = root; cur != NULL; cur = cur->next) {
>+ switch (cur->type & S_IFMT) {
>+ case S_IFREG:
>+ size = (cur->inode->st.st_size + 511) & ~511;
>+ fsopts->size += size;
>+ fsopts->inodes++;
>+ break;
>+ default:
>+ break;
>+ }
>+ }
>+
>+ /* leave 1 entry for EMPTY.FIL */
>+ if (fsopts->inodes > (rt11fs_opts.dir_segments * RT_DIRENTS - 1)) {
>+ errx(EXIT_FAILURE, "`%s' inode count of %lld is larger than the
>maximum of %d.",
>+ dir, fsopts->inodes, rt11fs_opts.dir_segments * RT_DIRENTS);
>+ }
>+ if (fsopts->maxsize > 0 && fsopts->size > fsopts->maxsize) {
>+ errx(EXIT_FAILURE, "`%s' size of %lld is larger than the
>maxsize of %lld.",
>+ dir, fsopts->size, fsopts->maxsize);
>+ }
>+ return failed ? 2 : 0;
>+}
>+
>+/*
>+- open 1st directory segment (populate word 4)
>+- for each file:
>+ - fill directory entry (status word = E.PERM)
>+ - write file data to image
>+ - find next directory entry in this segment
>+ - if none available, close this segment (populate word 1 and write
>+ E.EOS into last word, if available) and open a new segment
>+- close last and 1st (populate words 0 and 2) directory segments
>+- write directory to disk
>+*/
>+static int
>+rt11fs_populate(const char *dir, fsnode * root, fsinfo_t * fsopts)
>+{
>+ int error, failed, rt11fs_file, rt11fs_segment, fd, m, x;
>+ size_t blk_nr, blocks;
>+ char *name, empty_fil[10];
>+ uint8_t *buf;
>+ off_t blk_offset, bytes_read, bytes_written;
>+ fsnode *cur;
>+ struct rt_ent *entry;
>+
>+ assert(dir != NULL);
>+ assert(root != NULL);
>+ assert(fsopts != NULL);
>+
>+ error = failed = rt11fs_file = rt11fs_segment = m = x = 0;
>+ strncpy(empty_fil, "EMPTY.FIL", 10);
>+
>+ buf = emalloc(RT_BUFSIZE);
>+ name = emalloc(PATH_MAX);
>+
>+ blk_nr = RT_DIRBLK + rt11fs_opts.dir_segments * 2;
>+ if (debug & DEBUG_WALK_DIR)
>+ printf("rt11fs_populate_dir: data starts at block %d\n",
>blk_nr);
>+
>+ /* open 1st directory segment */
>+ rt11fs_dir[rt11fs_segment].rt_axhead.rt_numseg =
>rt11fs_opts.dir_segments;
>+ rt11fs_dir[rt11fs_segment].rt_axhead.rt_stfile = blk_nr;
>+
>+ for (cur = root; cur != NULL; cur = cur->next) {
>+ switch (cur->type & S_IFMT) {
>+ case S_IFREG:
>+ blocks = ((size_t) cur->inode->st.st_size + RT_SECSIZE
>- 1) / RT_SECSIZE;
>+ if (debug & DEBUG_WALK_DIR)
>+ printf("rt11fs_populate_dir: <%s> %lld bytes
>(%d blocks)\n",
>+ cur->name, cur->inode->st.st_size, blocks);
>+ entry =
>&rt11fs_dir[rt11fs_segment].rt_ents[rt11fs_file];
>+ entry->rt_stat = RT_E_PERM;
>+ if (!(cur->inode->st.st_mode & S_IWUSR))
>+ entry->rt_stat |= RT_E_READ;
>+ entry->rt_len = (uint16_t) blocks;
>+ rt11fs_name(cur->name, &entry->rt_name[0], &error);
>+ if (error)
>+ break;
>+ rt11fs_date(cur->inode->st.st_mtime, &entry->rt_date,
>&error);
>+ if (error)
>+ break;
>+
>+ /* ready to store the file */
>+ snprintf(name, PATH_MAX - 1, "%s/%s", dir, cur->name);
>+ fd = open(name, O_RDONLY, 0444);
>+ if (fd == -1) {
>+ warn("rt11fs_populate: open");
>+ break;
>+ }
>+ blk_offset = blk_nr * RT_SECSIZE;
>+ do {
>+ bytes_read = read(fd, buf, RT_BUFSIZE);
>+ if (bytes_read == -1) {
>+ warn("rt11fs_populate: read");
>+ break;
>+ }
>+ bytes_written = pwrite(fsopts->fd, buf,
>RT_BUFSIZE, blk_offset);
>+ if (bytes_written == -1) {
>+ warn("rt11fs_populate: write");
>+ break;
>+ }
>+ blk_offset += bytes_written;
>+ } while (bytes_read > 0);
>+ close(fd);
>+
>+ blk_nr += blocks;
>+ if (debug & DEBUG_WALK_DIR)
>+ printf("rt11fs_populate_dir: OK, seg %d (of %d)
>ent %d\n",
>+ rt11fs_segment,
>rt11fs_opts.dir_segments, rt11fs_file);
>+
>+ if (++rt11fs_file == RT_DIRENTS) {
>+ /* close this segment */
>+ rt11fs_dir[rt11fs_segment].rt_eos = RT_E_EOS;
>+ /* open next one, if available */
>+ if ((rt11fs_opts.dir_segments - rt11fs_segment)
>> 1) {
>+
>rt11fs_dir[rt11fs_segment].rt_axhead.rt_nxtseg = rt11fs_segment + 2;
>+ rt11fs_segment += 1;
>+
>rt11fs_dir[rt11fs_segment].rt_axhead.rt_stfile = blk_nr;
>+ rt11fs_file = 0;
>+ }
>+ }
>+ break;
>+ default:
>+ if ((debug & DEBUG_WALK_DIR) && strcmp(cur->name, "."))
>+ printf("rt11fs_populate_dir: can't handle file
><%s> of type %x\n",
>+ cur->name, cur->type & S_IFMT);
>+ break;
>+ }
>+ }
>+
>+ /* add E.MPTY entry, if there's space for it, and then close the
>segment */
>+ if (rt11fs_segment < rt11fs_opts.dir_segments) {
>+ rt11fs_dir[rt11fs_segment].rt_ents[rt11fs_file].rt_stat =
>RT_E_MPTY;
>+ /* name is irrelevant */
>+ rt11fs_name(empty_fil,
>&rt11fs_dir[rt11fs_segment].rt_ents[rt11fs_file].rt_name[0], &error);
>+ rt11fs_dir[rt11fs_segment].rt_ents[rt11fs_file].rt_len =
>(uint16_t)
>((fsopts->maxsize / RT_SECSIZE) - blk_nr);
>+ if (++rt11fs_file == RT_DIRENTS)
>+ rt11fs_dir[rt11fs_segment].rt_eos = RT_E_EOS;
>+ else
>+ rt11fs_dir[rt11fs_segment].rt_ents[rt11fs_file].rt_stat
>= RT_E_EOS;
>+ }
>+ /* close 1st segment (populate word 2), write directory */
>+ rt11fs_dir[0].rt_axhead.rt_lstseg = rt11fs_segment + 1;
>+
>+ /* byte-swap if necessary */
>+#if BYTE_ORDER == BIG_ENDIAN
>+ for (m = 0; m < rt11fs_opts.dir_segments; m++) {
>+ HTOLE16(rt11fs_dir[m].rt_axhead.rt_numseg);
>+ HTOLE16(rt11fs_dir[m].rt_axhead.rt_nxtseg);
>+ HTOLE16(rt11fs_dir[m].rt_axhead.rt_lstseg);
>+ HTOLE16(rt11fs_dir[m].rt_axhead.rt_entpad);
>+ HTOLE16(rt11fs_dir[m].rt_axhead.rt_stfile);
>+ HTOLE16(rt11fs_dir[m].rt_eos);
>+ for (x = 0; x < RT_DIRENTS; x++) {
>+ HTOLE16(rt11fs_dir[m].rt_ents[x].rt_stat);
>+ HTOLE16(rt11fs_dir[m].rt_ents[x].rt_len);
>+ HTOLE16(rt11fs_dir[m].rt_ents[x].rt_date);
>+ }
>+ }
>+#endif
>+
>+ blocks = rt11fs_opts.dir_segments * sizeof(struct rt_dir);
>+ if (pwrite(fsopts->fd, (void *) &rt11fs_dir, blocks, RT_SECSIZE *
>RT_DIRBLK) != blocks) {
>+ warn("Can't write directory (%d, %p, %d, %d)", fsopts->fd,
>(void *)
>&rt11fs_dir, blocks, RT_SECSIZE * RT_DIRBLK);
>+ failed = 1;
>+ }
>+ return failed ? 2 : 0;
>+}
>+
>+void
>+rt11fs_makefs(const char *image, const char *dir, fsnode * root,
>fsinfo_t * fsopts)
>+{
>+ struct timeval start;
>+
>+ assert(image != NULL);
>+ assert(dir != NULL);
>+ assert(root != NULL);
>+ assert(fsopts != NULL);
>+
>+ printf("Estimating `%s'\n", image);
>+ TIMER_START(start);
>+ if (rt11fs_estimate(dir, root, fsopts)) {
>+ warnx("Image file `%s' not estimated", image);
>+ }
>+ TIMER_RESULTS(start, "rt11fs_estimate");
>+
>+ printf("Creating `%s'\n", image);
>+ TIMER_START(start);
>+ if (rt11fs_create_image(image, fsopts) == -1) {
>+ errx(EXIT_FAILURE, "Image file `%s' not created", image);
>+ }
>+ TIMER_RESULTS(start, "rt11fs_create_image");
>+
>+ printf("Populating `%s'\n", image);
>+ TIMER_START(start);
>+ if (rt11fs_populate(dir, root, fsopts)) {
>+ errx(EXIT_FAILURE, "Image file `%s' not populated", image);
>+ }
>+ TIMER_RESULTS(start, "rt11fs_populate");
>+
>+ if (close(fsopts->fd) == -1) {
>+ err(EXIT_FAILURE, "Closing `%s'", image);
>+ }
>+ fsopts->fd = -1;
>+
>+ printf("Image `%s' complete\n", image);
>+}
>diff --exclude .git -ruN makefs/rt11fs_makefs.h makefs1/rt11fs_makefs.h
>--- makefs/rt11fs_makefs.h 1970-01-01 03:00:00.000000000 +0300
>+++ makefs1/rt11fs_makefs.h 2013-04-20 22:00:24.000000000 +0400
>@@ -0,0 +1,90 @@
>+/*-
>+ * All rights reserved.
>+ */
>+
>+#ifndef _RT11FS_MAKEFS_H
>+#define _RT11FS_MAKEFS_H
>+
>+typedef struct {
>+ int dir_segments;
>+ int sys_version;
>+ int y2k_date;
>+} rt11fs_opt_t;
>+
>+#define RT_BUFSIZE 16384
>+
>+#define RT_SECSIZE 512 /* block size */
>+#define RT_MAXSIZE 65536*RT_SECSIZE/* actually 65535 */
>+
>+#define RT_DIRBLK 6 /* directory's starting block */
>+#define RT_DIRSEGS 31 /* max # of directory segments */
>+#define RT_DIRENTS 72 /* # of directory entries per segment */
>+
>+extern rt11fs_opt_t rt11fs_opts;
>+
>+#define RT_E_TENT 000400 /* Tentative file */
>+#define RT_E_MPTY 001000 /* Empty area */
>+#define RT_E_PERM 002000 /* Permanent file */
>+#define RT_E_EOS 004000 /* End-of-segment marker */
>+#define RT_E_READ 040000 /* 5.6+: Protected by monitor from
>write operations */
>+#define RT_E_PROT 100000 /* Protected permanent file */
>+#define RT_E_PRE 000020 /* ?.?+: Prefix block indicator */
>+
>+struct rt_head {
>+ int16_t rt_numseg; /* # of segments available */
>+ int16_t rt_nxtseg; /* # of next logical segment */
>+ int16_t rt_lstseg; /* highest seg currently open */
>+ int16_t rt_entpad; /* extra words/directory entry */
>+ int16_t rt_stfile; /* block # where files begin */
>+} __packed;
>+
>+struct rt_ent {
>+ uint16_t rt_stat; /* type of entry, or end of seg */
>+ uint16_t rt_name[3]; /* name, 3 words in rad50 form */
>+ uint16_t rt_len; /* length of file */
>+ char rt_chan; /* only used in temporary files */
>+ char rt_job; /* only used in temporary files */
>+ uint16_t rt_date; /* creation date; w/ Y2K support as of
>5.7 */
>+} __packed;
>+
>+struct rt_dir {
>+ struct rt_head rt_axhead;
>+ struct rt_ent rt_ents[RT_DIRENTS];
>+ uint16_t rt_eos; /* end of segment */
>+ char _dirpad[4];
>+} __packed;
>+
>+/*
>+000-201 Bad block replacement table
>+202-203 ?
>+204-251 INITIALIZE/RESTORE data area
>+252-273 BUP information area
>+274-677 ?
>+700-701 (Reserved for Digital, must be zero)
>+702-703 (Reserved for Digital, must be zero)
>+704-721 ?
>+722-723 Pack cluster size (= 1)
>+724-725 Block number of first directory segment (= 6)
>+726-727 System version (RAD50 "V3A")
>+730-743 Volume Identification ("RT11A" and seven spaces)
>+744-757 Owner name
>+760-773 System Identification ("DECRT11A" and four spaces)
>+774-775 ?
>+776-777 Checksum (optional?)
>+
>+PDP-11 is little-endian in 16-bit words.
>+*/
>+struct rt_home {
>+ char rt_bbt[0202];
>+ char _pad1[0520];
>+ uint16_t rt_clsize;
>+ uint16_t rt_dirblk;
>+ uint16_t rt_sysver;
>+ char rt_volid[12];
>+ char rt_owner[12];
>+ char rt_sysid[12];
>+ char _pad2[2];
>+ uint16_t rt_cksum;
>+} __packed;
>+
>+#endif
>
>-=-=-=-=-=-
>-=-=-=-=-=-
>[Attachment type=application/pgp-signature, name=unknown]
>-=-=-=-=-=-
Home |
Main Index |
Thread Index |
Old Index