⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 swapfs.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* swapfs - swap a Minix file system	    Author: Niels C. Willems *//* $Id: swapfs.c,v 1.10 1992/04/15 10:51:46 ncwille Exp $ *//* Swapfs, a program to convert V1 or V2 Minix file systems from big endian   byte order to little endian and vv.   Some examples:   swapfs -v disk.01			! only show verbose information.   swapfs /dev/fd0 | compress > fd0r.Z	! convert and compress filesystem.   swapfs -v fileA fileA	! read, convert and write the same filesystem.  This program uses one byte of heap memory for each data block (1Kbytes)  in the file system, so with Minix-PC 16-bit you can't swap file systems  bigger than about 32 Mbytes  Be careful with 'swapfs fileA fileA'. If the program aborts e.g. by  user interrupt, power failure or an inconsistent file system, you  better have a backup of fileA  This program only converts directories and indirect blocks of files  that are in use. Converting indirect blocks or directories of deleted  files is hard and not yet done.  If you have a (1.6.xx, xx < 18) version of Minix that supports the  mounting of reversed file systems always mount them read-only and  avoid any attemp to modify them (mkdir, open, creat) too!  These problems have been fixed in Minix 1.6.18.  In this version you can get some more information about the  file system with the -d (debug) flag.      Please send your bug reports or ideas to ncwille@cs.vu.nl */#define _POSIX_SOURCE	1#include <sys/types.h>#include <sys/stat.h>#include <stdlib.h>#include <fcntl.h>#include <string.h>#include <unistd.h>#include <stdio.h>#include <assert.h>#if __STDC__ == 1#define	_PROTOTYPE(function, params)	function params#else#define	_PROTOTYPE(function, params)	function()#endif#define BLOCK_SIZE	1024#define BOOT_BLOCK_OFF	   (blockn_t) 0#define SUPER_BLOCK_OFF    (blockn_t) 1#define V1_MAGIC		0x137F#define V2_MAGIC		0x2468#define NINODES_OFFSET		     0#define V1_ZONES_OFFSET		     2#define IMAP_BLOCKS_OFFSET	     4#define ZMAP_BLOCKS_OFFSET	     6#define FIRSTDATAZONE_OFFSET	     8#define LOG_ZONE_SIZE_OFFSET        10#define MAGIC_OFFSET		    16#define V2_ZONES_OFFSET		    20#define NR_DIRECT_ZONES	 7#define V1_NR_TZONES	 9#define V2_NR_TZONES	10#define V1_INODE_SIZE	32#define V2_INODE_SIZE	64#define INODE1_MODE_OFF		 0#define INODE1_SIZE_OFF		 4#define INODE1_DIRECT_OFF	14#define INODE1_IND1_OFF		28#define INODE1_IND2_OFF		30#define INODE2_MODE_OFF		 0#define INODE2_SIZE_OFF		 8#define INODE2_DIRECT_OFF	24#define INODE2_IND1_OFF		52#define INODE2_IND2_OFF		56#define INODE2_IND3_OFF		60#define INODE_MODE_MASK		0xf000	/* file type mask    */#define INODE_DIR_MODE		0x4000	/* directory         */#define INODE_BLK_SPECIAL_MODE	0x6000	/* block special     */#define INODE_CHR_SPECIAL_MODE  0x2000	/* character special */#define T_MASK		0x1c#define T_UNKNOWN	0x00#define T_MAYBE_OLD_DIR	0x04#define T_OLD_NON_DIR	0x08#define T_DIR		0x0c#define T_NON_DIR	0x10#define INDIRECT_MASK	0x03#define IND_PROCESSED_BIT 0x20	/* set when all blocks in ind block are			 * marked */#define IND_CONFLICT_BIT  0x40#define TYPE_CONFLICT_BIT 0x80#define DIR_ENTRY_SIZE    16typedef enum {  Unused_zone, Old_zone, In_use_zone} class_t;typedef unsigned long blockn_t;typedef unsigned int inodesn_t;typedef struct {  inodesn_t ninodes;		/* # usable inodes on the minor device */  blockn_t imap_blocks;		/* # of blocks used by inode bit map */  blockn_t zmap_blocks;		/* # of blocks used by zone bit map */  blockn_t firstdatazone;	/* number of first data zone */  int log_zone_size;		/* log2 of blocks/zone */  blockn_t zones;		/* number of zones */  int version;			/* file system version */  inodesn_t inodes_per_block;  blockn_t first_imap_block;  blockn_t first_zmap_block;  blockn_t first_inode_block;	/* number of first block with inodes */  size_t dzmap_size;		/* # of data zone blocks */} super_t;typedef struct {		/* summary of inode */  long size;			/* current file size in bytes */  blockn_t direct[NR_DIRECT_ZONES];	/* block numbers for direct,					 * ind, ... */  blockn_t ind1;		/* single indirect block number */  blockn_t ind2;		/* double indirect block number */  blockn_t ind3;		/* triple indirect block number */  int ztype;			/* type of zones that belong to this inode */} inode_t;static char rcsid[] = "$Id: swapfs.c,v 1.10 1992/04/15 10:51:46 ncwille Exp $";static int super_format[] = {2, 2, 2, 2, 2, 2, 4, 2, 2, 4, 0};static int inode1_format[] = {2, 2, 4, 4, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0};static int inode2_format[] = {2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,		      4, 4, 0};static char *ind_str[4] = {"direct", "single indirect",		   "double indirect", "triple indirect"};static int big_endian_fs;	/* set in init_super(), 1 iff file system has			 * big endian byte order */static int verbose_flag;static int debug_flag;static int test_flag;typedef unsigned char *dzmap_t;int _PROTOTYPE(main, (int argc, char *argv[]));static void _PROTOTYPE(parse_args_init_io, (int argc, char *argv[]));static void _PROTOTYPE(rw_boot, (void));static void _PROTOTYPE(rw_init_super, (super_t * sp));static void _PROTOTYPE(init_dzmap, (dzmap_t * dzmap_ptr, size_t dzmap_size));static void _PROTOTYPE(rw_ibmap, (super_t super));static void _PROTOTYPE(rw_zbmap, (super_t super));static void _PROTOTYPE(print_stat, (dzmap_t dzmap, super_t super));static void _PROTOTYPE(p1_rw_inodes, (dzmap_t dzmap, super_t super));static void _PROTOTYPE(rd_indirects, (dzmap_t dzmap, super_t super, int ind,			       class_t required_class));static void _PROTOTYPE(rw_data_zones, (dzmap_t dzmap, super_t super));static int _PROTOTYPE(read_block, (char *buf, blockn_t offset));static void _PROTOTYPE(write_block, (char *buf));static int _PROTOTYPE(convcpy, (char *dst, char *src, int *format));static void _PROTOTYPE(conv2_blkcpy, (char *dst, char *src));static void _PROTOTYPE(conv4_blkcpy, (char *dst, char *src));static void _PROTOTYPE(conv2cpy, (char *dst, char *src));static int _PROTOTYPE(inode_size, (int version));static void _PROTOTYPE(init_super, (super_t * sp, char *buf));static void _PROTOTYPE(get_inode, (inode_t * ip, char *buf, int version));static int _PROTOTYPE(check_inode, (inode_t inode, super_t super));static int _PROTOTYPE(was_blk_special, (inode_t inode));static int _PROTOTYPE(check_blk_number, (blockn_t num, super_t super));static void _PROTOTYPE(cw_inode_block, (char *buf, inodesn_t ninodes,				 int version));static void _PROTOTYPE(proc_ind, (dzmap_t dzmap, size_t curr_ind,			   char *buf, super_t super));static void _PROTOTYPE(cw_dir_block, (char *buf));static void _PROTOTYPE(dzmap_add_inode, (dzmap_t dzmap, inode_t inode,				  super_t super));static void _PROTOTYPE(dz_update, (dzmap_t dzmap, blockn_t blknum,		     int new_indnum, int new_ztype, super_t super));static class_t _PROTOTYPE(ztype_class, (int ztype));static unsigned int _PROTOTYPE(two_bytes, (char buf[2]));static long _PROTOTYPE(four_bytes, (char buf[4]));static void _PROTOTYPE(fail, (char *string));static void _PROTOTYPE(usage, (char *arg0));int main(argc, argv)int argc;char *argv[];{  super_t super;  dzmap_t dzmap;  parse_args_init_io(argc, argv);  rw_boot();  rw_init_super(&super);  init_dzmap(&dzmap, super.dzmap_size);  rw_ibmap(super);  rw_zbmap(super);  p1_rw_inodes(dzmap, super);  rd_indirects(dzmap, super, 3, In_use_zone);  rd_indirects(dzmap, super, 2, In_use_zone);  rd_indirects(dzmap, super, 1, In_use_zone);  if (verbose_flag) putc('\n', stderr);  print_stat(dzmap, super);  rw_data_zones(dzmap, super);  return 0;}static void parse_args_init_io(argc, argv)int argc;char *argv[];{  char *str;  struct stat buf;  ino_t src_ino;  int i;  debug_flag = 0;  verbose_flag = 0;  test_flag = 0;  for (i = 1; i < argc; i++) {	str = argv[i];	if (*str != '-') break;	switch (*++str) {	    case 'v':	verbose_flag = 1;	break;	    case 'd':		debug_flag = 1;		verbose_flag = 1;		break;	    case 't':	test_flag = 1;	break;	    default:	usage(argv[0]);	}  }  if ((argc - i == 0 && isatty(0)) || (argc - i) > 2) usage(argv[0]);  if (argc - i > 0) {	(void) close(0);	if (open(argv[i], O_RDONLY) != 0) {		fprintf(stderr, "Can't open input file %s", argv[i]);		fail("");	}  }  if (isatty(1) || argc - i == 2) {	if (argc - i < 2)		test_flag = 1;	else {		i++;		(void) close(1);		(void) fstat(0, &buf);		src_ino = buf.st_ino;		if (stat(argv[i], &buf) == 0 && src_ino == buf.st_ino) {			/* Src and dest are the same */			if (open(argv[i], O_WRONLY) != 1) {				fprintf(stderr, "Can't open output file %s", argv[i]);				fail("");			}		} else if (creat(argv[i], 0644) != 1) {			fprintf(stderr, "Can't creat output file %s", argv[i]);			fail("");		}	}  }}static void rw_boot(){  char buf[BLOCK_SIZE];  if (read_block(buf, BOOT_BLOCK_OFF) != BLOCK_SIZE)	fail("Can't read bootblock");  write_block(buf);}static void rw_init_super(sp)super_t *sp;{  char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE];  if (read_block(ibuf, SUPER_BLOCK_OFF) != BLOCK_SIZE)	fail("Can't read superblock");  init_super(sp, ibuf);  memcpy(obuf, ibuf, (size_t) BLOCK_SIZE);	/* preserve 'unused' data */  (void) convcpy(obuf, ibuf, super_format);  write_block(obuf);}static void init_dzmap(dzmap_ptr, dzmap_size)dzmap_t *dzmap_ptr;size_t dzmap_size;{  if ((*dzmap_ptr = (dzmap_t) malloc(dzmap_size)) == (dzmap_t) NULL)	fail("Not enough space for data zone map");  memset(*dzmap_ptr, '\0', (size_t) dzmap_size);}static void rw_ibmap(super)super_t super;{  char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE];  blockn_t i;  for (i = 0; i < super.imap_blocks; i++) {	if (read_block(ibuf, super.first_imap_block + i) != BLOCK_SIZE)		fail("Can't read inode bit map");	conv2_blkcpy(obuf, ibuf);	write_block(obuf);  }}static void rw_zbmap(super)super_t super;{  char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE];  blockn_t i;  for (i = 0; i < super.zmap_blocks; i++) {	if (read_block(ibuf, super.first_zmap_block + i) != BLOCK_SIZE)		fail("Can't read zone bit map");	conv2_blkcpy(obuf, ibuf);	write_block(obuf);  }}static void p1_rw_inodes(dzmap, super)dzmap_t dzmap;super_t super;{  char buf[BLOCK_SIZE], *buf_ptr;  inodesn_t i, num_inodes;  blockn_t next_block;  inode_t inode;  next_block = super.first_inode_block;  for (i = 1; i <= super.ninodes; i++) {	if ((i - 1) % super.inodes_per_block == 0) {		if (read_block(buf, next_block) != BLOCK_SIZE)			fail("read failed in inode block");		buf_ptr = buf;		next_block++;		num_inodes = super.ninodes + 1 - i;		if (num_inodes > super.inodes_per_block)			num_inodes = super.inodes_per_block;		cw_inode_block(buf, num_inodes, super.version);	}	get_inode(&inode, buf_ptr, super.version);	dzmap_add_inode(dzmap, inode, super);	buf_ptr += inode_size(super.version);  }}static void print_stat(dzmap, super)dzmap_t dzmap;super_t super;{  size_t i;  register unsigned char dz;  int both_conflict = 0, ind_conflict = 0, type_conflict = 0, unreferenced = 0;  int not_in_use = 0;  if (!verbose_flag) return;  for (i = 0; i < super.dzmap_size; i++) {	dz = dzmap[i];	if (dz & IND_CONFLICT_BIT && dz & TYPE_CONFLICT_BIT)		both_conflict++;	else if (dz & IND_CONFLICT_BIT)		ind_conflict++;	else if (dz & TYPE_CONFLICT_BIT)		type_conflict++;	if (dz == 0) unreferenced++;	if (ztype_class(dz & T_MASK) < In_use_zone) not_in_use++;  }  if (debug_flag) {	fprintf(stderr, "%5d zone blocks with conflicting indir.\n",		ind_conflict);	fprintf(stderr, "%5d zone blocks with conflicting types.\n",		type_conflict);	fprintf(stderr, "%5d zone blocks with conflicting types and indir.\n",		both_conflict);	fprintf(stderr, "%5d zone blocks never referenced.\n", unreferenced);  }  fprintf(stderr, "%5d zone blocks not in use.\n", not_in_use);  putc('\n', stderr);}static void rd_indirects(dzmap, super, ind, required_class)dzmap_t dzmap;super_t super;int ind;class_t required_class;{  size_t i;  int ind_cnt;  off_t dz_offset;  char buf[BLOCK_SIZE];  dz_offset = super.firstdatazone;  ind_cnt = 0;  for (i = 0; i < super.dzmap_size; i++) {	if (ztype_class(dzmap[i] & T_MASK) != required_class ||	    (dzmap[i] & INDIRECT_MASK) != ind ||	    (dzmap[i] & IND_PROCESSED_BIT))		continue;	ind_cnt++;	if (read_block(buf, dz_offset + i) != BLOCK_SIZE) {		fprintf(stderr, "Can't read %s block", ind_str[ind]);		fail("");	}	proc_ind(dzmap, i, buf, super);  }  if ((verbose_flag && ind_cnt > 0) || debug_flag)	fprintf(stderr, "%5d %s zone blocks.\n", ind_cnt, ind_str[ind]);}static void rw_data_zones(dzmap, super)dzmap_t dzmap;super_t super;{  char ibuf[BLOCK_SIZE], obuf[BLOCK_SIZE];  size_t i;  int ztype, ind, last_read;  off_t dz_offset;  dz_offset = super.firstdatazone;  for (i = 0; i < super.dzmap_size; i++) {	last_read = read_block(ibuf, dz_offset + i);	if (last_read != BLOCK_SIZE) break;	ind = dzmap[i] & INDIRECT_MASK;	if (ind == 0) {		ztype = dzmap[i] & T_MASK;		if (ztype == T_DIR)			cw_dir_block(ibuf);		else			write_block(ibuf);	} else {		if (super.version == 1)			conv2_blkcpy(obuf, ibuf);		else			conv4_blkcpy(obuf, ibuf);		write_block(obuf);	}	if (verbose_flag && i && i % 1024 == 0) {		fprintf(stderr, ".");		fflush(stderr);	}  }  if (verbose_flag && i > 1024) putc('\n', stderr);  if (last_read != BLOCK_SIZE) for (; i < super.dzmap_size; i++)		if (ztype_class(dzmap[i] & T_MASK) == In_use_zone)			fail("Can't read data zone");}static int read_block(buf, offset)char *buf;blockn_t offset;{  static blockn_t curr_offset = 0;  int bytes;  if (offset != curr_offset) {	if (lseek(0, (off_t) offset * BLOCK_SIZE, 0) == -1)		fail("lseek failed on input file");	curr_offset = offset;  }  bytes = read(0, buf, BLOCK_SIZE);  if (bytes < 0) fail("read failed on input file");  curr_offset += bytes;  return bytes;}static void write_block(buf)char *buf;{  if (test_flag) return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -