I am now using the filp_open() call in kernel to scan for tape 
devices in lieu of chrdev_open()/blkdev_open(), but I have 
discovered that calling this api with non-existent devices 
appears to result in memory corruption and some nasty oops.

I have attached the code fragment and oops generated by calling
ScanTapeDevices().  This basically works the way Al Viro described,
and I like the auto-probing of the tape device via calls to 
filp_open(), which is really slick, if I can just get over 
the oops, I think it's there.

Jeff


read enter 
Unable to handle kernel paging request at virtual address c4035020 
current->tss.cr3 = 03dcc000, %cr3 = 03dcc000 
*pde = 03f7a063 
*pte = 00000000 
Oops: 0000 
CPU:    0 
EIP:    0010:[sys_mremap+31/884] 
EFLAGS: 00010206 
eax: ffffffff   ebx: c3fefb00   ecx: c023e964   edx: c404d020 
esi: c4035020   edi: c404d020   ebp: c3fefb60   esp: c238dd28 
ds: 0018   es: 0018   ss: 0018 
Process insmod (pid: 658, process nr: 23, stackpage=c238d000) 
Stack: c238dd74 c238ddc8 00000020 00000020 ffffffe0 c3fefb6c c238dd50 00000000  
       00000020 00000004 00000020 c4049c30 c404d020 00000048 00000020 00002000  
       00000000 00000000 c4049d35 00000000 c025b5a0 c01cb0b1 00000000 0000000d  
Call Trace: 
[lockd:nlm4_granted_Rea24c726+123124/114388216] 
[lockd:nlm4_granted_Rea24c726+136420/114374920] 
[lockd:nlm4_granted_Rea24c726+123385/114387955] 
[fbcon_cfb24_putc+69/808] 
[lockd:nlm4_granted_Rea24c726+143844/114367496] 
[lockd:nlm4_granted_Rea24c726+130960/114380380] 
[lockd:nlm4_granted_Rea24c726+143588/114367752]  
[lockd:nlm4_granted_Rea24c726+127420/114383920] 
[lockd:nlm4_granted_Rea24c726+126445/114384895] 
[lockd:nlm4_granted_Rea24c726+126268/114385072] 
[lockd:nlm4_granted_Rea24c726+121676/114389664] 
[lockd:nlm4_granted_Rea24c726+120083/114391257] 
[lockd:nlm4_granted_Rea24c726+144284/114367056] 
[ide_timer_expiry+172/436] 
[lockd:nlm4_granted_Rea24c726+126932/114384408]  
[lockd:nlm4_granted_Rea24c726+120004/114391336] 
[lockd:nlm4_granted_Rea24c726+127808/114383532] 
[lockd:nlm4_granted_Rea24c726+120004/114391336] 
[getrusage+263/924] 
[lockd:nlm4_granted_Rea24c726+142028/114369312] 
[lockd:nlm4_granted_Rea24c726+87236/114424104] 
[lockd:nlm4_granted_Rea24c726+120076/114391264] 
[do_signal+512/616]  
Code: ac ae 75 08 84 c0 75 f8 31 c0 eb 04 19 c0 0c 01 85 c0 75 d9  


BYTE *scsi_tape_handles[] =
{
    "/dev/st0",  "/dev/st1",  "/dev/st2",  "/dev/st3",  "/dev/st4",
    "/dev/st5",  "/dev/st6",  "/dev/st7",  "/dev/st8",  "/dev/st9",
    "/dev/st10", "/dev/st11", "/dev/st12", "/dev/st13", "/dev/st14",
    "/dev/st15", "/dev/st16", "/dev/st17", "/dev/st18", "/dev/st19",
    "/dev/st20", "/dev/st21", "/dev/st22", "/dev/st23", "/dev/st24",
    "/dev/st25", "/dev/st26", "/dev/st27", "/dev/st28", "/dev/st29",
    "/dev/st30", "/dev/st31",
    0,
};

