From ca187878c02aec8f447aa7245ca588a51b0c3fc7 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 12 Dec 2013 11:05:48 +0000 Subject: [PATCH] Fix long known bug with handling device aliases residing not in devfs root. Historically creation of device aliases created symbolic links using only name of target device as a link target, not considering current directory. Fix that by adding number of "../" chunks to the terget device name, required to get out of the current directory to devfs root first. MFC after: 1 month --- sys/fs/devfs/devfs_devs.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 6b6cf6e8be23..da21f97db390 100644 --- a/sys/fs/devfs/devfs_devs.c +++ b/sys/fs/devfs/devfs_devs.c @@ -486,9 +486,9 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) { struct cdev_priv *cdp; struct devfs_dirent *de; - struct devfs_dirent *dd; + struct devfs_dirent *dd, *dt; struct cdev *pdev; - int de_flags, j; + int de_flags, depth, j; char *q, *s; sx_assert(&dm->dm_lock, SX_XLOCKED); @@ -589,9 +589,17 @@ devfs_populate_loop(struct devfs_mount *dm, int cleanup) de->de_mode = 0755; de->de_dirent->d_type = DT_LNK; pdev = cdp->cdp_c.si_parent; - j = strlen(pdev->si_name) + 1; + dt = dd; + depth = 0; + while (dt != dm->dm_rootdir && + (dt = devfs_parent_dirent(dt)) != NULL) + depth++; + j = depth * 3 + strlen(pdev->si_name) + 1; de->de_symlink = malloc(j, M_DEVFS, M_WAITOK); - bcopy(pdev->si_name, de->de_symlink, j); + de->de_symlink[0] = 0; + while (depth-- > 0) + strcat(de->de_symlink, "../"); + strcat(de->de_symlink, pdev->si_name); } else { de->de_uid = cdp->cdp_c.si_uid; de->de_gid = cdp->cdp_c.si_gid;