LINUX.ORG.RU

При ошибочном чтении сбивается дескриптор?


0

0

Столкнулся вот с такой ситуацией. Говришь readу читать с диска данные объёмом 1 МГ с области где есть битые сектора,но где-то в середине. read, соответственно, возвращает ошибку. Перехожу читать эту же область но по-секторно...read быстро отвеает -1 с errno = Input/Output error.(в начале битых секторов точно нет) А вот если переоткрыть дескриптор после попытки чтения большим куском, то read также быстро и УДАЧНО читает по-секторно те же сектора! Пробовал через fcntl вернуть флаг состояния - одинаковый в обоих случаях. В чём причина не пойму!


Ответ на: комментарий от kemm

номер сектора передается при запуске
Если раскоментить секцию ReOpen disk, то сектора читаются, иначе -1!

int main(int _argc, char** _argv) {
    
    fd = open(devname,open_flags);
    if (fd < 0) {
        err = errno;
	perror(devname);
	exit(err);
    }
    else
        printf("Device opened \n");
    
    s = lseek64(fd,(off64_t)SectorN*512,SEEK_SET);
    printf("Made seek to %u bytes \n", s);

    /* read large amount of data */
    k = read (fd, buffer, 1*1048576);
    printf ("%d \n", k);
   
    //ReOpen disk
    /*close (fd);
    fd = open(devname,open_flags);
    s = lseek64(fd,(off64_t)SectorN*512,SEEK_SET);
    printf("Made seek to %u bytes \n", s);*/

    for(i=0;i < NUMBER_OF_READS;i++){
     
        k = read (fd, buffer, buf_size);
	printf ("%d \n", k);
        if(k != buf_size){
            printf("Error in reading %u sector \n%s \n",(SectorN+i),strerror(errno));
	    if (k == -1) lseek64 (fd, 512, SEEK_CUR);
        }
        else{
            printf("good reading, %d bytes \n",k);
        }
    }
    //difftime()
    close(fd);
    return (EXIT_SUCCESS);
}

krio
() автор топика
Ответ на: комментарий от kemm

делал. вызвал lseek вот так: s = lseek64(fd,0,SEEK_CUR); printf("pos", s); Заодно видел, что read после I/O error не сдвинул позицию. Далее перехродил читать область по-секторно, но как и писал без reopen disk ошибка.

krio
() автор топика
Ответ на: комментарий от krio

Зачем 0? Сразу сдвигай на сектор, read в случае EIO не изменяет позицию.

Или после дальнейших seek'ов всё равно всегда ошибка?

PS: В dd в случае noerror как-то примерно так и сделано.

kemm
()
Ответ на: комментарий от kemm

0 чтобы убедиться, что и вправду не сдвинулся(чтобы наверняка). После дальнейших seekoв всегда ошибка если не переоткрывать дескриптор! Если переоткрывать, то до середины области(там битые сектора) всё читеться. Так вопрос в том и есть, почему так? я и флаги выводил - одинаковые... Вопрос не втом чтобы дальше двигаться и читать, а чтобы прочитать хорошие сектора, которые почему-то "помечаются" как плохие....если конечно, не делать ReOpen!

krio
() автор топика
Ответ на: комментарий от krio

Интересные вещи вы тут пишите. Возможно, что при ошибке чтения идет reset винта и он появляется в системе заново. Что если в начале открыть два файловых дескриптора, потом один из них загнать в состояние ошибки, из второго можно будет читать?

mky ★★★★★
()
Ответ на: комментарий от mky

Сейчас поэксперементирую и скажу!

krio
() автор топика
Ответ на: комментарий от bvvv

Возможно, и даже скорее будет правильно так сделать. Но понять-то, что почём тоже хочется!

krio
() автор топика
Ответ на: комментарий от krio

> Но понять-то, что почём тоже хочется!

Прочитай man.

RETURN VALUE
       On  success,  the number of bytes read is returned (zero indicates
       end of file), and the file position is advanced  by  this  number.
       It  is  not  an error if this number is smaller than the number of
       bytes requested; this may happen for example because  fewer  bytes
       are  actually  available right now (maybe because we were close to
       end-of-file, or because we are reading from a pipe, or from a ter-
       minal),  or because read() was interrupted by a signal. ON ERROR,
       -1 IS RETURNED, AND ERRNO IS SET APPROPRIATELY.  IN THIS  CASE  IT
       IS LEFT UNSPECIFIED WHETHER THE FILE POSITION (IF ANY) CHANGES.

Нужное предложение выделено.

mv ★★★★★
()
Ответ на: комментарий от mv

Читал и не один раз, но тут нет объяснения почему хорошие сектора становятся плохими!!! Можете тыкать меня носом, но я не вижу!

krio
() автор топика
Ответ на: комментарий от mky

Сделал. Создал 2 дескриптора. Через один читал большой кусок, понятно ошибка. Затем ту же область стал читать через другой дескриптор по-секторно...опять мгновенно возвращает -1 на хороших секторах.
Пробовал переоткрывать первый дескриптор, никакой разницы.
Мне кажется, что запросы реально кешируются и область действительно помечается "плохой" иначе ниака не объяснить мгновенный  ответ read -1 на хороших секторах.

Код с переокрытием дескриптора хоть и работающий, и вся информация читается, но понять где же суть никак не могу ( 

krio
() автор топика
Ответ на: комментарий от bvvv

Прочитал. Там прямолинейный процесс копирования по заданному размера блока. И если ошибка в процессе чтения была, то нету режима опускания до чтения этого куска по-секторно и разбирательства что хорошее внутри, а что нет!

krio
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.