mirror of
https://git.proxmox.com/git/mirror_zfs.git
synced 2024-12-26 03:09:34 +03:00
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:
parent
c0b3dc7d07
commit
42ab36aa36
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user