Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Aug 2011 04:35:42 +0000 (UTC)
From:      "Justin T. Gibbs" <gibbs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r224901 - projects/zfsd/head/sys/fs/devfs
Message-ID:  <201108160435.p7G4ZgNO041036@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gibbs
Date: Tue Aug 16 04:35:42 2011
New Revision: 224901
URL: http://svn.freebsd.org/changeset/base/224901

Log:
  Correct the rendering of device aliases that reside in subdirectories
  of a devfs.
  
  devfs/devfs_vnops.c:
  	In devfs_readlink(), convert the devfs root relative path
  	of an alias's parent, that is recorded in the alias, into a
  	fully qualified path that includes the root of the containing
  	devfs.  This avoids the ugliness of generating a relative path
  	by prepending "../"'s.  For a non-jailed process, the "symlink
  	root" is the devfs's mount point.  For a jailed process, we
  	must remove any jail prefix in the mount point so that our
  	response matches the user process's world view.
  
  Sponsored by:	Spectra Logic Corporation

Modified:
  projects/zfsd/head/sys/fs/devfs/devfs_vnops.c

Modified: projects/zfsd/head/sys/fs/devfs/devfs_vnops.c
==============================================================================
--- projects/zfsd/head/sys/fs/devfs/devfs_vnops.c	Tue Aug 16 00:43:25 2011	(r224900)
+++ projects/zfsd/head/sys/fs/devfs/devfs_vnops.c	Tue Aug 16 04:35:42 2011	(r224901)
@@ -1248,8 +1248,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));
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201108160435.p7G4ZgNO041036>