MDS中file layout初始化过程

来源:互联网 发布:印象笔记导出为知笔记 编辑:程序博客网 时间:2024/06/06 13:24

    pNFS系统的部署过程见这篇文章:http://blog.csdn.net/ycnian/article/details/8523193。这篇文章中我们讲讲MDS的初始化过程,主要想讲讲向文件/proc/fs/nfsd/pnfs_dlm_device中写入数据后MDS做了哪些工作,以下面这条命令为例。

[root@180 ~]# echo "sdb:192.168.6.180,192.168.6.182" >/proc/fs/nfsd/pnfs_dlm_device

这个文件的处理函数是__write_pnfs_dlm_device(),这个函数很简单,代码如下:

static ssize_t __write_pnfs_dlm_device(struct file *file, char *buf,                                       size_t size){        char *mesg = buf;        char *pnfs_dlm_device;        int max_size = NFSD_PNFS_DLM_DEVICE_MAX;        int len, ret = 0;        if (size > 0) {         // 用户输入了内容.                ret = -EINVAL;                if (size > max_size || buf[size-1] != '\n')     // 不能超出最大长度.                        return ret;                buf[size-1] = 0;                pnfs_dlm_device = mesg;                len = qword_get(&mesg, pnfs_dlm_device, size);  // 获取文件内容.                if (len <= 0)                        return ret;                ret = nfsd4_set_pnfs_dlm_device(pnfs_dlm_device, len);        } else                return nfsd4_get_pnfs_dlm_device_list(buf, SIMPLE_TRANSACTION_LIMIT);        return ret <= 0 ? ret : strlen(buf);}

    很显然,当我们向文件中写入数据后执行的是nfsd4_set_pnfs_dlm_device()。讲解这个函数前我们先看一个数据结构struct dlm_device_entry:

struct dlm_device_entry {        struct list_head        dlm_dev_list;   // 链接到dlm_device_list中        char                    disk_name[DISK_NAME_LEN];       // 设备名称.        int                     num_ds;                         // 这个数据结构中DS的数量        char                    ds_list[NFSD_DLM_DS_LIST_MAX];  // DS列表};
    这个数据结构保存的是设备信息,包括设备名称和对应的DS信息两方面。当我们向文件pnfs_dlm_device中写入数据后就会创建一个新的dlm_device_entry结构,各个字段的信息如下:

struct dlm_device_entry {        char                    disk_name[DISK_NAME_LEN];       // sdb        int                     num_ds;                         // 2        char                    ds_list[NFSD_DLM_DS_LIST_MAX];  // 192.168.6.180,192.168.6.182};
    同时,MDS中还有一个全局链表dlm_device_list,系统中所有的dlm_device_entry结构保存在这个链表中。nfsd4_set_pnfs_dlm_device()的作用就是解析用户写入的数据,创建一个新的dlm_device_entry结构,添加到全局链表dlm_device_list中,这个函数的代码如下:

intnfsd4_set_pnfs_dlm_device(char *pnfs_dlm_device, int len){        struct dlm_device_entry *new, *found;        char *bufp = pnfs_dlm_device;           // 这是用户写入的字符串.        char *endp = bufp + strlen(bufp);       // 这是字符串结束位置.        int err = -ENOMEM;        dprintk("--> %s len %d\n", __func__, len);        // 创建一个新的dlm_device_entry结构        new = kzalloc(sizeof(*new), GFP_KERNEL);        if (!new)                return err;     // 内存分配失败        err = -EINVAL;        /* disk_name */        /* FIXME: need to check for valid disk_name. search superblocks?         * check for slash dev slash ?         */        len = strcspn(bufp, ":");        if (len > DISK_NAME_LEN)        // device 名称太长了                goto out_free;        memcpy(new->disk_name, bufp, len);      // 取出设备名称.        err = -EINVAL;        bufp += len + 1;        if (bufp >= endp)                goto out_free;          // 出错了,需要释放内存.        /* data server list */        /* FIXME: need to check for comma separated valid ip format */        len = strlen(bufp);        if (len > NFSD_DLM_DS_LIST_MAX)                goto out_free;        memcpy(new->ds_list, bufp, len);        // 拷贝DS列表        /*  validate the ips */        // 检查DS,计算了DS的数量.        if (!nfsd4_validate_pnfs_dlm_device(new->ds_list, &(new->num_ds)))                goto out_free;        dprintk("%s disk_name %s num_ds %d ds_list %s\n", __func__,                new->disk_name, new->num_ds, new->ds_list);     // 打印DS信息.        // 检查系统中是否存在同名的设备.        found = _nfsd4_find_pnfs_dlm_device(new->disk_name);        if (found) {    // 存在,更新设备信息.                /* FIXME: should compare found->ds_list with new->ds_list                 * and if it is different, kick off a CB_NOTIFY change                 * deviceid.                 */                dprintk("%s pnfs_dlm_device %s:%s already in cache "                        " replace ds_list with new ds_list %s\n", __func__,                        found->disk_name, found->ds_list, new->ds_list);                // 更新DS信息                // 这里有一个小bug,下面这条语句应该是                // memset(found->ds_list, 0, NFSD_DLM_DS_LIST_MAX);                memset(found->ds_list, 0, DISK_NAME_LEN);                memcpy(found->ds_list, new->ds_list, strlen(new->ds_list));     // 拷贝DS列表                found->num_ds = new->num_ds;            // 这是DS数量                kfree(new);             // 释放新申请的内存,不需要了.        } else {        // 不存在,就将这个设备添加到链表中.                dprintk("%s Adding pnfs_dlm_device %s:%s\n", __func__,                                new->disk_name, new->ds_list);                spin_lock(&dlm_device_list_lock);                // 添加到全局链表dlm_device_list中.                list_add(&new->dlm_dev_list, &dlm_device_list);                spin_unlock(&dlm_device_list_lock);        }        dprintk("<-- %s Success\n", __func__);        return 0;out_free:        kfree(new);             // 失败了,释放内存.        dprintk("<-- %s returns %d\n", __func__, err);        return err;}

原创粉丝点击