Главная » Просмотр файлов » Linux Device Drivers 2nd Edition

Linux Device Drivers 2nd Edition (779877), страница 82

Файл №779877 Linux Device Drivers 2nd Edition (Linux Device Drivers 2nd Edition) 82 страницаLinux Device Drivers 2nd Edition (779877) страница 822018-01-10СтудИзба
Просмтор этого файла доступен только зарегистрированным пользователям. Но у нас супер быстрая регистрация: достаточно только электронной почты!

Текст из файла (страница 82)

Since thisfunction operates only on the given request structure, calling it this way is safe—as long as the request is not on the queue. The call to end_that_r equest_last, however, requires that the lock be held, since it returns the request to the requestqueue’s free list.

The function also always exits from the outer loop (and the function as a whole) with the io_request_lock held and the device lock released.Multiqueue drivers must, of course, clean up all of their queues at module removaltime:for (i = 0; i < sbull_devs; i++)blk_cleanup_queue(&sbull_devices[i].queue);blk_dev[major].queue = NULL;It is worth noting, briefly, that this code could be made more efficient.

It allocatesa whole set of request queues at initialization time, even though some of themmay never be used. A request queue is a large structure, since many (perhapsthousands) of request structures are allocated when the queue is initialized. Amore clever implementation would allocate a request queue when needed ineither the open method or the queue function. We chose a simpler implementationfor sbull in order to avoid complicating the code.That covers the mechanics of multiqueue drivers. Drivers handling real hardwaremay have other issues to deal with, of course, such as serializing access to a controller. But the basic structure of multiqueue drivers is as we have seen here.Doing Without the Request QueueMuch of the discussion to this point has centered around the manipulation of theI/O request queue. The purpose of the request queue is to improve performanceby allowing the driver to act asynchronously and, crucially, by allowing the merging of contiguous (on the disk) operations.

For normal disk devices, operations oncontiguous blocks are common, and this optimization is necessary.34522 June 2001 16:41http://openlib.org.uaChapter 12: Loading Block DriversNot all block devices benefit from the request queue, however. sbull, for example,processes requests synchronously and has no problems with seek times. For sbull,the request queue actually ends up slowing things down. Other types of blockdevices also can be better off without a request queue. For example, RAIDdevices, which are made up of multiple disks, often spread ‘‘contiguous’’ blocksacross multiple physical devices. Block devices implemented by the logical volumemanager (LVM) capability (which first appeared in 2.4) also have an implementation that is more complex than the block interface that is presented to the rest ofthe kernel.In the 2.4 kernel, block I/O requests are placed on the queue by the function_ _make_r equest, which is also responsible for invoking the driver’s request function.

Block drivers that need more control over request queueing, however, canreplace that function with their own ‘‘make request’’ function. The RAID and LVMdrivers do so, providing their own variant that, eventually, requeues each I/Orequest (with different block numbers) to the appropriate low-level device (ordevices) that make up the higher-level device.

A RAM-disk driver, instead, can execute the I/O operation directly.sbull, when loaded with the noqueue=1 option on 2.4 systems, will provide itsown ‘‘make request’’ function and operate without a request queue. The first stepin this scenario is to replace _ _make_r equest. The ‘‘make request’’ function pointeris stored in the request queue, and can be changed with blk_queue_make_r equest:void blk_queue_make_request(request_queue_t *queue,make_request_fn *func);The make_request_fn type, in turn, is defined as follows:typedef int (make_request_fn) (request_queue_t *q, int rw,struct buffer_head *bh);The ‘‘make request’’ function must arrange to transfer the given block, and see toit that the b_end_io function is called when the transfer is done.

The kernel doesnot hold the io_request_lock lock when calling the make_r equest_fn function, so the function must acquire the lock itself if it will be manipulating therequest queue. If the transfer has been set up (not necessarily completed), thefunction should return 0.The phrase ‘‘arrange to transfer’’ was chosen carefully; often a driver-specific makerequest function will not actually transfer the data. Consider a RAID device. Whatthe function really needs to do is to map the I/O operation onto one of its constituent devices, then invoke that device’s driver to actually do the work.

