summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_mount.c
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2012-01-15 12:08:20 +0000
committermm <mm@FreeBSD.org>2012-01-15 12:08:20 +0000
commit9f44ed5ca827811dd8729bb0ab4397c71161fa9c (patch)
tree7cb3e09e5396eca584100f0f0377b0dd5a33d1ba /sys/kern/vfs_mount.c
parent4642718fb42bef8b06538195461ee680c22cd1f9 (diff)
downloadFreeBSD-src-9f44ed5ca827811dd8729bb0ab4397c71161fa9c.zip
FreeBSD-src-9f44ed5ca827811dd8729bb0ab4397c71161fa9c.tar.gz
Introduce vn_path_to_global_path()
This function updates path string to vnode's full global path and checks the size of the new path string against the pathlen argument. In vfs_domount(), sys_unmount() and kern_jail_set() this new function is used to update the supplied path argument to the respective global path. Unbreaks jailed zfs(8) with enforce_statfs set to 1. Reviewed by: kib MFC after: 1 month
Diffstat (limited to 'sys/kern/vfs_mount.c')
-rw-r--r--sys/kern/vfs_mount.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
index 873f425..9100a9c 100644
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1085,11 +1085,14 @@ vfs_domount(
NDFREE(&nd, NDF_ONLY_PNBUF);
vp = nd.ni_vp;
if ((fsflags & MNT_UPDATE) == 0) {
- error = vfs_domount_first(td, vfsp, fspath, vp, fsflags,
- optlist);
- } else {
+ error = vn_path_to_global_path(td, vp, fspath, MNAMELEN);
+ /* debug.disablefullpath == 1 results in ENODEV */
+ if (error == 0 || error == ENODEV) {
+ error = vfs_domount_first(td, vfsp, fspath, vp,
+ fsflags, optlist);
+ }
+ } else
error = vfs_domount_update(td, vp, fsflags, optlist);
- }
mtx_unlock(&Giant);
ASSERT_VI_UNLOCKED(vp, __func__);
@@ -1119,9 +1122,10 @@ sys_unmount(td, uap)
int flags;
} */ *uap;
{
+ struct nameidata nd;
struct mount *mp;
char *pathbuf;
- int error, id0, id1;
+ int error, id0, id1, vfslocked;
AUDIT_ARG_VALUE(uap->flags);
if (jailed(td->td_ucred) || usermount == 0) {
@@ -1155,6 +1159,21 @@ sys_unmount(td, uap)
mtx_unlock(&mountlist_mtx);
} else {
AUDIT_ARG_UPATH1(td, pathbuf);
+ /*
+ * Try to find global path for path argument.
+ */
+ NDINIT(&nd, LOOKUP,
+ FOLLOW | LOCKLEAF | MPSAFE | AUDITVNODE1,
+ UIO_SYSSPACE, pathbuf, td);
+ if (namei(&nd) == 0) {
+ vfslocked = NDHASGIANT(&nd);
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ error = vn_path_to_global_path(td, nd.ni_vp, pathbuf,
+ MNAMELEN);
+ if (error == 0 || error == ENODEV)
+ vput(nd.ni_vp);
+ VFS_UNLOCK_GIANT(vfslocked);
+ }
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH_REVERSE(mp, &mountlist, mntlist, mnt_list) {
if (strcmp(mp->mnt_stat.f_mntonname, pathbuf) == 0)
OpenPOWER on IntegriCloud