00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <sys/types.h>
00031 #include <stdint.h>
00032 #include <string.h>
00033 #include <assert.h>
00034 #include <limits.h>
00035 #include <err.h>
00036
00037 #include "support.h"
00038 #include "kern/sfs.h"
00039
00040
00041 #ifdef HOST
00042
00043 #include <netinet/in.h>
00044 #include <arpa/inet.h>
00045 #include "hostcompat.h"
00046 #define SWAPL(x) ntohl(x)
00047 #define SWAPS(x) ntohs(x)
00048
00049 #else
00050
00051 #define SWAPL(x) (x)
00052 #define SWAPS(x) (x)
00053
00054 #endif
00055
00056 #include "disk.h"
00057
00058 #define MAXBITBLOCKS 32
00059
00060 static
00061 void
00062 check(void)
00063 {
00064 assert(sizeof(struct sfs_super)==SFS_BLOCKSIZE);
00065 assert(sizeof(struct sfs_inode)==SFS_BLOCKSIZE);
00066 assert(SFS_BLOCKSIZE % sizeof(struct sfs_dir) == 0);
00067 }
00068
00069 static
00070 void
00071 writesuper(const char *volname, uint32_t nblocks)
00072 {
00073 struct sfs_super sp;
00074
00075 bzero((void *)&sp, sizeof(sp));
00076
00077 if (strlen(volname) >= SFS_VOLNAME_SIZE) {
00078 errx(1, "Volume name %s too long", volname);
00079 }
00080
00081 sp.sp_magic = SWAPL(SFS_MAGIC);
00082 sp.sp_nblocks = SWAPL(nblocks);
00083 strcpy(sp.sp_volname, volname);
00084
00085 diskwrite(&sp, SFS_SB_LOCATION);
00086 }
00087
00088 static
00089 void
00090 writerootdir(void)
00091 {
00092 struct sfs_inode sfi;
00093
00094 bzero((void *)&sfi, sizeof(sfi));
00095
00096 sfi.sfi_size = SWAPL(0);
00097 sfi.sfi_type = SWAPS(SFS_TYPE_DIR);
00098 sfi.sfi_linkcount = SWAPS(1);
00099
00100 diskwrite(&sfi, SFS_ROOT_LOCATION);
00101 }
00102
00103 static char bitbuf[MAXBITBLOCKS*SFS_BLOCKSIZE];
00104
00105 static
00106 void
00107 doallocbit(uint32_t bit)
00108 {
00109 uint32_t byte = bit/CHAR_BIT;
00110 unsigned char mask = (1<<(bit % CHAR_BIT));
00111
00112 assert((bitbuf[byte] & mask) == 0);
00113 bitbuf[byte] |= mask;
00114 }
00115
00116 static
00117 void
00118 writebitmap(uint32_t fsblocks)
00119 {
00120
00121 uint32_t nbits = SFS_BITMAPSIZE(fsblocks);
00122 uint32_t nblocks = SFS_BITBLOCKS(fsblocks);
00123 char *ptr;
00124 uint32_t i;
00125
00126 if (nblocks > MAXBITBLOCKS) {
00127 errx(1, "Filesystem too large "
00128 "- increase MAXBITBLOCKS and recompile");
00129 }
00130
00131 doallocbit(SFS_SB_LOCATION);
00132 doallocbit(SFS_ROOT_LOCATION);
00133 for (i=0; i<nblocks; i++) {
00134 doallocbit(SFS_MAP_LOCATION+i);
00135 }
00136 for (i=fsblocks; i<nbits; i++) {
00137 doallocbit(i);
00138 }
00139
00140 for (i=0; i<nblocks; i++) {
00141 ptr = bitbuf + i*SFS_BLOCKSIZE;
00142 diskwrite(ptr, SFS_MAP_LOCATION+i);
00143 }
00144 }
00145
00146 int
00147 main(int argc, char **argv)
00148 {
00149 uint32_t size, blocksize;
00150 char *volname, *s;
00151
00152 #ifdef HOST
00153 hostcompat_init(argc, argv);
00154 #endif
00155
00156 if (argc!=3) {
00157 errx(1, "Usage: mksfs device/diskfile volume-name");
00158 }
00159
00160 check();
00161
00162 volname = argv[2];
00163
00164
00165 s = strchr(volname, ':');
00166 if (s != NULL) {
00167 if (strlen(s)!=1) {
00168 errx(1, "Illegal volume name %s", volname);
00169 }
00170 *s = 0;
00171 }
00172
00173
00174 s = strchr(volname, '/');
00175 if (s != NULL) {
00176 errx(1, "Illegal volume name %s", volname);
00177 }
00178
00179 opendisk(argv[1]);
00180 blocksize = diskblocksize();
00181
00182 if (blocksize!=SFS_BLOCKSIZE) {
00183 errx(1, "Device has wrong blocksize %u (should be %u)\n",
00184 blocksize, SFS_BLOCKSIZE);
00185 }
00186 size = diskblocks();
00187
00188 writesuper(volname, size);
00189 writerootdir();
00190 writebitmap(size);
00191
00192 closedisk();
00193
00194 return 0;
00195 }