13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 257dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o * read_bb_file.c --- read a list of bad blocks from a FILE * 33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o * Copyright (C) 1994, 1995, 2000 Theodore Ts'o. 519c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * 619c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %Begin-Header% 7543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * This file may be redistributed under the terms of the GNU Library 8543547a52a20cb7e69d74921b2f691078fd55d83Theodore Ts'o * General Public License, version 2. 919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o * %End-Header% 103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h> 133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h> 144cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#if HAVE_UNISTD_H 153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h> 164cbe8af4b0d0c72fb28bb500c1bd8a46b00fdde3Theodore Ts'o#endif 173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <fcntl.h> 183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h> 191d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_STAT_H 203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/stat.h> 211d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif 221d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#if HAVE_SYS_TYPES_H 233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <sys/types.h> 241d2ff46ae7533ffd038534b189f272d2a4122e4eTheodore Ts'o#endif 253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 26b5abe6fac9c9e7caf4710501d1657d30e4857ef6Theodore Ts'o#include "ext2_fs.h" 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs.h" 283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Reads a list of bad blocks from a FILE * 313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 32efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, 3357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o ext2_badblocks_list *bb_list, 3450cd7e06e26d8cb232819b3d94b67e37ade80c0fTheodore Ts'o void *priv_data, 3557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o void (*invalid)(ext2_filsys fs, 3657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o blk_t blk, 3757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o char *badstr, 3850cd7e06e26d8cb232819b3d94b67e37ade80c0fTheodore Ts'o void *priv_data)) 393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 41e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall blk64_t blockno; 423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int count; 43f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o char buf[128]; 44f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 4557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o if (fs) 4657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!*bb_list) { 4919c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o retval = ext2fs_badblocks_list_create(bb_list, 10); 503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) 513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o while (!feof (f)) { 55f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (fgets(buf, sizeof(buf), f) == NULL) 563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o break; 57e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall count = sscanf(buf, "%llu", &blockno); 58f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (count <= 0) 59f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o continue; 60e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* Badblocks isn't going to be updated for 64bit */ 61e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (blockno >> 32) 62e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return EOVERFLOW; 6357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o if (fs && 6457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o ((blockno < fs->super->s_first_data_block) || 65e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall (blockno >= ext2fs_blocks_count(fs->super)))) { 663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (invalid) 6750cd7e06e26d8cb232819b3d94b67e37ade80c0fTheodore Ts'o (invalid)(fs, blockno, buf, priv_data); 683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o continue; 693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 7019c78dc07fce2d6f39b5e541562afc3ca1ea38ffTheodore Ts'o retval = ext2fs_badblocks_list_add(*bb_list, blockno); 71f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) 72f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return retval; 733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 779b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'ostruct compat_struct { 789b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o void (*invalid)(ext2_filsys, blk_t); 799b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o}; 809b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o 8157dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'ostatic void call_compat_invalid(ext2_filsys fs, blk_t blk, 82efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o char *badstr EXT2FS_ATTR((unused)), 83544349270e4c74a6feb971123884a8cf5052a7eeTheodore Ts'o void *priv_data) 8457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o{ 859b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o struct compat_struct *st; 8657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o 879b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o st = (struct compat_struct *) priv_data; 889b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o if (st->invalid) 899b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o (st->invalid)(fs, blk); 9057dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o} 9157dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o 9257dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o 9357dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o/* 9457dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o * Reads a list of bad blocks from a FILE * 9557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o */ 96efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, 9757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o ext2_badblocks_list *bb_list, 9857dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o void (*invalid)(ext2_filsys fs, blk_t blk)) 9957dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o{ 1009b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o struct compat_struct st; 1019b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o 1029b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o st.invalid = invalid; 1039b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o 1049b9a780f5a5823865f62f0c9fd194d262f63a06fTheodore Ts'o return ext2fs_read_bb_FILE2(fs, f, bb_list, &st, 10557dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o call_compat_invalid); 10657dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o} 10757dca85467cf3fc61565e916a5f2e35db8020d88Theodore Ts'o 1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 109