kdev_t scsi_tape_devs[] =
{
    0x0900, 0x0901, 0x0902, 0x0903, 0x0904, 0x0905, 0x0906, 0x0907, 
    0x0908, 0x0909, 0x090A, 0x090B, 0x090C, 0x090D, 0x090E, 0x090F,
    0x0910, 0x0911, 0x0912, 0x0913, 0x0914, 0x0915, 0x0916, 0x0917, 
    0x0918, 0x0919, 0x091A, 0x091B, 0x091C, 0x091D, 0x091E, 0x091F,  
    0,
};

BYTE *ide_tape_handles[] =
{
    "/dev/ht0",  "/dev/ht1",  "/dev/ht2",  "/dev/ht3",  "/dev/ht4", 
    "/dev/ht5",  "/dev/ht6",  "/dev/ht7",  "/dev/ht8",  "/dev/ht9",
    "/dev/ht10", "/dev/ht11", "/dev/ht12", "/dev/ht13", "/dev/ht14",
    "/dev/ht15", "/dev/ht16", "/dev/ht17", "/dev/ht18", "/dev/ht19", 
    "/dev/ht20", "/dev/ht21", "/dev/ht22", "/dev/ht23", "/dev/ht24", 
    "/dev/ht25", "/dev/ht26", "/dev/ht27", "/dev/ht28", "/dev/ht29", 
    "/dev/ht30", "/dev/ht31", 0
};

kdev_t ide_tape_devs[] =
{
    0x3700, 0x3701, 0x3702, 0x3703, 0x3704, 0x3705, 0x3706, 0x3707, 
    0x3708, 0x3709, 0x370A, 0x370B, 0x370C, 0x370D, 0x370E, 0x370F,
    0x3710, 0x3711, 0x3712, 0x3713, 0x3714, 0x3715, 0x3716, 0x3717, 
    0x3718, 0x3719, 0x371A, 0x371B, 0x371C, 0x371D, 0x371E, 0x371F,
    0 
};

ULONG max_scsi_tape_devs = sizeof(scsi_tape_devs) / sizeof(kdev_t);
ULONG max_ide_tape_devs = sizeof(ide_tape_devs) / sizeof(kdev_t);
ULONG max_scsi_tape_names = sizeof(scsi_tape_handles) / sizeof(BYTE *);
ULONG max_ide_tape_names = sizeof(ide_tape_handles) / sizeof(BYTE *);

void RemoveTapeDevices(void)
{
    register ULONG j;

    for (j=0; j < max_scsi_tape_names; j++)
    {
       if (SystemTape[j])
       {
          if (SystemTape[j]->filp) 
             filp_close(SystemTape[j]->filp, NULL);
          TRXDRVFree(SystemTape[j]);
          SystemTape[j] = 0;
       }
    }
}

void ScanTapeDevices(void)
{
    register ULONG j;

    for (j = 0; j < max_scsi_tape_names; j++)
    {
       if (!SystemTape[j])
       {
          if (!scsi_tape_devs[j])
             break;

          SystemTape[j] = (NWTAPE *) TRXDRVAlloc(sizeof(NWTAPE), NWTAPE_TAG);
          if (!SystemTape[j])
          {
              TRXDRVPrint("trxdrv: memory alloc failure in AddTapeDevices\n");
              continue;
          }
          TRXDRVSet(SystemTape[j], 0, sizeof(NWTAPE));
          
          TRXDRVPrint("filp_open %s\n", scsi_tape_handles[j]); 
          
          SystemTape[j]->filp = filp_open(scsi_tape_handles[j], O_RDWR, 0600);
          if (IS_ERR(SystemTape[j]->filp))
          {
             if (SystemTape[j])
                TRXDRVFree(SystemTape[j]);
             SystemTape[j] = 0;
             continue;
          }
          TRXDRVPrint("trxdrv:  tape device detected at %s\n", 
                      scsi_tape_handles[j]); 
       }
    }
    return;
}

Reply via email to