Blame


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