Scsi error handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm trying a small code on a bad scsi disk
and got the output

scsi0: MEDIUM ERROR on channel 0, id 0, lun 0, CDB: Read (6) 13 78 00 02
00
Info fld=0x0, Current sd08:00: sense key Medium Error
scsidisk I/O error: dev 08:00, sector 1275904

blocknr 637952 compl 1 bad

scsi0: MEDIUM ERROR on channel 0, id 0, lun 0, CDB: Read (6) 13 78 00 02
00
Info fld=0x0, Current sd08:00: sense key Medium Error
scsidisk I/O error: dev 08:00, sector 1275904
blocknr 637952 compl 358504 bad
scsi0: MEDIUM ERROR on channel 0, id 0, lun 0, CDB: Read (6) 13 78 00 02
00
Info fld=0x0, Current sd08:00: sense key Medium Error
scsidisk I/O error: dev 08:00, sector 1275904
blocknr 637952 compl 1030955 bad
blocknr = 638976 a block completed
-------------------------------------------------------------------------
What i observed was the buf_end_io function is called multiple times in
case of failure.
I can attribute those multiple messages as scsi retries, but i don't
understand why buf_endio is called multiple times.

regards
mgopi


My code is 

int mod_ioctl(struct inode * inode,struct file * filp,unsigned int
cmd,unsigned long arg);
struct file_operations mod_fops = {
	NULL,
	NULL,
	NULL,
	NULL,
	NULL,
	mod_ioctl,
	NULL
};
static int mod_major;
int mod_dochk(unsigned long);
int init_module(void){
	mod_major = register_chrdev(0,"mod",&mod_fops);
	if(mod_major < 0){
		printk(KERN_WARNING "mod : can't register\n");
		return mod_major;
	}	
	return 0;
}
void cleanup_module(void)
{
	unregister_chrdev(mod_major,"mod");
}
int mod_ioctl (struct inode * inode,struct file * filp,unsigned int
cmd,unsigned long arg)
{
	switch(cmd) {
		case MOD_CHK:
			if(access_ok(VERIFY_READ,arg,sizeof(int)) <
0) return -1;
			return mod_dochk(arg);
		default: 
			return -EINVAL;
	}
}
static volatile atomic_t completed;
struct wait_queue * wq = NULL;
static void buf_endio(struct buffer_head * bh,int uptodate)
{
	mark_buffer_uptodate(bh,uptodate);
	unlock_buffer(bh);
	if(!uptodate)
		printk(KERN_ERR"blocknr %ld compl %d
bad\n",bh->b_blocknr,atomic_read(&completed));
	/*if(atomic_read(&completed) < 2048)
	//printk("%d ",atomic_read(&completed));
	//else printk("\n");
		;*/
	atomic_inc(&completed);
//	if(atomic_read(&completed) == 1024)
//		wake_up(&wq);
}
int mod_dochk(unsigned long arg)
{
	kdev_t dev = MKDEV(8,0);
	struct buffer_head ** bufptr = NULL;
	int i = 0,j = 0;
	int blocknr = 0;
	bufptr = (struct buffer_head **) kmalloc(1024 * sizeof(struct
buffer_head *),GFP_KERNEL);
	if(bufptr == NULL) return -1;
	for(i = 0;i < 1024;i++)
	{
		bufptr[i] = (struct buffer_head *) kmalloc(sizeof(struct
buffer_head),GFP_KERNEL);
		if(bufptr[i] == NULL)
		{
			printk(KERN_INFO"mod_ioctl:cannot allocate
buffer\n");
			for(j = 0;j<i;j++)
				kfree(bufptr[j]);
			kfree(bufptr);
			return -1;
		}
		memset(bufptr[i],0,sizeof(struct buffer_head));
		bufptr[i]->b_data = (char *)kmalloc(1024 *
sizeof(char),GFP_KERNEL);
		if(bufptr[i]->b_data == NULL)
		{
			printk(KERN_INFO"mod_ioctl:cannot allocate
data\n");
			for(j = 0;j<i;j++)
			{
				kfree(bufptr[j]->b_data);
				kfree(bufptr[j]);
			}
			kfree(bufptr);
			return -1;
		}
		init_buffer(bufptr[i],dev,0,buf_endio,0);
		bufptr[i]->b_size 	= 1024;
		bufptr[i]->b_state	= (1<<BH_Req);
		bufptr[i]->b_rdev	= dev;
		bufptr[i]->b_count	= 1;
		bufptr[i]->b_list	= BUF_LOCKED;
	}
	j = 0;	
	//while(j < 1023)
	{
		
		//copy_from_user(&blocknr,(int *)arg,sizeof(int));
		atomic_set(&completed,0);
		get_user(blocknr,(int *)arg);
		printk(KERN_ERR"bl = %d\n",blocknr);
		for(i = 0;i<1024;i++)
		{
			bufptr[i]->b_blocknr = blocknr++;
			ll_rw_block(READ,1024,bufptr);
			if(blocknr % 1024 == 0) break;
		}

		//if(atomic_read(&completed) <
1024) interruptible_sleep_on(&wq);
		for(i = 0;i<1024;i++)
		wait_on_buffer(bufptr[i]);
		printk(KERN_ERR"blocknr = %d a block
completed\n",blocknr);
	//	j++;
	}
	for(j=0;j<1024;j++)
	{
		kfree(bufptr[j]->b_data);
		kfree(bufptr[j]);
	}
	kfree(bufptr);
	return 0;
}

-
Kernelnewbies: Help each other learn about the Linux kernel.
Archive:       http://mail.nl.linux.org/kernelnewbies/
IRC Channel:   irc.openprojects.net / #kernelnewbies
Web Page:      http://www.kernelnewbies.org/


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux