//ldd3第70页看到的scull_read描述如下:
ssize_t scull_read(struct file *filp,char __user *buf,size_t count,loff_t *f_pos)
{
struct scull_cdev *dev=filp->private_data;
struct scull_qset *dptr;//第一个链表项
int quantum=dev->quantum,qset=dev->qset;
int itemsize=quantum*qset; //该链表项中有多少字节
int item,s_pos,q_pos,rest;
ssize_t retval=0;
if(down_interruptible(&dev->sem))
return -ERESTARTSYS;
if(*f_pos>=dev->size)
goto out;
if(*f_pos+count>dev->size)
count=dev->size-*f_pos;
//在量子集中寻找链表项、qset索引以及偏移量
item=(long)*f_pos/itemsize;
rest=(long)*f_pos%itemsize;
s_pos=rest/quantum;
q_pos=rest%quantum;
//沿该链表前行,直到正确的位置(在其它地方定义)
dptr=scull_follow(dev,item);
if(dptr==NULL || !dptr->data || !dptr->data[s_pos])
goto out; //don't fill holes
//读取该量子的数据直到结尾
if(count>quantum-q_pos)
count=quantum-q_pos;
if(copy_to_user(buf,dptr->data[s_pos]+q_pos,count))
{
retval=-EFAULT;
goto out;
}
*f_pos+=count;
retval=count;
out:
up(&dev->sem);
return retval;
}
ssize_t scull_read(struct file *filp,char __user *buf,size_t count,loff_t *f_pos)
{
struct scull_cdev *dev=filp->private_data;
struct scull_qset *dptr;//第一个链表项
int quantum=dev->quantum,qset=dev->qset;
int itemsize=quantum*qset; //该链表项中有多少字节
int item,s_pos,q_pos,rest;
ssize_t retval=0;
if(down_interruptible(&dev->sem))
return -ERESTARTSYS;
if(*f_pos>=dev->size)
goto out;
if(*f_pos+count>dev->size)
count=dev->size-*f_pos;
//在量子集中寻找链表项、qset索引以及偏移量
item=(long)*f_pos/itemsize;
rest=(long)*f_pos%itemsize;
s_pos=rest/quantum;
q_pos=rest%quantum;
//沿该链表前行,直到正确的位置(在其它地方定义)
dptr=scull_follow(dev,item);
if(dptr==NULL || !dptr->data || !dptr->data[s_pos])
goto out; //don't fill holes
//读取该量子的数据直到结尾
if(count>quantum-q_pos)
count=quantum-q_pos;
if(copy_to_user(buf,dptr->data[s_pos]+q_pos,count))
{
retval=-EFAULT;
goto out;
}
*f_pos+=count;
retval=count;
out:
up(&dev->sem);
return retval;
}