summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2012-05-24 14:07:44 +0000
committermav <mav@FreeBSD.org>2012-05-24 14:07:44 +0000
commit96f3e42ce2c9de14b3e9a1de338ed639c1c8b596 (patch)
tree40272ce66d9fbbbec27ad859c9e9a595d6716bd3 /sys/fs
parent5b4a3e5f4a4045127c253ffac2a618946f83912b (diff)
downloadFreeBSD-src-96f3e42ce2c9de14b3e9a1de338ed639c1c8b596.zip
FreeBSD-src-96f3e42ce2c9de14b3e9a1de338ed639c1c8b596.tar.gz
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
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/devfs/devfs_vnops.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 4a58a42..8cbfb03 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));
}
OpenPOWER on IntegriCloud