diff options
author | Alexander Motin <mav@FreeBSD.org> | 2012-05-24 14:07:44 +0000 |
---|---|---|
committer | Alexander Motin <mav@FreeBSD.org> | 2012-05-24 14:07:44 +0000 |
commit | f6ad3f237a54ef1465271c7e96bf0f2e4f9277e5 (patch) | |
tree | 40272ce66d9fbbbec27ad859c9e9a595d6716bd3 /sys/fs | |
parent | 0fc0793eeededdb484f97575db48fc5dcdffccbb (diff) | |
download | src-f6ad3f237a54ef1465271c7e96bf0f2e4f9277e5.tar.gz src-f6ad3f237a54ef1465271c7e96bf0f2e4f9277e5.zip |
MFprojects/zfsd:
Revamp the CAM enclosure services driver.
This updated driver uses an in-kernel daemon to track state changes and
publishes physical path location information\for disk elements into the
CAM device database.
Sponsored by: Spectra Logic Corporation
Sponsored by: iXsystems, Inc.
Submitted by: gibbs, will, mav
Notes
Notes:
svn path=/head/; revision=235911
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/devfs/devfs_vnops.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 4a58a4297a69..8cbfb03f479d 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -1266,8 +1266,53 @@ static int devfs_readlink(struct vop_readlink_args *ap) { struct devfs_dirent *de; + struct cdev_priv *cdp; de = ap->a_vp->v_data; + cdp = de->de_cdp; + + if (cdp != NULL && (cdp->cdp_c.si_flags & SI_ALIAS) != 0) { + struct devfs_mount *dmp; + struct prison *pr; + char *mp; + int mp_len; + int pr_path_len; + int err; + + /* + * For device aliases, construct an absolute symlink (to + * shorten its length and avoid the ugliness of a relative + * link) by prepending the fully qualified path to the root + * of this devfs. For a non-jailed process, the devfs root + * is our mount point. For a jailed process, we must remove + * any jail prefix in our mount point so that our response + * matches the user process's world view. + */ + dmp = VFSTODEVFS(ap->a_vp->v_mount); + mp = dmp->dm_mount->mnt_stat.f_mntonname; + mp_len = strlen(mp); + + pr = ap->a_cred->cr_prison; + pr_path_len = strlen(pr->pr_path); + + if (strncmp(pr->pr_path, mp, pr_path_len) == 0 + && mp[pr_path_len] == '/') { + mp += pr_path_len; + mp_len -= pr_path_len; + } + + err = uiomove(mp, mp_len, ap->a_uio); + if (err != 0) + return (err); + + /* + * Devfs cannot be the root file system, so its + * mount point must always be terminated by a '/'. + */ + err = uiomove("/", 1, ap->a_uio); + if (err != 0) + return (err); + } return (uiomove(de->de_symlink, strlen(de->de_symlink), ap->a_uio)); } |