Remove unused mount functions

The functions zfs_mount_label_policy(), zfs_mountroot(), zfs_mount()
will not be needed because most of what they do is already handled
by the generic Linux VFS layer.  They all call zfs_domount() which
creates the actual dataset, the caller of this library call which
will be in the zpl layer is responsible for what's left.
This commit is contained in:
Brian Behlendorf 2011-01-05 16:56:49 -08:00
parent c0b3dc7d07
commit 42ab36aa36

View File

@ -68,10 +68,6 @@
#ifdef HAVE_ZPL
extern int sys_shutdown;
static int zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr);
static int zfs_mountroot(vfs_t *vfsp, enum whymountroot);
static void zfs_freevfs(vfs_t *vfsp);
/*
* We need to keep a count of active fs's.
* This is necessary to prevent our module
@ -1190,326 +1186,6 @@ zfs_check_global_label(const char *dsname, const char *hexsl)
}
#endif /* HAVE_MLSLABEL */
/*
* zfs_mount_label_policy:
* Determine whether the mount is allowed according to MAC check.
* by comparing (where appropriate) label of the dataset against
* the label of the zone being mounted into. If the dataset has
* no label, create one.
*
* Returns:
* 0 : access allowed
* >0 : error code, such as EACCES
*/
static int
zfs_mount_label_policy(vfs_t *vfsp, char *osname)
{
int error, retv;
zone_t *mntzone = NULL;
ts_label_t *mnt_tsl;
bslabel_t *mnt_sl;
bslabel_t ds_sl;
char ds_hexsl[MAXNAMELEN];
retv = EACCES; /* assume the worst */
/*
* Start by getting the dataset label if it exists.
*/
error = dsl_prop_get(osname, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
1, sizeof (ds_hexsl), &ds_hexsl, NULL);
if (error)
return (EACCES);
/*
* If labeling is NOT enabled, then disallow the mount of datasets
* which have a non-default label already. No other label checks
* are needed.
*/
if (!is_system_labeled()) {
if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
return (0);
return (EACCES);
}
/*
* Get the label of the mountpoint. If mounting into the global
* zone (i.e. mountpoint is not within an active zone and the
* zoned property is off), the label must be default or
* admin_low/admin_high only; no other checks are needed.
*/
mntzone = zone_find_by_any_path(refstr_value(vfsp->vfs_mntpt), B_FALSE);
if (mntzone->zone_id == GLOBAL_ZONEID) {
uint64_t zoned;
zone_rele(mntzone);
if (dsl_prop_get_integer(osname,
zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
return (EACCES);
if (!zoned)
return (zfs_check_global_label(osname, ds_hexsl));
else
/*
* This is the case of a zone dataset being mounted
* initially, before the zone has been fully created;
* allow this mount into global zone.
*/
return (0);
}
mnt_tsl = mntzone->zone_slabel;
ASSERT(mnt_tsl != NULL);
label_hold(mnt_tsl);
mnt_sl = label2bslabel(mnt_tsl);
if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0) {
/*
* The dataset doesn't have a real label, so fabricate one.
*/
char *str = NULL;
if (l_to_str_internal(mnt_sl, &str) == 0 &&
dsl_prop_set(osname, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
ZPROP_SRC_LOCAL, 1, strlen(str) + 1, str) == 0)
retv = 0;
if (str != NULL)
kmem_free(str, strlen(str) + 1);
} else if (hexstr_to_label(ds_hexsl, &ds_sl) == 0) {
/*
* Now compare labels to complete the MAC check. If the
* labels are equal then allow access. If the mountpoint
* label dominates the dataset label, allow readonly access.
* Otherwise, access is denied.
*/
if (blequal(mnt_sl, &ds_sl))
retv = 0;
else if (bldominates(mnt_sl, &ds_sl)) {
vfs_setmntopt(vfsp, MNTOPT_RO, NULL, 0);
retv = 0;
}
}
label_rele(mnt_tsl);
zone_rele(mntzone);
return (retv);
}
static int
zfs_mountroot(vfs_t *vfsp, enum whymountroot why)
{
int error = 0;
static int zfsrootdone = 0;
zfsvfs_t *zfsvfs = NULL;
znode_t *zp = NULL;
vnode_t *vp = NULL;
char *zfs_bootfs;
char *zfs_devid;
ASSERT(vfsp);
/*
* The filesystem that we mount as root is defined in the
* boot property "zfs-bootfs" with a format of
* "poolname/root-dataset-objnum".
*/
if (why == ROOT_INIT) {
if (zfsrootdone++)
return (EBUSY);
/*
* the process of doing a spa_load will require the
* clock to be set before we could (for example) do
* something better by looking at the timestamp on
* an uberblock, so just set it to -1.
*/
clkset(-1);
if ((zfs_bootfs = spa_get_bootprop("zfs-bootfs")) == NULL) {
cmn_err(CE_NOTE, "spa_get_bootfs: can not get "
"bootfs name");
return (EINVAL);
}
zfs_devid = spa_get_bootprop("diskdevid");
error = spa_import_rootpool(rootfs.bo_name, zfs_devid);
if (zfs_devid)
spa_free_bootprop(zfs_devid);
if (error) {
spa_free_bootprop(zfs_bootfs);
cmn_err(CE_NOTE, "spa_import_rootpool: error %d",
error);
return (error);
}
if (error = zfs_parse_bootfs(zfs_bootfs, rootfs.bo_name)) {
spa_free_bootprop(zfs_bootfs);
cmn_err(CE_NOTE, "zfs_parse_bootfs: error %d",
error);
return (error);
}
spa_free_bootprop(zfs_bootfs);
if (error = vfs_lock(vfsp))
return (error);
if (error = zfs_domount(vfsp, rootfs.bo_name)) {
cmn_err(CE_NOTE, "zfs_domount: error %d", error);
goto out;
}
zfsvfs = (zfsvfs_t *)vfsp->vfs_data;
ASSERT(zfsvfs);
if (error = zfs_zget(zfsvfs, zfsvfs->z_root, &zp)) {
cmn_err(CE_NOTE, "zfs_zget: error %d", error);
goto out;
}
vp = ZTOV(zp);
mutex_enter(&vp->v_lock);
vp->v_flag |= VROOT;
mutex_exit(&vp->v_lock);
rootvp = vp;
/*
* Leave rootvp held. The root file system is never unmounted.
*/
vfs_add((struct vnode *)0, vfsp,
(vfsp->vfs_flag & VFS_RDONLY) ? MS_RDONLY : 0);
out:
vfs_unlock(vfsp);
return (error);
} else if (why == ROOT_REMOUNT) {
readonly_changed_cb(vfsp->vfs_data, B_FALSE);
vfsp->vfs_flag |= VFS_REMOUNT;
/* refresh mount options */
zfs_unregister_callbacks(vfsp->vfs_data);
return (zfs_register_callbacks(vfsp));
} else if (why == ROOT_UNMOUNT) {
zfs_unregister_callbacks((zfsvfs_t *)vfsp->vfs_data);
(void) zfs_sync(vfsp, 0, 0);
return (0);
}
/*
* if "why" is equal to anything else other than ROOT_INIT,
* ROOT_REMOUNT, or ROOT_UNMOUNT, we do not support it.
*/
return (ENOTSUP);
}
/*ARGSUSED*/
static int
zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
{
char *osname;
pathname_t spn;
int error = 0;
uio_seg_t fromspace = (uap->flags & MS_SYSSPACE) ?
UIO_SYSSPACE : UIO_USERSPACE;
int canwrite;
if (mvp->v_type != VDIR)
return (ENOTDIR);
mutex_enter(&mvp->v_lock);
if ((uap->flags & MS_REMOUNT) == 0 &&
(uap->flags & MS_OVERLAY) == 0 &&
(mvp->v_count != 1 || (mvp->v_flag & VROOT))) {
mutex_exit(&mvp->v_lock);
return (EBUSY);
}
mutex_exit(&mvp->v_lock);
/*
* ZFS does not support passing unparsed data in via MS_DATA.
* Users should use the MS_OPTIONSTR interface; this means
* that all option parsing is already done and the options struct
* can be interrogated.
*/
if ((uap->flags & MS_DATA) && uap->datalen > 0)
return (EINVAL);
/*
* Get the objset name (the "special" mount argument).
*/
if ((error = pn_get(uap->spec, fromspace, &spn)))
return (error);
osname = spn.pn_path;
/*
* Check for mount privilege?
*
* If we don't have privilege then see if
* we have local permission to allow it
*/
error = secpolicy_fs_mount(cr, mvp, vfsp);
if (error) {
if (dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) == 0) {
vattr_t vattr;
/*
* Make sure user is the owner of the mount point
* or has sufficient privileges.
*/
vattr.va_mask = AT_UID;
if (VOP_GETATTR(mvp, &vattr, 0, cr, NULL)) {
goto out;
}
if (secpolicy_vnode_owner(cr, vattr.va_uid) != 0 &&
VOP_ACCESS(mvp, VWRITE, 0, cr, NULL) != 0) {
goto out;
}
secpolicy_fs_mount_clearopts(cr, vfsp);
} else {
goto out;
}
}
/*
* Refuse to mount a filesystem if we are in a local zone and the
* dataset is not visible.
*/
if (!INGLOBALZONE(curproc) &&
(!zone_dataset_visible(osname, &canwrite) || !canwrite)) {
error = EPERM;
goto out;
}
error = zfs_mount_label_policy(vfsp, osname);
if (error)
goto out;
/*
* When doing a remount, we simply refresh our temporary properties
* according to those options set in the current VFS options.
*/
if (uap->flags & MS_REMOUNT) {
/* refresh mount options */
zfs_unregister_callbacks(vfsp->vfs_data);
error = zfs_register_callbacks(vfsp);
goto out;
}
error = zfs_domount(vfsp, osname);
/*
* Add an extra VFS_HOLD on our parent vfs so that it can't
* disappear due to a forced unmount.
*/
if (error == 0 && ((zfsvfs_t *)vfsp->vfs_data)->z_issnap)
VFS_HOLD(mvp->v_vfsp);
out:
pn_free(&spn);
return (error);
}
int
zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp)
{
@ -1953,15 +1629,6 @@ zfs_freevfs(vfs_t *vfsp)
{
zfsvfs_t *zfsvfs = vfsp->vfs_data;
/*
* If this is a snapshot, we have an extra VFS_HOLD on our parent
* from zfs_mount(). Release it here. If we came through
* zfs_mountroot() instead, we didn't grab an extra hold, so
* skip the VFS_RELE for rootvfs.
*/
if (zfsvfs->z_issnap && (vfsp != rootvfs))
VFS_RELE(zfsvfs->z_parent->z_vfs);
zfsvfs_free(zfsvfs);
atomic_add_32(&zfs_active_fs_count, -1);