read_bb.c revision 357d1863d64ce807c2904e101fc87d3f6be2f3ca
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * read_bb --- read the bad blocks inode
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright (C) 1994 Theodore Ts'o.
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * %Begin-Header%
7971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com * This file may be redistributed under the terms of the GNU Public
857f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com * License.
957f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com * %End-Header%
1057f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com */
1157f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com
1257f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com#include <stdio.h>
1357f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com#include <string.h>
1457f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com#if HAVE_UNISTD_H
1557f7abc8659f17e58fc2d1410117033ad524f9d3epoger@google.com#include <unistd.h>
16b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com#endif
176f6568b27eae62fea23ab8192c6da02ab892bb5eepoger@google.com#include <fcntl.h>
1837269607334b99bf814c7dc6b426745d9b7c7e3fepoger@google.com#include <time.h>
197bc13a62609149f0b535c2f3ff7210eb834d8b36epoger@google.com#if HAVE_SYS_STAT_H
205f6a00775511b5675607c2bfdbb096c0a815025depoger@google.com#include <sys/stat.h>
21908f5836626d792c5e33ad93f44c6a418a0cc8f5epoger@google.com#endif
22b9b9a18ab459c2616ac4a52c9f8cc0637d284229reed@android.com#if HAVE_SYS_TYPES_H
23d9ba9a05d6f5766fdb1378b6ed84c0659009a8dascroggo@google.com#include <sys/types.h>
248a85d0c4938173476d037d7af0ee3b9436a1234ereed@google.com#endif
254370aedf7f55af74e9ebb4ad1c2e010c08236dfajunov@google.com
26971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "ext2_fs.h"
27de96163a80167636d95837f9ee6a2e98baf9d350epoger@google.com#include "ext2fs.h"
285af9b2032b552516c9223d9fb22185b022b13c62scroggo@google.com
298015dd83ae37147bb630d4751030868051ad0caereed@android.comstruct read_bb_record {
308015dd83ae37147bb630d4751030868051ad0caereed@android.com	ext2_badblocks_list	bb_list;
318015dd83ae37147bb630d4751030868051ad0caereed@android.com	errcode_t	err;
32e8ebeb1f8fde6525bbab988c6090a5d3ab19855bepoger@google.com};
339875dd14af6d768da8d1a4be58b98fc91ceca0ddtomhudson@google.com
34977b9c8af3ef1b9a2fa2a0037cf3734cf2ba13d9robertphillips@google.com/*
3572c9672ce274a3b6cb40800d66374edf25b157a3scroggo@google.com * Helper function for ext2fs_read_bb_inode()
362a48c3adb7cf4fc754f99a41352210b4a99edf04bsalomon@google.com */
37310478e72c63e639373465216271b81f1e4a9136epoger@google.com#ifdef __TURBOC__
383cb834bd27a16cc60ff30adae96659558c2dc91fjunov@chromium.org #pragma argsused
3972c9672ce274a3b6cb40800d66374edf25b157a3scroggo@google.com#endif
400770044da6d61dcbc8d9673fed8dd92460faa314reed@google.comstatic int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
4150c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com			  e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)),
4250c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com			  blk_t ref_block EXT2FS_ATTR((unused)),
4337269607334b99bf814c7dc6b426745d9b7c7e3fepoger@google.com			  int ref_offset EXT2FS_ATTR((unused)),
4450c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com			  void *priv_data)
4550c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com{
4650c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com	struct read_bb_record *rb = (struct read_bb_record *) priv_data;
47ee8a8e3931c1d3f39755ee8beaf0c7cb1ba91888epoger@google.com
4850c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com	if (blockcnt < 0)
4950c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com		return 0;
5050c79d886bf435d3a9cad056885370e2c3f526adbsalomon@google.com
51ee8a8e3931c1d3f39755ee8beaf0c7cb1ba91888epoger@google.com	if ((*block_nr < fs->super->s_first_data_block) ||
52cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com	    (*block_nr >= fs->super->s_blocks_count))
53cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com		return 0;	/* Ignore illegal blocks */
54cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com
55cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com	rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
566f6568b27eae62fea23ab8192c6da02ab892bb5eepoger@google.com	if (rb->err)
576f6568b27eae62fea23ab8192c6da02ab892bb5eepoger@google.com		return BLOCK_ABORT;
586f6568b27eae62fea23ab8192c6da02ab892bb5eepoger@google.com	return 0;
59cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com}
6080724dfeb320d1152128cd33636c9024952432d3epoger@google.com
61cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com/*
62123ac1d4eab757052407064623643fdc59f85363bsalomon@google.com * Reads the current bad blocks from the bad blocks inode.
63cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com */
64cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comerrcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
65cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com{
6676c913db20de7ae1baa49ae66e943bf7f40781ccepoger@google.com	errcode_t	retval;
6776c913db20de7ae1baa49ae66e943bf7f40781ccepoger@google.com	struct read_bb_record rb;
688923c6cfd580ac9accb11b909fa2a033d69553aareed@google.com	struct ext2_inode inode;
698923c6cfd580ac9accb11b909fa2a033d69553aareed@google.com	blk_t	numblocks;
700770044da6d61dcbc8d9673fed8dd92460faa314reed@google.com
719875dd14af6d768da8d1a4be58b98fc91ceca0ddtomhudson@google.com	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
729875dd14af6d768da8d1a4be58b98fc91ceca0ddtomhudson@google.com
730770044da6d61dcbc8d9673fed8dd92460faa314reed@google.com	if (!*bb_list) {
7400dae86f5872b60927b28a32b375bc01cd7c61c9reed@android.com		retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
75e3cc2eb88fef9b2123c6ea2ed813ce53b6385926epoger@google.com		if (retval)
76e3cc2eb88fef9b2123c6ea2ed813ce53b6385926epoger@google.com			return retval;
77e3cc2eb88fef9b2123c6ea2ed813ce53b6385926epoger@google.com		if (inode.i_blocks < 500)
78b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com			numblocks = (inode.i_blocks /
79b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com				     (fs->blocksize / 512)) + 20;
80b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com		else
81b29c883fb46ac6099440d82ac57b86d25386daedbungeman@google.com			numblocks = 500;
8246cce91f4859b9c229938d4d649870c0a43b1806reed@google.com		retval = ext2fs_badblocks_list_create(bb_list, numblocks);
8346cce91f4859b9c229938d4d649870c0a43b1806reed@google.com		if (retval)
840a09eef79053f93a9b2311c6a29275abf39f189ebsalomon@google.com			return retval;
8546cce91f4859b9c229938d4d649870c0a43b1806reed@google.com	}
860a09eef79053f93a9b2311c6a29275abf39f189ebsalomon@google.com
8746cce91f4859b9c229938d4d649870c0a43b1806reed@google.com	rb.bb_list = *bb_list;
8846cce91f4859b9c229938d4d649870c0a43b1806reed@google.com	rb.err = 0;
8900dae86f5872b60927b28a32b375bc01cd7c61c9reed@android.com	retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, BLOCK_FLAG_READ_ONLY,
9000dae86f5872b60927b28a32b375bc01cd7c61c9reed@android.com				       0, mark_bad_block, &rb);
9100dae86f5872b60927b28a32b375bc01cd7c61c9reed@android.com	if (retval)
9200dae86f5872b60927b28a32b375bc01cd7c61c9reed@android.com		return retval;
9300dae86f5872b60927b28a32b375bc01cd7c61c9reed@android.com
943914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com	return rb.err;
953914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com}
963914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com
973914958a49ee089ddeb04acc16373aae8bc2eaf7bsalomon@google.com
98dd0ac281e920b01a63789893cc3e7422789658ddreed@android.com