📄 io.c
字号:
return bytes < 0 ? -1 : (bytes != (ssize_t)bh->b_size ? 1 : 0);}struct buffer_head * bread (int dev, unsigned long block, size_t size){ struct buffer_head * bh; int ret; if (is_bad_block (block)) return 0; bh = getblk (dev, block, size); /*checkmem (bh->b_data, get_mem_size(bh->b_data));*/ if (buffer_uptodate (bh)) return bh; ret = f_read(bh); if (ret > 0) { die ("%s: End of file, cannot read the block (%lu).\n", __FUNCTION__, block); } else if (ret < 0) { /* BAD BLOCK LIST SUPPORT * die ("%s: Cannot read a block # %lu. Specify list of badblocks\n",*/ if (errno == EIO) { check_hd_msg(); die ("%s: Cannot read the block (%lu): (%s).\n", __FUNCTION__, block, strerror(errno)); } else { fprintf (stderr, "%s: Cannot read the block (%lu): (%s).\n", __FUNCTION__, block, strerror(errno)); return NULL; } } mark_buffer_uptodate (bh, 0); return bh;}#define ROLLBACK_FILE_START_MAGIC "_RollBackFileForReiserfsFSCK"static struct block_handler * rollback_blocks_array;static __u32 rollback_blocks_number = 0;static FILE * s_rollback_file = 0;static FILE * log_file;static int do_rollback = 0;static char * rollback_data;static int rollback_blocksize;void init_rollback_file (char * rollback_file, int *blocksize, FILE * log) { char * string; struct stat buf; if (rollback_file == NULL) return; stat(rollback_file, &buf); s_rollback_file = fopen (rollback_file, "w+"); if (s_rollback_file == NULL) { fprintf (stderr, "Cannot create file %s, work without a rollback file\n", rollback_file); return; } rollback_blocksize = *blocksize; string = ROLLBACK_FILE_START_MAGIC; fwrite (string, 28, 1, s_rollback_file); fwrite (&rollback_blocksize, sizeof (rollback_blocksize), 1, s_rollback_file); fwrite (&rollback_blocks_number, sizeof (rollback_blocks_number), 1, s_rollback_file); fflush(s_rollback_file); rollback_data = getmem(rollback_blocksize); // printf("\ncheckmem1");// fflush (stdout);// checkmem (rollback_data, get_mem_size((char *)rollback_data));// printf(" OK"); log_file = log; if (log_file) fprintf (log_file, "rollback: file (%s) initialize\n", rollback_file); do_rollback = 0;}#if 0static void erase_rollback_file (char * rollback_file) { close_rollback_file (); unlink (rollback_file); }#endifint open_rollback_file (char * rollback_file, FILE * log) { char string [28]; struct stat buf; if (rollback_file == NULL) return -1; if (stat(rollback_file, &buf)) { fprintf (stderr, "Cannot stat rollback file (%s)\n", rollback_file); return -1; } s_rollback_file = fopen (rollback_file, "r+"); if (s_rollback_file == NULL) { fprintf (stderr, "Cannot open file (%s)\n", rollback_file); return -1; } fread (string, 28, 1, s_rollback_file); if (!strcmp (string, ROLLBACK_FILE_START_MAGIC)) { fprintf (stderr, "Specified file (%s) does not look like a rollback file\n", rollback_file); fclose (s_rollback_file); s_rollback_file = 0; return -1; } fread (&rollback_blocksize, sizeof (rollback_blocksize), 1, s_rollback_file); if (rollback_blocksize <= 0) { fprintf(stderr, "rollback: wrong rollback blocksize, exit\n"); return -1; } log_file = log; if (log_file) fprintf (log_file, "rollback: file (%s) opened\n", rollback_file); do_rollback = 1; return 0;}void close_rollback_file () { if (s_rollback_file == 0) return; if (!do_rollback) { if (fseek (s_rollback_file, 28 + sizeof(int), SEEK_SET) == (loff_t)-1) return; fwrite (&rollback_blocks_number, sizeof (rollback_blocksize), 1, s_rollback_file); if (log_file != 0) fprintf (log_file, "rollback: %d blocks backed up\n", rollback_blocks_number); } fclose (s_rollback_file); freemem (rollback_data); freemem (rollback_blocks_array);// fprintf (stdout, "rollback: (%u) blocks saved, \n", rollback_blocks_number); /* for (i = 0; i < rollback_blocks_number; i++) fprintf(stdout, "device (%Lu), block number (%u)\n", rollback_blocks_array [i].device, rollback_blocks_array [i].blocknr); fprintf(stdout, "\n"); */}void do_fsck_rollback (int fd_device, int fd_journal_device, FILE * progress) { long long int offset; struct stat buf; int descriptor; ssize_t retval; int count_failed = 0; int count_rollbacked = 0; int b_dev; int n_dev = 0; int n_journal_dev = 0; unsigned long total, done = 0; if (fd_device == 0) { fprintf(stderr, "rollback: unspecified device, exit\n"); return; } if (fd_journal_device) { if (!fstat (fd_journal_device, &buf)) { n_journal_dev = buf.st_rdev; } else { fprintf(stderr, "rollback: specified journal device cannot be stated\n"); } } if (!fstat (fd_device, &buf)) { n_dev = buf.st_rdev; } else { fprintf(stderr, "rollback: specified device cannot be stated, exit\n"); return; } rollback_data = getmem (rollback_blocksize);// printf("\ncheckmem2");// fflush (stdout);// checkmem (rollback_data, get_mem_size((char *)rollback_data));// printf(" OK"); fread (&rollback_blocks_number, sizeof (rollback_blocks_number), 1, s_rollback_file); total = rollback_blocks_number; while (1) { print_how_far (progress, &done, rollback_blocks_number, 1, 0/*not quiet*/); descriptor = 0; if ((retval = fread (&b_dev, sizeof (b_dev), 1, s_rollback_file)) <= 0) { if (retval) fprintf (stderr, "rollback: fread: %s\n", strerror (errno)); break; } if ((retval = fread (&offset, sizeof (offset), 1, s_rollback_file)) <= 0) { if (retval) fprintf (stderr, "rollback: fread: %s\n", strerror (errno)); break; } if ((retval = fread (rollback_data, rollback_blocksize, 1, s_rollback_file)) <= 0) { if (retval) fprintf (stderr, "rollback: fread: %s\n", strerror (errno)); break; } if (n_dev == b_dev) descriptor = fd_device; if ((n_journal_dev) && (n_journal_dev == b_dev)) descriptor = fd_journal_device; if (descriptor == 0) { fprintf(stderr, "rollback: block from unknown device, skip block\n"); count_failed ++; continue; } if (lseek (descriptor, offset, SEEK_SET) == (loff_t)-1) { fprintf(stderr, "device cannot be lseeked, skip block\n"); count_failed ++; continue; } if (write (descriptor, rollback_data, rollback_blocksize) == -1) { fprintf (stderr, "rollback: write %d bytes returned error " "(block=%lld, dev=%d): %s\n", rollback_blocksize, offset/rollback_blocksize, b_dev, strerror (errno)); count_failed ++; } else { count_rollbacked ++; /*if you want to know what gets rollbacked, uncomment it*//* if (log_file != 0 && log_file != stdout) fprintf (log_file, "rollback: block %Lu of device %Lu was restored\n", (loff_t)offset/rollback_blocksize, b_dev);*/// fprintf (stdout, "rollback: block (%Ld) written\n", (loff_t)offset/rollback_blocksize); } } printf ("\n"); if (log_file != 0) fprintf (log_file, "rollback: (%u) blocks restored\n", count_rollbacked);}/*static void rollback__mark_block_saved (struct block_handler * rb_e) { if (rollback_blocks_array == NULL) rollback_blocks_array = getmem (ROLLBACK__INCREASE_BLOCK_NUMBER * sizeof (*rb_e)); if (rollback_blocks_number == get_mem_size ((void *)rollback_blocks_array) / sizeof (*rb_e)) rollback_blocks_array = expandmem (rollback_blocks_array, get_mem_size((void *)rollback_blocks_array), ROLLBACK__INCREASE_BLOCK_NUMBER * sizeof (*rb_e));// checkmem ((char *)rollback_blocks_array, get_mem_size((char *)rollback_blocks_array)); rollback_blocks_array[rollback_blocks_number] = *rb_e; rollback_blocks_number ++; qsort (rollback_blocks_array, rollback_blocks_number, sizeof (*rb_e), rollback_compare); // printf("\ncheckmem3");// fflush (stdout);// checkmem ((char *)rollback_blocks_array, get_mem_size((char *)rollback_blocks_array));// printf(" OK");}*//* for now - just make sure that bad blocks did not get here */int bwrite (struct buffer_head * bh){ unsigned long long offset; long long bytes, size; if (is_bad_block (bh->b_blocknr)) { fprintf (stderr, "bwrite: bad block is going to be written: %lu\n", bh->b_blocknr); exit(8); } if (!buffer_dirty (bh) || !buffer_uptodate (bh)) return 0; buffer_writes++ ; if (bh->b_start_io) /* this is used by undo feature of reiserfsck */ bh->b_start_io (bh->b_blocknr); size = bh->b_size; offset = (loff_t)size * (loff_t)bh->b_blocknr; if (lseek (bh->b_dev, offset, SEEK_SET) == (loff_t)-1){ fprintf (stderr, "bwrite: lseek to position %llu (block=%lu, dev=%d): %s\n", offset, bh->b_blocknr, bh->b_dev, strerror(errno)); exit(8); /* File system errors left uncorrected */ } if (s_rollback_file != NULL && bh->b_size == (unsigned long)rollback_blocksize) { struct stat buf; __u32 position; struct block_handler block_h; /*log previous content into the log*/ if (!fstat (bh->b_dev, &buf)) { block_h.blocknr = bh->b_blocknr; block_h.device = buf.st_rdev; if (reiserfs_bin_search(&block_h, rollback_blocks_array, rollback_blocks_number, sizeof (block_h), &position, blockdev_list_compare) != POSITION_FOUND) { /*read initial data from the disk*/ if (read(bh->b_dev, rollback_data, bh->b_size) == (long long)bh->b_size) { fwrite(&buf.st_rdev, sizeof (buf.st_rdev), 1, s_rollback_file); fwrite(&offset, sizeof (offset), 1, s_rollback_file); fwrite(rollback_data, rollback_blocksize, 1, s_rollback_file); fflush(s_rollback_file); blocklist__insert_in_position(&block_h, (void *)(&rollback_blocks_array), &rollback_blocks_number, sizeof(block_h), &position); /*if you want to know what gets saved, uncomment it*//* if (log_file != 0 && log_file != stdout) { fprintf (log_file, "rollback: block %lu of device %Lu was " "backed up\n", bh->b_blocknr, buf.st_rdev); }*/ } else { fprintf (stderr, "bwrite: read (block=%lu, dev=%d): %s\n", bh->b_blocknr, bh->b_dev, strerror (errno)); exit(8); } if (lseek (bh->b_dev, offset, SEEK_SET) == (loff_t)-1) { fprintf (stderr, "bwrite: lseek to position %llu (block=%lu, " "dev=%d): %s\n", offset, bh->b_blocknr, bh->b_dev, strerror(errno)); exit(8); } } } else { fprintf (stderr, "bwrite: fstat of (%d) returned -1: %s\n", bh->b_dev, strerror(errno)); } } else if (s_rollback_file != NULL) { fprintf (stderr, "rollback: block (%lu) has the size different from " "the fs uses, block skipped\n", bh->b_blocknr); } bytes = write(bh->b_dev, bh->b_data, size); if (bytes != size) { fprintf (stderr, "bwrite: write %lld bytes returned %lld (block=%ld, " "dev=%d): %s\n", size, bytes, bh->b_blocknr, bh->b_dev, strerror(errno)); exit(8); } mark_buffer_clean (bh); if (bh->b_end_io) { bh->b_end_io(bh, 1) ; } return 0;}static int _check_and_free_buffer_list(struct buffer_head *list) { struct buffer_head *next = list ; int count = 0 ; if (!list) return 0 ; for(;;) { if (next->b_count != 0) fprintf (stderr, "check_and_free_buffer_mem: not free buffer " "(%d, %ld, %ld, %d)\n", next->b_dev, next->b_blocknr, next->b_size, next->b_count); if (buffer_dirty (next) && buffer_uptodate (next)) fprintf (stderr, "check_and_free_buffer_mem: dirty buffer " "(%d %lu) found\n", next->b_dev, next->b_blocknr); freemem (next->b_data); count++; next = next->b_next; if (next == list) break; } return count;}static void check_and_free_buffer_mem (void){ int count = 0; struct buffer_head * next ;// printf("check and free buffer mem, hits %d misses %d reads %d writes %d\n", // buffer_hits, buffer_misses, buffer_reads, buffer_writes) ; /*sync_buffers (0, 0);*/ count = _check_and_free_buffer_list(Buffer_list_head); count += _check_and_free_buffer_list(g_free_buffers); if (count != g_nr_buffers) die ("check_and_free_buffer_mem: found %d buffers, must be %d", count, g_nr_buffers); /* free buffer heads */ while ((next = g_buffer_heads)) { g_buffer_heads = *(struct buffer_head **) (next + GROW_BUFFERS__NEW_BUFERS_PER_CALL); freemem (next); } return;}/* */void free_buffers (void){ check_and_free_buffer_mem ();}static void _invalidate_buffer_list(struct buffer_head *list, int dev){ struct buffer_head * next; if (!list) return; next = list; for (;;) { if (next->b_dev == dev) { if (buffer_dirty (next) || next->b_count) fprintf (stderr, "invalidate_buffers: dirty buffer or used buffer (%d %lu) found\n", next->b_count, next->b_blocknr); next->b_state = 0; remove_from_hash_queue (next); } next = next->b_next; if (next == list) break; }}/* forget all buffers of the given device */void invalidate_buffers (int dev){ _invalidate_buffer_list(Buffer_list_head, dev) ; _invalidate_buffer_list(g_free_buffers, dev) ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -