fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
033f983390fa5d2b54e3e09d83ac9000d71ddaaeek * Common Development and Distribution License (the "License").
033f983390fa5d2b54e3e09d83ac9000d71ddaaeek * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
dc7cd546d81fce970935f08099931c2ad2d57731Mark Shellenbaum * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens * Copyright (c) 2012, 2015 by Delphix. All rights reserved.
c3d26abc9ee97b4f60233556aadeb57e0bd30bb9Matthew Ahrens * Copyright (c) 2014 Integros [integros.com]
eb721827677c553ce8dd0d4390630a857f923f98Alek Pinchuk * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante/* Portions Copyright 2010 Robert Milkowski */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockstatic int zfs_mountroot(vfs_t *vfsp, enum whymountroot);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp);
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic const fs_operation_def_t zfs_vfsops_template[] = {
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic const fs_operation_def_t zfs_vfsops_eio_template[] = {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We need to keep a count of active fs's.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * This is necessary to prevent our module
fa9e4066f08beec538e775443c5be79dd423fcabahrens * from being unloaded after a umount -f
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic char *noatime_cancel[] = { MNTOPT_ATIME, NULL };
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic char *atime_cancel[] = { MNTOPT_NOATIME, NULL };
b510d37840323dfb912eab2c7f56325938ed47adlling * MO_DEFAULT is not used since the default value is determined
b510d37840323dfb912eab2c7f56325938ed47adlling * by the equivalent property.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*ARGSUSED*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Data integrity is job one. We don't want a compromised kernel
fa9e4066f08beec538e775443c5be79dd423fcabahrens * writing to the storage pool, so we never sync during panic.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * SYNC_ATTR is used by fsflush() to force old filesystems like UFS
fa9e4066f08beec538e775443c5be79dd423fcabahrens * to sync metadata, which they would otherwise cache indefinitely.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Semantically, the only requirement is that the sync be initiated.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The DMU syncs out txgs frequently, so there's nothing to do.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Sync a specific filesystem.
54d692b75b7a6f90ce7787309da5451f7458e66aGeorge Wilson * If the system is shutting down, then skip any
54d692b75b7a6f90ce7787309da5451f7458e66aGeorge Wilson * filesystems which may exist on a suspended pool.
54d692b75b7a6f90ce7787309da5451f7458e66aGeorge Wilson if (sys_shutdown && spa_suspended(dp->dp_spa)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Sync all ZFS filesystems. This is what happens when you
fa9e4066f08beec538e775443c5be79dd423fcabahrens * run sync(1M). Unlike other filesystems, ZFS honors the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * request by waiting for all pools to commit all dirty data.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * If we're still using the real major
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * number space. If we're using a getudev()'ed
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * major number, we can use all of its minors.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } while (vfs_devismounted(*dev) && zfs_minor != start);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * We are using all ~262,000 minor numbers for the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * current major number. Create a new major number.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "zfs_mount: Can't get unique major "
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock "device number.");
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (-1);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /* CONSTANTCONDITION */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } while (1);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOATIME, NULL, 0);
7b55fa8ea6046becb3b72f8886a503979c322084ckstatic void
7b55fa8ea6046becb3b72f8886a503979c322084ck /* XXX locking on vfs_flag? */
7b55fa8ea6046becb3b72f8886a503979c322084ck /* XXX locking on vfs_flag? */
b515258426fed6c7311fd3f1dea697cfbd4085c6Matthew Ahrens ASSERT3U(newval, <=, spa_maxblocksize(dmu_objset_spa(zfsvfs->z_os)));
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* XXX locking on vfs_flag? */
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* XXX locking on vfs_flag? */
fa9e4066f08beec538e775443c5be79dd423fcabahrens vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NODEVICES, NULL, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_DEVICES, NULL, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOSETUID, NULL, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_SETUID, NULL, 0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens vfs_setmntopt(zfsvfs->z_vfs, MNTOPT_NOEXEC, NULL, 0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The nbmand mount option can be changed at mount time.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * We can't allow it to be toggled on live file systems or incorrect
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * behavior may be seen from cifs clients
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This property isn't registered via dsl_prop_register(), but this callback
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * will be called when a file system is first mounted
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * The act of registering our callbacks will destroy any mount
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * options we may have. In order to enable temporary overrides
7b55fa8ea6046becb3b72f8886a503979c322084ck * of mount options, we stash away the current values and
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * restore them after we register the callbacks.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else if (vfs_optionisset(vfsp, MNTOPT_RW, NULL)) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL)) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling } else if (vfs_optionisset(vfsp, MNTOPT_DEVICES, NULL)) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL)) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else if (vfs_optionisset(vfsp, MNTOPT_SETUID, NULL)) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } else if (vfs_optionisset(vfsp, MNTOPT_EXEC, NULL)) {
b510d37840323dfb912eab2c7f56325938ed47adlling } else if (vfs_optionisset(vfsp, MNTOPT_ATIME, NULL)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * nbmand is a special property. It can only be changed at
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * mount time.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This is weird, but it is documented to only be changeable
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * at mount time.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else if (vfs_optionisset(vfsp, MNTOPT_NBMAND, NULL)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (error = dsl_prop_get_integer(osname, "nbmand", &nbmand,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Register property callbacks.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * It would probably be fine to just check for i/o error from
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * the first prop_register(), but I guess I like to go
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * overboard...
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_pool_config_enter(dmu_objset_pool(os), FTAG);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_ATIME), atime_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_XATTR), xattr_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_RECORDSIZE), blksz_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_READONLY), readonly_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_DEVICES), devices_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_SETUID), setuid_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_EXEC), exec_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_SNAPDIR), snapdir_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_ACLMODE), acl_mode_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_ACLINHERIT), acl_inherit_changed_cb,
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens zfs_prop_to_name(ZFS_PROP_VSCAN), vscan_changed_cb, zfsvfs);
3b2aab18808792cbd248a12f1edf139b89833c13Matthew Ahrens dsl_pool_config_exit(dmu_objset_pool(os), FTAG);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Invoke our callbacks to restore temporary mount options.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaumzfs_space_delta_cb(dmu_object_type_t bonustype, void *data,
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * Is it a valid type of object to track?
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (bonustype != DMU_OT_ZNODE && bonustype != DMU_OT_SA)
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * If we have a NULL data pointer
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * then assume the id's aren't changing and
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * return EEXIST to the dmu to let it know to
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * use the same ids
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * This should only happen for newly created
06e0070d70ba2ee95f5aa2645423eb2cf1546788Mark Shellenbaum * files that haven't had the znode data filled
e828a46d29ad418487f50d56b5c19e2a1f9033a7Matthew Ahrens sa.sa_layout_info = BSWAP_16(sa.sa_layout_info);
e828a46d29ad418487f50d56b5c19e2a1f9033a7Matthew Ahrens VERIFY3U(hdrsize, >=, sizeof (sa_hdr_phys_t));
e828a46d29ad418487f50d56b5c19e2a1f9033a7Matthew Ahrens *userp = *((uint64_t *)((uintptr_t)data + hdrsize +
e828a46d29ad418487f50d56b5c19e2a1f9033a7Matthew Ahrens *groupp = *((uint64_t *)((uintptr_t)data + hdrsize +
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensfuidstr_to_sid(zfsvfs_t *zfsvfs, const char *fuidstr,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens domain = zfs_fuid_find_by_idx(zfsvfs, FUID_INDEX(fuid));
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenszfs_userquota_prop_to_obj(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenszfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens uint64_t *cookiep, void *vbuf, uint64_t *bufsizep)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (!dmu_objset_userspace_present(zfsvfs->z_os))
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens obj = zfs_userquota_prop_to_obj(zfsvfs, type);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens for (zap_cursor_init_serialized(&zc, zfsvfs->z_os, obj, *cookiep);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens (error = zap_cursor_retrieve(&zc, &za)) == 0;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if ((uintptr_t)buf - (uintptr_t)vbuf + sizeof (zfs_useracct_t) >
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens buf->zu_domain, sizeof (buf->zu_domain), &buf->zu_rid);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens ASSERT3U((uintptr_t)buf - (uintptr_t)vbuf, <=, *bufsizep);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens *bufsizep = (uintptr_t)buf - (uintptr_t)vbuf;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * buf must be big enough (eg, 32 bytes)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrensid_to_fuidstr(zfsvfs_t *zfsvfs, const char *domain, uid_t rid,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens domainid = zfs_fuid_find_by_domain(zfsvfs, domain, NULL, addok);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens (void) sprintf(buf, "%llx", (longlong_t)fuid);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenszfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens const char *domain, uint64_t rid, uint64_t *valp)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (!dmu_objset_userspace_present(zfsvfs->z_os))
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens obj = zfs_userquota_prop_to_obj(zfsvfs, type);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_FALSE);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens err = zap_lookup(zfsvfs->z_os, obj, buf, 8, 1, valp);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenszfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens const char *domain, uint64_t rid, uint64_t quota)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (type != ZFS_PROP_USERQUOTA && type != ZFS_PROP_GROUPQUOTA)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (zfsvfs->z_version < ZPL_VERSION_USERSPACE)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens objp = (type == ZFS_PROP_USERQUOTA) ? &zfsvfs->z_userquota_obj :
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens err = id_to_fuidstr(zfsvfs, domain, rid, buf, B_TRUE);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens dmu_tx_hold_zap(tx, *objp ? *objp : DMU_NEW_OBJECT, B_TRUE, NULL);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens *objp = zap_create(zfsvfs->z_os, DMU_OT_USERGROUP_QUOTA,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens VERIFY(0 == zap_add(zfsvfs->z_os, MASTER_NODE_OBJ,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens zfs_userquota_prop_prefixes[type], 8, 1, objp, tx));
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens err = zap_remove(zfsvfs->z_os, *objp, buf, tx);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens err = zap_update(zfsvfs->z_os, *objp, buf, 8, 1, "a, tx);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaumzfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, uint64_t fuid)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens usedobj = isgroup ? DMU_GROUPUSED_OBJECT : DMU_USERUSED_OBJECT;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj;
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens (void) sprintf(buf, "%llx", (longlong_t)fuid);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens err = zap_lookup(zfsvfs->z_os, quotaobj, buf, 8, 1, "a);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens err = zap_lookup(zfsvfs->z_os, usedobj, buf, 8, 1, &used);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaumzfs_owner_overquota(zfsvfs_t *zfsvfs, znode_t *zp, boolean_t isgroup)
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum quotaobj = isgroup ? zfsvfs->z_groupquota_obj : zfsvfs->z_userquota_obj;
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum return (zfs_fuid_overquota(zfsvfs, isgroup, fuid));
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens * Associate this zfsvfs with the given objset, which must be owned.
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens * This will cache a bunch of on-disk state from the objset in the
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens error = zfs_get_zplprop(os, ZFS_PROP_VERSION, &zfsvfs->z_version);
dc7cd546d81fce970935f08099931c2ad2d57731Mark Shellenbaum zfs_zpl_version_map(spa_version(dmu_objset_spa(os)))) {
dc7cd546d81fce970935f08099931c2ad2d57731Mark Shellenbaum (void) printf("Can't mount a version %lld file system "
dc7cd546d81fce970935f08099931c2ad2d57731Mark Shellenbaum "on a version %lld pool\n. Pool must be upgraded to mount "
dc7cd546d81fce970935f08099931c2ad2d57731Mark Shellenbaum "this file system.", (u_longlong_t)zfsvfs->z_version,
dc7cd546d81fce970935f08099931c2ad2d57731Mark Shellenbaum (u_longlong_t)spa_version(dmu_objset_spa(os)));
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens error = zfs_get_zplprop(os, ZFS_PROP_NORMALIZE, &val);
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens error = zfs_get_zplprop(os, ZFS_PROP_UTF8ONLY, &val);
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens error = zfs_get_zplprop(os, ZFS_PROP_CASE, &val);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * Fold case on file systems that are always or sometimes case
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * insensitive.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens if (zfsvfs->z_case == ZFS_CASE_INSENSITIVE ||
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum /* should either have both of these objects or none */
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SA_ATTRS, 8, 1,
1d8ccc7bfd8ab0f27a23c5253d95c22ceb9c27f4Mark Shellenbaum error = sa_setup(os, sa_obj, zfs_attr_table, ZPL_END,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum sa_register_update_callback(os, zfs_sa_upgrade);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_ROOT_OBJ, 8, 1,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_UNLINKED_SET, 8, 1,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens zfs_userquota_prop_prefixes[ZFS_PROP_USERQUOTA],
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens else if (error != 0)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens zfs_userquota_prop_prefixes[ZFS_PROP_GROUPQUOTA],
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens else if (error != 0)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_FUID_TABLES, 8, 1,
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens else if (error != 0)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens error = zap_lookup(os, MASTER_NODE_OBJ, ZFS_SHARES_DIR, 8, 1,
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens else if (error != 0)
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrenszfsvfs_create(const char *osname, zfsvfs_t **zfvp)
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens * We claim to always be readonly so we can open snapshots;
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens * other ZPL code will prevent us from writing to snapshots.
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens error = dmu_objset_own(osname, DMU_OST_ZFS, B_TRUE, zfsvfs, &os);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens mutex_init(&zfsvfs->z_znodes_lock, NULL, MUTEX_DEFAULT, NULL);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens mutex_init(&zfsvfs->z_lock, NULL, MUTEX_DEFAULT, NULL);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens list_create(&zfsvfs->z_all_znodes, sizeof (znode_t),
c9030f6c93613fe30ee0c16f92b96da7816ac052Alexander Motin rrm_init(&zfsvfs->z_teardown_lock, B_FALSE);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens rw_init(&zfsvfs->z_teardown_inactive_lock, NULL, RW_DEFAULT, NULL);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens rw_init(&zfsvfs->z_fuid_lock, NULL, RW_DEFAULT, NULL);
1fdcbd00c9cbac286b5f92e08877e8cb3c448420Matthew Ahrens for (int i = 0; i != ZFS_OBJ_MTX_SZ; i++)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens mutex_init(&zfsvfs->z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL);
377c02aa0cc369d8f469c7540a74a132e77a2c59Neil Perrin zfsvfs->z_log = zil_open(zfsvfs->z_os, zfs_get_data);
f18faf3f3e5def85fdfff681617d227703ace2adek * If we are not mounting (ie: online recv), then we don't
f18faf3f3e5def85fdfff681617d227703ace2adek * have to worry about replaying the log as we blocked all
f18faf3f3e5def85fdfff681617d227703ace2adek * operations out since we closed the ZIL.
f18faf3f3e5def85fdfff681617d227703ace2adek * During replay we remove the read only flag to
f18faf3f3e5def85fdfff681617d227703ace2adek * allow replays to succeed.
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * Parse and replay the intent log.
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * Because of ziltest, this must be done after
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * zfs_unlinked_drain(). (Further note: ziltest
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * doesn't use readonly mounts, where
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * zfs_unlinked_drain() isn't called.) This is because
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * ziltest causes spa_sync() to think it's committed,
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * but actually it is not, so the intent log contains
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * many txg's worth of changes.
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * In particular, if object N is in the unlinked set in
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * the last txg to actually sync, then it could be
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * actually freed in a later txg and then reallocated
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * in a yet later txg. This would write a "create
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * object N" record to the intent log. Normally, this
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * would be fine because the spa_sync() would have
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * written out the fact that object N is free, before
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * we could write the "create object N" intent log
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * But when we are in ziltest mode, we advance the "open
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * txg" without actually spa_sync()-ing the changes to
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * disk. So we would see that object N is still
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * allocated and in the unlinked set, and there is an
55da60b91d96984f12de050ce428373ea25c7f35Mark J Musante * intent log record saying to allocate it.
f9af39bacaaa0f9dda3b75ff6858b9f3988a39afGeorge Wilson if (spa_writeable(dmu_objset_spa(zfsvfs->z_os))) {
f18faf3f3e5def85fdfff681617d227703ace2adek zfsvfs->z_vfs->vfs_flag |= readonly; /* restore readonly bit */
90f2c094b3822f4825f21cef2c2faf7d03b55139Andriy Gapon * Set the objset user_ptr to track its zfsvfs.
f18faf3f3e5def85fdfff681617d227703ace2adek return (0);
4e9583b23260dab68308b306795694143381ab0fTom Erickson extern krwlock_t zfsvfs_lock; /* in zfs_znode.c */
4e9583b23260dab68308b306795694143381ab0fTom Erickson * This is a barrier to prevent the filesystem from going away in
4e9583b23260dab68308b306795694143381ab0fTom Erickson * zfs_znode_move() until we can safely ensure that the filesystem is
4e9583b23260dab68308b306795694143381ab0fTom Erickson * not unmounted. We consider the filesystem valid before the barrier
4e9583b23260dab68308b306795694143381ab0fTom Erickson * and invalid after the barrier.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens for (i = 0; i != ZFS_OBJ_MTX_SZ; i++)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens zfsvfs->z_use_fuids = USE_FUIDS(zfsvfs->z_version, zfsvfs->z_os);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_set_feature(zfsvfs->z_vfs, VFSFT_XVATTR);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_set_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_set_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_set_feature(zfsvfs->z_vfs, VFSFT_REPARSE);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_clear_feature(zfsvfs->z_vfs, VFSFT_XVATTR);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_clear_feature(zfsvfs->z_vfs, VFSFT_SYSATTR_VIEWS);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACEMASKONACCESS);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACLONCREATE);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_clear_feature(zfsvfs->z_vfs, VFSFT_ACCESS_FILTER);
44bffe012cad6481c82ad67bacd6b40bd29def2bMark Shellenbaum vfs_clear_feature(zfsvfs->z_vfs, VFSFT_REPARSE);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum zfsvfs->z_use_sa = USE_SA(zfsvfs->z_version, zfsvfs->z_os);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /* Initialize the generic filesystem structure. */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (error = dsl_prop_get_integer(osname, "recordsize", &recordsize,
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * The fsid is 64 bits, composed of an 8-bit fs type, which
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * separates our fsid from any other filesystem types, and a
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * 56-bit objset unique ID. The objset unique ID is unique to
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * all objsets open on this system, provided by unique_create().
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * The 8-bit fs type must be put in the low bits of fsid[1]
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens * because that's where other Solaris filesystems put it.
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens fsid_guid = dmu_objset_fsid_guid(zfsvfs->z_os);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens vfsp->vfs_fsid.val[1] = ((fsid_guid>>32) << 8) |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Set features for file system.
c242f9a02a2ef021449275ae0a1d2581ee77231dchunli zhang - Sun Microsystems - Irvine United States vfs_set_feature(vfsp, VFSFT_ZEROCOPY_SUPPORTED);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (error = dsl_prop_get_integer(osname, "xattr", &pval, NULL))
503ad85c168c7992ccc310af845a581cff3c72b5Matthew Ahrens mutex_enter(&zfsvfs->z_os->os_user_ptr_lock);
03bad06fbb261fd4a7151a70dfeff2f5041cce1fJustin Gibbs dsl_prop_unregister_all(dmu_objset_ds(os), zfsvfs);
b1b8ab34de515a5e83206da22c3d7e563241b021lling * Convert a decimal digit string to a uint64_t integer.
b1b8ab34de515a5e83206da22c3d7e563241b021lling while (*str) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (0);
b1b8ab34de515a5e83206da22c3d7e563241b021lling * The boot path passed from the boot loader is in the form of
b1b8ab34de515a5e83206da22c3d7e563241b021lling * "rootpool-name/root-filesystem-object-number'. Convert this
b1b8ab34de515a5e83206da22c3d7e563241b021lling * string to a dataset name: "rootpool-name/root-filesystem-name".
b1b8ab34de515a5e83206da22c3d7e563241b021lling /* if no '/', just return the pool name */
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (0);
193974072f41a843678abf5f61979c748687e66bSherry Moore /* if not a number, just return the root dataset name */
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * Check that the hex label string is appropriate for the dataset being
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * mounted into the global_zone proper.
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * Return an error if the hex label string is not default or
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * admin_low/admin_high. For admin_low labels, the corresponding
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * dataset must be readonly.
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshirezfs_check_global_label(const char *dsname, const char *hexsl)
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire if (strcasecmp(hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire /* must be readonly */
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire zfs_prop_to_name(ZFS_PROP_READONLY), &rdonly, NULL))
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * Determine whether the mount is allowed according to MAC check.
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * by comparing (where appropriate) label of the dataset against
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * the label of the zone being mounted into. If the dataset has
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * no label, create one.
f7170741490edba9d1d9c697c177c887172bc741Will Andrews * Returns 0 if access allowed, error otherwise (e.g. EACCES)
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshirezfs_mount_label_policy(vfs_t *vfsp, char *osname)
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * Start by getting the dataset label if it exists.
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire error = dsl_prop_get(osname, zfs_prop_to_name(ZFS_PROP_MLSLABEL),
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * If labeling is NOT enabled, then disallow the mount of datasets
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * which have a non-default label already. No other label checks
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * are needed.
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0)
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * Get the label of the mountpoint. If mounting into the global
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * zone (i.e. mountpoint is not within an active zone and the
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * zoned property is off), the label must be default or
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * admin_low/admin_high only; no other checks are needed.
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire mntzone = zone_find_by_any_path(refstr_value(vfsp->vfs_mntpt), B_FALSE);
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire zfs_prop_to_name(ZFS_PROP_ZONED), &zoned, NULL))
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire return (zfs_check_global_label(osname, ds_hexsl));
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * This is the case of a zone dataset being mounted
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * initially, before the zone has been fully created;
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * allow this mount into global zone.
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) == 0) {
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * The dataset doesn't have a real label, so fabricate one.
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire } else if (hexstr_to_label(ds_hexsl, &ds_sl) == 0) {
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * Now compare labels to complete the MAC check. If the
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * labels are equal then allow access. If the mountpoint
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * label dominates the dataset label, allow readonly access.
4201a95e0468170d576f82c3aa63afecf718497aRic Aleshire * Otherwise, access is denied.
b1b8ab34de515a5e83206da22c3d7e563241b021lling * The filesystem that we mount as root is defined in the
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw * boot property "zfs-bootfs" with a format of
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw * the process of doing a spa_load will require the
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw * clock to be set before we could (for example) do
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw * something better by looking at the timestamp on
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw * an uberblock, so just set it to -1.
051aabe6136ff13e81542a427e9693ffe1503525taylor if ((zfs_bootfs = spa_get_bootprop("zfs-bootfs")) == NULL) {
051aabe6136ff13e81542a427e9693ffe1503525taylor "bootfs name");
051aabe6136ff13e81542a427e9693ffe1503525taylor error = spa_import_rootpool(rootfs.bo_name, zfs_devid);
e7cbe64f7a72dae5cb44f100db60ca88f3313c65gw if (error = zfs_parse_bootfs(zfs_bootfs, rootfs.bo_name)) {
40d3dfe15f0068009eaddacc3ded2afa9c994fa0marks * Leave rootvp held. The root file system is never unmounted.
b510d37840323dfb912eab2c7f56325938ed47adlling /* refresh mount options */
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock zfs_unregister_callbacks((zfsvfs_t *)vfsp->vfs_data);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock return (0);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * if "why" is equal to anything else other than ROOT_INIT,
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * ROOT_REMOUNT, or ROOT_UNMOUNT, we do not support it.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock/*ARGSUSED*/
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrockzfs_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * ZFS does not support passing unparsed data in via MS_DATA.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Users should use the MS_OPTIONSTR interface; this means
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * that all option parsing is already done and the options struct
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * can be interrogated.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Get the objset name (the "special" mount argument).
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks * Check for mount privilege?
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks * If we don't have privilege then see if
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks * we have local permission to allow it
98679b5614193e2e84c0b9fed6d7c0e92bc35509Mark Shellenbaum if (dsl_deleg_access(osname, ZFS_DELEG_PERM_MOUNT, cr) == 0) {
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks * Make sure user is the owner of the mount point
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks * or has sufficient privileges.
98679b5614193e2e84c0b9fed6d7c0e92bc35509Mark Shellenbaum if (VOP_GETATTR(mvp, &vattr, 0, cr, NULL)) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * Refuse to mount a filesystem if we are in a local zone and the
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock * dataset is not visible.
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock (!zone_dataset_visible(osname, &canwrite) || !canwrite)) {
b510d37840323dfb912eab2c7f56325938ed47adlling * When doing a remount, we simply refresh our temporary properties
b510d37840323dfb912eab2c7f56325938ed47adlling * according to those options set in the current VFS options.
b510d37840323dfb912eab2c7f56325938ed47adlling /* refresh mount options */
142ae85d92129bf4eed1eb71b99a957379f6083aChris Kirby * Add an extra VFS_HOLD on our parent vfs so that it can't
142ae85d92129bf4eed1eb71b99a957379f6083aChris Kirby * disappear due to a forced unmount.
984a131b733dcb12000748fcfcda5cac286ac00aChris Kirby if (error == 0 && ((zfsvfs_t *)vfsp->vfs_data)->z_issnap)
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The underlying storage pool actually uses multiple block sizes.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We report the fragsize as the smallest block size we support,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and we report our blocksize as the filesystem's maximum blocksize.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The following report "total" blocks of various kinds in the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file system, but reported in terms of f_frsize - the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * "fragment" size.
a2eea2e101e6a163a537dcc6d4e3c4da2a0ea5b2ahrens statp->f_blocks = (refdbytes + availbytes) >> SPA_MINBLOCKSHIFT;
fa9e4066f08beec538e775443c5be79dd423fcabahrens statp->f_bavail = statp->f_bfree; /* no root reservation */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * statvfs() should really be called statufs(), because it assumes
fa9e4066f08beec538e775443c5be79dd423fcabahrens * static metadata. ZFS doesn't preallocate files, so the best
fa9e4066f08beec538e775443c5be79dd423fcabahrens * we can do is report the max that could possibly fit in f_files,
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and that minus the number actually used in f_ffree.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * For f_ffree, report the smaller of the number of object available
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and the number of blocks (each object will take at least a block).
fa9e4066f08beec538e775443c5be79dd423fcabahrens statp->f_favail = statp->f_ffree; /* no "root reservation" */
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We're a zfs filesystem.
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) strcpy(statp->f_basetype, vfssw[vfsp->vfs_fstype].vsw_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * We have all of 32 characters to stuff a string here.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Is there anything useful we could/should provide?
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
f18faf3f3e5def85fdfff681617d227703ace2adek * Teardown the zfsvfs::z_os.
eb721827677c553ce8dd0d4390630a857f923f98Alek Pinchuk * Note, if 'unmounting' is FALSE, we return with the 'z_teardown_lock'
f18faf3f3e5def85fdfff681617d227703ace2adek * and 'z_teardown_inactive_lock' held.
c9030f6c93613fe30ee0c16f92b96da7816ac052Alexander Motin rrm_enter(&zfsvfs->z_teardown_lock, RW_WRITER, FTAG);
f18faf3f3e5def85fdfff681617d227703ace2adek * We purge the parent filesystem's vfsp as the parent
f18faf3f3e5def85fdfff681617d227703ace2adek * filesystem and all of its snapshots have their vnode's
f18faf3f3e5def85fdfff681617d227703ace2adek * v_vfsp set to the parent's filesystem's vfsp. Note,
f18faf3f3e5def85fdfff681617d227703ace2adek * 'z_parent' is self referential for non-snapshots.
f18faf3f3e5def85fdfff681617d227703ace2adek * Close the zil. NB: Can't close the zil while zfs_inactive
f18faf3f3e5def85fdfff681617d227703ace2adek * threads are blocked as zil_close can call zfs_inactive.
f18faf3f3e5def85fdfff681617d227703ace2adek * If we are not unmounting (ie: online recv) and someone already
f18faf3f3e5def85fdfff681617d227703ace2adek * unmounted this file system while we were doing the switcheroo,
f18faf3f3e5def85fdfff681617d227703ace2adek * or a reopen of z_os failed then just bail out now.
f18faf3f3e5def85fdfff681617d227703ace2adek if (!unmounting && (zfsvfs->z_unmounted || zfsvfs->z_os == NULL)) {
f18faf3f3e5def85fdfff681617d227703ace2adek * At this point there are no vops active, and any new vops will
f18faf3f3e5def85fdfff681617d227703ace2adek * fail with EIO since we have z_teardown_lock for writer (only
f18faf3f3e5def85fdfff681617d227703ace2adek * relavent for forced unmount).
f18faf3f3e5def85fdfff681617d227703ace2adek * Release all holds on dbufs.
874395d5f8cae2b9cd2d1fcbfcfe963a0c23966dmaybee for (zp = list_head(&zfsvfs->z_all_znodes); zp != NULL;
f18faf3f3e5def85fdfff681617d227703ace2adek * If we are unmounting, set the unmounted flag and let new vops
f18faf3f3e5def85fdfff681617d227703ace2adek * unblock. zfs_inactive will have the unmounted behavior, and all
f18faf3f3e5def85fdfff681617d227703ace2adek * other vops will fail with EIO.
f18faf3f3e5def85fdfff681617d227703ace2adek * z_os will be NULL if there was an error in attempting to reopen
f18faf3f3e5def85fdfff681617d227703ace2adek * zfsvfs, so just return as the properties had already been
f18faf3f3e5def85fdfff681617d227703ace2adek * unregistered and cached data had been evicted before.
f18faf3f3e5def85fdfff681617d227703ace2adek return (0);
f18faf3f3e5def85fdfff681617d227703ace2adek * Unregister properties.
f18faf3f3e5def85fdfff681617d227703ace2adek * Evict cached data
2e2c135528b3edfe9aaf67d1f004dc0202fa1a54Matthew Ahrens if (dsl_dataset_is_dirty(dmu_objset_ds(zfsvfs->z_os)) &&
2e2c135528b3edfe9aaf67d1f004dc0202fa1a54Matthew Ahrens txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), 0);
f18faf3f3e5def85fdfff681617d227703ace2adek return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*ARGSUSED*/
98679b5614193e2e84c0b9fed6d7c0e92bc35509Mark Shellenbaum if (dsl_deleg_access((char *)refstr_value(vfsp->vfs_resource),
ed097989586a51afeee476d7fbba56222d447ad8ek * We purge the parent filesystem's vfsp as the parent filesystem
ed097989586a51afeee476d7fbba56222d447ad8ek * and all of its snapshots have their vnode's v_vfsp set to the
ed097989586a51afeee476d7fbba56222d447ad8ek * parent's filesystem's vfsp. Note, 'z_parent' is self
ed097989586a51afeee476d7fbba56222d447ad8ek * referential for non-snapshots.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Unmount any snapshots mounted under .zfs before unmounting the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * dataset itself.
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks (ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0) {
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * Check the number of active vnodes in the file system.
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * Our count is maintained in the vfs structure, but the
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * number is off by 1 to indicate a hold on the vfs
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * structure itself.
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * The '.zfs' directory maintains a reference of its
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * own, and any active references underneath are
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * reflected in the vnode count.
f18faf3f3e5def85fdfff681617d227703ace2adek * z_os will be NULL if there was an error in
f18faf3f3e5def85fdfff681617d227703ace2adek * attempting to reopen zfsvfs.
f18faf3f3e5def85fdfff681617d227703ace2adek * Unset the objset user_ptr.
745cd3c5371d020efae7a911c58c526aa1fd0dbamaybee * Finally release the objset
91ebeef555ce7f899b6270a3c2df47b51f7ad59aahrens * We can now safely destroy the '.zfs' directory node.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens objsetid |= ((uint64_t)zlfid->zf_setid[i]) << (8 * i);
fa9e4066f08beec538e775443c5be79dd423fcabahrens setgen |= ((uint64_t)zlfid->zf_setgen[i]) << (8 * i);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (fidp->fid_len == SHORT_FID_LEN || fidp->fid_len == LONG_FID_LEN) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* A zero fid_gen means we are in the .zfs control directories */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (object == ZFSCTL_INO_ROOT || object == ZFSCTL_INO_SNAPDIR)) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens VERIFY(zfsctl_root_lookup(*vpp, "snapshot", vpp, NULL,
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens dprintf("getting %llu [%u mask %llx]\n", object, fid_gen, gen_mask);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zfsvfs), &zp_gen,
fa9e4066f08beec538e775443c5be79dd423fcabahrens dprintf("znode gen (%u) != fid gen (%u)\n", zp_gen, fid_gen);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
f18faf3f3e5def85fdfff681617d227703ace2adek * Block out VOPs and close zfsvfs_t::z_os
f18faf3f3e5def85fdfff681617d227703ace2adek * Note, if successful, then we return with the 'z_teardown_lock' and
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * 'z_teardown_inactive_lock' write held. We leave ownership of the underlying
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * dataset and objset intact so that they can be atomically handed off during
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * a subsequent rollback or recv operation and the resume thereafter.
f18faf3f3e5def85fdfff681617d227703ace2adek return (0);
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * Rebuild SA and release VOPs. Note that ownership of the underlying dataset
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * is an invariant across any of the operations that can be performed while the
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * filesystem was suspended. Whether it succeeded or failed, the preconditions
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * are the same: the relevant objset and associated dataset are owned by
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * zfsvfs, held, and long held on entry.
690041b9caf801816f2d0bac90bc7cecefb73523Andriy Gaponzfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
c9030f6c93613fe30ee0c16f92b96da7816ac052Alexander Motin ASSERT(RRM_WRITE_HELD(&zfsvfs->z_teardown_lock));
f18faf3f3e5def85fdfff681617d227703ace2adek ASSERT(RW_WRITE_HELD(&zfsvfs->z_teardown_inactive_lock));
690041b9caf801816f2d0bac90bc7cecefb73523Andriy Gapon * We already own this, so just update the objset_t, as the one we
690041b9caf801816f2d0bac90bc7cecefb73523Andriy Gapon * had before may have been evicted.
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski VERIFY(zfsvfs_setup(zfsvfs, B_FALSE) == 0);
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * Attempt to re-establish all the active znodes with
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * their dbufs. If a zfs_rezget() fails, then we'll let
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * any potential callers discover that via ZFS_ENTER_VERIFY_VP
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * when they try to use their znode.
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski for (zp = list_head(&zfsvfs->z_all_znodes); zp;
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski zp = list_next(&zfsvfs->z_all_znodes, zp)) {
f18faf3f3e5def85fdfff681617d227703ace2adek /* release the VOPs */
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * Since we couldn't setup the sa framework, try to force
91948b51b8e978ddc88a36b2bc3ae83c20cdc9aaKeith M Wesolowski * unmount this file system.
142ae85d92129bf4eed1eb71b99a957379f6083aChris Kirby * If this is a snapshot, we have an extra VFS_HOLD on our parent
f80ce222af313ec87dc070b2219b29c81c5e5d8cChris Kirby * from zfs_mount(). Release it here. If we came through
f80ce222af313ec87dc070b2219b29c81c5e5d8cChris Kirby * zfs_mountroot() instead, we didn't grab an extra hold, so
f80ce222af313ec87dc070b2219b29c81c5e5d8cChris Kirby * skip the VFS_RELE for rootvfs.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * VFS_INIT() initialization. Note that there is no VFS_FINI(),
fa9e4066f08beec538e775443c5be79dd423fcabahrens * so we can't safely do any non-idempotent initialization here.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Leave that to zfs_init() and zfs_fini(), which are called
fa9e4066f08beec538e775443c5be79dd423fcabahrens * from the module's _init() and _fini() entry points.
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*ARGSUSED*/
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Setup vfsops and vnodeops tables.
fa9e4066f08beec538e775443c5be79dd423fcabahrens error = vfs_setfsops(fstype, zfs_vfsops_template, &zfs_vfsops);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (error != 0) {
a0965f35d4137b1f6bb1655ae1cb8fee88dfa66fbonwick * Unique major number for all zfs mounts.
a0965f35d4137b1f6bb1655ae1cb8fee88dfa66fbonwick * If we run out of 32-bit minors, we'll getudev() another major.
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (0);
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize .zfs directory structures
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Initialize znode cache, vnode ops, etc...
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens dmu_objset_register_type(DMU_OST_ZFS, zfs_space_delta_cb);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrenszfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers)
e7437265dc2a4920c197ed4337665539d358b22cahrens if (newvers < ZPL_VERSION_INITIAL || newvers > ZPL_VERSION)
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_FALSE, ZPL_VERSION_STR);
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (newvers >= ZPL_VERSION_SA && !zfsvfs->z_use_sa) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, B_TRUE,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
148434217c040ea38dc844384f6ba68d9b325906Matthew Ahrens error = zap_update(os, MASTER_NODE_OBJ, ZPL_VERSION_STR,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum if (newvers >= ZPL_VERSION_SA && !zfsvfs->z_use_sa) {
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum ASSERT3U(spa_version(dmu_objset_spa(zfsvfs->z_os)), >=,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum sa_obj = zap_create(os, DMU_OT_SA_MASTER_NODE,
0a586cea3ceec7e5e50e7e54c745082a7a333ac2Mark Shellenbaum sa_register_update_callback(os, zfs_sa_upgrade);
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens spa_history_log_internal_ds(dmu_objset_ds(os), "upgrade", tx,
4445fffbbb1ea25fd0e9ea68b9380dd7a6709025Matthew Ahrens "from %llu to %llu", zfsvfs->z_version, newvers);
de8267e0f723ed2c38ea9def92d465f69a300f56timh * Read a property stored within the master node.
de8267e0f723ed2c38ea9def92d465f69a300f56timhzfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value)
de8267e0f723ed2c38ea9def92d465f69a300f56timh * Look up the file system's value for the property. For the
de8267e0f723ed2c38ea9def92d465f69a300f56timh * version property, we look up a slightly different string.
0a48a24e663a04e34e2ed4e55390ad96f178dbeatimh error = zap_lookup(os, MASTER_NODE_OBJ, pname, 8, 1, value);
de8267e0f723ed2c38ea9def92d465f69a300f56timh /* No value set, use the default value */
de8267e0f723ed2c38ea9def92d465f69a300f56timh switch (prop) {
eb721827677c553ce8dd0d4390630a857f923f98Alek Pinchuk * Return true if the coresponding vfs's unmounted flag is set.
eb721827677c553ce8dd0d4390630a857f923f98Alek Pinchuk * Otherwise return false.
eb721827677c553ce8dd0d4390630a857f923f98Alek Pinchuk * If this function returns true we know VFS unmount has been initiated.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw VSW_HASPROTO|VSW_CANRWRO|VSW_CANREMOUNT|VSW_VOLATILEDEV|VSW_STATS|
e7437265dc2a4920c197ed4337665539d358b22cahrens &mod_fsops, "ZFS filesystem version " SPA_VERSION_STRING, &vfw