2 * mkfs.bfs - Create SCO BFS filesystem - aeb, 1999-09-07
4 * Usage: mkfs.bfs [-N nr-of-inodes] [-V volume-name] [-F fsname] device
11 #include <sys/types.h>
13 #include <sys/ioctl.h>
20 /* cannot include <linux/fs.h> */
22 #define BLKGETSIZE _IO(0x12,96) /* return device size */
25 #define BFS_ROOT_INO 2
26 #define BFS_NAMELEN 14
27 #define BFS_BLOCKSIZE 512
28 #define BFS_SUPER_MAGIC 0x1badface
30 /* superblock - 512 bytes */
33 unsigned int s_start
; /* byte offset of start of data */
34 unsigned int s_end
; /* sizeof(slice)-1 */
36 /* for recovery during compaction */
37 int s_from
, s_to
; /* src and dest block of current transfer */
38 int s_backup_from
, s_backup_to
;
40 /* labels - may well contain garbage */
46 /* inode - 64 bytes */
49 unsigned char i_pad1
[2];
50 unsigned long i_first_block
;
51 unsigned long i_last_block
;
52 unsigned long i_bytes_to_end
;
53 unsigned long i_type
; /* 1: file, 2: the unique dir */
55 unsigned long i_uid
, i_gid
;
56 unsigned long i_nlinks
;
57 unsigned long i_atime
, i_mtime
, i_ctime
;
58 unsigned char i_pad2
[16];
61 #define BFS_DIR_TYPE 2
63 /* directory entry - 16 bytes */
66 char d_name
[BFS_NAMELEN
];
70 static char *progname
;
78 fprintf(stderr
, "\n%s: ", progname
);
79 vfprintf(stderr
, s
, p
);
81 fprintf(stderr
, "\n");
88 "Usage: %s [-v] [-N nr-of-inodes] [-V volume-name]\n"
89 " [-F fsname] device [block-count]\n"),
95 main(int argc
, char *argv
[]) {
96 char *device
, *volume
, *fsname
;
98 unsigned long total_blocks
, ino_bytes
, ino_blocks
, data_blocks
;
99 unsigned long user_specified_total_blocks
= 0;
111 if ((p
= strrchr(progname
, '/')) != NULL
)
118 (!strcmp(argv
[1], "-V") || !strcmp(argv
[1], "--version"))) {
119 printf(_("%s from %s\n"), progname
, util_linux_version
);
123 volume
= fsname
= " "; /* is there a default? */
126 while (EOF
!= (c
= getopt(argc
, argv
, "vF:N:V:cl:"))) {
129 inodes
= atol(optarg
);
133 len
= strlen(optarg
);
134 if (len
<= 0 || len
> 6)
135 fatal(_("volume name too long"));
136 volume
= strdup(optarg
);
140 len
= strlen(optarg
);
141 if (len
<= 0 || len
> 6)
142 fatal(_("fsname name too long"));
143 fsname
= strdup(optarg
);
150 /* when called via mkfs we may get options c,l,v */
163 device
= argv
[optind
++];
165 if (stat(device
, &statbuf
) == -1) {
167 fatal(_("cannot stat device %s"), device
);
170 if (!S_ISBLK(statbuf
.st_mode
))
171 fatal(_("%s is not a block special device"), device
);
173 fd
= open(device
, O_RDWR
);
176 fatal(_("cannot open %s"), device
);
179 if (optind
== argc
-1)
180 user_specified_total_blocks
= atoi(argv
[optind
]);
181 else if (optind
!= argc
)
184 if (ioctl(fd
, BLKGETSIZE
, &total_blocks
) == -1) {
185 if (!user_specified_total_blocks
) {
186 perror("BLKGETSIZE");
187 fatal(_("cannot get size of %s"), device
);
189 total_blocks
= user_specified_total_blocks
;
190 } else if (user_specified_total_blocks
) {
191 if (user_specified_total_blocks
> total_blocks
)
192 fatal(_("blocks argument too large, max is %lu"),
194 total_blocks
= user_specified_total_blocks
;
198 /* pick some reasonable default */
199 inodes
= 8*(total_blocks
/800);
205 /* believe the user */
207 fatal(_("too many inodes - max is 512"));
210 ino_bytes
= inodes
* sizeof(struct bfsi
);
211 ino_blocks
= (ino_bytes
+ BFS_BLOCKSIZE
- 1) / BFS_BLOCKSIZE
;
212 data_blocks
= total_blocks
- ino_blocks
- 1;
214 /* mimic the behaviour of SCO's mkfs - maybe this limit is needed */
215 if (data_blocks
< 32)
216 fatal(_("not enough space, need at least %lu blocks"),
219 memset(&sb
, 0, sizeof(sb
));
220 sb
.s_magic
= BFS_SUPER_MAGIC
;
221 sb
.s_start
= ino_bytes
+ sizeof(struct bfssb
);
222 sb
.s_end
= total_blocks
* BFS_BLOCKSIZE
- 1;
223 sb
.s_from
= sb
.s_to
= sb
.s_backup_from
= sb
.s_backup_to
= -1;
224 memcpy(sb
.s_fsname
, fsname
, 6);
225 memcpy(sb
.s_volume
, volume
, 6);
228 fprintf(stderr
, _("Device: %s\n"), device
);
229 fprintf(stderr
, _("Volume: <%-6s>\n"), volume
);
230 fprintf(stderr
, _("FSname: <%-6s>\n"), fsname
);
231 fprintf(stderr
, _("BlockSize: %d\n"), BFS_BLOCKSIZE
);
233 fprintf(stderr
, _("Inodes: %d (in 1 block)\n"),
236 fprintf(stderr
, _("Inodes: %d (in %ld blocks)\n"),
238 fprintf(stderr
, _("Blocks: %ld\n"), total_blocks
);
239 fprintf(stderr
, _("Inode end: %d, Data end: %d\n"),
240 sb
.s_start
-1, sb
.s_end
);
243 if (write(fd
, &sb
, sizeof(sb
)) != sizeof(sb
))
244 fatal(_("error writing superblock"));
246 memset(&ri
, 0, sizeof(ri
));
247 ri
.i_ino
= BFS_ROOT_INO
;
248 ri
.i_first_block
= 1 + ino_blocks
;
249 ri
.i_last_block
= ri
.i_first_block
+
250 (inodes
* sizeof(de
) - 1) / BFS_BLOCKSIZE
;
251 ri
.i_bytes_to_end
= ri
.i_first_block
* BFS_BLOCKSIZE
252 + 2 * sizeof(struct bfsde
) - 1;
253 ri
.i_type
= BFS_DIR_TYPE
;
254 ri
.i_mode
= S_IFDIR
| 0755; /* or just 0755 */
256 ri
.i_gid
= 1; /* random */
263 if (write(fd
, &ri
, sizeof(ri
)) != sizeof(ri
))
264 fatal(_("error writing root inode"));
266 memset(&ri
, 0, sizeof(ri
));
267 for (i
=1; i
<inodes
; i
++)
268 if (write(fd
, &ri
, sizeof(ri
)) != sizeof(ri
))
269 fatal(_("error writing inode"));
271 if (lseek(fd
, (1 + ino_blocks
)*BFS_BLOCKSIZE
, SEEK_SET
) == -1)
272 fatal(_("seek error"));
274 memset(&de
, 0, sizeof(de
));
275 de
.d_ino
= BFS_ROOT_INO
;
276 memcpy(de
.d_name
, ".", 1);
277 if (write(fd
, &de
, sizeof(de
)) != sizeof(de
))
278 fatal(_("error writing . entry"));
280 memcpy(de
.d_name
, "..", 2);
281 if (write(fd
, &de
, sizeof(de
)) != sizeof(de
))
282 fatal(_("error writing .. entry"));
284 if (close(fd
) == -1) {
286 fatal(_("error closing %s"), device
);