diff options
author | Robert Harris <Robert.Harris@Sun.COM> | 2010-07-23 04:16:05 -0700 |
---|---|---|
committer | Robert Harris <Robert.Harris@Sun.COM> | 2010-07-23 04:16:05 -0700 |
commit | d7de0cea9111a93d26efcfa259585dabbde02eea (patch) | |
tree | caa047d7621ae20b9a1b2351545cbea6f23c6108 | |
parent | 04fdf45595eefac2f4793a31f7be253c3ddd3368 (diff) | |
download | illumos-joyent-d7de0cea9111a93d26efcfa259585dabbde02eea.tar.gz |
6950914 remount can change mount point to "unspecified_mountpoint", causing panics
-rw-r--r-- | usr/src/uts/common/fs/fd/fdops.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/mntfs/mntvfsops.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/namefs/namevfs.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/nfs/nfs4_vfsops.c | 5 | ||||
-rw-r--r-- | usr/src/uts/common/fs/proc/prvfsops.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/tmpfs/tmp_vfsops.c | 2 | ||||
-rw-r--r-- | usr/src/uts/common/fs/vfs.c | 86 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/zfs_ctldir.c | 4 | ||||
-rw-r--r-- | usr/src/uts/common/sys/vfs.h | 9 |
9 files changed, 48 insertions, 66 deletions
diff --git a/usr/src/uts/common/fs/fd/fdops.c b/usr/src/uts/common/fs/fd/fdops.c index 8c398be2ee..a8c03455f3 100644 --- a/usr/src/uts/common/fs/fd/fdops.c +++ b/usr/src/uts/common/fs/fd/fdops.c @@ -383,7 +383,7 @@ fdmount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr) /* * Having the resource be anything but "fd" doesn't make sense */ - vfs_setresource(vfsp, "fd"); + vfs_setresource(vfsp, "fd", 0); vp = vn_alloc(KM_SLEEP); vp->v_vfsp = vfsp; diff --git a/usr/src/uts/common/fs/mntfs/mntvfsops.c b/usr/src/uts/common/fs/mntfs/mntvfsops.c index 102e681e8e..8f7f7c9f75 100644 --- a/usr/src/uts/common/fs/mntfs/mntvfsops.c +++ b/usr/src/uts/common/fs/mntfs/mntvfsops.c @@ -201,7 +201,7 @@ mntmount(struct vfs *vfsp, struct vnode *mvp, /* * Having the resource be anything but "mnttab" doesn't make sense */ - vfs_setresource(vfsp, "mnttab"); + vfs_setresource(vfsp, "mnttab", 0); mnt = kmem_zalloc(sizeof (*mnt), KM_SLEEP); mutex_enter(&mvp->v_lock); diff --git a/usr/src/uts/common/fs/namefs/namevfs.c b/usr/src/uts/common/fs/namefs/namevfs.c index 0725504842..13e620d410 100644 --- a/usr/src/uts/common/fs/namefs/namevfs.c +++ b/usr/src/uts/common/fs/namefs/namevfs.c @@ -522,7 +522,7 @@ nm_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *crp) "unspecified_%s", resource_nodetype); } - vfs_setresource(vfsp, resource_name); + vfs_setresource(vfsp, resource_name, 0); kmem_free(svfsp, sizeof (statvfs64_t)); kmem_free(resource_name, RESOURCE_NAME_SZ); diff --git a/usr/src/uts/common/fs/nfs/nfs4_vfsops.c b/usr/src/uts/common/fs/nfs/nfs4_vfsops.c index 040fbed7bd..35152c3a39 100644 --- a/usr/src/uts/common/fs/nfs/nfs4_vfsops.c +++ b/usr/src/uts/common/fs/nfs/nfs4_vfsops.c @@ -19,8 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. */ /* @@ -2616,7 +2615,7 @@ nfs4rootvp(vnode_t **rtvpp, vfs_t *vfsp, struct servinfo4 *svp_head, (void) strcat(resource, svp->sv_hostname); (void) strcat(resource, ":"); (void) strcat(resource, svp->sv_path); - vfs_setresource(vfsp, resource); + vfs_setresource(vfsp, resource, 0); kmem_free(resource, len); } diff --git a/usr/src/uts/common/fs/proc/prvfsops.c b/usr/src/uts/common/fs/proc/prvfsops.c index d0bebc7163..efc3c37ce7 100644 --- a/usr/src/uts/common/fs/proc/prvfsops.c +++ b/usr/src/uts/common/fs/proc/prvfsops.c @@ -211,7 +211,7 @@ prmount(struct vfs *vfsp, struct vnode *mvp, /* * Having the resource be anything but "proc" doesn't make sense */ - vfs_setresource(vfsp, "proc"); + vfs_setresource(vfsp, "proc", 0); pnp = kmem_alloc(sizeof (*pnp), KM_SLEEP); mutex_enter(&pr_mount_lock); diff --git a/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c b/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c index 9bb96e4165..f8a36a528f 100644 --- a/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c +++ b/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c @@ -259,7 +259,7 @@ tmp_mount( /* * Having the resource be anything but "swap" doesn't make sense. */ - vfs_setresource(vfsp, "swap"); + vfs_setresource(vfsp, "swap", 0); /* * now look for options we understand... diff --git a/usr/src/uts/common/fs/vfs.c b/usr/src/uts/common/fs/vfs.c index 2bfe3908f0..9a106fd3d0 100644 --- a/usr/src/uts/common/fs/vfs.c +++ b/usr/src/uts/common/fs/vfs.c @@ -670,8 +670,8 @@ vfs_mountdevices(void) /* * Set appropriate members and add to vfs list for mnttab display */ - vfs_setresource(&devices, "/devices"); - vfs_setmntpoint(&devices, "/devices"); + vfs_setresource(&devices, "/devices", 0); + vfs_setmntpoint(&devices, "/devices", 0); /* * Hold the root of /devices so it won't go away @@ -748,8 +748,8 @@ vfs_mountdev1(void) /* * Set appropriate members and add to vfs list for mnttab display */ - vfs_setresource(&dev, "/dev"); - vfs_setmntpoint(&dev, "/dev"); + vfs_setresource(&dev, "/dev", 0); + vfs_setmntpoint(&dev, "/dev", 0); /* * Hold the root of /dev so it won't go away @@ -832,7 +832,7 @@ vfs_mountroot(void) * to point to it. These are used by lookuppn() so that it * knows where to start from ('/' or '.'). */ - vfs_setmntpoint(rootvfs, "/"); + vfs_setmntpoint(rootvfs, "/", 0); if (VFS_ROOT(rootvfs, &rootdir)) panic("vfs_mountroot: no root vnode"); @@ -872,7 +872,7 @@ vfs_mountroot(void) /* * Set up mnttab information for root */ - vfs_setresource(rootvfs, rootfs.bo_name); + vfs_setresource(rootvfs, rootfs.bo_name, 0); /* * Notify cluster software that the root filesystem is available. @@ -930,7 +930,7 @@ vfs_mountroot(void) * mnttab should reflect the new root device */ vfs_lock_wait(rootvfs); - vfs_setresource(rootvfs, rootfs.bo_name); + vfs_setresource(rootvfs, rootfs.bo_name, 0); vfs_unlock(rootvfs); } #endif /* __sparc */ @@ -962,39 +962,6 @@ vfs_mountroot(void) } /* - * If remount failed and we're in a zone we need to check for the zone - * root path and strip it before the call to vfs_setpath(). - * - * If strpath doesn't begin with the zone_rootpath the original - * strpath is returned unchanged. - */ -static const char * -stripzonepath(const char *strpath) -{ - char *str1, *str2; - int i; - zone_t *zonep = curproc->p_zone; - - if (zonep->zone_rootpath == NULL || strpath == NULL) { - return (NULL); - } - - /* - * we check for the end of the string at one past the - * current position because the zone_rootpath always - * ends with "/" but we don't want to strip that off. - */ - str1 = zonep->zone_rootpath; - str2 = (char *)strpath; - ASSERT(str1[0] != '\0'); - for (i = 0; str1[i + 1] != '\0'; i++) { - if (str1[i] != str2[i]) - return ((char *)strpath); - } - return (&str2[i]); -} - -/* * Check to see if our "block device" is actually a file. If so, * automatically add a lofi device, and keep track of this fact. */ @@ -1645,8 +1612,8 @@ domount(char *fsname, struct mounta *uap, vnode_t *vp, struct cred *credp, if ((oldmntpt = vfsp->vfs_mntpt) != NULL) refstr_hold(oldmntpt); } - vfs_setresource(vfsp, resource); - vfs_setmntpoint(vfsp, mountpt); + vfs_setresource(vfsp, resource, 0); + vfs_setmntpoint(vfsp, mountpt, 0); /* * going to mount on this vnode, so notify. @@ -1667,12 +1634,12 @@ domount(char *fsname, struct mounta *uap, vnode_t *vp, struct cred *credp, if (remount) { /* put back pre-remount options */ vfs_swapopttbl(&mnt_mntopts, &vfsp->vfs_mntopts); - vfs_setmntpoint(vfsp, (stripzonepath( - refstr_value(oldmntpt)))); + vfs_setmntpoint(vfsp, refstr_value(oldmntpt), + VFSSP_VERBATIM); if (oldmntpt) refstr_rele(oldmntpt); - vfs_setresource(vfsp, (stripzonepath( - refstr_value(oldresource)))); + vfs_setresource(vfsp, refstr_value(oldresource), + VFSSP_VERBATIM); if (oldresource) refstr_rele(oldresource); vfsp->vfs_flag = ovflags; @@ -1842,7 +1809,11 @@ errout: } static void -vfs_setpath(struct vfs *vfsp, refstr_t **refp, const char *newpath) +vfs_setpath( + struct vfs *vfsp, /* vfs being updated */ + refstr_t **refp, /* Ref-count string to contain the new path */ + const char *newpath, /* Path to add to refp (above) */ + uint32_t flag) /* flag */ { size_t len; refstr_t *ref; @@ -1871,9 +1842,16 @@ vfs_setpath(struct vfs *vfsp, refstr_t **refp, const char *newpath) if (*refp != NULL) refstr_rele(*refp); - /* Do we need to modify the path? */ - - if (zone == global_zone || *newpath != '/') { + /* + * If we are in a non-global zone then we prefix the supplied path, + * newpath, with the zone's root path, with two exceptions. The first + * is where we have been explicitly directed to avoid doing so; this + * will be the case following a failed remount, where the path supplied + * will be a saved version which must now be restored. The second + * exception is where newpath is not a pathname but a descriptive name, + * e.g. "procfs". + */ + if (zone == global_zone || (flag & VFSSP_VERBATIM) || *newpath != '/') { ref = refstr_alloc(newpath); goto out; } @@ -1925,11 +1903,11 @@ out: * If vfsp is already mounted, caller must hold the vfs lock. */ void -vfs_setresource(struct vfs *vfsp, const char *resource) +vfs_setresource(struct vfs *vfsp, const char *resource, uint32_t flag) { if (resource == NULL || resource[0] == '\0') resource = VFS_NORESOURCE; - vfs_setpath(vfsp, &vfsp->vfs_resource, resource); + vfs_setpath(vfsp, &vfsp->vfs_resource, resource, flag); } /* @@ -1937,11 +1915,11 @@ vfs_setresource(struct vfs *vfsp, const char *resource) * If vfsp is already mounted, caller must hold the vfs lock. */ void -vfs_setmntpoint(struct vfs *vfsp, const char *mntpt) +vfs_setmntpoint(struct vfs *vfsp, const char *mntpt, uint32_t flag) { if (mntpt == NULL || mntpt[0] == '\0') mntpt = VFS_NOMNTPT; - vfs_setpath(vfsp, &vfsp->vfs_mntpt, mntpt); + vfs_setpath(vfsp, &vfsp->vfs_mntpt, mntpt, flag); } /* Returns the vfs_resource. Caller must call refstr_rele() when finished. */ diff --git a/usr/src/uts/common/fs/zfs/zfs_ctldir.c b/usr/src/uts/common/fs/zfs/zfs_ctldir.c index 362de4dd15..07f18f29f0 100644 --- a/usr/src/uts/common/fs/zfs/zfs_ctldir.c +++ b/usr/src/uts/common/fs/zfs/zfs_ctldir.c @@ -590,7 +590,7 @@ zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm) ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath)); (void) strcat(newpath, nm); refstr_rele(pathref); - vfs_setmntpoint(vfsp, newpath); + vfs_setmntpoint(vfsp, newpath, 0); pathref = vfs_getresource(vfsp); (void) strncpy(newpath, refstr_value(pathref), sizeof (newpath)); @@ -599,7 +599,7 @@ zfsctl_rename_snap(zfsctl_snapdir_t *sdp, zfs_snapentry_t *sep, const char *nm) ASSERT3U(strlen(newpath) + strlen(nm), <, sizeof (newpath)); (void) strcat(newpath, nm); refstr_rele(pathref); - vfs_setresource(vfsp, newpath); + vfs_setresource(vfsp, newpath, 0); vfs_unlock(vfsp); } diff --git a/usr/src/uts/common/sys/vfs.h b/usr/src/uts/common/sys/vfs.h index 97e176fc1a..5fca4584eb 100644 --- a/usr/src/uts/common/sys/vfs.h +++ b/usr/src/uts/common/sys/vfs.h @@ -442,6 +442,11 @@ enum { #define VSW_INSTALLED 0x8000 /* this vsw is associated with a file system */ +/* + * A flag for vfs_setpath(). + */ +#define VFSSP_VERBATIM 0x1 /* do not prefix the supplied path */ + #if defined(_KERNEL) /* * Public operations. @@ -502,8 +507,8 @@ void vfs_mnttab_modtimeupd(void); void vfs_clearmntopt(struct vfs *, const char *); void vfs_setmntopt(struct vfs *, const char *, const char *, int); -void vfs_setresource(struct vfs *, const char *); -void vfs_setmntpoint(struct vfs *, const char *); +void vfs_setresource(struct vfs *, const char *, uint32_t); +void vfs_setmntpoint(struct vfs *, const char *, uint32_t); refstr_t *vfs_getresource(const struct vfs *); refstr_t *vfs_getmntpoint(const struct vfs *); int vfs_optionisset(const struct vfs *, const char *, char **); |