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

📄 badblo~1.c

📁 操作系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* badblocks - collect bad blocks in a file	Author: Jacob Bunschoten *//* Usage "badblocks block_special [Up_to_7_blocks]" *//* This program is written to handle BADBLOCKS on a hard or floppy disk. * The program asks for block_numbers. These numbers can be obtained with * the program readall, written by A. Tanenbaum.  It then creates a * file on the disk containing up to 7 bad blocks. * * BUG: * *	When the zone_size > block_size it can happen that *	the zone is already allocated. This means some *	file is using this zone and may use all the blocks including *	the bad one. This can be cured by inspecting the zone_bitmap *	(is already done) and change the file if this zone is used. *	This means that another zone must be allocated and *	the inode wich claims this zone must be found and changed. * */#include <sys/types.h>#include <sys/stat.h>#include <minix/config.h>#include <minix/type.h>#include <fcntl.h>#include <unistd.h>#include <stdlib.h>#include "../../fs/const.h"	/* must be included before stdio.h */#undef printf			/* so its define of printf can be undone */#include "../../fs/type.h"#include <string.h>#include <stdio.h>_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(void rw_super, (int flag));_PROTOTYPE(void get_super, (void));_PROTOTYPE(void put_super, (void));_PROTOTYPE(void rw_inode, (struct stat * stat_ptr, int rw_mode));_PROTOTYPE(void get_inode, (struct stat * stat_ptr));_PROTOTYPE(void put_inode, (struct stat * stat_ptr));_PROTOTYPE(long rd_cmdline, (int argc, char *argv[]));_PROTOTYPE(void modify, (int nr_blocks));_PROTOTYPE(void save_blk, (block_t blk_num));_PROTOTYPE(void reset_blks, (void));_PROTOTYPE(void show_blks, (void));_PROTOTYPE(int blk_is_used, (block_t blk_num));_PROTOTYPE(int blk_ok, (block_t num));_PROTOTYPE(void set_bit, (zone_t num));_PROTOTYPE(long rd_num, (void));_PROTOTYPE(int ok, (char *str));_PROTOTYPE(void done, (int nr));/* 		Super block table. * * 	The disk layout is: * *      Item        # block *    boot block      1 *    super block     1 *    inode map     s_imap_blocks *    zone map      s_zmap_blocks *    inodes        (s_ninodes + 1 + inodes_per_block - 1)/inodes_per_block *    unused *    data zones    (s_nzones - s_firstdatazone) << s_log_zone_size * */#define OK	0#define NOT_OK	1#define QUIT	2#define READ 	0#define WRITE	1#define HARMLESS	0#define DIR_CREATED	1#define DEV_MOUNTED	2#define FILE_EXISTS	3#define SUCCESS		4#define BYTE         0377#define BLOCK_SIZE   1024#define SIZE_OF_INT   (sizeof (int) )/* Define V_NR_DZONES as the larger of V1_NR_DZONES and V2_NR_DZONES. */#if (V1_NR_DZONES > V2_NR_DZONES)#define V_NR_DZONES V1_NR_DZONES#define V_SMALLER   V2_NR_DZONES#else#define V_NR_DZONES V2_NR_DZONES#define V_SMALLER   V1_NR_DZONES#endifstruct super_block {  ino_t s_ninodes;		/* # usable inodes on the minor device */  zone1_t s_nzones;		/* total device size, including bit maps etc */  short s_imap_blocks;		/* # of blocks used by inode bit map */  short s_zmap_blocks;		/* # of blocks used by zone bit map */  zone1_t s_firstdatazone;	/* number of first data zone */  short s_log_zone_size;	/* log2 of blocks/zone */  off_t s_max_size;		/* maximum file size on this device */  short s_magic;		/* magic number to recognize super-blocks */  short s_pad;			/* try to avoid compiler-dependent padding */  zone_t s_zones;		/* number of zones (replaces s_nzones in V2) */} super_block; /* ====== globals ======= */char *dev_name;char f_name[] = ".Bad_XXXXXX";char file_name[50];char dir_name[] = "/tmpXXXXXX";block_t block[V_NR_DZONES + 1];	/* last block contains zero */int interactive;		/* 1 if interactive (argc == 2) */int position = 2;		/* next block # is argv[position] */FILE *f;int fd;int eofseen;			/* set if '\n' seen */struct stat stat_buf;struct super_block *sp;int inodes_per_block;size_t inode_size;int v1fs;			/* TRUE for V1 file system, FALSE for V2 */d1_inode d1inode;		/* declare a V1 disk inode */d1_inode *ip1;d2_inode d2inode;		/* declare a V2 disk inode */d2_inode *ip2; /* ====== super block routines ======= */void rw_super(flag)int flag;{				/* read or write a superblock */  int rwd;  lseek(fd, 0L, SEEK_SET);	/* rewind */  lseek(fd, (long) BLOCK_SIZE, SEEK_SET);	/* seek */  if (flag == READ)	rwd = read(fd, (char *) sp, SUPER_SIZE);  else	rwd = write(fd, (char *) sp, SUPER_SIZE);  if (rwd != SUPER_SIZE) {	/* ok ? */	printf("Bad %s in get_super() (should be %u is %d)\n",	       flag == READ ? "read" : "write",	       (unsigned) SUPER_SIZE, rwd);	done(DIR_CREATED);  }}void get_super() /* Get super_block. global pointer sp is used */{  rw_super(READ);  if (sp->s_magic == SUPER_MAGIC) {	/* This is a V1 file system. */	v1fs = 1;		/* file system is not V2 */  } else if (sp->s_magic == SUPER_V2) {	/* This is a V2 file system. */	v1fs = 0;		/* this is a V2 file system */  } else {	/* Neither V1 nor V2. */	printf("Bad magic number in super_block (0x%x)\n",	       (unsigned) sp->s_magic);	done(DIR_CREATED);  }}void put_super(){  rw_super(WRITE);} /* ========== inode routines =========== */void rw_inode(stat_ptr, rw_mode)struct stat *stat_ptr;int rw_mode;{  int rwd;  ino_t i_num;  block_t blk, offset;  i_num = stat_ptr->st_ino;  blk = (block_t) (2 + sp->s_imap_blocks + sp->s_zmap_blocks);  blk += (block_t) ((i_num - 1) / inodes_per_block);  blk *= (block_t) (BLOCK_SIZE);/* this block */  offset = (block_t) ((i_num - 1) % inodes_per_block);  offset *= (block_t) (inode_size);	/* and this offset */  lseek(fd, (off_t) 0, SEEK_SET);	/* rewind */  lseek(fd, (off_t) (blk + offset), SEEK_SET);	/* seek */  /* Pointer is at the inode */  if (v1fs) {	/* This is a V1 file system. */	if (rw_mode == READ) {	/* read it */		rwd = read(fd, (char *) ip1, inode_size);	} else {		/* write it */		rwd = write(fd, (char *) ip1, inode_size);	}  } else {	/* This is a V2 file system. */	if (rw_mode == READ) {	/* read it */		rwd = read(fd, (char *) ip2, inode_size);	} else {		/* write it */		rwd = write(fd, (char *) ip2, inode_size);	}  }  if (rwd != inode_size) {	/* ok ? */	printf("Bad %s in get_inode()\n", (rw_mode == READ) ? "read" :	       "write");	done(DIR_CREATED);  }}void get_inode(stat_ptr)struct stat *stat_ptr;{  int cnt;  rw_inode(stat_ptr, READ);  if (v1fs) {	for (cnt = 0; cnt < V1_NR_TZONES; cnt++)		ip1->d1_zone[cnt] = 0;	/* Just to be safe */  } else {	for (cnt = 0; cnt < V2_NR_TZONES; cnt++)		ip2->d2_zone[cnt] = 0;	/* Just to be safe */  }}void put_inode(stat_ptr)struct stat *stat_ptr;{  rw_inode(stat_ptr, WRITE);} /* ==============  main program ================= */int main(argc, argv)int argc;char *argv[];{  int cnt, finished;  block_t blk_nr;  struct stat dev_stat;  FILE *fp;  sp = &super_block;  ip1 = &d1inode;  ip2 = &d2inode;  if (argc < 2 || argc > 9) {	fprintf(stderr, "Usage: %s block_special [up_to_7_blocks]\n", argv[0]);	done(HARMLESS);  }  interactive = (argc == 2 ? 1 : 0);  /* Do some test. */  if (geteuid()) {	printf("Sorry, not in superuser mode \n");	printf("Set_uid bit must be on or you must become super_user\n");	done(HARMLESS);  }  dev_name = argv[1];  mktemp(dir_name);  if (mkdir(dir_name, 0777) == -1) {	fprintf(stderr, "%s is already used in system\n", dir_name);	done(HARMLESS);  }  /* Mount device. This call may fail. */  mount(dev_name, dir_name, 0);  /* Succes. dev was mounted, try to umount */  /* Umount device. Playing with the file system while other processes   * have access to this device is asking for trouble */  if (umount(dev_name) == -1) {	printf("Could not umount device %s.\n", dev_name);	done(HARMLESS);  }  mktemp(f_name);  /* Create "/tmpXXXXpid/.BadXXpid" */  strcat(file_name, dir_name);  strcat(file_name, "/");  strcat(file_name, f_name);  if (mount(dev_name, dir_name, 0) == -1) {	/* this call should work */	fprintf(stderr, "Could not mount device anymore\n");	done(HARMLESS);  }  if (stat(file_name, &stat_buf) != -1) {	printf("File %s already exists\n", file_name);	done(DEV_MOUNTED);  }  if ((fp = fopen(file_name, "w")) == NULL) {	printf("Cannot create file %s\n", file_name);	done(DEV_MOUNTED);  }  chmod(file_name, 0);		/* "useless" file */  if (stat(file_name, &stat_buf) == -1) {	printf("What? Second call from stat failed\n");	done(FILE_EXISTS);  }  /* Stat buf must be safed. We can now calculate the inode on disk */  fclose(fp);  /* ===== the badblock file is created ===== */

⌨️ 快捷键说明

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