NFS中 readdir操作流程

入口函数

nfs3d_proc_readdir(): 完成对resp中相关字段的处理:fhp,count,buff等

然后调用nfsd_readdir(),函数返回后resp->count = resp->buff - argp->buff,这个说明了什么?

 nfsd_readdir():打开要读取的文件,设置文件内偏移的指针(应该是由于RPC传输长度限制,需要多次读一个文件的原因),然后调用nfsd_buffered_readdir();

nfsd_buffered_readdir(这个是完成读操作的主要函数)

     首先定义了两个变量:

    struct readdir_data buf;
    struct buffered_dirent *de

    buf中包含一个char 指针以及长度和full标志;

   struct buffered_dirent {
    u64        ino;
    loff_t        offset;
    int        namlen;
    unsigned int    d_type;
    char        name[];
  };

看上述的定义,可知其与单个dentry对应。

static __be32 nfsd_buffered_readdir(struct file *file, filldir_t func,
                    struct readdir_cd *cdp, loff_t *offsetp)
{
    struct readdir_data buf;
    struct buffered_dirent *de;
    int host_err;
    int size;
    loff_t offset;

    buf.dirent = (void *)__get_free_page(GFP_KERNEL);
    if (!buf.dirent)
        return nfserrno(-ENOMEM);

    offset = *offsetp;

    while (1) {
        struct inode *dir_inode = file->f_path.dentry->d_inode;
        unsigned int reclen;

        cdp->err = nfserr_eof; /* will be cleared on successful read */
        buf.used = 0;
        buf.full = 0;

        host_err = vfs_readdir(file, nfsd_buffered_filldir, &buf);
        if (buf.full)
            host_err = 0;

        if (host_err < 0)
            break;

        size = buf.used;

        if (!size)
            break;

        /*
         * Various filldir functions may end up calling back into
         * lookup_one_len() and the file system's ->lookup() method.
         * These expect i_mutex to be held, as it would within readdir.
         */
        host_err = mutex_lock_killable(&dir_inode->i_mutex);
        if (host_err)
            break;

        de = (struct buffered_dirent *)buf.dirent;
        while (size > 0) {
            offset = de->offset;

            if (func(cdp, de->name, de->namlen, de->offset,
                 de->ino, de->d_type))
                break;

            if (cdp->err != nfs_ok)
                break;

             = ALIGN(sizeof(*de) + de->namlen,
                       sizeof(u64));
            size -= reclen;
            de = (struct buffered_dirent *)((char *)de + reclen);
        }
        mutex_unlock(&dir_inode->i_mutex);
        if (size > 0) /* We bailed out early */
            break;

        offset = vfs_llseek(file, 0, SEEK_CUR);
    }

    free_page((unsigned long)(buf.dirent));

    if (host_err)
        return nfserrno(host_err);

    *offsetp = offset;
    return cdp->err;

}

函数 先申请一个内存页,然后每次循环调用 vfs_readdir,从下层(即VFS下层文件系统)读出每个dentry的内容,buffer的地址就是struct readdir_data buf

这里涉及到指针转换问题------把一个char* 型指针,转换成一个结构体的指针。

vfs_readdir读出dentry之后,使用while()循环把buff中的内容读出来,之后用上层传下来的func()函数,编码并存到别的地方中,根据人口函数推测是resp->buff。

这样就完成了整个流程。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值