Thismapping is done by setting the b_rdev member of the buffer_head structureto the number of the ‘‘real’’ device that will do the transfer, then signaling that theblock still needs to be written by returning a nonzero value.34622 June 2001 16:41http://openlib.org.uaHandling Requests: The Detailed ViewWhen the kernel sees a nonzero return value from the make request function, itconcludes that the job is not done and will try again. But first it will look up themake request function for the device indicated in the b_rdev field. Thus, in theRAID case, the RAID driver’s ‘‘make request’’ function will not be called again;instead, the kernel will pass the block to the appropriate function for the underlying device.sbull, at initialization time, sets up its make request function as follows:if (noqueue)blk_queue_make_request(BLK_DEFAULT_QUEUE(major), sbull_make_request);It does not call blk_init_queue when operating in this mode, because the requestqueue will not be used.When the kernel generates a request for an sbull device, it will callsbull_make_r equest, which is as follows:int sbull_make_request(request_queue_t *queue, int rw,struct buffer_head *bh){u8 *ptr;/* Figure out what we are doing */Sbull_Dev *device = sbull_devices + MINOR(bh->b_rdev);ptr = device->data + bh->b_rsector * sbull_hardsect;/* Paranoid check; this apparently can really happen */if (ptr + bh->b_size > device->data + sbull_blksize*sbull_size) {static int count = 0;if (count++ < 5)printk(KERN_WARNING "sbull: request past end of device\n");bh->b_end_io(bh, 0);return 0;}/* This could be a high-memory buffer; shift it down */#if CONFIG_HIGHMEMbh = create_bounce(rw, bh);#endif/* Do the transfer */switch(rw) {case READ:case READA: /* Read ahead */memcpy(bh->b_data, ptr, bh->b_size); /* from sbull to buffer */bh->b_end_io(bh, 1);break;case WRITE:refile_buffer(bh);memcpy(ptr, bh->b_data, bh->b_size); /* from buffer to sbull */mark_buffer_uptodate(bh, 1);34722 June 2001 16:41http://openlib.org.uaChapter 12: Loading Block Driversbh->b_end_io(bh, 1);break;default:/* can’t happen */bh->b_end_io(bh, 0);break;}/* Nonzero return means we’re done */return 0;}For the most part, this code should look familiar.

It contains the usual calculationsto determine where the block lives within the sbull device and uses memcpy toperform the operation. Because the operation completes immediately, it is able tocall bh->b_end_io to indicate the completion of the operation, and it returns 0to the kernel.There is, however, one detail that the ‘‘make request’’ function must take care of.The buffer to be transferred could be resident in high memory, which is notdirectly accessible by the kernel. High memory is covered in detail in Chapter 13.We won’t repeat the discussion here; suffice it to say that one way to deal with theproblem is to replace a high-memory buffer with one that is in accessible memory.The function cr eate_bounce will do so, in a way that is transparent to the driver.The kernel normally uses cr eate_bounce before placing buffers in the driver’srequest queue; if the driver implements its own make_r equest_fn, however, it musttake care of this task itself.How Mounting and Unmounting WorksBlock devices differ from char devices and normal files in that they can bemounted on the computer’s filesystem.

Mounting provides a level of indirectionnot seen with char devices, which are accessed through a struct file pointerthat is held by a specific process. When a filesystem is mounted, there is no process holding that file structure.When the kernel mounts a device in the filesystem, it invokes the normal openmethod to access the driver. However, in this case both the filp and inodearguments to open are dummy variables. In the file structure, only the f_modeand f_flags fields hold anything meaningful; in the inode structure onlyi_rdev may be used. The remaining fields hold random values and should notbe used. The value of f_mode tells the driver whether the device is to bemounted read-only (f_mode == FMODE_READ) or read/write (f_mode ==(FMODE_READ|FMODE_WRITE)).34822 June 2001 16:41http://openlib.org.uaThe ioctl MethodThis interface may seem a little strange; it is done this way for two reasons.

First isthat the open method can still be called normally by a process that accesses thedevice directly — the mkfs utility, for example. The other reason is a historical artifact: block devices once used the same file_operations structure as chardevices, and thus had to conform to the same interface.Other than the limitations on the arguments to the open method, the driver doesnot really see anything unusual when a filesystem is mounted. The device isopened, and then the request method is invoked to transfer blocks back and forth.The driver cannot really tell the difference between operations that happen inresponse to an individual process (such as fsck) and those that originate in thefilesystem layers of the kernel.As far as umount is concerned, it just flushes the buffer cache and calls the releasedriver method.

Since there is no meaningful filp to pass to the release method,the kernel uses NULL. Since the release implementation of a block driver can’t usefilp->private_data to access device information, it uses inode->i_rdev todifferentiate between devices instead. This is how sbull implements release:int sbull_release (struct inode *inode, struct file *filp){Sbull_Dev *dev = sbull_devices + MINOR(inode->i_rdev);spin_lock(&dev->lock);dev->usage--;MOD_DEC_USE_COUNT;spin_unlock(&dev->lock);return 0;}Other driver functions are not affected by the ‘‘missing filp’’ problem becausethey aren’t involved with mounted filesystems. For example, ioctl is issued only byprocesses that explicitly open the device.The ioctl MethodLike char devices, block devices can be acted on by using the ioctl system call.The only relevant difference between block and char ioctl implementations is thatblock drivers share a number of common ioctl commands that most drivers areexpected to support.The commands that block drivers usually handle are the following, declared in<linux/fs.h>.BLKGETSIZERetrieve the size of the current device, expressed as the number of sectors.The value of arg passed in by the system call is a pointer to a long value34922 June 2001 16:41http://openlib.org.uaChapter 12: Loading Block Driversand should be used to copy the size to a user-space variable.

