Blob


1 #include <sys/stat.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <fcntl.h>
7 #include <err.h>
8 #include "sufs.h"
10 void xwrite (int fd, const char *buf, size_t num)
11 {
12 if (write (fd, buf, num) < 0)
13 err (1, "write()");
14 }
16 void xlseek (int fd, off_t pos)
17 {
18 if (lseek (fd, pos, SEEK_SET) < 0)
19 err (1, "lseek()");
20 }
22 int main (int argc, char *argv[])
23 {
24 struct sufs_superblock sb;
25 struct sufs_inode in;
26 struct sufs_dirent *ent;
27 struct stat st;
28 uint64_t size, nib, nino, ndata;
29 uint32_t bs = -1, nibms, ndbms, offset = SUFS_BOOTSIZE;
30 int64_t now;
31 char *endp, *buf;
32 int fd, option;
34 while ((option = getopt (argc, argv, "b:n")) != -1) {
35 switch (option) {
36 case 'b':
37 bs = (uint32_t)strtoul (optarg, &endp, 10);
38 if (*endp != '\0')
39 errx (1, "invalid block size");
40 if (bs < 128)
41 errx (1, "block size less than 128 is not supported");
42 break;
43 case 'n':
44 offset = 0;
45 break;
46 default:
47 return 1;
48 }
49 }
51 argc -= optind;
52 argv += optind;
54 if (argc != 1) {
55 fputs ("Usage: newfs_sufs file\n", stderr);
56 return 1;
57 }
59 fd = open (argv[0], O_WRONLY);
60 if (fd < 0)
61 err (1, "open()");
63 if (fstat (fd, &st) < 0)
64 err (1, "stat()");
66 if (bs == -1)
67 bs = st.st_blksize;
69 // Skip bootblocks
70 xlseek (fd, offset);
72 // total number of blocks
73 size = st.st_size / bs;
75 size -= offset / bs;
77 // number of inode blocks
78 nib = size / 1024;
80 if ((nib * bs / sizeof (struct sufs_inode)) < 64)
81 nib = 64 * sizeof (struct sufs_inode) / bs;
83 if (nib == 0)
84 nib = 1;
86 // number of inodes
87 nino = nib * bs / sizeof (struct sufs_inode);
89 // number of inode bitmap blocks
90 nibms = (nino + 8 * bs - 1) / (8 * bs);
92 // number of data blocks
93 ndata = size - nib - nibms - (offset / bs) - 1;
94 if (ndata > size)
95 errx (1, "overflow");
97 // number of data bitmap blocks
98 ndbms = (ndata + 8 * bs - 1) / (8 * bs);
100 // adjust for number of data bitmap blocks
101 ndata -= ndbms;
103 memset (&sb, 0, sizeof (sb));
104 sb.magic = SUFS_MAGIC;
105 sb.bsize = bs;
106 sb.nino = nino;
107 sb.ndata = ndata;
108 sb.clean = 1;
109 sb.ibmoff = offset / bs + 1;
110 sb.dbmoff = sb.ibmoff + nibms;
111 sb.ioff = sb.dbmoff + ndbms;
112 sb.doff = sb.ioff + nib;
113 buf = calloc (1, bs);
114 memcpy (buf, &sb, sizeof (sb));
115 xwrite (fd, buf, bs);
117 printf ("size = %zu\n", (size_t)size);
118 printf ("blksize = %zu\n", (size_t)bs);
119 printf ("nib = %zu\n", (size_t)nib);
120 printf ("nino = %zu\n", (size_t)nino);
121 printf ("nibms = %zu\n", (size_t)nibms);
122 printf ("ndbms = %zu\n", (size_t)ndbms);
123 printf ("ndata = %zu\n", (size_t)ndata);
124 printf ("ibmoff = %zu\n", (size_t)sb.ibmoff);
125 printf ("dbmoff = %zu\n", (size_t)sb.dbmoff);
126 printf ("ioff = %zu\n", (size_t)sb.ioff);
127 printf ("doff = %zu\n", (size_t)sb.doff);
129 // clear inode bitmap
130 xlseek (fd, sb.ibmoff * bs);
131 memset (buf, 0xff, bs);
132 buf[0] = 0xfc;
133 xwrite (fd, buf, bs);
134 buf[0] = 0xff;
135 for (uint32_t i = 1; i < nibms; ++i)
136 xwrite (fd, buf, bs);
138 // clear data bitmap
139 xlseek (fd, sb.dbmoff * bs);
140 buf[0] = 0xfe;
141 xwrite (fd, buf, bs);
142 buf[0] = 0xff;
143 for (uint32_t i = 1; i < ndbms; ++i)
144 xwrite (fd, buf, bs);
146 // initialize root directory
147 memset (buf, 0, bs);
148 ent = (struct sufs_dirent *)buf;
149 ent->ino = SUFS_INO_ROOT;
150 ent->len = 1;
151 ent->size = 16;
152 ent->name[0] = '.';
153 ent = (struct sufs_dirent *)(buf + 16);
154 ent->ino = SUFS_INO_ROOT;
155 ent->len = 2;
156 ent->size = bs - 16;
157 ent->name[0] = '.';
158 ent->name[1] = '.';
159 xlseek (fd, sb.doff * bs);
160 xwrite (fd, buf, bs);
162 // initialize inode 0 & 1
163 now = (int64_t)time (NULL);
164 memset (&in, 0, sizeof (in));
165 in.mode = S_IFDIR | 0755;
166 in.spare = 0;
167 in.uid = 0;
168 in.gid = 0;
169 in.nlink = 3;
170 in.size = 0;
171 in.blocks = 1;
172 in.atime = now;
173 in.mtime = now;
174 in.ctime = now;
175 in.direct[0] = sb.doff;
176 memset (buf, 0, bs);
177 memcpy (buf + sizeof (in), &in, sizeof (in));
178 xlseek (fd, sb.ioff * bs);
179 xwrite (fd, buf, bs);
181 close (fd);
182 return 0;