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