summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-12-12 11:05:48 +0000
committermav <mav@FreeBSD.org>2013-12-12 11:05:48 +0000
commit794856e581ae12763c22f57153e4b1f52f21b819 (patch)
tree60c796f78e18daf119147eba4fdb8543d6c28539 /sys/fs
parentade78829a0b8ff766c53fbf136a30ca65a311a1a (diff)
downloadFreeBSD-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')
-rw-r--r--sys/fs/devfs/devfs_devs.c16
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;
OpenPOWER on IntegriCloud