fsck_v7fs.c revision 1.1
11.1Such/* $NetBSD: fsck_v7fs.c,v 1.1 2011/06/27 11:52:58 uch Exp $ */ 21.1Such 31.1Such/*- 41.1Such * Copyright (c) 2004, 2011 The NetBSD Foundation, Inc. 51.1Such * All rights reserved. 61.1Such * 71.1Such * This code is derived from software contributed to The NetBSD Foundation 81.1Such * by UCHIYAMA Yasushi. 91.1Such * 101.1Such * Redistribution and use in source and binary forms, with or without 111.1Such * modification, are permitted provided that the following conditions 121.1Such * are met: 131.1Such * 1. Redistributions of source code must retain the above copyright 141.1Such * notice, this list of conditions and the following disclaimer. 151.1Such * 2. Redistributions in binary form must reproduce the above copyright 161.1Such * notice, this list of conditions and the following disclaimer in the 171.1Such * documentation and/or other materials provided with the distribution. 181.1Such * 191.1Such * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 201.1Such * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 211.1Such * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 221.1Such * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 231.1Such * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 241.1Such * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 251.1Such * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 261.1Such * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 271.1Such * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 281.1Such * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 291.1Such * POSSIBILITY OF SUCH DAMAGE. 301.1Such */ 311.1Such 321.1Such#include <sys/cdefs.h> 331.1Such#ifndef lint 341.1Such__RCSID("$NetBSD: fsck_v7fs.c,v 1.1 2011/06/27 11:52:58 uch Exp $"); 351.1Such#endif /* not lint */ 361.1Such 371.1Such#include <stdio.h> 381.1Such#include <stdlib.h> 391.1Such#include <string.h> 401.1Such#include <unistd.h> 411.1Such#include <fcntl.h> 421.1Such#include <err.h> 431.1Such#include <sys/ioctl.h> 441.1Such#include <sys/disklabel.h> 451.1Such 461.1Such#include <fs/v7fs/v7fs.h> 471.1Such#include "v7fs_impl.h" 481.1Such#include "fsck_v7fs.h" 491.1Such#include "progress.h" 501.1Such 511.1Suchstatic void usage(void) __dead; 521.1Suchstatic void catopt(char **, const char *); 531.1Such 541.1Suchenum fsck_operate fsck_operate; 551.1Suchbool verbose = true; 561.1Such#define VPRINTF(fmt, args...) { if (verbose) printf(fmt, ##args); } 571.1Such 581.1Suchint 591.1Suchmain(int argc, char **argv) 601.1Such{ 611.1Such const char *device; 621.1Such struct disklabel d; 631.1Such struct partition *p; 641.1Such struct stat st; 651.1Such int Fflag = 0; 661.1Such int part; 671.1Such int fd, ch; 681.1Such int endian = _BYTE_ORDER; 691.1Such int openflags = O_RDWR; 701.1Such size_t part_sectors; 711.1Such int fsck_flags = 0; 721.1Such char *options = 0; 731.1Such bool progress_bar_enable = false; 741.1Such 751.1Such fsck_operate = ASK; 761.1Such 771.1Such if (argc < 2) 781.1Such usage(); 791.1Such 801.1Such while ((ch = getopt(argc, argv, "pPqynfx:dFB:o:")) != -1) { 811.1Such switch (ch) { 821.1Such /* 831.1Such * generic fsck options 841.1Such */ 851.1Such case 'd': /* Not supported */ 861.1Such break; 871.1Such case 'f': /* Always forced */ 881.1Such break; 891.1Such case 'p': 901.1Such fsck_operate = PREEN; 911.1Such break; 921.1Such case 'y': 931.1Such fsck_operate = ALWAYS_YES; 941.1Such break; 951.1Such case 'n': 961.1Such fsck_operate = ALWAYS_NO; 971.1Such openflags = O_RDONLY; 981.1Such break; 991.1Such case 'P': 1001.1Such progress_bar_enable = true; 1011.1Such break; 1021.1Such case 'q': /* Not supported */ 1031.1Such break; 1041.1Such case 'x': /* Not supported */ 1051.1Such break; 1061.1Such /* 1071.1Such * v7fs fsck options 1081.1Such */ 1091.1Such case 'F': 1101.1Such Fflag = 1; 1111.1Such break; 1121.1Such case 'B': 1131.1Such switch (optarg[0]) { 1141.1Such case 'l': 1151.1Such endian = _LITTLE_ENDIAN; 1161.1Such break; 1171.1Such case 'b': 1181.1Such endian = _BIG_ENDIAN; 1191.1Such break; 1201.1Such case 'p': 1211.1Such endian = _PDP_ENDIAN; 1221.1Such break; 1231.1Such } 1241.1Such break; 1251.1Such case 'o': /* datablock, freeblock duplication check */ 1261.1Such if (*optarg) 1271.1Such catopt(&options, optarg); 1281.1Such break; 1291.1Such default: 1301.1Such usage(); 1311.1Such /*NOTREACHED*/ 1321.1Such } 1331.1Such } 1341.1Such 1351.1Such argc -= optind; 1361.1Such argv += optind; 1371.1Such 1381.1Such if (argc != 1) 1391.1Such usage(); 1401.1Such device = argv[0]; 1411.1Such 1421.1Such if (options) { 1431.1Such if (strstr(options, "data")) 1441.1Such fsck_flags |= V7FS_FSCK_DATABLOCK_DUP; 1451.1Such if (strstr(options, "free")) 1461.1Such fsck_flags |= V7FS_FSCK_FREEBLOCK_DUP; 1471.1Such } 1481.1Such 1491.1Such if (Fflag) { 1501.1Such if ((fd = open(device, openflags)) == -1) { 1511.1Such pfatal("%s", device); 1521.1Such } 1531.1Such if (fstat(fd, &st)) { 1541.1Such pfatal("stat"); 1551.1Such } 1561.1Such part_sectors = st.st_size >> V7FS_BSHIFT; 1571.1Such setcdevname(device, fsck_operate == PREEN); 1581.1Such } else { 1591.1Such /* blockcheck sets 'hot' */ 1601.1Such device = blockcheck(device); 1611.1Such setcdevname(device, fsck_operate == PREEN); 1621.1Such 1631.1Such if ((fd = open(device, openflags)) == -1) { 1641.1Such pfatal("%s", device); 1651.1Such } 1661.1Such part = DISKPART(st.st_rdev); 1671.1Such 1681.1Such if (ioctl(fd, DIOCGDINFO, &d) == -1) { 1691.1Such pfatal("DIOCGDINFO"); 1701.1Such } 1711.1Such p = &d.d_partitions[part]; 1721.1Such part_sectors = p->p_size; 1731.1Such VPRINTF("partition=%d size=%d offset=%d fstype=%d secsize=%d\n", 1741.1Such part, p->p_size, p->p_offset, p->p_fstype, d.d_secsize); 1751.1Such if (p->p_fstype != FS_V7) { 1761.1Such pfatal("not a Version 7 partition."); 1771.1Such } 1781.1Such } 1791.1Such 1801.1Such progress_switch(progress_bar_enable); 1811.1Such progress_init(); 1821.1Such progress(&(struct progress_arg){ .cdev = device }); 1831.1Such 1841.1Such struct v7fs_mount_device mount; 1851.1Such mount.device.fd = fd; 1861.1Such mount.endian = endian; 1871.1Such mount.sectors = part_sectors; 1881.1Such int error = v7fs_fsck(&mount, fsck_flags); 1891.1Such 1901.1Such close(fd); 1911.1Such 1921.1Such return error; 1931.1Such} 1941.1Such 1951.1Suchstatic void 1961.1Suchcatopt(char **sp, const char *o) 1971.1Such{ 1981.1Such char *s, *n; 1991.1Such 2001.1Such s = *sp; 2011.1Such if (s) { 2021.1Such if (asprintf(&n, "%s,%s", s, o) < 0) 2031.1Such err(1, "asprintf"); 2041.1Such free(s); 2051.1Such s = n; 2061.1Such } else 2071.1Such s = strdup(o); 2081.1Such *sp = s; 2091.1Such} 2101.1Such 2111.1Suchstatic void 2121.1Suchusage(void) 2131.1Such{ 2141.1Such 2151.1Such (void)fprintf(stderr, "usage: %s [-ynpP] [-o options] [-B endian] " 2161.1Such "special-device\n", 2171.1Such getprogname()); 2181.1Such (void)fprintf(stderr, "usage: %s -F [-ynpP] [-o options] [-B endian] " 2191.1Such "file\n", 2201.1Such getprogname()); 2211.1Such 2221.1Such exit(FSCK_EXIT_USAGE); 2231.1Such} 224