1 /* $NetBSD: newfs_sysvbfs.c,v 1.2 2008/04/28 20:23:09 martin Exp $ */ 2 3 /*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <stdio.h> 35 #include <stdlib.h> 36 #include <string.h> 37 #include <unistd.h> 38 #include <fcntl.h> 39 #include <time.h> 40 #include <assert.h> 41 #include <sys/errno.h> 42 #include <sys/ioctl.h> 43 #include <sys/disklabel.h> 44 45 #include <fs/sysvbfs/bfs.h> 46 47 static void usage(void); 48 static int bfs_newfs(int, uint32_t); 49 50 int 51 main(int argc, char **argv) 52 { 53 const char *device; 54 struct disklabel d; 55 struct partition *p; 56 struct stat st; 57 int part; 58 int fd; 59 60 if (argc != 2) 61 usage(); 62 device = argv[1]; 63 64 if ((fd = open(device, O_RDWR)) == -1) { 65 perror("open device"); 66 exit(EXIT_FAILURE); 67 } 68 if (fstat(fd, &st) != 0) { 69 perror("device stat"); 70 goto err_exit; 71 } 72 if (!S_ISCHR(st.st_mode)) { 73 fprintf(stderr, "WARNING: not a raw device.\n"); 74 } 75 76 part = DISKPART(st.st_rdev); 77 78 if (ioctl(fd, DIOCGDINFO, &d) == -1) { 79 perror("disklabel"); 80 goto err_exit; 81 } 82 p = &d.d_partitions[part]; 83 printf("partition = %d\n", part); 84 printf("size=%d offset=%d fstype=%d secsize=%d\n", 85 p->p_size, p->p_offset, p->p_fstype, d.d_secsize); 86 87 if (p->p_fstype != FS_SYSVBFS) { 88 fprintf(stderr, "not a SysVBFS partition.\n"); 89 goto err_exit; 90 } 91 92 if (bfs_newfs(fd, p->p_size) != 0) 93 goto err_exit; 94 95 close(fd); 96 97 return 0; 98 err_exit: 99 close(fd); 100 exit(EXIT_FAILURE); 101 } 102 103 int 104 bfs_newfs(int fd, uint32_t nsectors) 105 { 106 uint8_t buf[DEV_BSIZE]; 107 struct bfs_super_block *bfs = (void *)buf; 108 struct bfs_inode *inode = (void *)buf; 109 struct bfs_dirent *dirent = (void *)buf; 110 time_t t = time(0); 111 int err; 112 113 /* Super block */ 114 memset(buf, 0, DEV_BSIZE); 115 bfs->header.magic = BFS_MAGIC; 116 bfs->header.data_start_byte = DEV_BSIZE * 2; /* super block + inode */ 117 bfs->header.data_end_byte = nsectors * BFS_BSIZE - 1; 118 bfs->compaction.from = 0xffffffff; 119 bfs->compaction.to = 0xffffffff; 120 bfs->compaction.from_backup = 0xffffffff; 121 bfs->compaction.to_backup = 0xffffffff; 122 123 if ((err = lseek(fd, 0, SEEK_SET)) == -1) { 124 perror("seek super block"); 125 return -1; 126 } 127 if (write(fd, buf, BFS_BSIZE) < 0) { 128 perror("write super block"); 129 return -1; 130 } 131 132 /* i-node table */ 133 memset(buf, 0, BFS_BSIZE); 134 inode->number = BFS_ROOT_INODE; 135 inode->start_sector = 2; 136 inode->end_sector = 2; 137 inode->eof_offset_byte = sizeof(struct bfs_dirent) + 138 inode->start_sector * BFS_BSIZE; 139 inode->attr.atime = t; 140 inode->attr.mtime = t; 141 inode->attr.ctime = t; 142 inode->attr.mode = 0755; 143 inode->attr.type = 2; /* DIR */ 144 inode->attr.nlink = 2; /* . + .. */ 145 if (write(fd, buf, BFS_BSIZE) < 0) { 146 perror("write i-node"); 147 return -1; 148 } 149 150 /* dirent table */ 151 memset(buf, 0, BFS_BSIZE); 152 dirent->inode = BFS_ROOT_INODE; 153 sprintf(dirent->name, "."); 154 dirent++; 155 dirent->inode = BFS_ROOT_INODE; 156 sprintf(dirent->name, ".."); 157 if (write(fd, buf, BFS_BSIZE) < 0) { 158 perror("write dirent"); 159 return -1; 160 } 161 162 return 0; 163 } 164 165 void 166 usage(void) 167 { 168 169 (void)fprintf(stderr, "usage: %s special-device\n", getprogname()); 170 exit(EXIT_FAILURE); 171 } 172