/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- check
- writesuper
- writerootdir
- doallocbit
- writebitmap
- main
1 /*
2 * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
3 * The President and Fellows of Harvard College.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 #include <sys/types.h>
31 #include <stdint.h>
32 #include <string.h>
33 #include <assert.h>
34 #include <limits.h>
35 #include <err.h>
36
37 #include "support.h"
38 #include "kern/sfs.h"
39
40
41 #ifdef HOST
42
43 #include <netinet/in.h> // for arpa/inet.h
44 #include <arpa/inet.h> // for ntohl
45 #include "hostcompat.h"
46 #define SWAPL(x) ntohl(x)
47 #define SWAPS(x) ntohs(x)
48
49 #else
50
51 #define SWAPL(x) (x)
52 #define SWAPS(x) (x)
53
54 #endif
55
56 #include "disk.h"
57
58 #define MAXBITBLOCKS 32
59
60 static
61 void
62 check(void)
63 {
64 assert(sizeof(struct sfs_super)==SFS_BLOCKSIZE);
65 assert(sizeof(struct sfs_inode)==SFS_BLOCKSIZE);
66 assert(SFS_BLOCKSIZE % sizeof(struct sfs_dir) == 0);
67 }
68
69 static
70 void
71 writesuper(const char *volname, uint32_t nblocks)
72 {
73 struct sfs_super sp;
74
75 bzero((void *)&sp, sizeof(sp));
76
77 if (strlen(volname) >= SFS_VOLNAME_SIZE) {
78 errx(1, "Volume name %s too long", volname);
79 }
80
81 sp.sp_magic = SWAPL(SFS_MAGIC);
82 sp.sp_nblocks = SWAPL(nblocks);
83 strcpy(sp.sp_volname, volname);
84
85 diskwrite(&sp, SFS_SB_LOCATION);
86 }
87
88 static
89 void
90 writerootdir(void)
91 {
92 struct sfs_inode sfi;
93
94 bzero((void *)&sfi, sizeof(sfi));
95
96 sfi.sfi_size = SWAPL(0);
97 sfi.sfi_type = SWAPS(SFS_TYPE_DIR);
98 sfi.sfi_linkcount = SWAPS(1);
99
100 diskwrite(&sfi, SFS_ROOT_LOCATION);
101 }
102
103 static char bitbuf[MAXBITBLOCKS*SFS_BLOCKSIZE];
104
105 static
106 void
107 doallocbit(uint32_t bit)
108 {
109 uint32_t byte = bit/CHAR_BIT;
110 unsigned char mask = (1<<(bit % CHAR_BIT));
111
112 assert((bitbuf[byte] & mask) == 0);
113 bitbuf[byte] |= mask;
114 }
115
116 static
117 void
118 writebitmap(uint32_t fsblocks)
119 {
120
121 uint32_t nbits = SFS_BITMAPSIZE(fsblocks);
122 uint32_t nblocks = SFS_BITBLOCKS(fsblocks);
123 char *ptr;
124 uint32_t i;
125
126 if (nblocks > MAXBITBLOCKS) {
127 errx(1, "Filesystem too large "
128 "- increase MAXBITBLOCKS and recompile");
129 }
130
131 doallocbit(SFS_SB_LOCATION);
132 doallocbit(SFS_ROOT_LOCATION);
133 for (i=0; i<nblocks; i++) {
134 doallocbit(SFS_MAP_LOCATION+i);
135 }
136 for (i=fsblocks; i<nbits; i++) {
137 doallocbit(i);
138 }
139
140 for (i=0; i<nblocks; i++) {
141 ptr = bitbuf + i*SFS_BLOCKSIZE;
142 diskwrite(ptr, SFS_MAP_LOCATION+i);
143 }
144 }
145
146 int
147 main(int argc, char **argv)
148 {
149 uint32_t size, blocksize;
150 char *volname, *s;
151
152 #ifdef HOST
153 hostcompat_init(argc, argv);
154 #endif
155
156 if (argc!=3) {
157 errx(1, "Usage: mksfs device/diskfile volume-name");
158 }
159
160 check();
161
162 volname = argv[2];
163
164 /* Remove one trailing colon from volname, if present */
165 s = strchr(volname, ':');
166 if (s != NULL) {
167 if (strlen(s)!=1) {
168 errx(1, "Illegal volume name %s", volname);
169 }
170 *s = 0;
171 }
172
173 /* Don't allow slashes */
174 s = strchr(volname, '/');
175 if (s != NULL) {
176 errx(1, "Illegal volume name %s", volname);
177 }
178
179 opendisk(argv[1]);
180 blocksize = diskblocksize();
181
182 if (blocksize!=SFS_BLOCKSIZE) {
183 errx(1, "Device has wrong blocksize %u (should be %u)\n",
184 blocksize, SFS_BLOCKSIZE);
185 }
186 size = diskblocks();
187
188 writesuper(volname, size);
189 writerootdir();
190 writebitmap(size);
191
192 closedisk();
193
194 return 0;
195 }