Я только что реализовал виртуальное блочное устройство, и во время игры с ним я увидел странное поведение, связанное с ioctls.
Мое устройство - это просто зона памяти, разделенная на два сектора по 512 байт. В настоящее время я могу читать / писать из / в него с определенным смещением, используя системные вызовы.
Устройство также защищено от одновременного доступа к записи. Он принимает неограниченное количество читателей, но только один писатель за раз, и только если в настоящее время никто не читает с него.
Ioctl еще не обработан, но, несмотря на это, я регистрировал связанную информацию.
int block_mod_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg)
{
DEBUG("Entering IOCTL handling function\n");
switch(cmd)
{
default:
WARNING("Unknown ioctl call: %x\n", cmd);
WARNING("Ioctl: type=%x\tnumber=%x\tdirection=%x\tsize=%x\n", _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_DIR(cmd), _IOC_SIZE(cmd));
return -1;
}
return 0;
}
Я играл с dd
и обнаружил странное поведение, которое я не понимаю после некоторого копания.
# dd if=/dev/blkmodtest of=file.out seek=10
[ 107.367797] Oppened in read only mode
[ 107.368595] Read access: 1 Write access: 0
[ 107.370367] Reading from device
[ 107.372939] Closed read only mode
[ 107.373690] Read access: 0 Write access: 0
2+0 records in
2+0 records out
1024 bytes (1.0 kB, 1.0 KiB) copied, 0.00584625 s, 175 kB/s
# dd if=/dev/blkmodtest of=file.out skip=10
[ 111.982493] Oppened in read only mode
[ 111.983326] Read access: 1 Write access: 0
[ 111.985247] Unknown ioctl call: 80306d02
[ 111.986096] Ioctl: type=6d number=2 direction=2 size=30
[ 111.987618] Unknown ioctl call: 80306d02
[ 111.988436] Ioctl: type=6d number=2 direction=2 size=30
dd: /dev/blkmodtest: cannot skip: Invalid argument
[ 111.991032] Closed read only mode
[ 111.991705] Read access: 0 Write access: 0
0+0 records in
0+0 records out
0 bytes copied, 0.00783969 s, 0.0 kB/s
Похоже, что dd
выполняет вызов ioctl, который мой драйвер не может (очевидно) обработать. Я знаю, что я не должен давать skip=10
, но seek=10
, поскольку я читаю с устройства, но это было для целей тестирования.
В настоящее время я пытаюсь понять почему этот ioctl выпущен и для с какой целью ?
Если я хорошо понимаю найденную документацию, тип ioctl будет 'm'
, который должен быть описан в одном из следующих файлов ( source ):
'm' 00-09 linux/mmtimer.h conflict!
'm' all linux/mtio.h conflict!
'm' all linux/soundcard.h conflict!
'm' all linux/synclink.h conflict!
'm' 00-19 drivers/message/fusion/mptctl.h conflict!
'm' 00 drivers/scsi/megaraid/megaraid_ioctl.h conflict!
Я проверил эти файлы, но не могу найти полезную информацию, которая помогла бы мне лучше понять, что происходит в этом конкретном случае.