Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 10 Oct 2019 05:49:55 +0000
From:      <Zhichao1.Li@dell.com>
To:        <freebsd-fs@freebsd.org>, <freebsd-drivers@freebsd.org>
Cc:        <Shunchao.Hu@dell.com>
Subject:   a issue about getting a devfs node's fullpath 
Message-ID:  <c6d34bd0b4114bee956b0af6d680a67f@KULX13MDC103.APAC.DELL.COM>

next in thread | raw e-mail | index | archive | help

Dear freebsd developers
I know you're swamped, so I'll be brief.
I am trying to get a node's full under /dev by calling the function 'vn_fullpath', when dealing with things like '/dev/null' or '/dev/usb/1.0.1', it works well.
However when dealing a node under more than 2 sub directories (e.g. /dev/bus/usb/001/002)  which I made by calling 'make_dev_s' , it goes a little bit different, I got a string "/dev/bus/usb/bus/usb/001/002"
And I found the function 'devfs_vptocnp' gets the string wrongly when dealing multi slashes path string, I have remark the code as followed and put some comments
would you please take a look, and tell me what the purpose this func pass the string that way?
static int
devfs_vptocnp(struct vop_vptocnp_args *ap)
{
        struct vnode *vp = ap->a_vp;
        struct vnode **dvp = ap->a_vpp;
        struct devfs_mount *dmp;
        char *buf = ap->a_buf;
        int *buflen = ap->a_buflen;
        struct devfs_dirent *dd, *de;
        int i, error;

        dmp = VFSTODEVFS(vp->v_mount);

        error = devfs_populate_vp(vp);
        if (error != 0)
                return (error);

        i = *buflen;
        dd = vp->v_data;

        if (vp->v_type == VCHR) {
                i -= strlen(dd->de_cdp->cdp_c.si_name);
                if (i < 0) {
                        error = ENOMEM;
                        goto finished;
                }
                bcopy(dd->de_cdp->cdp_c.si_name, buf + i,
                    strlen(dd->de_cdp->cdp_c.si_name));
               /*
* when dealing with VCHR
                * the element 'si_name' already
                * holds the full path string
                * except rootdir, why not just go
                * to the rootdir?
                */
                de = dd->de_dir;
        } else if (vp->v_type == VDIR) {
                if (dd == dmp->dm_rootdir) {
                        *dvp = vp;
                        vref(*dvp);
                        goto finished;
                }
                i -= dd->de_dirent->d_namlen;
                if (i < 0) {
error = ENOMEM;
                             goto finished;
                }
                bcopy(dd->de_cdp->cdp_c.si_name, buf + i,
                    strlen(dd->de_cdp->cdp_c.si_name));
                de = dd->de_dir;
        } else if (vp->v_type == VDIR) {
                if (dd == dmp->dm_rootdir) {
                        *dvp = vp;
                        vref(*dvp);
                        goto finished;
                }
                i -= dd->de_dirent->d_namlen;
                if (i < 0) {
                        error = ENOMEM;
                        goto finished;
                }
                bcopy(dd->de_dirent->d_name, buf + i,
                    dd->de_dirent->d_namlen);
                de = dd;
        } else {
                error = ENOENT;
                goto finished;
        }
        *buflen = i;
        de = devfs_parent_dirent(de);
        if (de == NULL) {
                error = ENOENT;
                goto finished;
        }
        mtx_lock(&devfs_de_interlock);
        *dvp = de->de_vnode;
        if (*dvp != NULL) {
                VI_LOCK(*dvp);
                mtx_unlock(&devfs_de_interlock);
                vholdl(*dvp);
                VI_UNLOCK(*dvp);
                vref(*dvp);
                vdrop(*dvp);
        } else {
               mtx_unlock(&devfs_de_interlock);
error = ENOENT;
        }
finished:
        sx_xunlock(&dmp->dm_lock);
        return (error);
}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?c6d34bd0b4114bee956b0af6d680a67f>