devfs_vptocnp(): correct the component name when node is not at top.

Node' cdp.si_name is the full path as provided by make_dev(9), it
should not be returned by VOP_VPTOCNP() when only the last component
is requested.  Use the dirent entry instead.

With this note, handling of VDIR and VCHR nodes only differs in
handling of root vnode, which simplifies and unifies the logic.

Reported by:	Li, Zhichao1 <Zhichao_Li1@Dell.com>
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
kib 2019-10-11 18:41:24 +00:00
parent 852150953b
commit 0dd6fd8974

View File

@ -284,38 +284,27 @@ devfs_vptocnp(struct vop_vptocnp_args *ap)
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));
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 {
if (vp->v_type != VCHR && vp->v_type != VDIR) {
error = ENOENT;
goto finished;
}
dd = vp->v_data;
if (vp->v_type == VDIR && dd == dmp->dm_rootdir) {
*dvp = vp;
vref(*dvp);
goto finished;
}
i = *buflen;
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);
*buflen = i;
de = devfs_parent_dirent(de);
de = devfs_parent_dirent(dd);
if (de == NULL) {
error = ENOENT;
goto finished;