首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >在scull的proc read实现中,这些参数意味着什么?

在scull的proc read实现中,这些参数意味着什么?
EN

Stack Overflow用户
提问于 2019-05-28 06:48:46
回答 1查看 270关注 0票数 0

在LDD3 (Linux设备驱动程序第三版)的scullpipe中,static int scull_read_p_mem(char *buf, char **start, off_t offset, int count, int *eof, void *data)中的参数意味着什么?具体地说,我不理解startpageoffset之间的区别。

关于实际实现本身,我有一些问题(可以在下面找到):

代码语言:javascript
复制
struct scull_pipe {
        wait_queue_head_t inq, outq;       /* read and write queues */
        char *buffer, *end;                /* begin of buf, end of buf */
        int buffersize;                    /* used in pointer arithmetic */
        char *rp, *wp;                     /* where to read, where to write */
        int nreaders, nwriters;            /* number of openings for r/w */
        struct fasync_struct *async_queue; /* asynchronous readers */
        struct semaphore sem;              /* mutual exclusion semaphore */
        struct cdev cdev;                  /* Char device structure */
};

int scull_p_nr_devs;            /* the number of scull_pipe devices */
scull_pipe *scull_p_devices;    /* scull_pipe devices to be malloc'ed */

/* ...... */

/* our proc read implementation */
static int scull_read_p_mem(char *buf, char **start, off_t offset, int count,
        int *eof, void *data)
{
    int i, len;
    struct scull_pipe *p;

#define LIMIT (PAGE_SIZE-200)   /* don't print any more after this size */
    *start = buf;
    len = sprintf(buf, "Default buffersize is %i\n", scull_p_buffer);
    for(i = 0; i < scull_p_nr_devs && len <= LIMIT; i++) {
        p = &scull_p_devices[i];
        if (down_interruptible(&p->sem))
            return -ERESTARTSYS;
        len += sprintf(buf+len, "\nDevice %i: %p\n", i, p);
        len += sprintf(buf+len, "   Buffer: %p to %p (%i bytes)\n", 
                                    p->buffer, p->end, p->buffersize);
        len += sprintf(buf+len, "   rp %p   wp %p\n", p->rp, p->wp);
        len += sprintf(buf+len, "   readers %i   writers %i\n", 
                                    p->nreaders, p->nwriters);
        up(&p->sem);
        scullp_proc_offset(buf, start, &offset, &len);
    }
    *eof = (len <= LIMIT);
    return len;
}


static void scullp_proc_offset(char *buf, char **start, off_t *offset, int *len)
{
    /* QUESTION: what does this function do? */
    if (*offset == 0)
        return;
    if (*offset >= *len) {
        *offset -= *len;    /* QUESTION: what is the purpose of this? */
        *len = 0;
    }
    else {
        *start = buf + *offset; /* QUESTION: why do you need to change "start"? */
        *offset = 0;
    }
}
EN

回答 1

Stack Overflow用户

发布于 2020-11-12 10:48:33

buf指向应该存储读取结果的内存页的基址。

offset建议在虚拟文件中从哪里开始读取。

作为返回值的start可以表示以下几点:

  1. if start == null,我们有写入buf + offset
  2. if start == some int < buf地址的结果,我们有写入buf内buf
  3. if start == some地址的结果,我们有启动

的写入结果

该函数应解释如下。

代码语言:javascript
复制
// context:
// 1. We have set start to be the beginning of buf
//     *start = buf;
// 2. We have fill some string into the buf and increment len
static void scullp_proc_offset(char *buf, char **start, off_t *offset, int *len)
{
    // If offset is zero, we are filling a new buf.
    // (Or we have finished catching up as shown below)
    // We can continue to do so until we reach buf size
    if (*offset == 0)
        return;

    // Otherwise, we have some offset to catch up to.
    if (*offset >= *len) {
        // The offset might be still ahead given we have filled len.
        // So, we reduce offset(meaning that we have done some catch up)
        // and reset len(because we are still working on old data)
        *offset -= *len;
        *len = 0;
    }
    else {
        // Or, the offset might be already behind us
        // So, we set start to indicate that the write starts from this address
        // (case 2 in fs/proc/generic.c#L76)
        // and reset offset (meaning that we are done with catching up)
        *start = buf + *offset;
        *offset = 0;
        // this part might lack the handling of len
        // but it might be true if the structure is the same between two calls.
    }
}

总之,作者使用此函数来使写入始终从buf开始,但仅在赶上前一个偏移量之后计数len。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56333180

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档