Характеристики

Тип файла
PDF-файл
Размер
7,36 Mb
Тип материала
Высшее учебное заведение

Список файлов книги

Свежие статьи
Популярно сейчас
А знаете ли Вы, что из года в год задания практически не меняются? Математика, преподаваемая в учебных заведениях, никак не менялась минимум 30 лет. Найдите нужный учебный материал на СтудИзбе!
Ответы на популярные вопросы
Да! Наши авторы собирают и выкладывают те работы, которые сдаются в Вашем учебном заведении ежегодно и уже проверены преподавателями.
Да! У нас любой человек может выложить любую учебную работу и зарабатывать на её продажах! Но каждый учебный материал публикуется только после тщательной проверки администрацией.
Вернём деньги! А если быть более точными, то автору даётся немного времени на исправление, а если не исправит или выйдет время, то вернём деньги в полном объёме!
Да! На равне с готовыми студенческими работами у нас продаются услуги. Цены на услуги видны сразу, то есть Вам нужно только указать параметры и сразу можно оплачивать.
Отзывы студентов
Ставлю 10/10
Все нравится, очень удобный сайт, помогает в учебе. Кроме этого, можно заработать самому, выставляя готовые учебные материалы на продажу здесь. Рейтинги и отзывы на преподавателей очень помогают сориентироваться в начале нового семестра. Спасибо за такую функцию. Ставлю максимальную оценку.
Лучшая платформа для успешной сдачи сессии
Познакомился со СтудИзбой благодаря своему другу, очень нравится интерфейс, количество доступных файлов, цена, в общем, все прекрасно. Даже сам продаю какие-то свои работы.
Студизба ван лав ❤
Очень офигенный сайт для студентов. Много полезных учебных материалов. Пользуюсь студизбой с октября 2021 года. Серьёзных нареканий нет. Хотелось бы, что бы ввели подписочную модель и сделали материалы дешевле 300 рублей в рамках подписки бесплатными.
Отличный сайт
Лично меня всё устраивает - и покупка, и продажа; и цены, и возможность предпросмотра куска файла, и обилие бесплатных файлов (в подборках по авторам, читай, ВУЗам и факультетам). Есть определённые баги, но всё решаемо, да и администраторы реагируют в течение суток.
Маленький отзыв о большом помощнике!
Студизба спасает в те моменты, когда сроки горят, а работ накопилось достаточно. Довольно удобный сайт с простой навигацией и огромным количеством материалов.
Студ. Изба как крупнейший сборник работ для студентов
Тут дофига бывает всего полезного. Печально, что бывают предметы по которым даже одного бесплатного решения нет, но это скорее вопрос к студентам. В остальном всё здорово.
Спасательный островок
Если уже не успеваешь разобраться или застрял на каком-то задание поможет тебе быстро и недорого решить твою проблему.
Всё и так отлично
Всё очень удобно. Особенно круто, что есть система бонусов и можно выводить остатки денег. Очень много качественных бесплатных файлов.
Отзыв о системе "Студизба"
Отличная платформа для распространения работ, востребованных студентами. Хорошо налаженная и качественная работа сайта, огромная база заданий и аудитория.
Отличный помощник
Отличный сайт с кучей полезных файлов, позволяющий найти много методичек / учебников / отзывов о вузах и преподователях.
Отлично помогает студентам в любой момент для решения трудных и незамедлительных задач
Хотелось бы больше конкретной информации о преподавателях. А так в принципе хороший сайт, всегда им пользуюсь и ни разу не было желания прекратить. Хороший сайт для помощи студентам, удобный и приятный интерфейс. Из недостатков можно выделить только отсутствия небольшого количества файлов.
Спасибо за шикарный сайт
Великолепный сайт на котором студент за не большие деньги может найти помощь с дз, проектами курсовыми, лабораторными, а также узнать отзывы на преподавателей и бесплатно скачать пособия.
Популярные преподаватели
Добавляйте материалы
и зарабатывайте!
Продажи идут автоматически
6294
Авторов
на СтудИзбе
314
Средний доход
с одного платного файла
Обучение Подробнее