对于scull_read的理解

//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;
}

你可能感兴趣的:(struct,File,user,REST,null,UP)