Разбираясь во внутренностях VFS для 2.6.14-ого ядра
дошел до функции (mm/filemap.c:968) __generic_file_aio_read
964 * This is the "read()" routine for all filesystems
965 * that can use the page cache directly.
966 */
967 ssize_t
968 __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
969 unsigned long nr_segs, loff_t *ppos)
970 {
971 struct file *filp = iocb->ki_filp;
972 ssize_t retval;
973 unsigned long seg;
974 size_t count;
975
976 count = 0;
977 for (seg = 0; seg < nr_segs; seg++) {
978 const struct iovec *iv = &iov[seg];
979
980 /*
981 * If any segment has a negative length, or the cumulative
982 * length ever wraps negative then return -EINVAL.
983 */
984 count += iv->iov_len;
985 if (unlikely((ssize_t)(count|iv->iov_len) < 0))
986 return -EINVAL;
987 if (access_ok(VERIFY_WRITE, iv->iov_base, iv->iov_len))
988 continue;
989 if (seg == 0)
990 return -EFAULT;
991 nr_segs = seg;
992 count -= iv->iov_len; /* This segment is no good */
993 break;
994 }
995
996 /* coalesce the iovecs and go direct-to-BIO for O_DIRECT */
997 if (filp->f_flags & O_DIRECT) {
998 loff_t pos = *ppos, size;
999 struct address_space *mapping;
1000 struct inode *inode;
1001
1002 mapping = filp->f_mapping;
1003 inode = mapping->host;
1004 retval = 0;
1005 if (!count)
1006 goto out; /* skip atime */
1007 size = i_size_read(inode);
1008 if (pos < size) {
1009 retval = generic_file_direct_IO(READ, iocb,
1010 iov, pos, nr_segs);
1011 if (retval > 0 && !is_sync_kiocb(iocb))
1012 retval = -EIOCBQUEUED;
1013 if (retval > 0)
1014 *ppos = pos + retval;
1015 }
1016 file_accessed(filp);
1017 goto out;
1018 }
1019
1020 retval = 0;
1021 if (count) {
1022 for (seg = 0; seg < nr_segs; seg++) {
1023 read_descriptor_t desc;
1024
1025 desc.written = 0;
1026 desc.arg.buf = iov[seg].iov_base;
1027 desc.count = iov[seg].iov_len;
1028 if (desc.count == 0)
1029 continue;
1030 desc.error = 0;
1031 do_generic_file_read(filp,ppos,&desc,file_read_actor);
1032 retval += desc.written;
1033 if (!retval) {
1034 retval = desc.error;
1035 break;
1036 }
1037 }
1038 }
1039 out:
1040 return retval;
1041 }
Собственно в ней все понятно кроме последнего блока(for) 1022-1037стр
происходит заполнение структуры read_descriptor_t desc 1025-1030стр
и собственно чтение 1031стр
проверка прочитанного 1033
Но почему критерием выхода из цикла является (!retval) ????
ведь это правельно только в случае nr_segs=1.
Допустим обабатывая сиситемный вызов readv(fd,iovec,10) то nr_segs будет равно 10
Поадая в цикл ситуацтя может развится следующим образом
Первая итерация : seg=0
после 1025-1030стр: desc.cout=10 desc.written=0;desc.error=0;retval=0
после 1031-1032стр:desc.cout=0 ;desc.written=10;desc.error=0;retval=10
1033 проверка (!retval) так как retval=10 то продолжить
Вторая итерация : seg=1
после 1025-1030стр: desc.cout=7 desc.written=0;desc.error=0;retval=10
при чтении произошла ошибка на 1031стр
после 1031-1032стр:desc.cout=7 ;desc.written=0;desc.error=(ERRNO);retval=10
По идее теперь надо выходить но
1033 проверка (!retval) так как retval=10 то продолжить
ПОЧЕМУ проверяется не условие (desc.count==0) а условие (!retval)
Ответ на:
комментарий
от idle
Ответ на:
Да вроде стандартный с www.kernel.org
от ia32
Ответ на:
комментарий
от idle
Ответ на:
комментарий
от idle
Ответ на:
комментарий
от anonymous
Ответ на:
комментарий
от idle
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Похожие темы
- Форум Почему не видно устройства, и как исправить это? (2017)
- Форум Всё ли нормально в символьном устройстве? (2017)
- Форум Pomogite s LPT portom (2004)
- Форум draiver dlia izvlecenija dannih iz LPT porta (2004)
- Форум Dannie iz LPT porta (2004)
- Форум Мы нашли очередную порцию глюков в Linux Kernel (2016)
- Форум Логика (2008)
- Форум Логика (2006)
- Форум ath9k_htc борьба с дропами wifi под нагрузкой клиентов и в шумной среде. патчи и настройки. (2019)
- Форум Логика $HOME = / (2016)