* enforced (but it's not much fun on a character device :-).
*/
-#include "busybox.h"
+#include "libbb.h"
#include <mntent.h>
#include "minix.h"
static int namelen = 14;
static char *inode_buffer;
-//xzalloc?
-static char super_block_buffer[BLOCK_SIZE];
+
+static struct {
+ char super_block_buffer[BLOCK_SIZE];
+ char add_zone_ind_blk[BLOCK_SIZE];
+ char add_zone_dind_blk[BLOCK_SIZE];
+ USE_FEATURE_MINIX2(char add_zone_tind_blk[BLOCK_SIZE];)
+ char check_file_blk[BLOCK_SIZE];
+} *blockbuf;
#define Inode1 (((struct minix1_inode *) inode_buffer)-1)
#define Inode2 (((struct minix2_inode *) inode_buffer)-1)
-#define Super (*(struct minix_super_block *)super_block_buffer)
+#define Super (*(struct minix_super_block *)(blockbuf->super_block_buffer))
#if ENABLE_FEATURE_MINIX2
# define ZONES ((unsigned)(version2 ? Super.s_zones : Super.s_nzones))
#define MAGIC (Super.s_magic)
/* gcc likes this more (code is smaller) than macro variant */
-static ATTRIBUTE_ALWAYS_INLINE unsigned div_roundup(unsigned size, unsigned n)
+static ALWAYS_INLINE unsigned div_roundup(unsigned size, unsigned n)
{
- return (size + n-1) / n;
+ return (size + n-1) / n;
}
#if ENABLE_FEATURE_MINIX2
static unsigned char *inode_count;
static unsigned char *zone_count;
-static int bit(char *a, unsigned int i)
+/* Before you ask "where they come from?": */
+/* setbit/clrbit are supplied by sys/param.h */
+
+static int minix_bit(const char *a, unsigned i)
+{
+ return (a[i >> 3] & (1<<(i & 7)));
+}
+
+static void minix_setbit(char *a, unsigned i)
+{
+ setbit(a, i);
+ changed = 1;
+}
+static void minix_clrbit(char *a, unsigned i)
{
- return (a[i >> 3] & (1<<(i & 7))) != 0;
+ clrbit(a, i);
+ changed = 1;
}
-#define inode_in_use(x) (bit(inode_map,(x)))
-#define zone_in_use(x) (bit(zone_map,(x)-FIRSTZONE+1))
+/* Note: do not assume 0/1, it is 0/nonzero */
+#define zone_in_use(x) (minix_bit(zone_map,(x)-FIRSTZONE+1))
+#define inode_in_use(x) (minix_bit(inode_map,(x)))
-#define mark_inode(x) (setbit(inode_map,(x)),changed=1)
-#define unmark_inode(x) (clrbit(inode_map,(x)),changed=1)
+#define mark_inode(x) (minix_setbit(inode_map,(x)))
+#define unmark_inode(x) (minix_clrbit(inode_map,(x)))
-#define mark_zone(x) (setbit(zone_map,(x)-FIRSTZONE+1),changed=1)
-#define unmark_zone(x) (clrbit(zone_map,(x)-FIRSTZONE+1),changed=1)
+#define mark_zone(x) (minix_setbit(zone_map,(x)-FIRSTZONE+1))
+#define unmark_zone(x) (minix_clrbit(zone_map,(x)-FIRSTZONE+1))
-static void recursive_check(unsigned int ino);
+static void recursive_check(unsigned ino);
#if ENABLE_FEATURE_MINIX2
-static void recursive_check2(unsigned int ino);
+static void recursive_check2(unsigned ino);
#endif
-static void leave(int) ATTRIBUTE_NORETURN;
-static void leave(int status)
+static void die(const char *str) ATTRIBUTE_NORETURN;
+static void die(const char *str)
{
if (termios_set)
tcsetattr(0, TCSANOW, &termios);
- exit(status);
-}
-
-static void die(const char *str)
-{
- bb_error_msg("%s", str);
- leave(8);
+ bb_error_msg_and_die("%s", str);
}
/* File-name data */
/*
* read-block reads block nr into the buffer at addr.
*/
-static void read_block(unsigned int nr, char *addr)
+static void read_block(unsigned nr, char *addr)
{
if (!nr) {
memset(addr, 0, BLOCK_SIZE);
/*
* write_block writes block nr to disk.
*/
-static void write_block(unsigned int nr, char *addr)
+static void write_block(unsigned nr, char *addr)
{
if (!nr)
return;
* It sets 'changed' if the inode has needed changing, and re-writes
* any indirect blocks with errors.
*/
-static int map_block(struct minix1_inode *inode, unsigned int blknr)
+static int map_block(struct minix1_inode *inode, unsigned blknr)
{
uint16_t ind[BLOCK_SIZE >> 1];
uint16_t dind[BLOCK_SIZE >> 1];
}
#if ENABLE_FEATURE_MINIX2
-static int map_block2(struct minix2_inode *inode, unsigned int blknr)
+static int map_block2(struct minix2_inode *inode, unsigned blknr)
{
uint32_t ind[BLOCK_SIZE >> 2];
uint32_t dind[BLOCK_SIZE >> 2];
if (BLOCK_SIZE != lseek(IN, BLOCK_SIZE, SEEK_SET))
die("seek failed in write_super_block");
- if (BLOCK_SIZE != write(IN, super_block_buffer, BLOCK_SIZE))
+ if (BLOCK_SIZE != write(IN, blockbuf->super_block_buffer, BLOCK_SIZE))
die("cannot write super-block");
}
{
if (BLOCK_SIZE != lseek(IN, BLOCK_SIZE, SEEK_SET))
die("seek failed");
- if (BLOCK_SIZE != read(IN, super_block_buffer, BLOCK_SIZE))
+ if (BLOCK_SIZE != read(IN, blockbuf->super_block_buffer, BLOCK_SIZE))
die("cannot read super block");
/* already initialized to:
namelen = 14;
}
}
-static struct minix1_inode *get_inode(unsigned int nr)
+static struct minix1_inode *get_inode(unsigned nr)
{
struct minix1_inode *inode;
inode = Inode1 + nr;
if (!inode_count[nr]) {
if (!inode_in_use(nr)) {
- printf("Inode1 %d is marked as 'unused', but it is used "
+ printf("Inode %d is marked as 'unused', but it is used "
"for file '%s'\n", nr, current_name);
if (repair) {
if (ask("Mark as 'in use'", 1))
mark_inode(nr);
- } else {
- errors_uncorrected = 1;
+ else
+ errors_uncorrected = 1;
}
}
if (S_ISDIR(inode->i_mode))
}
#if ENABLE_FEATURE_MINIX2
-static struct minix2_inode *get_inode2(unsigned int nr)
+static struct minix2_inode *get_inode2(unsigned nr)
{
struct minix2_inode *inode;
inode = Inode2 + nr;
if (!inode_count[nr]) {
if (!inode_in_use(nr)) {
- printf("Inode1 %d is marked as 'unused', but it is used "
+ printf("Inode %d is marked as 'unused', but it is used "
"for file '%s'\n", nr, current_name);
if (repair) {
if (ask("Mark as 'in use'", 1))
static void add_zone_ind(uint16_t *znr, smallint *corrected)
{
- static char blk[BLOCK_SIZE];
+#define blk (blockbuf->add_zone_ind_blk)
int i;
int block;
smallint chg_blk = 0;
add_zone(i + (uint16_t *) blk, &chg_blk);
if (chg_blk)
write_block(block, blk);
+#undef blk
}
#if ENABLE_FEATURE_MINIX2
static void add_zone_ind2(uint32_t *znr, smallint *corrected)
{
- static char blk[BLOCK_SIZE];
+#define blk (blockbuf->add_zone_ind_blk)
int i;
int block;
smallint chg_blk = 0;
add_zone2(i + (uint32_t *) blk, &chg_blk);
if (chg_blk)
write_block(block, blk);
+#undef blk
}
#endif
static void add_zone_dind(uint16_t *znr, smallint *corrected)
{
- static char blk[BLOCK_SIZE];
+#define blk (blockbuf->add_zone_dind_blk)
int i;
int block;
smallint chg_blk = 0;
add_zone_ind(i + (uint16_t *) blk, &chg_blk);
if (chg_blk)
write_block(block, blk);
+#undef blk
}
#if ENABLE_FEATURE_MINIX2
static void add_zone_dind2(uint32_t *znr, smallint *corrected)
{
- static char blk[BLOCK_SIZE];
+#define blk (blockbuf->add_zone_dind_blk)
int i;
int block;
smallint chg_blk = 0;
add_zone_ind2(i + (uint32_t *) blk, &chg_blk);
if (chg_blk)
write_block(block, blk);
+#undef blk
}
static void add_zone_tind2(uint32_t *znr, smallint *corrected)
{
- static char blk[BLOCK_SIZE];
+#define blk (blockbuf->add_zone_tind_blk)
int i;
int block;
smallint chg_blk = 0;
add_zone_dind2(i + (uint32_t *) blk, &chg_blk);
if (chg_blk)
write_block(block, blk);
+#undef blk
}
#endif
-static void check_zones(unsigned int i)
+static void check_zones(unsigned i)
{
struct minix1_inode *inode;
}
#if ENABLE_FEATURE_MINIX2
-static void check_zones2(unsigned int i)
+static void check_zones2(unsigned i)
{
struct minix2_inode *inode;
}
#endif
-static void check_file(struct minix1_inode *dir, unsigned int offset)
+static void check_file(struct minix1_inode *dir, unsigned offset)
{
- static char blk[BLOCK_SIZE];
+#define blk (blockbuf->check_file_blk)
struct minix1_inode *inode;
int ino;
char *name;
if (inode && S_ISDIR(inode->i_mode))
recursive_check(ino);
pop_filename();
+#undef blk
}
#if ENABLE_FEATURE_MINIX2
-static void check_file2(struct minix2_inode *dir, unsigned int offset)
+static void check_file2(struct minix2_inode *dir, unsigned offset)
{
- static char blk[BLOCK_SIZE];
+#define blk (blockbuf->check_file_blk)
struct minix2_inode *inode;
int ino;
char *name;
if (inode && S_ISDIR(inode->i_mode))
recursive_check2(ino);
pop_filename();
+#undef blk
}
#endif
-static void recursive_check(unsigned int ino)
+static void recursive_check(unsigned ino)
{
struct minix1_inode *dir;
- unsigned int offset;
+ unsigned offset;
dir = Inode1 + ino;
if (!S_ISDIR(dir->i_mode))
}
#if ENABLE_FEATURE_MINIX2
-static void recursive_check2(unsigned int ino)
+static void recursive_check2(unsigned ino)
{
struct minix2_inode *dir;
- unsigned int offset;
+ unsigned offset;
dir = Inode2 + ino;
if (!S_ISDIR(dir->i_mode))
for (i = 1; i <= INODES; i++) {
if (warn_mode && Inode1[i].i_mode && !inode_in_use(i)) {
- printf("Inode1 %d has non-zero mode. ", i);
+ printf("Inode %d has non-zero mode. ", i);
if (ask("Clear", 1)) {
Inode1[i].i_mode = 0;
changed = 1;
continue;
}
if (!inode_in_use(i)) {
- printf("Inode1 %d is used, but marked as 'unused' in the bitmap. ", i);
+ printf("Inode %d is used, but marked as 'unused' in the bitmap. ", i);
if (ask("Set", 1))
mark_inode(i);
}
if (Inode1[i].i_nlinks != inode_count[i]) {
- printf("Inode1 %d (mode=%07o), i_nlinks=%d, counted=%d. ",
- i, Inode1[i].i_mode, Inode1[i].i_nlinks, inode_count[i]);
+ printf("Inode %d (mode=%07o), i_nlinks=%d, counted=%d. ",
+ i, Inode1[i].i_mode, Inode1[i].i_nlinks,
+ inode_count[i]);
if (ask("Set i_nlinks to count", 1)) {
Inode1[i].i_nlinks = inode_count[i];
changed = 1;
}
}
for (i = FIRSTZONE; i < ZONES; i++) {
- if (zone_in_use(i) == zone_count[i])
+ if ((zone_in_use(i) != 0) == zone_count[i])
continue;
if (!zone_count[i]) {
if (bad_zone(i))
for (i = 1; i <= INODES; i++) {
if (warn_mode && Inode2[i].i_mode && !inode_in_use(i)) {
- printf("Inode1 %d has non-zero mode. ", i);
+ printf("Inode %d has non-zero mode. ", i);
if (ask("Clear", 1)) {
Inode2[i].i_mode = 0;
changed = 1;
continue;
}
if (!inode_in_use(i)) {
- printf("Inode1 %d is used, but marked as 'unused' in the bitmap. ", i);
+ printf("Inode %d is used, but marked as 'unused' in the bitmap. ", i);
if (ask("Set", 1))
mark_inode(i);
}
if (Inode2[i].i_nlinks != inode_count[i]) {
printf("Inode %d (mode=%07o), i_nlinks=%d, counted=%d. ",
- i, Inode2[i].i_mode, Inode2[i].i_nlinks,
- inode_count[i]);
+ i, Inode2[i].i_mode, Inode2[i].i_nlinks,
+ inode_count[i]);
if (ask("Set i_nlinks to count", 1)) {
Inode2[i].i_nlinks = inode_count[i];
changed = 1;
}
}
for (i = FIRSTZONE; i < ZONES; i++) {
- if (zone_in_use(i) == zone_count[i])
+ if ((zone_in_use(i) != 0) == zone_count[i])
continue;
if (!zone_count[i]) {
if (bad_zone(i))
void check2(void);
#endif
+int fsck_minix_main(int argc, char **argv);
int fsck_minix_main(int argc, char **argv)
{
struct termios tmp;
int retcode = 0;
xfunc_error_retval = 8;
+ blockbuf = xzalloc(sizeof(*blockbuf));
alloc_current_name();
#if ENABLE_FEATURE_CLEAN_UP