我正在研究通过网络连接硬盘的驱动程序.有一个错误,如果我在计算机上启用两个或更多硬盘,只有第一个硬盘可以查看和识别分区.结果是,如果我在hda上有1个分区,在hdb上有1个分区,只要我连接hda,就会有一个可以挂载的分区.所以hda1一旦安装就会得到一个blkid xyz123.但是当我继续安装hdb1时,它也会出现相同的blkid,实际上,驱动程序是从hda而不是hdb读取它.
所以我想我找到了司机弄乱的地方.下面是一个调试输出,包括dump_stack,我把它放在第一个看似访问错误设备的地方.
这是代码部分:
/*basically, this is just the request_queue processor. In the log output that
follows, the second device, (hdb) has just been connected, right after hda
was connected and hda1 was mounted to the system. */
void nblk_request_proc(struct request_queue *q)
{
struct request *req;
ndas_error_t err = NDAS_OK;
dump_stack();
while((req = NBLK_NEXT_REQUEST(q)) != NULL)
{
dbgl_blk(8,"processing queue request from slot %d",SLOT_R(req));
if (test_bit(NDAS_FLAG_QUEUE_SUSPENDED, &(NDAS_GET_SLOT_DEV(SLOT_R(req))->queue_flags))) {
printk ("ndas: Queue is suspended\n");
/* Queue is suspended */
#if ( LINUX_VERSION_CODE …Run Code Online (Sandbox Code Playgroud) 所以我试图找出哪些内核进程正在调用块驱动程序中的某些函数.我认为在C库中包含backtrace()可以让它变得简单.但是我无法加载回溯.
我复制了这个示例函数来显示回溯:
http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l1.html
所有编译尝试都在一个地方或另一个地方发生错误,导致无法找到文件或未定义函数.
这是最接近的.
在Makefile中我放了编译器指令:
-rdynamic -I/usr/include
Run Code Online (Sandbox Code Playgroud)
如果我省略第二个,-I/usr/include,那么编译器报告它找不到所需的头文件execinfo.h.
接下来,在我想要进行回溯的代码中,我从示例中复制了该函数:
//trying to include the c backtrace capability
#include <execinfo.h>
void show_stackframe() {
void *trace[16];
char **messages = (char **)NULL;
int i, trace_size = 0;
trace_size = backtrace(trace, 16);
messages = backtrace_symbols(trace, trace_size);
printk(KERN_ERR "[bt] Execution path:\n");
for (i=0; i<trace_size; ++i)
printk(KERN_ERR "[bt] %s\n", messages[i]);
}
//backtrace function
Run Code Online (Sandbox Code Playgroud)
我稍后在块驱动程序函数中调用此函数,其中发生错误的第一个符号.只是:
show_stackframe();
Run Code Online (Sandbox Code Playgroud)
所以当我编译它时,会出现以下错误:
user@slinux:~/2.6-32$ make -s
Invoking make againt the kernel at /lib/modules/2.6.32-5-686/build
In file included from /usr/include/features.h:346,
from /usr/include/execinfo.h:22,
from /home/linux/2.6-32/block/block26.c:49:
/usr/include/sys/cdefs.h:287:1: …Run Code Online (Sandbox Code Playgroud) 谢谢你看这篇文章.我正在尝试修补网络块设备驱动程序.如果您需要查看源代码,请访问http://code.ximeta.com.
我注意到从linux 2.6.37开始,lock_kernel()似乎已被弃用.我读了"ioctl()的新方法",发现设备驱动程序现在应该在操作之前执行特定的锁定.
所以如果可能的话,我想要一些建议.
我在块文件夹部分找到了当前代码中我认为相关的两个部分.
Source
block->io.c
->ctrldev.c
Run Code Online (Sandbox Code Playgroud)
我把每个片段都放在你的考虑范围内.
io.c包含对lock_kernel的一次调用:
NDAS_SAL_API xbool sal_file_get_size(sal_file file, xuint64* size)
{
definitions and declarations etc..
lock_kernel();
#ifdef HAVE_UNLOCKED_IOCTL
if (filp->f_op->unlocked_ioctl) {
some small statements
error = filp->f_op->unlocked_ioctl(filp, BLKGETSIZE64, (unsigned long)size);
actions if error or not etc.
}
#endif
unlock_kernel();
return ret;
}
Run Code Online (Sandbox Code Playgroud)
并且ctrldev.c包含主要的io函数:
#include <linux/spinlock.h> // spinklock_t
#include <linux/semaphore.h> // struct semaphore
#include <asm/atomic.h> // atomic
#include <linux/interrupt.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/ide.h>
#include <linux/smp_lock.h>
#include <linux/time.h>
......
int ndas_ctrldev_ioctl(struct inode *inode, struct …Run Code Online (Sandbox Code Playgroud)