Mercurial > illumos > illumos-gate
changeset 12906:3ca11e9f39b7
6950914 remount can change mount point to "unspecified_mountpoint", causing panics
author | Robert Harris <Robert.Harris@Sun.COM> |
---|---|
date | Fri, 23 Jul 2010 04:16:05 -0700 |
parents | f5b5eba6d470 |
children | 805f5f4df09e |
files | usr/src/uts/common/fs/fd/fdops.c usr/src/uts/common/fs/mntfs/mntvfsops.c usr/src/uts/common/fs/namefs/namevfs.c usr/src/uts/common/fs/nfs/nfs4_vfsops.c usr/src/uts/common/fs/proc/prvfsops.c usr/src/uts/common/fs/tmpfs/tmp_vfsops.c usr/src/uts/common/fs/vfs.c usr/src/uts/common/fs/zfs/zfs_ctldir.c usr/src/uts/common/sys/vfs.h |
diffstat | 9 files changed, 48 insertions(+), 66 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/fd/fdops.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/fd/fdops.c Fri Jul 23 04:16:05 2010 -0700 @@ -383,7 +383,7 @@ /* * 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;
--- a/usr/src/uts/common/fs/mntfs/mntvfsops.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/mntfs/mntvfsops.c Fri Jul 23 04:16:05 2010 -0700 @@ -201,7 +201,7 @@ /* * 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);
--- a/usr/src/uts/common/fs/namefs/namevfs.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/namefs/namevfs.c Fri Jul 23 04:16:05 2010 -0700 @@ -522,7 +522,7 @@ "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);
--- a/usr/src/uts/common/fs/nfs/nfs4_vfsops.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/nfs/nfs4_vfsops.c Fri Jul 23 04:16:05 2010 -0700 @@ -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 @@ (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); }
--- a/usr/src/uts/common/fs/proc/prvfsops.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/proc/prvfsops.c Fri Jul 23 04:16:05 2010 -0700 @@ -211,7 +211,7 @@ /* * 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);
--- a/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/tmpfs/tmp_vfsops.c Fri Jul 23 04:16:05 2010 -0700 @@ -259,7 +259,7 @@ /* * 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...
--- a/usr/src/uts/common/fs/vfs.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/vfs.c Fri Jul 23 04:16:05 2010 -0700 @@ -670,8 +670,8 @@ /* * 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 @@ /* * 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 @@ * 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 @@ /* * 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 @@ * 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 @@ } /* - * 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ * 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 @@ * 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. */
--- a/usr/src/uts/common/fs/zfs/zfs_ctldir.c Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/fs/zfs/zfs_ctldir.c Fri Jul 23 04:16:05 2010 -0700 @@ -590,7 +590,7 @@ 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 @@ 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); }
--- a/usr/src/uts/common/sys/vfs.h Fri Jul 23 08:57:27 2010 +0100 +++ b/usr/src/uts/common/sys/vfs.h Fri Jul 23 04:16:05 2010 -0700 @@ -442,6 +442,11 @@ #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_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 **);