3636#include <sys/ioctl.h>
3737#include <linux/fs.h>
3838
39+ const char * program_name ;
40+
3941int badblocks = 0 ;
4042int recovered = 0 ;
4143int destroyed = 0 ;
@@ -46,7 +48,6 @@ unsigned int phys_block_size = 0;
4648char * buf = NULL ;
4749
4850int fd = 0 ;
49- int randfd = 0 ;
5051
5152int64_t length = 0 ;
5253
@@ -146,6 +147,13 @@ int correctsector(int64_t sectornum)
146147 return 0 ;
147148}
148149
150+ void usage ()
151+ {
152+ fprintf (stderr , "Usage: %s [-s <logical start block>] [-e <logical end block>] <block device>\n" ,
153+ program_name );
154+ exit (EXIT_FAILURE );
155+ }
156+
149157int main (int argc , char * * argv , char * * envp )
150158{
151159 printf (PACKAGE " version " VERSION "\n" );
@@ -157,13 +165,31 @@ int main(int argc, char **argv, char **envp)
157165 fprintf (stderr , "Exiting\n" );
158166 return 1 ;
159167 }
160- if (argc != 2 ) {
161- fprintf (stderr , "Usage %s <block device>\n" , * argv );
162- return 1 ;
168+
169+ program_name = argv [0 ];
170+ int64_t logical_start_block = 0 ;
171+ int64_t logical_end_block = 0 ;
172+
173+ int opt ;
174+ while ((opt = getopt (argc , argv , "s:e:" )) != -1 ) {
175+ switch (opt ) {
176+ case 's' :
177+ logical_start_block = atoll (optarg );
178+ break ;
179+ case 'e' :
180+ logical_end_block = atoll (optarg );
181+ break ;
182+ default :
183+ usage ();
184+ }
163185 }
164- fd = open (argv [1 ], O_RDWR | O_DIRECT );
186+
187+ if (optind > argc - 1 )
188+ usage ();
189+
190+ fd = open (argv [optind ], O_RDWR | O_DIRECT );
165191 if (fd < 0 ) {
166- fprintf (stderr , "Failed to open file '%s': %s\n" , argv [1 ], strerror (errno ));
192+ fprintf (stderr , "Failed to open device '%s': %s\n" , argv [optind ], strerror (errno ));
167193 return 1 ;
168194 }
169195
@@ -190,15 +216,39 @@ int main(int argc, char **argv, char **envp)
190216 }
191217 length /= phys_block_size ;
192218
193- printf ("Disk is %ld sectors big\n" , length );
219+ unsigned int logical_block_size = 0 ;
220+ if (ioctl (fd , BLKSSZGET , & logical_block_size ) == -1 ) {
221+ fprintf (stderr , "Failed to get logical block size of device: %s\n" , strerror (errno ));
222+ return 1 ;
223+ }
224+
225+ printf ("Logical sector size is %u bytes\n" , logical_block_size );
226+ printf ("Physical sector size is %u bytes\n" , phys_block_size );
227+ printf ("Disk is %ld physical sectors big\n" , length );
194228
195229 time_t starttime ;
196230 time (& starttime );
197231
198232 time_t lasttime ;
199233 time (& lasttime );
200234
201- int64_t sectornum = 0 ;
235+ int64_t sectornum = logical_start_block / (phys_block_size / logical_block_size );
236+
237+ if (logical_end_block ) {
238+ int64_t new_length = logical_end_block / (phys_block_size / logical_block_size );
239+
240+ if (new_length > length ) {
241+ fprintf (stderr , "Logical end block is out of range!\n" );
242+ return 1 ;
243+ }
244+ else
245+ length = new_length ;
246+ }
247+
248+ if (sectornum >= length ) {
249+ fprintf (stderr , "Logical start block is out of range!\n" );
250+ return 1 ;
251+ }
202252
203253 int blocksize = phys_block_size * 20 ;
204254
0 commit comments