diff options
author | mav <mav@FreeBSD.org> | 2013-12-12 11:05:48 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2013-12-12 11:05:48 +0000 |
commit | 794856e581ae12763c22f57153e4b1f52f21b819 (patch) | |
tree | 60c796f78e18daf119147eba4fdb8543d6c28539 /sys/fs/devfs | |
parent | ade78829a0b8ff766c53fbf136a30ca65a311a1a (diff) | |
download | FreeBSD-src-794856e581ae12763c22f57153e4b1f52f21b819.zip FreeBSD-src-794856e581ae12763c22f57153e4b1f52f21b819.tar.gz |
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
Diffstat (limited to 'sys/fs/devfs')
-rw-r--r-- | sys/fs/devfs/devfs_devs.c | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/sys/fs/devfs/devfs_devs.c b/sys/fs/devfs/devfs_devs.c index 6b6cf6e..da21f97 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; |